@kalyptos/narcissus 0.2.0 → 0.2.1

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.
@@ -116,7 +116,7 @@ function S(e, t, n, r) {
116
116
  }
117
117
  //#endregion
118
118
  //#region src/engine/gpu/masks.ts
119
- var C = 8, w = 3e38, T = class {
119
+ var C = 8, w = 3e38, T = 4, E = class {
120
120
  layout;
121
121
  #e;
122
122
  #t;
@@ -129,8 +129,9 @@ var C = 8, w = 3e38, T = class {
129
129
  0
130
130
  ];
131
131
  #o = [];
132
+ #s = null;
132
133
  constructor(e) {
133
- this.#e = e, this.layout = x(e, "masks", GPUShaderStage.COMPUTE, ["read-only-storage"]), this.#t = this.#s(64);
134
+ this.#e = e, this.layout = x(e, "masks", GPUShaderStage.COMPUTE, ["read-only-storage"]), this.#t = this.#c(64);
134
135
  }
135
136
  get group() {
136
137
  return this.#n ??= S(this.#e, "masks", this.layout, [this.#t]);
@@ -151,20 +152,21 @@ var C = 8, w = 3e38, T = class {
151
152
  targets: t,
152
153
  enabled: !0,
153
154
  area: r
154
- }), this.#i;
155
+ }), this.#s = null, this.#i;
155
156
  }
156
157
  enable(e, t) {
157
158
  let n = this.#r.get(e);
158
159
  n && (n.enabled = t);
159
160
  }
160
161
  delete(e) {
161
- this.#r.delete(e);
162
+ this.#r.delete(e) && (this.#s = null);
162
163
  }
163
164
  area(e) {
164
165
  return this.#r.get(e)?.area;
165
166
  }
166
167
  relate(e, t, n, r) {
167
- for (let [i, { prism: a, targets: o, enabled: s, area: c }] of this.#r) {
168
+ for (let i of (this.#s ??= new D(this.#r)).near(t, n)) {
169
+ let { prism: a, targets: o, enabled: s, area: c } = this.#r.get(i);
168
170
  if (!s || !o.has(e) || n[0] < c[0] || n[1] < c[1] || t[0] > c[2] || t[1] > c[3]) continue;
169
171
  let l = y(a, t, n);
170
172
  if (l === 1) return !0;
@@ -195,19 +197,55 @@ var C = 8, w = 3e38, T = class {
195
197
  o.set(e, c++);
196
198
  }
197
199
  for (let n = 0; n < e.length; n++) t[s + n] = o.get(e[n]) ?? 0;
198
- t.byteLength > this.#t.size && (this.#t.destroy(), this.#t = this.#s(t.byteLength), this.#n = null), t.length && this.#e.queue.writeBuffer(this.#t, 0, t);
200
+ t.byteLength > this.#t.size && (this.#t.destroy(), this.#t = this.#c(t.byteLength), this.#n = null), t.length && this.#e.queue.writeBuffer(this.#t, 0, t);
199
201
  }
200
202
  destroy() {
201
203
  this.#t.destroy();
202
204
  }
203
- #s(e) {
205
+ #c(e) {
204
206
  return this.#e.createBuffer({
205
207
  label: "masks",
206
208
  size: Math.max(256, 2 ** Math.ceil(Math.log2(e))),
207
209
  usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST
208
210
  });
209
211
  }
210
- }, E = 19, D = 23, O = 7, k = 11, A = [], j = 1024, M = class {
212
+ }, D = class {
213
+ #e;
214
+ #t;
215
+ #n = /* @__PURE__ */ new Map();
216
+ #r = [];
217
+ constructor(e) {
218
+ this.#e = [...e.keys()];
219
+ let t = [...e.values()].map(({ area: e }) => Math.max(e[2] - e[0], e[3] - e[1])).sort((e, t) => e - t);
220
+ this.#t = Math.max(t[t.length >> 1] ?? 1, .001);
221
+ for (let [t, { area: n }] of e) {
222
+ let [e, r, i, a] = O(n[0], n[1], n[2], n[3], this.#t);
223
+ if (i - e >= T || a - r >= T) this.#r.push(t);
224
+ else for (let n = e; n <= i; n++) for (let e = r; e <= a; e++) {
225
+ let r = this.#n.get(`${n},${e}`);
226
+ r ? r.push(t) : this.#n.set(`${n},${e}`, [t]);
227
+ }
228
+ }
229
+ }
230
+ near(e, t) {
231
+ let [n, r, i, a] = O(e[0], e[1], t[0], t[1], this.#t);
232
+ if ((i - n + 1) * (a - r + 1) > this.#e.length) return this.#e;
233
+ let o = new Set(this.#r);
234
+ for (let e = n; e <= i; e++) for (let t = r; t <= a; t++) for (let n of this.#n.get(`${e},${t}`) ?? []) o.add(n);
235
+ return o;
236
+ }
237
+ };
238
+ function O(e, t, n, r, i) {
239
+ return [
240
+ Math.floor(e / i),
241
+ Math.floor(t / i),
242
+ Math.floor(n / i),
243
+ Math.floor(r / i)
244
+ ];
245
+ }
246
+ //#endregion
247
+ //#region src/engine/gpu/pool.ts
248
+ var k = 19, A = 23, j = 7, M = 11, N = [], ee = 1024, te = class {
211
249
  #e = [];
212
250
  mark(e, t) {
213
251
  this.#e.push([e, t]);
@@ -220,11 +258,11 @@ var C = 8, w = 3e38, T = class {
220
258
  this.#e = [];
221
259
  for (let i = 0; i < r.length;) {
222
260
  let a = r[i][0], o = r[i++][1];
223
- for (; i < r.length && r[i][0] <= o + j;) o = Math.max(o, r[i++][1]);
261
+ for (; i < r.length && r[i][0] <= o + ee;) o = Math.max(o, r[i++][1]);
224
262
  e.writeBuffer(t, a * 4, n, a, o - a);
225
263
  }
226
264
  }
227
- }, ee = class {
265
+ }, ne = class {
228
266
  geometry;
229
267
  colour;
230
268
  pages;
@@ -249,25 +287,26 @@ var C = 8, w = 3e38, T = class {
249
287
  ];
250
288
  #u;
251
289
  #d;
252
- #f = new M();
290
+ #f = new te();
253
291
  #p;
254
292
  #m;
255
- #h = new M();
293
+ #h = new te();
256
294
  #g;
257
295
  #_ = [];
258
296
  #v;
259
297
  #y;
260
298
  #b = !1;
299
+ #x = null;
261
300
  constructor(e, t) {
262
- this.capacity = t, this.masks = new T(e), this.#e = e;
301
+ this.capacity = t, this.masks = new E(e), this.#e = e;
263
302
  let n = this.slots;
264
- this.#S(), this.#a = new Uint8Array(n), this.#o = n, this.#c = Array.from({ length: n }, (e, t) => n - 1 - t), this.#u = new Uint32Array(n * 36), this.#d = new Float32Array(this.#u.buffer), this.#p = new Uint32Array(n * 12), this.#m = new Float32Array(this.#p.buffer), this.#g = new Uint32Array(n), this.#v = new Uint8Array(n), this.#y = Array(n).fill(A);
303
+ this.#w(), this.#a = new Uint8Array(n), this.#o = n, this.#c = Array.from({ length: n }, (e, t) => n - 1 - t), this.#u = new Uint32Array(n * 36), this.#d = new Float32Array(this.#u.buffer), this.#p = new Uint32Array(n * 12), this.#m = new Float32Array(this.#p.buffer), this.#g = new Uint32Array(n), this.#v = new Uint8Array(n), this.#y = Array(n).fill(N);
265
304
  }
266
305
  get slots() {
267
306
  return this.capacity / 256;
268
307
  }
269
308
  get bytes() {
270
- return this.#x().reduce((e, t) => e + t.size, 0);
309
+ return this.#C().reduce((e, t) => e + t.size, 0);
271
310
  }
272
311
  has(e) {
273
312
  let t = this.#t.get(e);
@@ -282,13 +321,13 @@ var C = 8, w = 3e38, T = class {
282
321
  add(t, n, r, i, a = 0) {
283
322
  if (this.#t.has(t)) return !0;
284
323
  let o = d(n.count) / 256;
285
- if (!this.#T(o, i)) return !1;
324
+ if (!this.#D(o, i)) return !1;
286
325
  let s = e.origin, c = {
287
326
  id: t,
288
327
  previous: null,
289
328
  next: null,
290
329
  page: n,
291
- slots: this.#N(o),
330
+ slots: this.#F(o),
292
331
  active: [],
293
332
  mask: 0,
294
333
  table: this.#c.pop(),
@@ -300,14 +339,14 @@ var C = 8, w = 3e38, T = class {
300
339
  factors: 0,
301
340
  layer: a
302
341
  };
303
- return this.#t.set(t, c), this.#w(c), this.#i.add(t), !0;
342
+ return this.#t.set(t, c), this.#E(c), this.#i.add(t), !0;
304
343
  }
305
344
  remove(e) {
306
345
  let t = this.#t.get(e);
307
346
  if (t) {
308
- this.#C(t), this.#t.delete(e), this.#i.delete(e);
309
- for (let e of t.slots) this.#a[e] = 0, this.#v[e] = 0, this.#y[e].length && (this.#b = !0), this.#y[e] = A;
310
- this.#s = Math.min(this.#s, t.slots[0]), this.#o += t.slots.length, this.#c.push(t.table), t.page === null && t.factors !== 0 && this.#O(t, 0);
347
+ this.#T(t), this.#t.delete(e), this.#i.delete(e);
348
+ for (let e of t.slots) this.#a[e] = 0, this.#v[e] = 0, this.#y[e].length && (this.#b = !0), this.#y[e] = N;
349
+ this.#s = Math.min(this.#s, t.slots[0]), this.#o += t.slots.length, this.#c.push(t.table), t.page === null && t.factors !== 0 && this.#A(t, 0);
311
350
  }
312
351
  }
313
352
  clear() {
@@ -320,19 +359,20 @@ var C = 8, w = 3e38, T = class {
320
359
  let t = 0;
321
360
  for (let n of this.#i) {
322
361
  if (t >= e) break;
323
- t += this.#E(this.#t.get(n)), this.#i.delete(n);
362
+ t += this.#O(this.#t.get(n)), this.#i.delete(n);
324
363
  }
325
364
  return t;
326
365
  }
327
366
  draw(e) {
367
+ this.#x &&= (this.#j(this.#x), null);
328
368
  let t = 0, n = 0, r = !1;
329
369
  for (let { id: i, factors: a } of e) {
330
370
  let e = this.#t.get(i);
331
371
  if (!e || e.page !== null) continue;
332
372
  let o = e.active;
333
- (e.factors !== a || e.mask < 0) && this.#O(e, a), r ||= o !== e.active, this.#w(e), r ||= this.#_[n] !== e, this.#_[n++] = e, r && this.#g.set(e.active, t), t += e.active.length;
373
+ (e.factors !== a || e.mask < 0) && this.#A(e, a), r ||= o !== e.active, this.#E(e), r ||= this.#_[n] !== e, this.#_[n++] = e, r && this.#g.set(e.active, t), t += e.active.length;
334
374
  }
335
- r ||= this.#_.length !== n, this.#_.length = n, this.listed = t, this.#b && this.#M();
375
+ r ||= this.#_.length !== n, this.#_.length = n, this.listed = t, this.#b && this.#P();
336
376
  let i = this.#e.queue;
337
377
  this.#f.flush(i, this.pages, this.#u), this.#h.flush(i, this.clusters, this.#p), r && t && i.writeBuffer(this.list, 0, this.#g, 0, t);
338
378
  }
@@ -342,26 +382,35 @@ var C = 8, w = 3e38, T = class {
342
382
  e[1],
343
383
  e[2]
344
384
  ];
345
- for (let e of this.#t.values()) e.page === null && this.#D(e);
385
+ for (let e of this.#t.values()) e.page === null && this.#k(e);
346
386
  this.#e.queue.writeBuffer(this.pages, 0, this.#u), this.#f.clear(), this.masks.setOrigin(this.#l), this.masks.size && this.masks.write();
347
387
  }
348
388
  addMask(e, t) {
349
389
  let n = this.masks.add(e, t);
350
- return this.#k(this.masks.area(n)), n;
390
+ return this.#S(this.masks.area(n)), n;
351
391
  }
352
392
  enableMask(e, t) {
353
- this.masks.enable(e, t), this.#k(this.masks.area(e));
393
+ this.masks.enable(e, t), this.#S(this.masks.area(e));
354
394
  }
355
395
  deleteMask(e) {
356
396
  let t = this.masks.area(e);
357
- this.masks.delete(e), this.#k(t);
397
+ this.masks.delete(e), this.#S(t);
398
+ }
399
+ #S(e) {
400
+ let t = this.#x ??= [
401
+ Infinity,
402
+ Infinity,
403
+ -Infinity,
404
+ -Infinity
405
+ ];
406
+ t[0] = Math.min(t[0], e[0]), t[1] = Math.min(t[1], e[1]), t[2] = Math.max(t[2], e[2]), t[3] = Math.max(t[3], e[3]);
358
407
  }
359
408
  grow(e) {
360
409
  if (e <= this.capacity) return;
361
- let t = this.slots, n = this.#x();
362
- this.capacity = e, this.#S();
410
+ let t = this.slots, n = this.#C();
411
+ this.capacity = e, this.#w();
363
412
  let r = this.#e.createCommandEncoder({ label: "pool grow" });
364
- this.#x().forEach((e, t) => r.copyBufferToBuffer(n[t], 0, e, 0, n[t].size)), this.#e.queue.submit([r.finish()]);
413
+ this.#C().forEach((e, t) => r.copyBufferToBuffer(n[t], 0, e, 0, n[t].size)), this.#e.queue.submit([r.finish()]);
365
414
  for (let e of n) e.destroy();
366
415
  let i = this.slots, a = new Uint8Array(i);
367
416
  a.set(this.#a), this.#a = a, this.#o += i - t;
@@ -374,13 +423,13 @@ var C = 8, w = 3e38, T = class {
374
423
  c.set(this.#g), this.#g = c;
375
424
  let l = new Uint8Array(i);
376
425
  l.set(this.#v), this.#v = l;
377
- for (let e = t; e < i; e++) this.#y.push(A);
426
+ for (let e = t; e < i; e++) this.#y.push(N);
378
427
  }
379
428
  destroy() {
380
- for (let e of this.#x()) e.destroy();
429
+ for (let e of this.#C()) e.destroy();
381
430
  this.masks.destroy();
382
431
  }
383
- #x() {
432
+ #C() {
384
433
  return [
385
434
  this.geometry,
386
435
  this.colour,
@@ -389,7 +438,7 @@ var C = 8, w = 3e38, T = class {
389
438
  this.list
390
439
  ];
391
440
  }
392
- #S() {
441
+ #w() {
393
442
  let { capacity: e, slots: t } = this, n = GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC, r = (e, t) => this.#e.createBuffer({
394
443
  label: e,
395
444
  size: t,
@@ -397,13 +446,13 @@ var C = 8, w = 3e38, T = class {
397
446
  });
398
447
  this.geometry = r("pool geometry", e * 4 * 4), this.colour = r("pool colour", e * 3 * 4), this.pages = r("pool pages", t * 36 * 4), this.clusters = r("pool clusters", t * 12 * 4), this.list = r("pool list", t * 4);
399
448
  }
400
- #C(e) {
449
+ #T(e) {
401
450
  e.previous ? e.previous.next = e.next : this.#n === e && (this.#n = e.next), e.next ? e.next.previous = e.previous : this.#r === e && (this.#r = e.previous), e.previous = null, e.next = null;
402
451
  }
403
- #w(e) {
404
- this.#r !== e && (this.#C(e), e.previous = this.#r, this.#r ? this.#r.next = e : this.#n = e, this.#r = e);
452
+ #E(e) {
453
+ this.#r !== e && (this.#T(e), e.previous = this.#r, this.#r ? this.#r.next = e : this.#n = e, this.#r = e);
405
454
  }
406
- #T(e, t) {
455
+ #D(e, t) {
407
456
  let n = this.#o;
408
457
  if (n >= e) return !0;
409
458
  let r = [];
@@ -412,7 +461,7 @@ var C = 8, w = 3e38, T = class {
412
461
  for (let e of r) this.remove(e);
413
462
  return !0;
414
463
  }
415
- #E(t) {
464
+ #O(t) {
416
465
  let n = t.page, { slots: r } = t, i = this.#e.queue, a = r.length, o = this.#p, s = this.#m;
417
466
  for (let e = 0; e < a; e++) {
418
467
  let i = r[e] * 12;
@@ -426,13 +475,13 @@ var C = 8, w = 3e38, T = class {
426
475
  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.#h.mark(r[e] * 12, (r[e] + t) * 12), e += t;
427
476
  }
428
477
  let c = t.table * 36, l = this.#u, u = this.#d, d = n.params, [f, p, m] = n.quadrants;
429
- return l.fill(0, c, c + 36), this.#D(t), l[c + 3] = n.count, u.set(d.subarray(e.step, e.step + 3), c + 4), l[c + 7] = f, u.set(d.subarray(e.scaleMin, e.scaleMin + 3), c + 8), l[c + 11] = p, u.set(d.subarray(e.scaleMax, e.scaleMax + 3), c + 12), l[c + 15] = m, u.set(d.subarray(e.dcMin, e.dcMin + 3), c + 16), u.set(d.subarray(e.dcMax, e.dcMax + 3), c + 20), l[c + D] = t.layer, u.set(d.subarray(e.shScale, e.shScale + 9), c + 24), this.#f.mark(c, c + 36), t.page = null, this.masks.size && this.#j(t), n.count * 7 * 4 + a * 12 * 4 + 144;
478
+ return l.fill(0, c, c + 36), this.#k(t), l[c + 3] = n.count, u.set(d.subarray(e.step, e.step + 3), c + 4), l[c + 7] = f, u.set(d.subarray(e.scaleMin, e.scaleMin + 3), c + 8), l[c + 11] = p, u.set(d.subarray(e.scaleMax, e.scaleMax + 3), c + 12), l[c + 15] = m, u.set(d.subarray(e.dcMin, e.dcMin + 3), c + 16), u.set(d.subarray(e.dcMax, e.dcMax + 3), c + 20), l[c + A] = t.layer, u.set(d.subarray(e.shScale, e.shScale + 9), c + 24), this.#f.mark(c, c + 36), t.page = null, this.masks.size && this.#N(t), n.count * 7 * 4 + a * 12 * 4 + 144;
430
479
  }
431
- #D(e) {
480
+ #k(e) {
432
481
  let t = e.table * 36;
433
482
  for (let n = 0; n < 3; n++) this.#d[t + n] = e.base[n] - this.#l[n];
434
483
  }
435
- #O(e, t) {
484
+ #A(e, t) {
436
485
  let n = 0;
437
486
  for (let e = 0; e < 4; e++) t >>> 8 * e & 255 && (n |= 1 << e);
438
487
  if (n !== e.mask) {
@@ -450,10 +499,10 @@ var C = 8, w = 3e38, T = class {
450
499
  }
451
500
  }
452
501
  e.factors = t;
453
- let r = e.table * 36 + E;
502
+ let r = e.table * 36 + k;
454
503
  this.#u[r] = t, this.#f.mark(r, r + 1);
455
504
  }
456
- #k(e) {
505
+ #j(e) {
457
506
  let t = [
458
507
  0,
459
508
  0,
@@ -463,14 +512,14 @@ var C = 8, w = 3e38, T = class {
463
512
  0,
464
513
  0
465
514
  ];
466
- for (let r of this.#t.values()) r.page === null && r.slots.some((i) => (this.#A(r, i, t, n), n[0] >= e[0] && n[1] >= e[1] && t[0] <= e[2] && t[1] <= e[3])) && this.#j(r);
515
+ for (let r of this.#t.values()) r.page === null && r.slots.some((i) => (this.#M(r, i, t, n), n[0] >= e[0] && n[1] >= e[1] && t[0] <= e[2] && t[1] <= e[3])) && this.#N(r);
467
516
  this.#b = !0;
468
517
  }
469
- #A(e, t, n, r) {
518
+ #M(e, t, n, r) {
470
519
  let i = this.#m, a = t * 12;
471
520
  for (let t = 0; t < 3; t++) n[t] = e.base[t] + i[a + 4 + t], r[t] = e.base[t] + i[a + 8 + t];
472
521
  }
473
- #j(e) {
522
+ #N(e) {
474
523
  let t = [
475
524
  0,
476
525
  0,
@@ -481,23 +530,23 @@ var C = 8, w = 3e38, T = class {
481
530
  0
482
531
  ];
483
532
  for (let r of e.slots) {
484
- this.#A(e, r, t, n);
533
+ this.#M(e, r, t, n);
485
534
  let i = [], a = +!!this.masks.relate(e.layer, t, n, i), o = this.#y[r];
486
- a !== this.#v[r] && (e.mask = -1), this.#v[r] = a, (o.length || i.length) && (this.#b = !0), this.#y[r] = i.length ? i : A;
535
+ a !== this.#v[r] && (e.mask = -1), this.#v[r] = a, (o.length || i.length) && (this.#b = !0), this.#y[r] = i.length ? i : N;
487
536
  }
488
537
  }
489
- #M() {
538
+ #P() {
490
539
  this.#b = !1;
491
540
  let e = this.#p, t = [], n = this.masks.listBase;
492
541
  for (let r = 0; r < this.#y.length; r++) {
493
542
  let i = this.#y[r], a = r * 12, o = i.length ? n : 0;
494
- (e[a + O] !== o || e[a + k] !== i.length) && (e[a + O] = o, e[a + k] = i.length, this.#h.mark(a, a + 12));
543
+ (e[a + j] !== o || e[a + M] !== i.length) && (e[a + j] = o, e[a + M] = i.length, this.#h.mark(a, a + 12));
495
544
  for (let e of i) t.push(e);
496
545
  n += i.length;
497
546
  }
498
547
  this.masks.write(t);
499
548
  }
500
- #N(e) {
549
+ #F(e) {
501
550
  let t = this.#a, n = -1;
502
551
  for (let r = this.#s; r <= t.length - e;) {
503
552
  let i = r;
@@ -518,7 +567,7 @@ var C = 8, w = 3e38, T = class {
518
567
  };
519
568
  //#endregion
520
569
  //#region src/engine/math/mat4.ts
521
- function te(e, t) {
570
+ function re(e, t) {
522
571
  let n = Math.cos(t);
523
572
  return [
524
573
  Math.sin(e) * n,
@@ -526,30 +575,30 @@ function te(e, t) {
526
575
  Math.sin(t)
527
576
  ];
528
577
  }
529
- function ne(e, t, n, r) {
530
- let [i, a, o] = te(n, r), s = Math.cos(n), c = -Math.sin(n), l = c * o, u = -s * o, d = s * a - c * i;
578
+ function ie(e, t, n, r) {
579
+ let [i, a, o] = re(n, r), s = Math.cos(n), c = -Math.sin(n), l = c * o, u = -s * o, d = s * a - c * i;
531
580
  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;
532
581
  }
533
- function re(e, t, n, r, i) {
582
+ function ae(e, t, n, r, i) {
534
583
  let a = 1 / Math.tan(t / 2);
535
584
  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;
536
585
  }
537
- var ie = /* @__PURE__ */ new Float64Array(16);
538
- function N(e, t, n) {
586
+ var oe = /* @__PURE__ */ new Float64Array(16);
587
+ function P(e, t, n) {
539
588
  for (let e = 0; e < 4; e++) for (let r = 0; r < 4; r++) {
540
589
  let i = 0;
541
590
  for (let a = 0; a < 4; a++) i += t[a * 4 + r] * n[e * 4 + a];
542
- ie[e * 4 + r] = i;
591
+ oe[e * 4 + r] = i;
543
592
  }
544
- return e.set(ie), e;
593
+ return e.set(oe), e;
545
594
  }
546
- function ae(e, t) {
595
+ function se(e, t) {
547
596
  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;
548
597
  if (!A) return null;
549
598
  let j = 1 / A;
550
599
  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;
551
600
  }
552
- function oe(e, t) {
601
+ function ce(e, t) {
553
602
  let [n, r, i] = t;
554
603
  return [
555
604
  e[0] * n + e[4] * r + e[8] * i + e[12],
@@ -560,7 +609,7 @@ function oe(e, t) {
560
609
  }
561
610
  //#endregion
562
611
  //#region src/engine/gpu/common.wgsl?raw
563
- var P = "// 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 // 0 for the world, else the layer that holds the page\n layer: 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 // word in masks.wgsl's buffer of the list of masks that may hide some of its splats\n maskList: u32,\n boxMax: vec3f,\n maskCount: 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", se = "// 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@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)) {\n return;\n }\n atomicStore(&work[WORK_LIST + atomicAdd(&work[WORK_VISIBLE], 1u)], slot);\n}\n", ce = 64, le = class {
612
+ var F = "// 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 // 0 for the world, else the layer that holds the page\n layer: 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 // word in masks.wgsl's buffer of the list of masks that may hide some of its splats\n maskList: u32,\n boxMax: vec3f,\n maskCount: 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", le = "// 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@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)) {\n return;\n }\n atomicStore(&work[WORK_LIST + atomicAdd(&work[WORK_VISIBLE], 1u)], slot);\n}\n", ue = 64, de = class {
564
613
  #e;
565
614
  #t;
566
615
  #n;
@@ -574,7 +623,7 @@ var P = "// shared by every engine pass; sizes and word offsets mirror format/sp
574
623
  "storage"
575
624
  ]), i = e.createShaderModule({
576
625
  label: "cull",
577
- code: `${P}\n${se}`
626
+ code: `${F}\n${le}`
578
627
  });
579
628
  this.#t = e.createComputePipeline({
580
629
  label: "cull",
@@ -598,10 +647,10 @@ var P = "// shared by every engine pass; sizes and word offsets mirror format/sp
598
647
  label: "cull",
599
648
  timestampWrites: t
600
649
  });
601
- n.setBindGroup(0, this.#n), n.setPipeline(this.#t), this.#e.listed && n.dispatchWorkgroups(Math.ceil(this.#e.listed / ce)), n.end();
650
+ n.setBindGroup(0, this.#n), n.setPipeline(this.#t), this.#e.listed && n.dispatchWorkgroups(Math.ceil(this.#e.listed / ue)), n.end();
602
651
  }
603
- }, ue = "// prisms that hide splats by centre; masks.ts writes the records, their vertices, then the clusters' lists\n\n// words of a record: min x y, max x y, min z, max z (f32), first vertex word, vertices\nconst MASK_WORDS: u32 = 8u;\n\n@group(1) @binding(0) var<storage, read> masks: array<u32>;\n\nfn maskFloat(k: u32) -> f32 {\n return bitcast<f32>(masks[k]);\n}\n\n// p, floating-origin frame, inside a mask of the cluster's list: its polygon by the even-odd rule and its z range\nfn masked(cluster: Cluster, p: vec3f) -> bool {\n for (var k = 0u; k < cluster.maskCount; k++) {\n let m = masks[cluster.maskList + k] * MASK_WORDS;\n if (p.x < maskFloat(m) || p.y < maskFloat(m + 1u) || p.x > maskFloat(m + 2u) ||\n p.y > maskFloat(m + 3u) || p.z < maskFloat(m + 4u) || p.z > maskFloat(m + 5u)) {\n continue;\n }\n let first = masks[m + 6u];\n let n = masks[m + 7u];\n var odd = false;\n var b = vec2f(maskFloat(first + 2u * n - 2u), maskFloat(first + 2u * n - 1u));\n for (var i = 0u; i < n; i++) {\n let a = vec2f(maskFloat(first + 2u * i), maskFloat(first + 2u * i + 1u));\n if ((a.y > p.y) != (b.y > p.y) && p.x < (b.x - a.x) * (p.y - a.y) / (b.y - a.y) + a.x) {\n odd = !odd;\n }\n b = a;\n }\n if (odd) {\n return true;\n }\n }\n return false;\n}\n", de = "// 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 if (masked(cluster, p)) {\n continue;\n }\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", fe = 32, pe = .5, me = 1;
604
- function he(e) {
652
+ }, fe = "// prisms that hide splats by centre; masks.ts writes the records, their vertices, then the clusters' lists\n\n// words of a record: min x y, max x y, min z, max z (f32), first vertex word, vertices\nconst MASK_WORDS: u32 = 8u;\n\n@group(1) @binding(0) var<storage, read> masks: array<u32>;\n\nfn maskFloat(k: u32) -> f32 {\n return bitcast<f32>(masks[k]);\n}\n\n// p, floating-origin frame, inside a mask of the cluster's list: its polygon by the even-odd rule and its z range\nfn masked(cluster: Cluster, p: vec3f) -> bool {\n for (var k = 0u; k < cluster.maskCount; k++) {\n let m = masks[cluster.maskList + k] * MASK_WORDS;\n if (p.x < maskFloat(m) || p.y < maskFloat(m + 1u) || p.x > maskFloat(m + 2u) ||\n p.y > maskFloat(m + 3u) || p.z < maskFloat(m + 4u) || p.z > maskFloat(m + 5u)) {\n continue;\n }\n let first = masks[m + 6u];\n let n = masks[m + 7u];\n var odd = false;\n var b = vec2f(maskFloat(first + 2u * n - 2u), maskFloat(first + 2u * n - 1u));\n for (var i = 0u; i < n; i++) {\n let a = vec2f(maskFloat(first + 2u * i), maskFloat(first + 2u * i + 1u));\n if ((a.y > p.y) != (b.y > p.y) && p.x < (b.x - a.x) * (p.y - a.y) / (b.y - a.y) + a.x) {\n odd = !odd;\n }\n b = a;\n }\n if (odd) {\n return true;\n }\n }\n return false;\n}\n", pe = "// 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 if (masked(cluster, p)) {\n continue;\n }\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", me = 32, he = .5, ge = 1;
653
+ function _e(e) {
605
654
  let t = new Uint32Array(e.length);
606
655
  for (let n = 0; n < e.length; n++) {
607
656
  let r = e[n];
@@ -609,7 +658,7 @@ function he(e) {
609
658
  }
610
659
  return new Float32Array(t.buffer);
611
660
  }
612
- var ge = class {
661
+ var ve = class {
613
662
  #e;
614
663
  #t;
615
664
  #n;
@@ -623,7 +672,7 @@ var ge = class {
623
672
  "read-only-storage",
624
673
  "storage"
625
674
  ]);
626
- let n = `${P}\n${ue}\n${de}`, r = e.createShaderModule({
675
+ let n = `${F}\n${fe}\n${pe}`, r = e.createShaderModule({
627
676
  label: "heights",
628
677
  code: n
629
678
  });
@@ -639,7 +688,7 @@ var ge = class {
639
688
  encode(e, t, n, r, i) {
640
689
  let a = this.#e, o = this.#t, { listed: s } = o, c = r * r * 4, l = a.createBuffer({
641
690
  label: "heights area",
642
- size: fe,
691
+ size: me,
643
692
  usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
644
693
  }), u = a.createBuffer({
645
694
  label: "heights",
@@ -649,14 +698,14 @@ var ge = class {
649
698
  label: "heights readback",
650
699
  size: c,
651
700
  usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
652
- }), f = /* @__PURE__ */ new ArrayBuffer(fe);
701
+ }), f = /* @__PURE__ */ new ArrayBuffer(me);
653
702
  new Float32Array(f).set([
654
703
  t,
655
704
  n,
656
705
  0,
657
706
  0,
658
- pe,
659
- me
707
+ he,
708
+ ge
660
709
  ]), new Uint32Array(f).set([r, s], 2), a.queue.writeBuffer(l, 0, f);
661
710
  let p = [
662
711
  l,
@@ -669,11 +718,11 @@ var ge = class {
669
718
  label: "heights",
670
719
  timestampWrites: i
671
720
  });
672
- return g.setPipeline(this.#r), g.setBindGroup(0, h), g.setBindGroup(1, o.masks.group), s > 0 && g.dispatchWorkgroups(...m(s)), g.end(), e.copyBufferToBuffer(u, 0, d, 0, c), () => d.mapAsync(GPUMapMode.READ).then(() => he(new Uint32Array(d.getMappedRange())), () => null).finally(() => {
721
+ return g.setPipeline(this.#r), g.setBindGroup(0, h), g.setBindGroup(1, o.masks.group), s > 0 && g.dispatchWorkgroups(...m(s)), g.end(), e.copyBufferToBuffer(u, 0, d, 0, c), () => d.mapAsync(GPUMapMode.READ).then(() => _e(new Uint32Array(d.getMappedRange())), () => null).finally(() => {
673
722
  l.destroy(), u.destroy(), d.destroy();
674
723
  });
675
724
  }
676
- }, _e = "@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", ve = class {
725
+ }, ye = "@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", be = class {
677
726
  #e;
678
727
  #t;
679
728
  #n;
@@ -682,7 +731,7 @@ var ge = class {
682
731
  constructor(e, t, n, r) {
683
732
  let i = e.createShaderModule({
684
733
  label: t,
685
- code: _e + n
734
+ code: ye + n
686
735
  });
687
736
  this.#e = e, this.#t = t, this.#n = e.createRenderPipeline({
688
737
  label: t,
@@ -717,7 +766,7 @@ var ge = class {
717
766
  });
718
767
  r.setPipeline(this.#n), r.setBindGroup(0, this.#i), r.draw(3), r.end();
719
768
  }
720
- }, ye = "// 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", be = (e, t) => new ve(e, "present", ye, t), xe = "// workgroups loop over visible clusters, one thread per splat\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\n@group(0) @binding(9) var<uniform> visible: u32;\nvar<workgroup> kept: atomic<u32>;\nvar<workgroup> base: u32;\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 var s: Splat;\n var g: vec4u;\n if (!decode(cluster, t, &s, &g)) {\n return false;\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 let cov = covariance(g, s.scale, viewPos);\n let a = cov.x;\n let b = cov.y;\n let c = cov.z;\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(\n @builtin(workgroup_id) wid: vec3u,\n @builtin(num_workgroups) groups: vec3u,\n @builtin(local_invocation_index) t: u32\n) {\n for (var index = wid.y * groups.x + wid.x; index < visible; index += groups.x * groups.y) {\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 cluster\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], atomicExchange(&kept, 0u));\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}\n", Se = "// a pool splat decoded and its screen covariance, shared by project and pick; each declares the\n// uniforms, geometry, colours and pages bindings these read\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// splat t of a cluster in the floating-origin frame, its record in g; false when a mask hides it\nfn decode(cluster: Cluster, t: u32, s: ptr<function, Splat>, g: ptr<function, vec4u>) -> bool {\n let page = pages[cluster.page];\n let rec = cluster.slot + t;\n *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 var d: Splat;\n let q = vec3f(f32((*g).x & 0xffffu), f32((*g).x >> 16u), f32((*g).y & 0xffffu));\n d.position = page.origin + q * page.step;\n if (masked(cluster, d.position)) {\n return false;\n }\n d.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 d.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 toward = normalize(d.position - uniforms.camera);\n d.colour = max(0.5 + C0 * dc + C1 * (-toward.y * m0 + toward.z * m1 - toward.x * m2), vec3f(0.0));\n d.depth = -(uniforms.view * vec4f(d.position, 1.0)).z;\n *s = d;\n return true;\n}\n\n// ewa: view-space covariance wm wm^T through the jacobian of the pixel projection, as a b c in px²\nfn covariance(g: vec4u, scale: vec3f, viewPos: vec3f) -> vec3f {\n let depth = -viewPos.z;\n let r = rotate(rotation(g));\n let m = mat3x3f(r[0] * scale.x, r[1] * scale.y, r[2] * 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 return vec3f(dot(u, u) + uniforms.lowPass, dot(u, v), dot(v, v) + uniforms.lowPass);\n}\n", Ce = class {
769
+ }, xe = "// 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", Se = (e, t) => new be(e, "present", xe, t), Ce = "// workgroups loop over visible clusters, one thread per splat\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\n@group(0) @binding(9) var<uniform> visible: u32;\nvar<workgroup> kept: atomic<u32>;\nvar<workgroup> base: u32;\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 var s: Splat;\n var g: vec4u;\n if (!decode(cluster, t, &s, &g)) {\n return false;\n }\n shade(&s);\n var d: Drawn;\n if (!drawn(s, g, &d)) {\n return false;\n }\n *dest = Projected(\n d.centre,\n vec2u(pack2x16float(d.axis * d.major), pack2x16float(vec2f(-d.axis.y, d.axis.x) * d.minor)),\n vec2u(pack2x16float(s.colour.rg), pack2x16float(vec2f(s.colour.b, s.opacity)))\n );\n let span = clamp(log(d.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(\n @builtin(workgroup_id) wid: vec3u,\n @builtin(num_workgroups) groups: vec3u,\n @builtin(local_invocation_index) t: u32\n) {\n for (var index = wid.y * groups.x + wid.x; index < visible; index += groups.x * groups.y) {\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 cluster\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], atomicExchange(&kept, 0u));\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}\n", we = "// a pool splat decoded, its screen covariance and how the frame draws it, shared by project and\n// pick; each declares the uniforms, geometry, colours and pages bindings these read\n\n// ndc reach past the frustum, so splats centred just outside still cover the edge\nconst GUARD: f32 = 1.3;\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// splat t of a cluster in the floating-origin frame, its record in g; false when a mask hides it\nfn decode(cluster: Cluster, t: u32, s: ptr<function, Splat>, g: ptr<function, vec4u>) -> bool {\n let page = pages[cluster.page];\n let rec = cluster.slot + t;\n *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 var d: Splat;\n let q = vec3f(f32((*g).x & 0xffffu), f32((*g).x >> 16u), f32((*g).y & 0xffffu));\n d.position = page.origin + q * page.step;\n if (masked(cluster, d.position)) {\n return false;\n }\n d.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 d.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 toward = normalize(d.position - uniforms.camera);\n d.colour = max(0.5 + C0 * dc + C1 * (-toward.y * m0 + toward.z * m1 - toward.x * m2), vec3f(0.0));\n d.depth = -(uniforms.view * vec4f(d.position, 1.0)).z;\n *s = d;\n return true;\n}\n\n// ewa: view-space covariance wm wm^T through the jacobian of the pixel projection, as a b c in px²\nfn covariance(g: vec4u, scale: vec3f, viewPos: vec3f) -> vec3f {\n let depth = -viewPos.z;\n let r = rotate(rotation(g));\n let m = mat3x3f(r[0] * scale.x, r[1] * scale.y, r[2] * 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 return vec3f(dot(u, u) + uniforms.lowPass, dot(u, v), dot(v, v) + uniforms.lowPass);\n}\n\n// a splat as the frame draws it: its view depth, its centre in pixels from the bottom-left, and\n// its quad's axis with the sigmas along it and across\nstruct Drawn {\n depth: f32,\n centre: vec2f,\n axis: vec2f,\n major: f32,\n minor: f32,\n}\n\n// false where the frame draws none of the shaded splat: too faint, out of range, centred past the\n// guard band, under half a pixel, or off the screen\nfn drawn(s: Splat, g: vec4u, d: ptr<function, Drawn>) -> bool {\n if (s.opacity < 1.0 / 255.0) {\n return false;\n }\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 let cov = covariance(g, s.scale, viewPos);\n let mid = 0.5 * (cov.x + cov.z);\n let rad = length(vec2f(0.5 * (cov.x - cov.z), cov.y));\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 * cov.y, cov.x - cov.z);\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 *d = Drawn(depth, centre, axis, major, minor);\n return true;\n}\n", Te = class {
721
770
  #e;
722
771
  #t;
723
772
  #n;
@@ -767,11 +816,11 @@ var ge = class {
767
816
  i.setPipeline(this.#n ??= this.#c()), i.setBindGroup(0, this.#i), i.setBindGroup(1, this.#a.masks.group), i.dispatchWorkgroups(r), i.end();
768
817
  }
769
818
  #c() {
770
- let e = we([
771
- P,
772
- ue,
773
- Se,
774
- xe
819
+ let e = Ee([
820
+ F,
821
+ fe,
822
+ we,
823
+ Ce
775
824
  ], this.#r), t = this.#e.createShaderModule({
776
825
  label: "project",
777
826
  code: e
@@ -786,7 +835,7 @@ var ge = class {
786
835
  });
787
836
  }
788
837
  };
789
- function we(e, t) {
838
+ function Ee(e, t) {
790
839
  let n = t.map(({ shade: e, slot: t }) => {
791
840
  let n = Array.from({ length: e.uniforms }, (e, n) => `plugins[${t + n}]`);
792
841
  return `\t${e.name}(s, array<vec4f, ${e.uniforms}>(${n.join(", ")}));`;
@@ -801,10 +850,10 @@ function we(e, t) {
801
850
  }
802
851
  //#endregion
803
852
  //#region src/engine/gpu/overlay.wgsl?raw
804
- var Te = "// host graphics over the frame: capsules in screen space from a to b, a marker where a is b\n\n// share of the view depth an occluding fragment may lie behind the splats, so a line on the ground clears their fringe\nconst SLACK: f32 = 0.02;\n\nstruct Capsule {\n @location(0) a: vec3f,\n @location(1) b: vec3f,\n // pixels\n @location(2) radius: f32,\n @location(3) colour: vec4f,\n @location(4) occlude: u32,\n}\n\nstruct Fragment {\n @builtin(position) position: vec4f,\n // target pixels from the top-left, of the ends\n @location(0) @interpolate(flat) a: vec2f,\n @location(1) @interpolate(flat) b: vec2f,\n // view depth of the ends\n @location(2) @interpolate(flat) depths: vec2f,\n @location(3) @interpolate(flat) radius: f32,\n @location(4) @interpolate(flat) colour: vec4f,\n @location(5) @interpolate(flat) occlude: u32,\n}\n\n@group(0) @binding(0) var<uniform> uniforms: FrameUniforms;\n@group(0) @binding(1) var depth: texture_depth_2d;\n\nfn pixel(view: vec3f) -> vec2f {\n let clip = uniforms.proj * vec4f(view, 1.0);\n let ndc = clip.xy / clip.w;\n return vec2f(ndc.x * 0.5 + 0.5, 0.5 - ndc.y * 0.5) * uniforms.viewport;\n}\n\n@vertex\nfn vs(@builtin(vertex_index) v: u32, c: Capsule) -> Fragment {\n var a = (uniforms.view * vec4f(c.a, 1.0)).xyz;\n var b = (uniforms.view * vec4f(c.b, 1.0)).xyz;\n var out: Fragment;\n // cut the part behind the near plane; nothing left draws nothing\n let near = -uniforms.near;\n if (a.z > near && b.z > near) {\n out.position = vec4f(2.0, 2.0, 0.0, 1.0);\n return out;\n }\n if (a.z > near) {\n a = mix(b, a, (near - b.z) / (a.z - b.z));\n } else if (b.z > near) {\n b = mix(a, b, (near - a.z) / (b.z - a.z));\n }\n let pa = pixel(a);\n let pb = pixel(b);\n let span = pb - pa;\n let along = select(vec2f(1.0, 0.0), normalize(span), dot(span, span) > 1e-6);\n let across = vec2f(-along.y, along.x);\n let r = c.radius + 1.0;\n let corner = select(pa - along * r, pb + along * r, (v & 1u) == 1u) + across * r * select(-1.0, 1.0, v > 1u);\n out.position = vec4f(corner.x / uniforms.viewport.x * 2.0 - 1.0, 1.0 - corner.y / uniforms.viewport.y * 2.0, 0.0, 1.0);\n out.a = pa;\n out.b = pb;\n out.depths = vec2f(-a.z, -b.z);\n out.radius = c.radius;\n out.colour = c.colour;\n out.occlude = c.occlude;\n return out;\n}\n\n@fragment\nfn fs(f: Fragment) -> @location(0) vec4f {\n let p = f.position.xy;\n let span = f.b - f.a;\n let t = select(0.0, clamp(dot(p - f.a, span) / dot(span, span), 0.0, 1.0), dot(span, span) > 1e-6);\n let coverage = clamp(f.radius - distance(p, f.a + span * t) + 0.5, 0.0, 1.0);\n if (coverage <= 0.0) {\n discard;\n }\n if (f.occlude != 0u) {\n // screen-linear in 1 / depth along a segment\n let here = 1.0 / mix(1.0 / f.depths.x, 1.0 / f.depths.y, t);\n let stored = textureLoad(depth, vec2i(p), 0);\n let scene = uniforms.near * pow(uniforms.far / uniforms.near, stored);\n if (stored < 1.0 && here > scene * (1.0 + SLACK)) {\n discard;\n }\n }\n let a = f.colour.a * coverage;\n return vec4f(f.colour.rgb * a, a);\n}\n", Ee = 36, De = {
853
+ var De = "// host graphics over the frame: capsules in screen space from a to b, a marker where a is b\n\n// share of the view depth an occluding fragment may lie behind the splats, so a line on the ground clears their fringe\nconst SLACK: f32 = 0.02;\n\nstruct Capsule {\n @location(0) a: vec3f,\n @location(1) b: vec3f,\n // pixels\n @location(2) radius: f32,\n @location(3) colour: vec4f,\n @location(4) occlude: u32,\n}\n\nstruct Fragment {\n @builtin(position) position: vec4f,\n // target pixels from the top-left, of the ends\n @location(0) @interpolate(flat) a: vec2f,\n @location(1) @interpolate(flat) b: vec2f,\n // view depth of the ends\n @location(2) @interpolate(flat) depths: vec2f,\n @location(3) @interpolate(flat) radius: f32,\n @location(4) @interpolate(flat) colour: vec4f,\n @location(5) @interpolate(flat) occlude: u32,\n}\n\n@group(0) @binding(0) var<uniform> uniforms: FrameUniforms;\n@group(0) @binding(1) var depth: texture_depth_2d;\n\nfn pixel(view: vec3f) -> vec2f {\n let clip = uniforms.proj * vec4f(view, 1.0);\n let ndc = clip.xy / clip.w;\n return vec2f(ndc.x * 0.5 + 0.5, 0.5 - ndc.y * 0.5) * uniforms.viewport;\n}\n\n@vertex\nfn vs(@builtin(vertex_index) v: u32, c: Capsule) -> Fragment {\n var a = (uniforms.view * vec4f(c.a, 1.0)).xyz;\n var b = (uniforms.view * vec4f(c.b, 1.0)).xyz;\n var out: Fragment;\n // cut the part behind the near plane; nothing left draws nothing\n let near = -uniforms.near;\n if (a.z > near && b.z > near) {\n out.position = vec4f(2.0, 2.0, 0.0, 1.0);\n return out;\n }\n if (a.z > near) {\n a = mix(b, a, (near - b.z) / (a.z - b.z));\n } else if (b.z > near) {\n b = mix(a, b, (near - a.z) / (b.z - a.z));\n }\n let pa = pixel(a);\n let pb = pixel(b);\n let span = pb - pa;\n let along = select(vec2f(1.0, 0.0), normalize(span), dot(span, span) > 1e-6);\n let across = vec2f(-along.y, along.x);\n let r = c.radius + 1.0;\n let corner = select(pa - along * r, pb + along * r, (v & 1u) == 1u) + across * r * select(-1.0, 1.0, v > 1u);\n out.position = vec4f(corner.x / uniforms.viewport.x * 2.0 - 1.0, 1.0 - corner.y / uniforms.viewport.y * 2.0, 0.0, 1.0);\n out.a = pa;\n out.b = pb;\n out.depths = vec2f(-a.z, -b.z);\n out.radius = c.radius;\n out.colour = c.colour;\n out.occlude = c.occlude;\n return out;\n}\n\n@fragment\nfn fs(f: Fragment) -> @location(0) vec4f {\n let p = f.position.xy;\n let span = f.b - f.a;\n let t = select(0.0, clamp(dot(p - f.a, span) / dot(span, span), 0.0, 1.0), dot(span, span) > 1e-6);\n let coverage = clamp(f.radius - distance(p, f.a + span * t) + 0.5, 0.0, 1.0);\n if (coverage <= 0.0) {\n discard;\n }\n if (f.occlude != 0u) {\n // screen-linear in 1 / depth along a segment\n let here = 1.0 / mix(1.0 / f.depths.x, 1.0 / f.depths.y, t);\n let stored = textureLoad(depth, vec2i(p), 0);\n let scene = uniforms.near * pow(uniforms.far / uniforms.near, stored);\n if (stored < 1.0 && here > scene * (1.0 + SLACK)) {\n discard;\n }\n }\n let a = f.colour.a * coverage;\n return vec4f(f.colour.rgb * a, a);\n}\n", Oe = 36, ke = {
805
854
  srcFactor: "one",
806
855
  dstFactor: "one-minus-src-alpha"
807
- }, Oe = class {
856
+ }, Ae = class {
808
857
  #e;
809
858
  #t;
810
859
  #n;
@@ -816,7 +865,7 @@ var Te = "// host graphics over the frame: capsules in screen space from a to b,
816
865
  this.#e = e, this.#t = n;
817
866
  let r = e.createShaderModule({
818
867
  label: "overlay",
819
- code: P + Te
868
+ code: F + De
820
869
  }), i = [
821
870
  {
822
871
  shaderLocation: 0,
@@ -851,7 +900,7 @@ var Te = "// host graphics over the frame: capsules in screen space from a to b,
851
900
  module: r,
852
901
  entryPoint: "vs",
853
902
  buffers: [{
854
- arrayStride: Ee,
903
+ arrayStride: Oe,
855
904
  stepMode: "instance",
856
905
  attributes: i
857
906
  }]
@@ -862,8 +911,8 @@ var Te = "// host graphics over the frame: capsules in screen space from a to b,
862
911
  targets: [{
863
912
  format: t,
864
913
  blend: {
865
- color: De,
866
- alpha: De
914
+ color: ke,
915
+ alpha: ke
867
916
  }
868
917
  }]
869
918
  },
@@ -875,9 +924,9 @@ var Te = "// host graphics over the frame: capsules in screen space from a to b,
875
924
  }
876
925
  set(e, t) {
877
926
  if (this.#i = e.length, !e.length) return;
878
- let n = /* @__PURE__ */ new ArrayBuffer(e.length * Ee), r = new Float32Array(n), i = new Uint32Array(n), a = new Uint8Array(n);
927
+ let n = /* @__PURE__ */ new ArrayBuffer(e.length * Oe), r = new Float32Array(n), i = new Uint32Array(n), a = new Uint8Array(n);
879
928
  e.forEach(({ a: e, b: n, radius: o, colour: s, occlude: c }, l) => {
880
- let u = l * Ee / 4;
929
+ let u = l * Oe / 4;
881
930
  for (let i = 0; i < 3; i++) r[u + i] = e[i] - t[i], r[u + 3 + i] = n[i] - t[i];
882
931
  r[u + 6] = o, s.forEach((e, t) => a[(u + 7) * 4 + t] = Math.round(Math.min(1, Math.max(0, e)) * 255)), i[u + 8] = +!!c;
883
932
  }), (!this.#r || this.#r.size < n.byteLength) && (this.#r?.destroy(), this.#r = this.#e.createBuffer({
@@ -912,7 +961,7 @@ var Te = "// host graphics over the frame: capsules in screen space from a to b,
912
961
  destroy() {
913
962
  this.#r?.destroy();
914
963
  }
915
- }, ke = [
964
+ }, je = [
916
965
  [
917
966
  0,
918
967
  -1,
@@ -944,15 +993,15 @@ var Te = "// host graphics over the frame: capsules in screen space from a to b,
944
993
  -1
945
994
  ]
946
995
  ];
947
- function Ae(e, t, n) {
948
- return ke.forEach(([r, i, a], o) => {
996
+ function Me(e, t, n) {
997
+ return je.forEach(([r, i, a], o) => {
949
998
  let s = n?.[o] ?? i;
950
999
  for (let n = 0; n < 4; n++) e[o * 4 + n] = a * (t[n * 4 + r] - s * t[n * 4 + 3]);
951
1000
  let c = Math.hypot(e[o * 4], e[o * 4 + 1], e[o * 4 + 2]) || 1;
952
1001
  for (let t = 0; t < 4; t++) e[o * 4 + t] /= c;
953
1002
  }), e;
954
1003
  }
955
- function je(e, t, n) {
1004
+ function Ne(e, t, n) {
956
1005
  for (let r = 0; r < 24; r += 4) {
957
1006
  let i = e[r] >= 0 ? n[0] : t[0], a = e[r + 1] >= 0 ? n[1] : t[1], o = e[r + 2] >= 0 ? n[2] : t[2];
958
1007
  if (e[r] * i + e[r + 1] * a + e[r + 2] * o + e[r + 3] < 0) return !1;
@@ -961,13 +1010,7 @@ function je(e, t, n) {
961
1010
  }
962
1011
  //#endregion
963
1012
  //#region src/engine/gpu/pick.wgsl?raw
964
- var Me = "// the nearest solid splat under one pixel, over the last frame's visible clusters\n\n// workgroups of the dispatch, pick.ts's GROUPS; each loops over the visible clusters\nconst PICK_GROUPS: u32 = 256u;\n// least alpha at the pixel of a splat that counts as the surface\nconst SOLID: f32 = 0.5;\n\nstruct Probe {\n // target pixel, y up from the bottom-left\n pixel: vec2f,\n // the pixel's frustum sides; inside when dot(plane.xyz, p) + plane.w >= 0\n planes: array<vec4f, 4>,\n}\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> work: array<u32>;\n@group(0) @binding(7) var<uniform> probe: Probe;\n// view depth bits of the nearest hit, then its layer, then its normal\n@group(0) @binding(8) var<storage, read_write> hit: array<atomic<u32>>;\n\n// false only when the box lies wholly outside one side of the pixel\nfn under(lo: vec3f, hi: vec3f) -> bool {\n for (var p = 0u; p < 4u; p++) {\n let plane = probe.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// splat t of the cluster draws the pixel solid; its view depth and decoded splat then\nfn covers(cluster: Cluster, t: u32, s: ptr<function, Splat>, g: ptr<function, vec4u>) -> bool {\n if (!decode(cluster, t, s, g)) {\n return false;\n }\n shade(s);\n let viewPos = (uniforms.view * vec4f((*s).position, 1.0)).xyz;\n let depth = -viewPos.z;\n if ((*s).opacity < SOLID || depth < uniforms.near || depth > uniforms.far) {\n return false;\n }\n let clip = uniforms.proj * vec4f(viewPos, 1.0);\n let centre = (clip.xy / clip.w * 0.5 + 0.5) * uniforms.viewport;\n let cov = covariance(*g, (*s).scale, viewPos);\n let d = probe.pixel - centre;\n let power = (cov.z * d.x * d.x - 2.0 * cov.y * d.x * d.y + cov.x * d.y * d.y) / (cov.x * cov.z - cov.y * cov.y);\n (*s).depth = depth;\n return (*s).opacity * exp(-0.5 * power) >= SOLID;\n}\n\n// the cluster of visible index under the pixel, or none\nfn candidate(index: u32, cluster: ptr<function, Cluster>) -> bool {\n *cluster = clusters[work[WORK_LIST + index]];\n let page = pages[(*cluster).page];\n return under(page.origin + (*cluster).boxMin, page.origin + (*cluster).boxMax);\n}\n\n@compute @workgroup_size(256)\nfn nearest(@builtin(workgroup_id) wid: vec3u, @builtin(local_invocation_index) t: u32) {\n for (var index = wid.x; index < work[WORK_VISIBLE]; index += PICK_GROUPS) {\n var cluster: Cluster;\n var s: Splat;\n var g: vec4u;\n if (candidate(index, &cluster) && t < cluster.count && covers(cluster, t, &s, &g)) {\n atomicMin(&hit[0], bitcast<u32>(s.depth));\n }\n }\n}\n\n// the splat at the nearest depth writes its layer and its thinnest axis, toward the camera\n@compute @workgroup_size(256)\nfn surface(@builtin(workgroup_id) wid: vec3u, @builtin(local_invocation_index) t: u32) {\n let nearest = atomicLoad(&hit[0]);\n for (var index = wid.x; index < work[WORK_VISIBLE]; index += PICK_GROUPS) {\n var cluster: Cluster;\n var s: Splat;\n var g: vec4u;\n if (candidate(index, &cluster) && t < cluster.count && covers(cluster, t, &s, &g) &&\n bitcast<u32>(s.depth) == nearest) {\n let r = rotate(rotation(g));\n let k = select(select(2u, 1u, s.scale.y <= s.scale.z), 0u,\n s.scale.x <= s.scale.y && s.scale.x <= s.scale.z);\n let normal = r[k] * sign(dot(r[k], uniforms.camera - s.position) + 1e-20);\n atomicStore(&hit[1], pages[cluster.page].layer);\n atomicStore(&hit[2], bitcast<u32>(normal.x));\n atomicStore(&hit[3], bitcast<u32>(normal.y));\n atomicStore(&hit[4], bitcast<u32>(normal.z));\n }\n }\n}\n", Ne = 256, Pe = 80, Fe = 4294967295, Ie = new Uint32Array([
965
- Fe,
966
- 0,
967
- 0,
968
- 0,
969
- 0
970
- ]), Le = class {
1013
+ var Pe = "// every splat the last frame drew over one pixel, with its alpha there, over the frame's visible\n// clusters; the host blends them front to back as the frame did\n\n// workgroups of the dispatch, pick.ts's GROUPS; each loops over the visible clusters\nconst PICK_GROUPS: u32 = 256u;\n\nstruct Probe {\n // target pixel, y up from the bottom-left\n pixel: vec2f,\n // the pixel's frustum sides; inside when dot(plane.xyz, p) + plane.w >= 0\n planes: array<vec4f, 4>,\n}\n\n// a splat over the pixel: its face toward the camera, its view depth, which orders the blend, the\n// view depth where the pixel's ray meets its plane, its alpha at the pixel and its layer\nstruct Entry {\n normal: vec3f,\n depth: f32,\n meets: f32,\n alpha: f32,\n layer: u32,\n}\n\n// entries past the buffer's length are counted and not kept\nstruct Hits {\n count: atomic<u32>,\n entries: array<Entry>,\n}\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> work: array<u32>;\n@group(0) @binding(7) var<uniform> probe: Probe;\n@group(0) @binding(8) var<storage, read_write> hits: Hits;\n\n// false only when the box lies wholly outside one side of the pixel\nfn under(lo: vec3f, hi: vec3f) -> bool {\n for (var p = 0u; p < 4u; p++) {\n let plane = probe.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// the cluster of visible index under the pixel, or none\nfn candidate(index: u32, cluster: ptr<function, Cluster>) -> bool {\n *cluster = clusters[work[WORK_LIST + index]];\n let page = pages[(*cluster).page];\n return under(page.origin + (*cluster).boxMin, page.origin + (*cluster).boxMax);\n}\n\n// the alpha a drawn splat gives the pixel as raster.wgsl blends it: its quad stops at reach\n// sigmas along each axis, and a fragment under 1/255 is discarded\nfn coverage(s: Splat, d: Drawn) -> f32 {\n let off = probe.pixel - d.centre;\n let uv = vec2f(dot(off, d.axis) / d.major, dot(off, vec2f(-d.axis.y, d.axis.x)) / d.minor);\n if (any(abs(uv) > vec2f(reach(s.opacity)))) {\n return 0.0;\n }\n let a = s.opacity * exp(-0.5 * dot(uv, uv));\n return select(0.0, a, a >= 1.0 / 255.0);\n}\n\n// the splat's thinnest axis, toward the camera\nfn face(s: Splat, g: vec4u) -> vec3f {\n let r = rotate(rotation(g));\n let k = select(select(2u, 1u, s.scale.y <= s.scale.z), 0u,\n s.scale.x <= s.scale.y && s.scale.x <= s.scale.z);\n return r[k] * sign(dot(r[k], uniforms.camera - s.position) + 1e-20);\n}\n\n// the view depth where the pixel's ray meets the plane of the splat's face, kept within its\n// reach of the centre: a splat seen edge on meets the ray far off\nfn meets(s: Splat, d: Drawn, normal: vec3f) -> f32 {\n let ndc = probe.pixel / uniforms.viewport * 2.0 - 1.0;\n let ray = vec3f(ndc.x / uniforms.proj[0].x, ndc.y / uniforms.proj[1].y, -1.0);\n let n = (uniforms.view * vec4f(normal, 0.0)).xyz;\n let centre = (uniforms.view * vec4f(s.position, 1.0)).xyz;\n let across = dot(n, ray);\n if (abs(across) < 1e-6) {\n return d.depth;\n }\n let spread = reach(s.opacity) * max(s.scale.x, max(s.scale.y, s.scale.z));\n return clamp(dot(n, centre) / across, d.depth - spread, d.depth + spread);\n}\n\n@compute @workgroup_size(256)\nfn gather(@builtin(workgroup_id) wid: vec3u, @builtin(local_invocation_index) t: u32) {\n for (var index = wid.x; index < work[WORK_VISIBLE]; index += PICK_GROUPS) {\n var cluster: Cluster;\n var s: Splat;\n var g: vec4u;\n if (!candidate(index, &cluster) || t >= cluster.count || !decode(cluster, t, &s, &g)) {\n continue;\n }\n shade(&s);\n var d: Drawn;\n if (!drawn(s, g, &d)) {\n continue;\n }\n let a = coverage(s, d);\n if (a == 0.0) {\n continue;\n }\n let normal = face(s, g);\n let slot = atomicAdd(&hits.count, 1u);\n if (slot < arrayLength(&hits.entries)) {\n hits.entries[slot] = Entry(normal, d.depth, meets(s, d, normal), a, pages[cluster.page].layer);\n }\n }\n}\n", Fe = 256, Ie = 80, I = 16, Le = 32, Re = 4096, ze = new Uint32Array([0]), Be = class {
971
1014
  #e;
972
1015
  #t;
973
1016
  #n;
@@ -976,10 +1019,12 @@ var Me = "// the nearest solid splat under one pixel, over the last frame's visi
976
1019
  #a = [];
977
1020
  #o = /* @__PURE__ */ new Float32Array(16);
978
1021
  #s = /* @__PURE__ */ new Float32Array(24);
979
- #c = new Float32Array(Pe / 4);
1022
+ #c = new Float32Array(Ie / 4);
980
1023
  #l;
981
1024
  #u;
982
- #d;
1025
+ #d = 0;
1026
+ #f;
1027
+ #p;
983
1028
  constructor(e, t, n) {
984
1029
  this.#e = e, this.#t = t, this.#n = x(e, "pick", GPUShaderStage.COMPUTE, [
985
1030
  "uniform",
@@ -993,12 +1038,8 @@ var Me = "// the nearest solid splat under one pixel, over the last frame's visi
993
1038
  "storage"
994
1039
  ]), this.#r = e.createPipelineLayout({ bindGroupLayouts: [this.#n, t.masks.layout] }), this.#l = e.createBuffer({
995
1040
  label: "pick probe",
996
- size: Pe,
1041
+ size: Ie,
997
1042
  usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
998
- }), this.#u = e.createBuffer({
999
- label: "pick",
1000
- size: 20,
1001
- usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST
1002
1043
  });
1003
1044
  let { uniforms: r, plugins: i, work: a } = n, o = [
1004
1045
  r,
@@ -1008,77 +1049,90 @@ var Me = "// the nearest solid splat under one pixel, over the last frame's visi
1008
1049
  t.pages,
1009
1050
  t.clusters
1010
1051
  ];
1011
- this.#d = S(e, "pick", this.#n, [
1052
+ this.#u = [
1012
1053
  ...o,
1013
1054
  a,
1014
- this.#l,
1015
- this.#u
1016
- ]);
1055
+ this.#l
1056
+ ], this.#m(Re);
1017
1057
  }
1018
1058
  hooks(e) {
1019
1059
  this.#a = e, this.#i = void 0;
1020
1060
  }
1021
1061
  run(e, t, n) {
1022
- let r = this.#e, i = this.#t, a = r.createBuffer({
1062
+ let r = this.#e, i = this.#t, a = this.#d, o = I + a * Le, s = r.createBuffer({
1023
1063
  label: "pick readback",
1024
- size: 20,
1064
+ size: o,
1025
1065
  usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
1026
- }), o = this.#c, s = n.height - t;
1027
- o.set([e, s], 0), o.set(this.#f(e, s, n), 4), r.queue.writeBuffer(this.#l, 0, o), r.queue.writeBuffer(this.#u, 0, Ie);
1028
- let c = this.#i ??= this.#p(), l = r.createCommandEncoder({ label: "pick" }), u = l.beginComputePass({ label: "pick" });
1029
- return u.setBindGroup(0, this.#d), u.setBindGroup(1, i.masks.group), u.setPipeline(c.nearest), u.dispatchWorkgroups(Ne), u.setPipeline(c.surface), u.dispatchWorkgroups(Ne), u.end(), l.copyBufferToBuffer(this.#u, 0, a, 0, 20), r.queue.submit([l.finish()]), a.mapAsync(GPUMapMode.READ).then(() => {
1030
- let e = new Uint32Array(a.getMappedRange());
1031
- if (e[0] === Fe) return null;
1032
- let t = new Float32Array(e.buffer), n = [
1033
- t[2],
1034
- t[3],
1035
- t[4]
1036
- ];
1037
- return {
1038
- depth: t[0],
1039
- layer: e[1],
1040
- normal: n
1041
- };
1042
- }, () => null).finally(() => a.destroy());
1066
+ }), c = this.#c, l = n.height - t;
1067
+ c.set([e, l], 0), c.set(this.#h(e, l, n), 4), r.queue.writeBuffer(this.#l, 0, c), r.queue.writeBuffer(this.#f, 0, ze);
1068
+ let u = r.createCommandEncoder({ label: "pick" }), d = u.beginComputePass({ label: "pick" });
1069
+ return d.setBindGroup(0, this.#p), d.setBindGroup(1, i.masks.group), d.setPipeline(this.#i ??= this.#g()), d.dispatchWorkgroups(Fe), d.end(), u.copyBufferToBuffer(this.#f, 0, s, 0, o), r.queue.submit([u.finish()]), s.mapAsync(GPUMapMode.READ).then(() => {
1070
+ let e = s.getMappedRange(), t = new Uint32Array(e, 0, 1)[0];
1071
+ return t > a ? (this.#m(2 ** Math.ceil(Math.log2(t))), null) : Ve(new Float32Array(e, I), new Uint32Array(e, I), t);
1072
+ }, () => null).finally(() => s.destroy());
1043
1073
  }
1044
1074
  destroy() {
1045
- this.#l.destroy(), this.#u.destroy();
1075
+ this.#l.destroy(), this.#f.destroy();
1076
+ }
1077
+ #m(e) {
1078
+ let t = this.#f;
1079
+ this.#d = e, this.#f = this.#e.createBuffer({
1080
+ label: "pick",
1081
+ size: I + e * Le,
1082
+ usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC | GPUBufferUsage.COPY_DST
1083
+ }), this.#p = S(this.#e, "pick", this.#n, [...this.#u, this.#f]), t?.destroy();
1046
1084
  }
1047
- #f(e, t, n) {
1048
- let r = (e, t) => 2 * e / t - 1, i = N(this.#o, n.proj, n.view), a = [
1085
+ #h(e, t, n) {
1086
+ let r = (e, t) => 2 * e / t - 1, i = P(this.#o, n.proj, n.view), a = [
1049
1087
  r(e - .5, n.width),
1050
1088
  r(e + .5, n.width),
1051
1089
  r(t - .5, n.height),
1052
1090
  r(t + .5, n.height)
1053
1091
  ];
1054
- return Ae(this.#s, i, a), this.#s.subarray(0, 16);
1055
- }
1056
- #p() {
1057
- let e = we([
1058
- P,
1059
- ue,
1060
- Se,
1061
- Me
1092
+ return Me(this.#s, i, a), this.#s.subarray(0, 16);
1093
+ }
1094
+ #g() {
1095
+ let e = Ee([
1096
+ F,
1097
+ fe,
1098
+ we,
1099
+ Pe
1062
1100
  ], this.#a), t = this.#e.createShaderModule({
1063
1101
  label: "pick",
1064
1102
  code: e
1065
- }), n = (e) => this.#e.createComputePipeline({
1066
- label: `pick ${e}`,
1103
+ });
1104
+ return this.#e.createComputePipeline({
1105
+ label: "pick",
1067
1106
  layout: this.#r,
1068
1107
  compute: {
1069
1108
  module: t,
1070
- entryPoint: e
1109
+ entryPoint: "gather"
1071
1110
  }
1072
1111
  });
1073
- return {
1074
- nearest: n("nearest"),
1075
- surface: n("surface")
1112
+ }
1113
+ };
1114
+ function Ve(e, t, n) {
1115
+ let r = Le / 4, i = Array.from({ length: n }, (e, t) => t).sort((t, n) => e[t * r + 3] - e[n * r + 3]), a = 1;
1116
+ for (let n of i) {
1117
+ let i = n * r;
1118
+ if (a *= 1 - e[i + 5], a <= .5) return {
1119
+ depth: e[i + 4],
1120
+ layer: t[i + 6],
1121
+ normal: [
1122
+ e[i],
1123
+ e[i + 1],
1124
+ e[i + 2]
1125
+ ]
1076
1126
  };
1077
1127
  }
1078
- }, Re = "// 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", ze = "rgb10a2unorm", Be = "depth16unorm", Ve = {
1128
+ return null;
1129
+ }
1130
+ //#endregion
1131
+ //#region src/engine/gpu/raster.wgsl?raw
1132
+ var He = "// 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", Ue = "rgb10a2unorm", We = "depth16unorm", Ge = {
1079
1133
  srcFactor: "one",
1080
1134
  dstFactor: "one-minus-src-alpha"
1081
- }, He = class {
1135
+ }, Ke = class {
1082
1136
  #e;
1083
1137
  #t;
1084
1138
  #n;
@@ -1111,7 +1165,7 @@ var Me = "// the nearest solid splat under one pixel, over the last frame's visi
1111
1165
  ]);
1112
1166
  let a = e.createShaderModule({
1113
1167
  label: "raster",
1114
- code: P + Re
1168
+ code: F + He
1115
1169
  }), o = e.createPipelineLayout({ bindGroupLayouts: [i] }), s = (t, n) => e.createRenderPipeline({
1116
1170
  label: `raster ${t}`,
1117
1171
  layout: o,
@@ -1123,10 +1177,10 @@ var Me = "// the nearest solid splat under one pixel, over the last frame's visi
1123
1177
  module: a,
1124
1178
  entryPoint: "fs",
1125
1179
  targets: [{
1126
- format: ze,
1180
+ format: Ue,
1127
1181
  blend: {
1128
- color: Ve,
1129
- alpha: Ve
1182
+ color: Ge,
1183
+ alpha: Ge
1130
1184
  }
1131
1185
  }]
1132
1186
  },
@@ -1134,7 +1188,7 @@ var Me = "// the nearest solid splat under one pixel, over the last frame's visi
1134
1188
  depthStencil: n
1135
1189
  });
1136
1190
  this.#n = s("Colour"), this.#r = s("Depth", {
1137
- format: Be,
1191
+ format: We,
1138
1192
  depthWriteEnabled: !0,
1139
1193
  depthCompare: "always"
1140
1194
  });
@@ -1161,7 +1215,7 @@ var Me = "// the nearest solid splat under one pixel, over the last frame's visi
1161
1215
  destroy() {
1162
1216
  this.#t.destroy();
1163
1217
  }
1164
- }, Ue = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan, a stable scatter; no spin-waits\n\nconst THREADS: u32 = 128u;\nconst ITEMS: u32 = 8u;\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> bitValues: atomic<u32>;\nvar<workgroup> activeBits: u32;\nvar<workgroup> sk: array<u32, BLOCK>;\nvar<workgroup> sv: array<u32, BLOCK>;\n// three 10-bit counts; the fourth follows from the number of items\nvar<workgroup> counts: array<u32, THREADS * 2u>;\nvar<workgroup> tail: u32;\nvar<workgroup> starts: array<u32, DIGITS>;\nvar<workgroup> offsets: array<u32, DIGITS>;\n\nfn unpack(packed: u32, count: u32) -> vec4u {\n let a = packed & 1023u;\n let b = (packed >> 10u) & 1023u;\n let c = (packed >> 20u) & 1023u;\n return vec4u(a, b, c, count - a - b - c);\n}\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 for (var block = wid.y * groups.x + wid.x; block < state.blocks; block += groups.x * groups.y) {\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 for (var d = t; d < DIGITS; d += THREADS) {\n hist[block * DIGITS + d] = atomicExchange(&bins[d], 0u);\n }\n workgroupBarrier();\n }\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 // a bit varies only when both zero and one occur in nonempty digits\n if (run > 0u) {\n atomicOr(&bitValues, t | ((255u ^ t) << 8u));\n }\n workgroupBarrier();\n if (t == 0u) {\n let values = atomicLoad(&bitValues);\n sums[arrayLength(&sums) - 1u] = values & (values >> 8u);\n }\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 first = wid.y * groups.x + wid.x;\n if (first >= state.blocks) {\n return;\n }\n if (t == 0u) {\n activeBits = sums[arrayLength(&sums) - 1u];\n }\n let bits = workgroupUniformLoad(&activeBits);\n for (var block = first; block < state.blocks; block += groups.x * groups.y) {\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 for (var d = t; d < DIGITS; d += THREADS) {\n offsets[d] = hist[block * DIGITS + d];\n }\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 if ((bits & (3u << bit)) == 0u) {\n continue;\n }\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.x | (mine.y << 10u) | (mine.z << 20u);\n if (t == THREADS - 1u) {\n tail = counts[t];\n }\n workgroupBarrier();\n // separate reads and writes need only one barrier per scan step\n var source = 0u;\n for (var o = 1u; o < THREADS; o *= 2u) {\n var x = counts[source + t];\n if (t >= o) {\n x += counts[source + t - o];\n }\n let dest = source ^ THREADS;\n counts[dest + t] = x;\n workgroupBarrier();\n source = dest;\n }\n // prefixes stop at 1016 items, so no count carries into its neighbour\n let total = unpack(counts[source + THREADS - 2u], BLOCK - ITEMS) + unpack(tail, ITEMS);\n var prior = vec4u(0u);\n if (t > 0u) {\n prior = unpack(counts[source + t - 1u], t * ITEMS);\n }\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 workgroupBarrier();\n }\n}\n", We = 1024, Ge = 64, Ke = 256, F = 3, I = 256, qe = 32, Je = class {
1218
+ }, qe = "// lsd radix sort, 8 bits a pass: block digit counts, a two-level scan, a stable scatter; no spin-waits\n\nconst THREADS: u32 = 128u;\nconst ITEMS: u32 = 8u;\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> bitValues: atomic<u32>;\nvar<workgroup> activeBits: u32;\nvar<workgroup> sk: array<u32, BLOCK>;\nvar<workgroup> sv: array<u32, BLOCK>;\n// three 10-bit counts; the fourth follows from the number of items\nvar<workgroup> counts: array<u32, THREADS * 2u>;\nvar<workgroup> tail: u32;\nvar<workgroup> starts: array<u32, DIGITS>;\nvar<workgroup> offsets: array<u32, DIGITS>;\n\nfn unpack(packed: u32, count: u32) -> vec4u {\n let a = packed & 1023u;\n let b = (packed >> 10u) & 1023u;\n let c = (packed >> 20u) & 1023u;\n return vec4u(a, b, c, count - a - b - c);\n}\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 for (var block = wid.y * groups.x + wid.x; block < state.blocks; block += groups.x * groups.y) {\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 for (var d = t; d < DIGITS; d += THREADS) {\n hist[block * DIGITS + d] = atomicExchange(&bins[d], 0u);\n }\n workgroupBarrier();\n }\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 // a bit varies only when both zero and one occur in nonempty digits\n if (run > 0u) {\n atomicOr(&bitValues, t | ((255u ^ t) << 8u));\n }\n workgroupBarrier();\n if (t == 0u) {\n let values = atomicLoad(&bitValues);\n sums[arrayLength(&sums) - 1u] = values & (values >> 8u);\n }\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 first = wid.y * groups.x + wid.x;\n if (first >= state.blocks) {\n return;\n }\n if (t == 0u) {\n activeBits = sums[arrayLength(&sums) - 1u];\n }\n let bits = workgroupUniformLoad(&activeBits);\n for (var block = first; block < state.blocks; block += groups.x * groups.y) {\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 for (var d = t; d < DIGITS; d += THREADS) {\n offsets[d] = hist[block * DIGITS + d];\n }\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 if ((bits & (3u << bit)) == 0u) {\n continue;\n }\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.x | (mine.y << 10u) | (mine.z << 20u);\n if (t == THREADS - 1u) {\n tail = counts[t];\n }\n workgroupBarrier();\n // separate reads and writes need only one barrier per scan step\n var source = 0u;\n for (var o = 1u; o < THREADS; o *= 2u) {\n var x = counts[source + t];\n if (t >= o) {\n x += counts[source + t - o];\n }\n let dest = source ^ THREADS;\n counts[dest + t] = x;\n workgroupBarrier();\n source = dest;\n }\n // prefixes stop at 1016 items, so no count carries into its neighbour\n let total = unpack(counts[source + THREADS - 2u], BLOCK - ITEMS) + unpack(tail, ITEMS);\n var prior = vec4u(0u);\n if (t > 0u) {\n prior = unpack(counts[source + t - 1u], t * ITEMS);\n }\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 workgroupBarrier();\n }\n}\n", Je = 1024, Ye = 64, Xe = 256, L = 3, R = 256, Ze = 32, Qe = class {
1165
1219
  keys;
1166
1220
  values;
1167
1221
  bytes;
@@ -1174,21 +1228,21 @@ var Me = "// the nearest solid splat under one pixel, over the last frame's visi
1174
1228
  constructor(e, t) {
1175
1229
  let { capacity: n } = t;
1176
1230
  this.keys = n * 8, this.values = n * 12;
1177
- let r = Math.max(1, Math.ceil(n / We));
1231
+ let r = Math.max(1, Math.ceil(n / Je));
1178
1232
  this.#a = r;
1179
- let i = Math.ceil(r / Ge), a = (t, n, r) => e.createBuffer({
1233
+ let i = Math.ceil(r / Ye), a = (t, n, r) => e.createBuffer({
1180
1234
  label: t,
1181
1235
  size: n,
1182
1236
  usage: r
1183
- }), o = GPUBufferUsage.STORAGE, s = a("sort params", F * I, GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST), c = a("sort histograms", r * Ke * 4, o), l = a("sort chunk sums", (i * Ke + 1) * 4, o), u = a("sort state", 12, o);
1237
+ }), o = GPUBufferUsage.STORAGE, s = a("sort params", L * R, GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST), c = a("sort histograms", r * Xe * 4, o), l = a("sort chunk sums", (i * Xe + 1) * 4, o), u = a("sort state", 12, o);
1184
1238
  this.#e = [
1185
1239
  s,
1186
1240
  c,
1187
1241
  l,
1188
1242
  u
1189
1243
  ], this.bytes = this.#e.reduce((e, t) => e + t.size, 0);
1190
- let d = new Uint32Array(F * I / 4);
1191
- for (let e = 0; e < F; e++) {
1244
+ let d = new Uint32Array(L * R / 4);
1245
+ for (let e = 0; e < L; e++) {
1192
1246
  let [t, r] = e % 2 ? [2 * n, 0] : [0, 2 * n];
1193
1247
  d.set([
1194
1248
  8 * e,
@@ -1197,7 +1251,7 @@ var Me = "// the nearest solid splat under one pixel, over the last frame's visi
1197
1251
  n,
1198
1252
  f.projected,
1199
1253
  f.drawArgs
1200
- ], e * I / 4);
1254
+ ], e * R / 4);
1201
1255
  }
1202
1256
  e.queue.writeBuffer(s, 0, d);
1203
1257
  let p = (e, t) => ({
@@ -1219,7 +1273,7 @@ var Me = "// the nearest solid splat under one pixel, over the last frame's visi
1219
1273
  ]
1220
1274
  }), g = e.createShaderModule({
1221
1275
  label: "sort",
1222
- code: P + Ue
1276
+ code: F + qe
1223
1277
  }), _ = (t, n) => e.createComputePipeline({
1224
1278
  label: `sort ${t}`,
1225
1279
  layout: e.createPipelineLayout({ bindGroupLayouts: [n] }),
@@ -1237,8 +1291,8 @@ var Me = "// the nearest solid splat under one pixel, over the last frame's visi
1237
1291
  ].map((e) => _(e, m));
1238
1292
  let v = (e) => ({
1239
1293
  buffer: s,
1240
- offset: e * I,
1241
- size: qe
1294
+ offset: e * R,
1295
+ size: Ze
1242
1296
  });
1243
1297
  this.#r = e.createBindGroup({
1244
1298
  label: "sort prepare",
@@ -1257,7 +1311,7 @@ var Me = "// the nearest solid splat under one pixel, over the last frame's visi
1257
1311
  resource: { buffer: t.work }
1258
1312
  }
1259
1313
  ]
1260
- }), this.#i = Array.from({ length: F }, (n, r) => e.createBindGroup({
1314
+ }), this.#i = Array.from({ length: L }, (n, r) => e.createBindGroup({
1261
1315
  label: `sort pass ${r}`,
1262
1316
  layout: m,
1263
1317
  entries: [
@@ -1285,7 +1339,7 @@ var Me = "// the nearest solid splat under one pixel, over the last frame's visi
1285
1339
  }));
1286
1340
  }
1287
1341
  encode(e, t, n, r) {
1288
- let [i, a, o, s, c] = this.#n, l = Math.max(1, Math.min(this.#a, Math.ceil(t / We))), u = Math.max(l / 16, (n || t) / We), d = m(Math.min(Math.ceil(l / 4), Math.ceil(u))), f = Math.ceil(l / Ge), p = e.beginComputePass({
1342
+ let [i, a, o, s, c] = this.#n, l = Math.max(1, Math.min(this.#a, Math.ceil(t / Je))), u = Math.max(l / 16, (n || t) / Je), d = m(Math.min(Math.ceil(l / 4), Math.ceil(u))), f = Math.ceil(l / Ye), p = e.beginComputePass({
1289
1343
  label: "sort",
1290
1344
  timestampWrites: r
1291
1345
  });
@@ -1296,7 +1350,7 @@ var Me = "// the nearest solid splat under one pixel, over the last frame's visi
1296
1350
  destroy() {
1297
1351
  for (let e of this.#e) e.destroy();
1298
1352
  }
1299
- }, Ye = class {
1353
+ }, $e = class {
1300
1354
  ms = {};
1301
1355
  #e;
1302
1356
  #t;
@@ -1347,14 +1401,14 @@ var Me = "// the nearest solid splat under one pixel, over the last frame's visi
1347
1401
  destroy() {
1348
1402
  this.#t?.destroy(), this.#n?.destroy(), this.#r?.destroy();
1349
1403
  }
1350
- }, Xe = [
1404
+ }, et = [
1351
1405
  "cull",
1352
1406
  "project",
1353
1407
  "sort",
1354
1408
  "raster",
1355
1409
  "heights",
1356
1410
  "post"
1357
- ], L = {
1411
+ ], z = {
1358
1412
  view: 0,
1359
1413
  proj: 16,
1360
1414
  viewProj: 32,
@@ -1367,7 +1421,7 @@ var Me = "// the nearest solid splat under one pixel, over the last frame's visi
1367
1421
  far: 81,
1368
1422
  lowPass: 82,
1369
1423
  clusters: 83
1370
- }, Ze = class {
1424
+ }, tt = class {
1371
1425
  #e;
1372
1426
  #t;
1373
1427
  #n;
@@ -1398,7 +1452,7 @@ var Me = "// the nearest solid splat under one pixel, over the last frame's visi
1398
1452
  #D = 0;
1399
1453
  constructor(e, t, n, r) {
1400
1454
  let { device: i } = e;
1401
- this.#e = i, this.#t = t, this.#n = e.format, this.#r = n, this.#i = b(i, r, n.slots), this.#a = new le(i, n, this.#i), this.#o = new Ce(i, n, this.#i), this.#s = new Je(i, this.#i), this.#c = new He(i, this.#i, this.#s), this.#u = new ge(i, n), this.#d = new Le(i, n, this.#i), this.#f = new Oe(i, e.format, this.#i.uniforms), this.#p = new Ye(i, e.timestamps, Xe), this.#w = i.createBuffer({
1455
+ this.#e = i, this.#t = t, this.#n = e.format, this.#r = n, this.#i = b(i, r, n.slots), this.#a = new de(i, n, this.#i), this.#o = new Te(i, n, this.#i), this.#s = new Qe(i, this.#i), this.#c = new Ke(i, this.#i, this.#s), this.#u = new ve(i, n), this.#d = new Be(i, n, this.#i), this.#f = new Ae(i, e.format, this.#i.uniforms), this.#p = new $e(i, e.timestamps, et), this.#w = i.createBuffer({
1402
1456
  label: "counts readback",
1403
1457
  size: (f.projected + 1) * 4,
1404
1458
  usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
@@ -1435,7 +1489,7 @@ var Me = "// the nearest solid splat under one pixel, over the last frame's visi
1435
1489
  this.#f.set(e, t);
1436
1490
  }
1437
1491
  render(e, t, n, r) {
1438
- let i = this.#e, a = this.#p, o = this.#y, s = this.#j(this.#A("colour", ze)), c = this.#f.count > 0, l = c || o.some(({ post: e }) => e.depth), u = this.#M("depth", Be, l), d = u ? this.#j(u) : null, p = [this.#M("ping", this.#n, o.length > 1), this.#M("pong", this.#n, o.length > 2)];
1492
+ let i = this.#e, a = this.#p, o = this.#y, s = this.#j(this.#A("colour", Ue)), c = this.#f.count > 0, l = c || o.some(({ post: e }) => e.depth), u = this.#M("depth", We, l), d = u ? this.#j(u) : null, p = [this.#M("ping", this.#n, o.length > 1), this.#M("pong", this.#n, o.length > 2)];
1439
1493
  this.#k(e, t);
1440
1494
  let m = i.createCommandEncoder({ label: "frame" });
1441
1495
  m.clearBuffer(this.#i.work, 0, f.list * 4), this.#a.encode(m, a.writes("cull")), this.#o.encode(m, this.#D, a.writes("project")), this.#s.encode(m, this.#r.listed * 256, this.#E, a.writes("sort")), this.#c.encode(m, s, d, n, a.writes("raster"));
@@ -1451,7 +1505,7 @@ var Me = "// the nearest solid splat under one pixel, over the last frame's visi
1451
1505
  } }).end();
1452
1506
  }
1453
1507
  let _ = this.#t.getCurrentTexture().createView();
1454
- if (!o.length) this.#l ??= be(i, this.#n), this.#l.encode(m, [s], _);
1508
+ if (!o.length) this.#l ??= Se(i, this.#n), this.#l.encode(m, [s], _);
1455
1509
  else {
1456
1510
  let t = s;
1457
1511
  o.forEach(({ post: n, pass: r }, i) => {
@@ -1493,7 +1547,7 @@ var Me = "// the nearest solid splat under one pixel, over the last frame's visi
1493
1547
  }
1494
1548
  #k(e, t) {
1495
1549
  let n = this.#m, [r, i] = [this.#S, this.#C];
1496
- n.set(e.view, L.view), n.set(e.proj, L.proj), n.set(N(this.#g, e.proj, e.view), L.viewProj), n.set(t, L.planes), n.set(e.camera.subarray(0, 3), L.camera), n[L.time] = e.time, n.set([r, i], L.viewport), n.set([e.proj[0] * r / 2, e.proj[5] * i / 2], L.focal), n[L.near] = e.near, n[L.far] = e.far, n[L.lowPass] = h, this.#h[L.clusters] = this.#r.listed, this.#e.queue.writeBuffer(this.#i.uniforms, 0, n);
1550
+ n.set(e.view, z.view), n.set(e.proj, z.proj), n.set(P(this.#g, e.proj, e.view), z.viewProj), n.set(t, z.planes), n.set(e.camera.subarray(0, 3), z.camera), n[z.time] = e.time, n.set([r, i], z.viewport), n.set([e.proj[0] * r / 2, e.proj[5] * i / 2], z.focal), n[z.near] = e.near, n[z.far] = e.far, n[z.lowPass] = h, this.#h[z.clusters] = this.#r.listed, this.#e.queue.writeBuffer(this.#i.uniforms, 0, n);
1497
1551
  for (let { shade: t, slot: n } of this.#v) t.update(e, this.#_.subarray(n * 4, (n + t.uniforms) * 4));
1498
1552
  this.#v.length && this.#e.queue.writeBuffer(this.#i.plugins, 0, this.#_);
1499
1553
  }
@@ -1529,7 +1583,7 @@ var Me = "// the nearest solid splat under one pixel, over the last frame's visi
1529
1583
  };
1530
1584
  //#endregion
1531
1585
  //#region src/engine/layer.ts
1532
- async function Qe(e, n) {
1586
+ async function nt(e, n) {
1533
1587
  let i = await r(async (t, n) => e.subarray(t, n), e.length);
1534
1588
  if (i.length === 0) throw Error("the pack holds no pages");
1535
1589
  let a = Math.min(...i.map((e) => e.g));
@@ -1541,7 +1595,7 @@ async function Qe(e, n) {
1541
1595
  };
1542
1596
  }));
1543
1597
  }
1544
- function $e(e) {
1598
+ function rt(e) {
1545
1599
  let t = (t) => [Math.min(...e.map((e) => e[t])), Math.max(...e.map((e) => e[t + 3]))];
1546
1600
  return {
1547
1601
  e: t(0),
@@ -1549,19 +1603,19 @@ function $e(e) {
1549
1603
  h: t(2)
1550
1604
  };
1551
1605
  }
1552
- var et = class {
1606
+ var it = class {
1553
1607
  #e = /* @__PURE__ */ new Map();
1554
1608
  update(e, t, n, r) {
1555
- let i = this.#e, a = tt(e, t), o = -1;
1556
- for (let [e, r] of i) t(r.page.id) ? (o = Math.max(o, r.level), !r.held && (r.start !== null && n - r.start >= 250 && (r.start = null), a.has(e) || (r.frozen = R(r, n), r.start = null, r.out = null, r.covered = !1, r.held = !0))) : i.delete(e);
1609
+ let i = this.#e, a = at(e, t), o = -1;
1610
+ for (let [e, r] of i) t(r.page.id) ? (o = Math.max(o, r.level), !r.held && (r.start !== null && n - r.start >= 250 && (r.start = null), a.has(e) || (r.frozen = B(r, n), r.start = null, r.out = null, r.covered = !1, r.held = !0))) : i.delete(e);
1557
1611
  let s = /* @__PURE__ */ new Set();
1558
1612
  for (let [e, t] of a) {
1559
1613
  let r = i.get(e);
1560
1614
  if (!r) {
1561
- let r = nt(t, e % 4, n);
1615
+ let r = ot(t, e % 4, n);
1562
1616
  o = Math.max(o, r.level), i.set(e, r), s.add(r);
1563
1617
  } else if (r.held) {
1564
- let e = R(r, n);
1618
+ let e = B(r, n);
1565
1619
  r.held = !1, r.out = null, e < 255 && (r.start = n - e / 255 * 250, s.add(r));
1566
1620
  }
1567
1621
  }
@@ -1569,14 +1623,14 @@ var et = class {
1569
1623
  for (let e of i.values()) if (e.held) {
1570
1624
  c.set(e.cell, e);
1571
1625
  for (let t = e.level, n = e.col, r = e.row; t <= o; t++, n >>= 1, r >>= 1) {
1572
- let i = rt(t, n, r), a = l.get(i);
1626
+ let i = st(t, n, r), a = l.get(i);
1573
1627
  a ? a.push(e) : l.set(i, [e]);
1574
1628
  }
1575
1629
  }
1576
1630
  let u = (e) => {
1577
1631
  let t = [...l.get(e.cell) ?? []];
1578
1632
  for (let n = e.level + 1, r = e.col >> 1, i = e.row >> 1; n <= o; n++, r >>= 1, i >>= 1) {
1579
- let e = c.get(rt(n, r, i));
1633
+ let e = c.get(st(n, r, i));
1580
1634
  e && t.push(e);
1581
1635
  }
1582
1636
  return t;
@@ -1600,13 +1654,13 @@ var et = class {
1600
1654
  }
1601
1655
  let v = /* @__PURE__ */ new Map(), y = !1;
1602
1656
  for (let [e, t] of i) {
1603
- if (t.held && f.has(t)) t.out !== null && (t.frozen = R(t, n)), t.out = null, t.covered = !0;
1604
- else if (t.held && (t.covered && t.out === null && (t.out = n), !t.covered || R(t, n) === 0)) {
1657
+ if (t.held && f.has(t)) t.out !== null && (t.frozen = B(t, n)), t.out = null, t.covered = !0;
1658
+ else if (t.held && (t.covered && t.out === null && (t.out = n), !t.covered || B(t, n) === 0)) {
1605
1659
  i.delete(e);
1606
1660
  continue;
1607
1661
  }
1608
1662
  (t.held || t.start !== null) && (y = !0);
1609
- let r = R(t, n);
1663
+ let r = B(t, n);
1610
1664
  if (!r) continue;
1611
1665
  let a = v.get(t.page.id);
1612
1666
  a ? a.factors = (a.factors | r << 8 * t.q) >>> 0 : v.set(t.page.id, {
@@ -1620,7 +1674,7 @@ var et = class {
1620
1674
  };
1621
1675
  }
1622
1676
  };
1623
- function tt(e, t) {
1677
+ function at(e, t) {
1624
1678
  let n = new Set(e), r = /* @__PURE__ */ new Set(), i = [];
1625
1679
  for (let t of e) for (let e = t; e && !r.has(e); e = e.parent) r.add(e), e.parent || i.push(e);
1626
1680
  let a = /* @__PURE__ */ new Map(), o = (e) => {
@@ -1632,7 +1686,7 @@ function tt(e, t) {
1632
1686
  for (let e of i) t(e.id) && o(e);
1633
1687
  return a;
1634
1688
  }
1635
- function nt(e, t, n) {
1689
+ function ot(e, t, n) {
1636
1690
  let r = c * 2 ** e.g, i = e.g - 1, a = 2 * (Math.round(e.unit.e / r) + e.row.i) + (t & 1), o = 2 * (Math.round(e.unit.n / r) + e.row.j) + (t >> 1);
1637
1691
  return {
1638
1692
  page: e,
@@ -1640,8 +1694,8 @@ function nt(e, t, n) {
1640
1694
  level: i,
1641
1695
  col: a,
1642
1696
  row: o,
1643
- cell: rt(i, a, o),
1644
- splats: it(e.row, t),
1697
+ cell: st(i, a, o),
1698
+ splats: ct(e.row, t),
1645
1699
  start: n,
1646
1700
  frozen: 0,
1647
1701
  out: null,
@@ -1649,56 +1703,56 @@ function nt(e, t, n) {
1649
1703
  held: !1
1650
1704
  };
1651
1705
  }
1652
- var rt = (e, t, n) => ((e + 1) * 2 ** 21 + t) * 2 ** 21 + n;
1653
- function it({ count: e, quadrants: t }, n) {
1706
+ var st = (e, t, n) => ((e + 1) * 2 ** 21 + t) * 2 ** 21 + n;
1707
+ function ct({ count: e, quadrants: t }, n) {
1654
1708
  return (n < 3 ? t[n] : e) - (n > 0 ? t[n - 1] : 0);
1655
1709
  }
1656
- function R(e, t) {
1710
+ function B(e, t) {
1657
1711
  return e.held ? e.out === null ? e.frozen : Math.max(0, Math.round(e.frozen * (1 - (t - e.out) / 250))) : e.start === null ? 255 : Math.min(255, Math.round((t - e.start) / 250 * 255));
1658
1712
  }
1659
1713
  //#endregion
1660
1714
  //#region src/engine/plan/footprint.ts
1661
- var at = [
1715
+ var lt = [
1662
1716
  0,
1663
1717
  0,
1664
1718
  0
1665
1719
  ];
1666
- function ot(e, t, n, r) {
1720
+ function ut(e, t, n, r) {
1667
1721
  let i = (e * e + e * t + t * t + n * n + n * r + r * r) / 3;
1668
1722
  return 1 + 15 * Math.max(0, 1 - i) ** 2;
1669
1723
  }
1670
- function st(e, t, n, r, i, a, o, s = 1, c = {
1724
+ function dt(e, t, n, r, i, a, o, s = 1, c = {
1671
1725
  shown: !1,
1672
1726
  pixels: 0,
1673
1727
  weight: 1
1674
- }, l = at) {
1728
+ }, l = lt) {
1675
1729
  let u = (e[0] + e[3]) / 2 - l[0], d = (e[1] + e[4]) / 2 - l[1], f = (e[2] + e[5]) / 2 - l[2], p = (e[3] - e[0]) / 2, m = (e[4] - e[1]) / 2, h = (e[5] - e[2]) / 2, g = t[0] * u + t[4] * d + t[8] * f + t[12], _ = t[1] * u + t[5] * d + t[9] * f + t[13], v = -(t[2] * u + t[6] * d + t[10] * f + t[14]), y = Math.abs(t[0]) * p + Math.abs(t[4]) * m + Math.abs(t[8]) * h, b = Math.abs(t[1]) * p + Math.abs(t[5]) * m + Math.abs(t[9]) * h, x = Math.abs(t[2]) * p + Math.abs(t[6]) * m + Math.abs(t[10]) * h;
1676
1730
  if (c.pixels = 0, c.weight = 1, c.shown = !1, v + x < a || v - x > o) return c;
1677
1731
  let S = Math.max(a, v - x), C = Math.max(a, v + x), w = i * n / r;
1678
1732
  if (Math.abs(g) - y > s * w * C || Math.abs(_) - b > s * i * C) return c;
1679
1733
  let T = Math.min((g - y) / S, (g - y) / C) / w, E = Math.max((g + y) / S, (g + y) / C) / w, D = Math.min((_ - b) / S, (_ - b) / C) / i, O = Math.max((_ + b) / S, (_ + b) / C) / i;
1680
1734
  if (E < -s || T > s || O < -s || D > s) return c;
1681
- let k = Math.max(-s, T), A = Math.min(s, E), j = Math.max(-s, D), M = Math.min(s, O), ee = (E - T) * (O - D), te = (A - k) * (M - j);
1682
- return ee <= 0 || te <= 0 || (c.shown = E > -1 && T < 1 && O > -1 && D < 1, c.pixels = ee * n * r / 4, c.weight = ot(k, A, j, M)), c;
1735
+ let k = Math.max(-s, T), A = Math.min(s, E), j = Math.max(-s, D), M = Math.min(s, O), N = (E - T) * (O - D), ee = (A - k) * (M - j);
1736
+ return N <= 0 || ee <= 0 || (c.shown = E > -1 && T < 1 && O > -1 && D < 1, c.pixels = N * n * r / 4, c.weight = ut(k, A, j, M)), c;
1683
1737
  }
1684
- var z = /* @__PURE__ */ new Float64Array(6), ct = {
1738
+ var V = /* @__PURE__ */ new Float64Array(6), ft = {
1685
1739
  shown: !1,
1686
1740
  pixels: 0,
1687
1741
  weight: 1
1688
1742
  };
1689
- function lt(e, [t, n, r], i, a, o, s, c, l, u = at) {
1743
+ function pt(e, [t, n, r], i, a, o, s, c, l, u = lt) {
1690
1744
  let d = r / 2, f = Math.max(0, t - e[0], n - e[1], e[3] - t - r, e[4] - n - r);
1691
- z[2] = e[2], z[5] = e[5];
1745
+ V[2] = e[2], V[5] = e[5];
1692
1746
  let p = 0;
1693
1747
  for (let r = 0; r < 4; r++) {
1694
1748
  let m = t + (r & 1) * d, h = n + (r >> 1) * d;
1695
- z[0] = Math.max(e[0], m - f), z[1] = Math.max(e[1], h - f), z[3] = Math.min(e[3], m + d + f), z[4] = Math.min(e[4], h + d + f), !(z[0] > z[3] || z[1] > z[4]) && st(z, i, a, o, s, c, l, 1, ct, u).shown && (p |= 1 << r);
1749
+ V[0] = Math.max(e[0], m - f), V[1] = Math.max(e[1], h - f), V[3] = Math.min(e[3], m + d + f), V[4] = Math.min(e[4], h + d + f), !(V[0] > V[3] || V[1] > V[4]) && dt(V, i, a, o, s, c, l, 1, ft, u).shown && (p |= 1 << r);
1696
1750
  }
1697
1751
  return p;
1698
1752
  }
1699
1753
  //#endregion
1700
1754
  //#region src/engine/world/tree.ts
1701
- var B = (e, t, n) => (e * 256 + t) * 256 + n, ut = class {
1755
+ var H = (e, t, n) => (e * 256 + t) * 256 + n, mt = class {
1702
1756
  roots = [];
1703
1757
  pages = /* @__PURE__ */ new Map();
1704
1758
  units = /* @__PURE__ */ new Map();
@@ -1708,10 +1762,10 @@ var B = (e, t, n) => (e * 256 + t) * 256 + n, ut = class {
1708
1762
  #r = /* @__PURE__ */ new Map();
1709
1763
  #i = /* @__PURE__ */ new Map();
1710
1764
  constructor(e) {
1711
- this.#e = new Set(e.roots.map(V)), this.#t = Math.max(...e.roots.map((e) => e.level));
1765
+ this.#e = new Set(e.roots.map(U)), this.#t = Math.max(...e.roots.map((e) => e.level));
1712
1766
  }
1713
1767
  add(e, t) {
1714
- let n = V(e), r = this.units.get(n);
1768
+ let n = U(e), r = this.units.get(n);
1715
1769
  if (r) return r;
1716
1770
  let a = /* @__PURE__ */ new Map(), o = {
1717
1771
  level: e.level,
@@ -1738,34 +1792,34 @@ var B = (e, t, n) => (e * 256 + t) * 256 + n, ut = class {
1738
1792
  null
1739
1793
  ]
1740
1794
  };
1741
- this.pages.set(r.id, r), o.pages.push(r), a.set(B(t.g, t.i, t.j), r);
1795
+ this.pages.set(r.id, r), o.pages.push(r), a.set(H(t.g, t.i, t.j), r);
1742
1796
  }
1743
1797
  this.units.set(n, o), this.#r.delete(n);
1744
1798
  for (let t = e.level + 1; t <= this.#t; t++) {
1745
- let n = V(H(e, t));
1799
+ let n = U(W(e, t));
1746
1800
  this.#i.set(n, (this.#i.get(n) ?? 0) + 1);
1747
1801
  }
1748
1802
  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));
1749
1803
  for (let e of o.pages) {
1750
1804
  let { g: t, i: n, j: r } = e.row;
1751
- c.has(t + 1) && (e.parent = a.get(B(t + 1, n >> 1, r >> 1)) ?? null);
1805
+ c.has(t + 1) && (e.parent = a.get(H(t + 1, n >> 1, r >> 1)) ?? null);
1752
1806
  for (let i = 0; i < 4; i++) {
1753
1807
  let o = 2 * n + (i & 1), s = 2 * r + (i >> 1);
1754
- c.has(t - 1) ? e.children[i] = a.get(B(t - 1, o, s)) ?? null : t === u && t > 0 && (e.children[i] = d.has((o >> 3) + 2 * (s >> 3)) ? void 0 : null);
1808
+ c.has(t - 1) ? e.children[i] = a.get(H(t - 1, o, s)) ?? null : t === u && t > 0 && (e.children[i] = d.has((o >> 3) + 2 * (s >> 3)) ? void 0 : null);
1755
1809
  }
1756
1810
  }
1757
1811
  if (this.#e.has(n)) for (let e of o.pages) e.g === l && this.roots.push(e);
1758
1812
  else {
1759
- let t = this.units.get(V(H(e, e.level + 1)));
1813
+ let t = this.units.get(U(W(e, e.level + 1)));
1760
1814
  t && this.#o(t, o);
1761
1815
  }
1762
1816
  let f = i(o.idx);
1763
1817
  for (let { key: t } of f) {
1764
- let n = t.level === e.level - 1 ? this.units.get(V(t)) : void 0;
1818
+ let n = t.level === e.level - 1 ? this.units.get(U(t)) : void 0;
1765
1819
  n && this.#o(o, n);
1766
1820
  }
1767
1821
  for (let { key: e, hash: t } of f) {
1768
- let n = V(e);
1822
+ let n = U(e);
1769
1823
  if (this.units.has(n)) continue;
1770
1824
  let r = this.#r.get(n);
1771
1825
  if (r && r.from <= o.level) continue;
@@ -1786,19 +1840,19 @@ var B = (e, t, n) => (e * 256 + t) * 256 + n, ut = class {
1786
1840
  }
1787
1841
  ground(e, t) {
1788
1842
  for (let n of this.roots) {
1789
- let [r, i, a] = ft(n);
1843
+ let [r, i, a] = gt(n);
1790
1844
  if (e < r || e >= r + a || t < i || t >= i + a) continue;
1791
1845
  let o = n;
1792
1846
  for (;;) {
1793
1847
  let n = +(e >= r + a / 2), s = +(t >= i + a / 2), c = o.children[n + 2 * s];
1794
1848
  if (!c) return o.box[2];
1795
- o = c, [r, i, a] = ft(o);
1849
+ o = c, [r, i, a] = gt(o);
1796
1850
  }
1797
1851
  }
1798
1852
  }
1799
1853
  async load(e, t, n) {
1800
1854
  for (;;) {
1801
- let r = this.wanted().filter((n) => dt(n, e, t));
1855
+ let r = this.wanted().filter((n) => ht(n, e, t));
1802
1856
  if (r.length === 0) return;
1803
1857
  (await Promise.all(r.map((e) => n(e.path)))).forEach((e, t) => this.add(e, r[t].path));
1804
1858
  }
@@ -1806,7 +1860,7 @@ var B = (e, t, n) => (e * 256 + t) * 256 + n, ut = class {
1806
1860
  prune(e) {
1807
1861
  let t = [], n = [...this.units.values()].sort((e, t) => e.level - t.level);
1808
1862
  for (let r of n) {
1809
- let n = V(r);
1863
+ let n = U(r);
1810
1864
  if (this.#e.has(n) || this.#i.has(n) || r.pages.some((t) => e.has(t.id))) continue;
1811
1865
  for (let e of r.pages) this.pages.delete(e.id), t.push(e.id);
1812
1866
  let a = r.parent;
@@ -1816,7 +1870,7 @@ var B = (e, t, n) => (e * 256 + t) * 256 + n, ut = class {
1816
1870
  }
1817
1871
  this.units.delete(n);
1818
1872
  for (let e = r.level + 1; e <= this.#t; e++) {
1819
- let t = V(H(r, e)), n = this.#i.get(t) - 1;
1873
+ let t = U(W(r, e)), n = this.#i.get(t) - 1;
1820
1874
  n ? this.#i.set(t, n) : this.#i.delete(t);
1821
1875
  }
1822
1876
  for (let { key: e } of i(r.idx)) this.#a(e);
@@ -1825,12 +1879,12 @@ var B = (e, t, n) => (e * 256 + t) * 256 + n, ut = class {
1825
1879
  return t;
1826
1880
  }
1827
1881
  #a(e) {
1828
- let t = V(e);
1882
+ let t = U(e);
1829
1883
  this.#r.delete(t);
1830
1884
  for (let n = e.level + 1; n <= e.level + 3; n++) {
1831
- let r = this.units.get(V(H(e, n)));
1885
+ let r = this.units.get(U(W(e, n)));
1832
1886
  if (!r) continue;
1833
- let a = i(r.idx).find((e) => V(e.key) === t);
1887
+ let a = i(r.idx).find((e) => U(e.key) === t);
1834
1888
  if (!a) continue;
1835
1889
  let o = {
1836
1890
  level: e.level,
@@ -1852,23 +1906,23 @@ var B = (e, t, n) => (e * 256 + t) * 256 + n, ut = class {
1852
1906
  for (let n of this.#s(e, t)) n.children.fill(null);
1853
1907
  for (let e of t.pages) {
1854
1908
  if (e.g !== n) continue;
1855
- let t = 8 * i + e.row.i, r = 8 * a + e.row.j, s = o.get(B(n + 1, t >> 1, r >> 1)) ?? null;
1909
+ let t = 8 * i + e.row.i, r = 8 * a + e.row.j, s = o.get(H(n + 1, t >> 1, r >> 1)) ?? null;
1856
1910
  e.parent = s, s && (s.children[(t & 1) + 2 * (r & 1)] = e);
1857
1911
  }
1858
1912
  }
1859
1913
  #s(e, t) {
1860
1914
  let n = e.level + 1, r = c * 2 ** n, i = (t.e - e.e) / r, a = (t.n - e.n) / r, o = 250 * 2 ** t.level / r, s = [];
1861
1915
  for (let t = a; t < a + o; t++) for (let r = i; r < i + o; r++) {
1862
- let i = e.grid.get(B(n, r, t));
1916
+ let i = e.grid.get(H(n, r, t));
1863
1917
  i && s.push(i);
1864
1918
  }
1865
1919
  return s;
1866
1920
  }
1867
1921
  };
1868
- function V(e) {
1922
+ function U(e) {
1869
1923
  return `${e.level}/${e.e}/${e.n}`;
1870
1924
  }
1871
- function H(e, t) {
1925
+ function W(e, t) {
1872
1926
  let n = 250 * 2 ** t;
1873
1927
  return {
1874
1928
  level: t,
@@ -1876,11 +1930,11 @@ function H(e, t) {
1876
1930
  n: Math.floor(e.n / n) * n
1877
1931
  };
1878
1932
  }
1879
- function dt(e, t, n) {
1933
+ function ht(e, t, n) {
1880
1934
  let r = 250 * 2 ** e.level;
1881
1935
  return t >= e.e && t < e.e + r && n >= e.n && n < e.n + r;
1882
1936
  }
1883
- function ft(e) {
1937
+ function gt(e) {
1884
1938
  let t = c * 2 ** e.g;
1885
1939
  return [
1886
1940
  e.unit.e + e.row.i * t,
@@ -1890,7 +1944,7 @@ function ft(e) {
1890
1944
  }
1891
1945
  //#endregion
1892
1946
  //#region src/engine/plan/cut.ts
1893
- var pt = 1 / .8 ** 2, mt = 1.1, ht = class {
1947
+ var _t = 1 / .8 ** 2, vt = 1.1, yt = class {
1894
1948
  #e = /* @__PURE__ */ new Map();
1895
1949
  #t = /* @__PURE__ */ new Map();
1896
1950
  #n = {
@@ -1899,13 +1953,13 @@ var pt = 1 / .8 ** 2, mt = 1.1, ht = class {
1899
1953
  weight: 1
1900
1954
  };
1901
1955
  plan(e, t, n, r) {
1902
- let { budget: i, capacity: a, now: o, predicted: s } = r, c = [], l = [], u = [], f = /* @__PURE__ */ new Map(), p = /* @__PURE__ */ new Map(), m = e.wanted(), h = /* @__PURE__ */ new Map(), g = new vt(), _ = 0, v = 0, y = (e) => {
1956
+ let { budget: i, capacity: a, now: o, predicted: s } = r, c = [], l = [], u = [], f = /* @__PURE__ */ new Map(), p = /* @__PURE__ */ new Map(), m = e.wanted(), h = /* @__PURE__ */ new Map(), g = new St(), _ = 0, v = 0, y = (e) => {
1903
1957
  let t = e.page, r = t.row.count;
1904
1958
  c.push(t), l.push(e.visible), u.push(e.near), v += d(r), _ += e.visible;
1905
1959
  let i = this.#e.get(t.id), a = i !== void 0, s = e.pixels * e.weight, f = s / Math.max(1, r);
1906
1960
  m.length && e.pixels > 0 && h.set(t.id, f);
1907
1961
  let p = a && !e.shown && o - (this.#t.get(t.id) ?? -Infinity) <= 1500 ? i : null;
1908
- (r < s * (a ? pt : 1) || p !== null) && _t(t, n) && g.push({
1962
+ (r < s * (a ? _t : 1) || p !== null) && xt(t, n) && g.push({
1909
1963
  page: t,
1910
1964
  shown: e.shown,
1911
1965
  held: p,
@@ -1965,35 +2019,35 @@ var pt = 1 / .8 ** 2, mt = 1.1, ht = class {
1965
2019
  };
1966
2020
  }
1967
2021
  #r(e, t, n) {
1968
- let r = this.#i(e, t, mt), i = r.shown, { pixels: a, weight: o } = r, s = i;
2022
+ let r = this.#i(e, t, vt), i = r.shown, { pixels: a, weight: o } = r, s = i;
1969
2023
  if (n) {
1970
- let t = this.#i(e, n, mt);
2024
+ let t = this.#i(e, n, vt);
1971
2025
  t.pixels > a && ({pixels: a, weight: o} = t), s ||= t.shown;
1972
2026
  }
1973
2027
  return {
1974
2028
  page: e,
1975
2029
  shown: i,
1976
2030
  near: s,
1977
- visible: i ? gt(e, t) : 0,
2031
+ visible: i ? bt(e, t) : 0,
1978
2032
  pixels: a,
1979
2033
  weight: o
1980
2034
  };
1981
2035
  }
1982
2036
  #i(e, t, n) {
1983
2037
  let { width: r, height: i, tan: a, near: o, far: s } = t;
1984
- return st(e.box, t.view, r, i, a, o, s, n, this.#n, t.origin);
2038
+ return dt(e.box, t.view, r, i, a, o, s, n, this.#n, t.origin);
1985
2039
  }
1986
2040
  };
1987
- function gt(e, t) {
1988
- let { width: n, height: r, tan: i, near: a, far: o, origin: s } = t, c = lt(e.box, ft(e), t.view, n, r, i, a, o, s), l = 0;
1989
- for (let t = 0; t < 4; t++) c & 1 << t && (l += it(e.row, t));
2041
+ function bt(e, t) {
2042
+ let { width: n, height: r, tan: i, near: a, far: o, origin: s } = t, c = pt(e.box, gt(e), t.view, n, r, i, a, o, s), l = 0;
2043
+ for (let t = 0; t < 4; t++) c & 1 << t && (l += ct(e.row, t));
1990
2044
  return l;
1991
2045
  }
1992
- function _t(e, t) {
2046
+ function xt(e, t) {
1993
2047
  let { children: n } = e;
1994
2048
  return e.g > 0 && t(e.id) && !n.includes(void 0) && n.some((e) => e !== null);
1995
2049
  }
1996
- var vt = class {
2050
+ var St = class {
1997
2051
  #e = [];
1998
2052
  get size() {
1999
2053
  return this.#e.length;
@@ -2004,7 +2058,7 @@ var vt = class {
2004
2058
  let n = t.length - 1;
2005
2059
  for (; n > 0;) {
2006
2060
  let r = n - 1 >> 1;
2007
- if (!U(e, t[r])) break;
2061
+ if (!Ct(e, t[r])) break;
2008
2062
  t[n] = t[r], n = r;
2009
2063
  }
2010
2064
  t[n] = e;
@@ -2015,7 +2069,7 @@ var vt = class {
2015
2069
  let t = 0;
2016
2070
  for (; 2 * t + 1 < e.length;) {
2017
2071
  let r = 2 * t + 1;
2018
- if (r + 1 < e.length && U(e[r + 1], e[r]) && r++, !U(e[r], n)) break;
2072
+ if (r + 1 < e.length && Ct(e[r + 1], e[r]) && r++, !Ct(e[r], n)) break;
2019
2073
  e[t] = e[r], t = r;
2020
2074
  }
2021
2075
  e[t] = n;
@@ -2023,21 +2077,21 @@ var vt = class {
2023
2077
  return t;
2024
2078
  }
2025
2079
  };
2026
- function U(e, t) {
2080
+ function Ct(e, t) {
2027
2081
  return e.shown === t.shown ? e.ratio > t.ratio : e.shown;
2028
2082
  }
2029
2083
  //#endregion
2030
2084
  //#region src/engine/quality.ts
2031
- var yt = 5e5, bt = 2073600, xt = [1, .85], St = 30, Ct = 55, wt = 2e3, Tt = 5e3, Et = 5e5, Dt = .9;
2032
- function Ot(e, t, n, r) {
2033
- return Math.min(n, Math.sqrt(bt / Math.max(1, e * t))) * r;
2085
+ var wt = 5e5, Tt = 2073600, Et = [1, .85], Dt = 30, Ot = 55, kt = 2e3, At = 5e3, jt = 5e5, Mt = .9;
2086
+ function Nt(e, t, n, r) {
2087
+ return Math.min(n, Math.sqrt(Tt / Math.max(1, e * t))) * r;
2034
2088
  }
2035
- function kt(e, t) {
2089
+ function Pt(e, t) {
2036
2090
  if (!e.length) return 0;
2037
2091
  let n = [...e].sort((e, t) => e - t);
2038
2092
  return n[Math.ceil(n.length * t) - 1];
2039
2093
  }
2040
- var At = class {
2094
+ var Ft = class {
2041
2095
  #e = 0;
2042
2096
  #t;
2043
2097
  #n;
@@ -2050,7 +2104,7 @@ var At = class {
2050
2104
  this.#n = t, this.#r = Math.max(t, n), this.#t = Math.min(this.#r, Math.max(this.#n, e));
2051
2105
  }
2052
2106
  get scale() {
2053
- return xt[this.#e];
2107
+ return Et[this.#e];
2054
2108
  }
2055
2109
  get budget() {
2056
2110
  return this.#t;
@@ -2069,19 +2123,19 @@ var At = class {
2069
2123
  ms: e
2070
2124
  }), this.#i = this.#i.filter((n) => t - n.time <= Math.max(1e3, 2 * e)), t - this.#i[0].time < 300) return !1;
2071
2125
  let a = this.#i.reduce((e, t) => e + t.ms, 0) / this.#i.length;
2072
- if (this.#o = a > 1e3 / St ? this.#o + i : 0, this.#s = a <= 1e3 / Ct ? this.#s + i : 0, this.#o >= wt) {
2073
- let e = Math.floor(Math.min(.9, 1e3 / St / a) * this.#t);
2126
+ if (this.#o = a > 1e3 / Dt ? this.#o + i : 0, this.#s = a <= 1e3 / Ot ? this.#s + i : 0, this.#o >= kt) {
2127
+ let e = Math.floor(Math.min(.9, 1e3 / Dt / a) * this.#t);
2074
2128
  if (this.#t > this.#n) this.#t = Math.max(this.#n, e);
2075
- else if (this.#e < xt.length - 1) this.#e++;
2129
+ else if (this.#e < Et.length - 1) this.#e++;
2076
2130
  else return !1;
2077
- } else if (this.#s >= Tt) {
2131
+ } else if (this.#s >= At) {
2078
2132
  if (this.#e > 0) this.#e--;
2079
- else if (this.#t < this.#r && r >= Dt * this.#t) this.#t = Math.min(this.#r, this.#t + Et);
2133
+ else if (this.#t < this.#r && r >= Mt * this.#t) this.#t = Math.min(this.#r, this.#t + jt);
2080
2134
  else return !1;
2081
2135
  } else return !1;
2082
2136
  return this.#c(), !0;
2083
2137
  }
2084
- }, jt = class {
2138
+ }, It = class {
2085
2139
  #e;
2086
2140
  #t = [];
2087
2141
  #n = /* @__PURE__ */ new Set();
@@ -2160,12 +2214,12 @@ var At = class {
2160
2214
  pages: o
2161
2215
  };
2162
2216
  }
2163
- }, Mt = {
2217
+ }, Lt = {
2164
2218
  idx: 8,
2165
2219
  concurrency: 8,
2166
2220
  gap: 65536,
2167
2221
  span: 2097152
2168
- }, Nt = 1e3, Pt = 3e4, Ft = 1e3, It = 2e3, Lt = class {
2222
+ }, Rt = 1e3, zt = 3e4, Bt = 1e3, Vt = 2e3, Ht = class {
2169
2223
  #e;
2170
2224
  #t;
2171
2225
  #n;
@@ -2195,8 +2249,8 @@ var At = class {
2195
2249
  #y = -Infinity;
2196
2250
  #b = !1;
2197
2251
  #x = !1;
2198
- constructor(e, t, n, r, i, a = Mt) {
2199
- this.#e = e, this.#t = t, this.#n = n, this.#r = r, this.#i = i, this.#a = a, this.#o = new jt(a);
2252
+ constructor(e, t, n, r, i, a = Lt) {
2253
+ this.#e = e, this.#t = t, this.#n = n, this.#r = r, this.#i = i, this.#a = a, this.#o = new It(a);
2200
2254
  }
2201
2255
  update(e, t, n) {
2202
2256
  if (!this.#x) {
@@ -2262,7 +2316,7 @@ var At = class {
2262
2316
  #T = ({ id: e, page: t }) => {
2263
2317
  if (this.#x) return;
2264
2318
  let n = this.#e.pages.get(e);
2265
- n && (this.#n.add(e, t, [n.unit.e, n.unit.n], this.protects) ? (this.#g.add(e), this.#m.delete(e) && this.#j(e)) : (this.#m.set(e, this.#u + Ft), this.#A(e, Ft)), this.#r());
2319
+ n && (this.#n.add(e, t, [n.unit.e, n.unit.n], this.protects) ? (this.#g.add(e), this.#m.delete(e) && this.#j(e)) : (this.#m.set(e, this.#u + Bt), this.#A(e, Bt)), this.#r());
2266
2320
  };
2267
2321
  #E(e) {
2268
2322
  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());
@@ -2276,7 +2330,7 @@ var At = class {
2276
2330
  this.#b = !0, this.#i();
2277
2331
  return;
2278
2332
  }
2279
- let n = this.#p.get(e), r = n ? Math.min(2 * n.delay, Pt) : Nt;
2333
+ let n = this.#p.get(e), r = n ? Math.min(2 * n.delay, zt) : Rt;
2280
2334
  this.#p.set(e, {
2281
2335
  delay: r,
2282
2336
  until: this.#u + r
@@ -2297,11 +2351,11 @@ var At = class {
2297
2351
  }
2298
2352
  #M() {
2299
2353
  let e = this.#u;
2300
- if (e - this.#y < It) return;
2354
+ if (e - this.#y < Vt) return;
2301
2355
  this.#y = e;
2302
2356
  for (let e of this.#g) this.#n.holds(e) || this.#g.delete(e);
2303
2357
  for (let [t, n] of this.#m) n <= e && this.#m.delete(t);
2304
- for (let [t, n] of this.#_) e - n >= It && this.#_.delete(t);
2358
+ for (let [t, n] of this.#_) e - n >= Vt && this.#_.delete(t);
2305
2359
  let { keep: t } = this.#s;
2306
2360
  if (this.#e.pages.size <= 2 * (this.#g.size + t.size)) return;
2307
2361
  let n = /* @__PURE__ */ new Set([
@@ -2326,7 +2380,7 @@ var At = class {
2326
2380
  };
2327
2381
  //#endregion
2328
2382
  //#region src/engine/stream/remote.ts
2329
- function Rt(e, t) {
2383
+ function Ut(e, t) {
2330
2384
  let n = /* @__PURE__ */ new Map();
2331
2385
  return (r) => {
2332
2386
  if ("unfetch" in r) return void n.get(r.unfetch)?.abort();
@@ -2349,29 +2403,29 @@ function Rt(e, t) {
2349
2403
  }
2350
2404
  //#endregion
2351
2405
  //#region src/engine/stream/worker.ts?worker&inline
2352
- var zt = "(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}let O=(e,t,n)=>Math.min(n,Math.max(t,e));function k(e,t,n){return n>t?O(Math.round((e-t)/(n-t)*255),0,255):0}function A(e,t){return t>0?O(Math.round(e/t*127),-127,127):0}function j(e){return e&=1023,e=(e|e<<16)&50331903,e=(e|e<<8)&50393103,e=(e|e<<4)&51130563,(e|e<<2)&153391689}function M(e,t,n){return j(e>>6)|j(t>>6)<<1|j(n>>6)<<2}function N(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 P(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]=A(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 F(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]=O(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+M(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]),A=[0,0,0];for(let e=1;e<4;e++)A[e-1]=T.filter(t=>t<e).length;let j=u?N(u,n):/* @__PURE__ */ new Float32Array(9),{book:F,labels:I}=u?P(u,n,j):{book:null,labels:null},L=F?F.length/9:0,R=17+(L>0?2:0),z=new Uint8Array(128+R*n+L*9),B=new DataView(z.buffer);B.setUint32(0,n,!0),A.forEach((e,t)=>B.setUint32(4+4*t,e,!0)),B.setUint16(16,L,!0),[...v,...y,...p,...m,...h,...g,...j].forEach((e,t)=>B.setFloat32(20+4*t,e,!0));let V=e=>128+e*n,H=new Float32Array([...d,...f]),U=/* @__PURE__ */ new Float64Array(4),W=/* @__PURE__ */ new Float64Array(3),G=[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]-G[n]<<16>>16,i=r<0?-2*r-1:2*r;G[n]=b[t*3+n],z[V(a.position+2*n)+e]=i&255,z[V(a.position+2*n+1)+e]=i>>8}z[V(a.alpha)+e]=O(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++)U[e]=o[t*4+e]/n;let r=0;for(let e=1;e<4;e++)Math.abs(U[e])>Math.abs(U[r])&&(r=e);let u=U[r]<0?-1:1;z[V(a.rotationIndex)+e]=r;for(let t=0,n=0;t<4;t++){if(t===r)continue;let i=Math.round((u*U[t]/Math.SQRT2+.5)*255);z[V(a.rotation+n++)+e]=O(i,0,255)}for(let n=0;n<3;n++)z[V(a.scale+n)+e]=k(s[t*3+n],p[n],m[n]),z[V(a.dc+n)+e]=k(l[t*3+n],h[n],g[n]);I&&(z[V(a.label)+e]=I[t]&255,z[V(a.label+1)+e]=I[t]>>8);let[d,f,_]=[0,1,2].map(e=>Math.exp(s[t*3+e]));x(U,d,f,_,W);for(let e=0;e<3;e++)H[e]=Math.min(H[e],i[t*3+e]-W[e]),H[3+e]=Math.max(H[3+e],i[t*3+e]+W[e])}return F&&z.set(new Uint8Array(F.buffer),V(R)),{payload:z,row:{g:t.g,i:t.i,j:t.j,count:n,quadrants:A,box:H,offset:0,length:0}}}function I(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 L(e,t,n){for(let r=0;r<4;r++)e[t+r]=n.charCodeAt(r)}function R(e){return Uint8Array.from({length:8},(t,n)=>parseInt(e.slice(2*n,2*n+2),16))}async function z(e,t){let n=await l(e),r=new Uint8Array(8+n.length);return L(r,0,t),new DataView(r.buffer).setUint16(4,1,!0),r.set(n,8),r}async function B(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(R(e.pack),12),o.setUint32(20,e.packSize,!0),e.col&&a.set(R(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)I(o,s,e),s+=52;for(let e of n)o.setUint8(s,e.quadrant),a.set(R(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(R(e.idx),s+3),s+=11;return z(a,i)}function V(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 H(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}}async function U(e,t){return p(await G(e,t))}async function*W(e,t,n,r){let i=t.col===null?null:te(e,t.col,n),a=await ee(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 G(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 ee(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 te(e,t,n){let r=n.get(t);if(r)n.delete(t);else{let i=G(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 ne(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 re(e,t){let n;try{n=await(await ae()).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 ce(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 oe(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 se(n,i,r)&&(o(i,r.length),c())}}}async function ie(e){let t=new Set(Array.from({length:e},(e,t)=>String(t)));try{let e=await ae(),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 ae(){return(await navigator.storage.getDirectory()).getDirectoryHandle(`cache`,{create:!0})}async function oe(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 se(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 ce(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 le(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 K=16384,ue=1408,de=65535,q=324121,fe=.4,pe=[[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]],me=pe.reduce((e,[t,n,,r])=>e+t*(n+r),0),he=Float32Array.from({length:ue*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}),J=new TextEncoder,ge={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,Y(e,`idx`),`idx`)})),extent:{e:[44e4,9e5],n:[605e4,641e4],h:[0,80]}},_e=J.encode(JSON.stringify(ge));function ve(){return async(t,n)=>{if(t.endsWith(`world.json`))return be(_e,n);let r=g(t),i=t.slice(t.lastIndexOf(`.`)+1);if(!r||i!==`idx`&&i!==`pack`||!xe(r)||r.hash!==Y(r,i))throw new e(`no file ${t}`);return i===`idx`?be(await De(r),n):Oe(r,n,t)}}function ye(e,t){let n=30;for(let[r,i,a,o,s]of pe)n+=r*Math.sin(i*e+a)*Math.sin(o*t+s);return n}function be(e,t){return t?e.slice(t[0],t[1]):e.slice()}function Y(e,t){return V(J.encode(`${e.level}/${e.e}/${e.n}.${t}`))}function X(e,t,n){let{e:r,n:i}=ge.extent;return e<r[1]&&e+n>r[0]&&t<i[1]&&t+n>i[0]}function xe({level:e,e:t,n}){let r=250*2**e;return e<=12&&t%r===0&&n%r===0&&X(t,n,r)}function Se(e){return e===0?[1,0]:e===12?[16,15,14,13]:[e+1]}function Ce(e){let t=0;for(let n=0;n<8;n++)t|=(e>>2*n&1)<<n;return t}function we(e){let t=[];for(let n of Se(e.level)){let i=r*2**n,a=250*2**e.level/i;for(let r=0;r<a*a;r++){let a=Ce(r),o=Ce(r>>1);X(e.e+a*i,e.n+o*i,i)&&t.push({g:n,i:a,j:o})}}return t}function Te(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};X(t.e,t.n,r)&&i.push({column:o,row:a,unit:t})}return i}function Ee(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=ye(e.e+(n+.5)*o,e.n+(i+.5)*o),d=me*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=K/4;return{g:t,i:n,j:i,count:K,quadrants:[p,2*p,3*p],box:f,offset:a,length:q}}function De(e){let t=we(e),n=[];for(let{column:t,row:r,unit:i}of Te(e,1))n.push({quadrant:t+2*r,idx:Y(i,`idx`)});let r=[];for(let t of[2,3])for(let{column:n,row:i,unit:a}of Te(e,t))r.push({depth:t,column:n,row:i,idx:Y(a,`idx`)});return B({level:e.level,e:e.e,n:e.n,pack:Y(e,`pack`),packSize:t.length*324173+16,col:null,rows:t.map((t,n)=>Ee(e,t,n*q)),children:n,descendants:r})}function Oe(e,t,n){let r=we(e);if(!t||t[0]%q!=0||t[1]%q!=0||t[0]>=t[1]||t[1]>r.length*q)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+=q)ke(je(e,r[(t[0]+n)/q]),i,n);return i}function ke(e,t,n){let r=n;for(let n=0;n<e.length;n+=de){let i=Math.min(de,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 Ae=e=>H(parseInt(V(J.encode(e)).slice(8),16));function je(e,{g:t,i,j:a}){let o=K,s=r*2**t/128,c=Ae(`${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+fe*(2*c()-1))*s,o=(a*128+Math.floor(t/128)+.5+fe*(2*c()-1))*s,h=ye(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%ue;m.set(he.subarray(9*b,9*(b+1)),9*t)}return F({count:o,position:l,rotation:u,scale:d,alpha:f,dc:p,sh:m},{g:t,i,j:a}).payload}let Z=2**20,Q=self,$,Me=/* @__PURE__ */ new Map,Ne=/* @__PURE__ */ new Map,Pe=le(e=>Q.postMessage(e,[]));Q.onmessage=({data:e})=>{`fetched`in e?Pe.take(e):e.type===`init`?($=Fe(e),$.catch(()=>void 0)):e.type===`abort`?Ne.get(e.id)?.abort():Re(e)};async function Fe(e){return e.source===`synthetic`?{fetch:ve(),cache:await Ie({...e,cache:`none`}),base:e.base}:{fetch:e.source===`page`?Pe.fetch:t,cache:await Ie(e),base:e.base}}async function Ie({cache:e,shard:t,shards:n}){return e===`memory`?ne(256*Z):e===`none`?{get:async()=>void 0,put:async()=>void 0}:(t===0&&ie(n),await re(await Le()/n,t)??ne(256*Z))}async function Le(){try{let{quota:e}=await navigator.storage.estimate();return Math.min(4096*Z,e===void 0?1/0:e/2)}catch{return 4096*Z}}async function Re(t){let{id:n}=t,r=new AbortController;Ne.set(n,r);try{if(!$)throw Error(`stream worker used before init`);let e=await $;if(t.type===`idx`)Q.postMessage({id:n,value:await U(e,t.path)},[]);else{for await(let i of W(e,t.batch,Me,r.signal))Q.postMessage({id:n,page:i},ze(i));Q.postMessage({id:n,done:!0},[])}}catch(t){let r=t instanceof Error?t.message:String(t);Q.postMessage({id:n,error:r,missing:t instanceof e},[])}finally{Ne.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]}})();", Bt = typeof self < "u" && self.Blob && new Blob(["(self.URL || self.webkitURL).revokeObjectURL(self.location.href);", zt], { type: "text/javascript;charset=utf-8" });
2353
- function Vt(e) {
2406
+ var Wt = "(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}let O=(e,t,n)=>Math.min(n,Math.max(t,e));function k(e,t,n){return n>t?O(Math.round((e-t)/(n-t)*255),0,255):0}function A(e,t){return t>0?O(Math.round(e/t*127),-127,127):0}function j(e){return e&=1023,e=(e|e<<16)&50331903,e=(e|e<<8)&50393103,e=(e|e<<4)&51130563,(e|e<<2)&153391689}function M(e,t,n){return j(e>>6)|j(t>>6)<<1|j(n>>6)<<2}function N(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 P(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]=A(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 F(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]=O(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+M(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]),A=[0,0,0];for(let e=1;e<4;e++)A[e-1]=T.filter(t=>t<e).length;let j=u?N(u,n):/* @__PURE__ */ new Float32Array(9),{book:F,labels:I}=u?P(u,n,j):{book:null,labels:null},L=F?F.length/9:0,R=17+(L>0?2:0),z=new Uint8Array(128+R*n+L*9),B=new DataView(z.buffer);B.setUint32(0,n,!0),A.forEach((e,t)=>B.setUint32(4+4*t,e,!0)),B.setUint16(16,L,!0),[...v,...y,...p,...m,...h,...g,...j].forEach((e,t)=>B.setFloat32(20+4*t,e,!0));let V=e=>128+e*n,H=new Float32Array([...d,...f]),U=/* @__PURE__ */ new Float64Array(4),W=/* @__PURE__ */ new Float64Array(3),G=[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]-G[n]<<16>>16,i=r<0?-2*r-1:2*r;G[n]=b[t*3+n],z[V(a.position+2*n)+e]=i&255,z[V(a.position+2*n+1)+e]=i>>8}z[V(a.alpha)+e]=O(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++)U[e]=o[t*4+e]/n;let r=0;for(let e=1;e<4;e++)Math.abs(U[e])>Math.abs(U[r])&&(r=e);let u=U[r]<0?-1:1;z[V(a.rotationIndex)+e]=r;for(let t=0,n=0;t<4;t++){if(t===r)continue;let i=Math.round((u*U[t]/Math.SQRT2+.5)*255);z[V(a.rotation+n++)+e]=O(i,0,255)}for(let n=0;n<3;n++)z[V(a.scale+n)+e]=k(s[t*3+n],p[n],m[n]),z[V(a.dc+n)+e]=k(l[t*3+n],h[n],g[n]);I&&(z[V(a.label)+e]=I[t]&255,z[V(a.label+1)+e]=I[t]>>8);let[d,f,_]=[0,1,2].map(e=>Math.exp(s[t*3+e]));x(U,d,f,_,W);for(let e=0;e<3;e++)H[e]=Math.min(H[e],i[t*3+e]-W[e]),H[3+e]=Math.max(H[3+e],i[t*3+e]+W[e])}return F&&z.set(new Uint8Array(F.buffer),V(R)),{payload:z,row:{g:t.g,i:t.i,j:t.j,count:n,quadrants:A,box:H,offset:0,length:0}}}function I(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 L(e,t,n){for(let r=0;r<4;r++)e[t+r]=n.charCodeAt(r)}function R(e){return Uint8Array.from({length:8},(t,n)=>parseInt(e.slice(2*n,2*n+2),16))}async function z(e,t){let n=await l(e),r=new Uint8Array(8+n.length);return L(r,0,t),new DataView(r.buffer).setUint16(4,1,!0),r.set(n,8),r}async function B(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(R(e.pack),12),o.setUint32(20,e.packSize,!0),e.col&&a.set(R(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)I(o,s,e),s+=52;for(let e of n)o.setUint8(s,e.quadrant),a.set(R(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(R(e.idx),s+3),s+=11;return z(a,i)}function V(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 H(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}}async function U(e,t){return p(await G(e,t))}async function*W(e,t,n,r){let i=t.col===null?null:te(e,t.col,n),a=await ee(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 G(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 ee(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 te(e,t,n){let r=n.get(t);if(r)n.delete(t);else{let i=G(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 ne(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 re(e,t){let n;try{n=await(await ae()).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 ce(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 oe(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 se(n,i,r)&&(o(i,r.length),c())}}}async function ie(e){let t=new Set(Array.from({length:e},(e,t)=>String(t)));try{let e=await ae(),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 ae(){return(await navigator.storage.getDirectory()).getDirectoryHandle(`cache`,{create:!0})}async function oe(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 se(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 ce(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 le(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 K=16384,ue=1408,de=65535,q=324121,fe=.4,pe=[[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]],me=pe.reduce((e,[t,n,,r])=>e+t*(n+r),0),he=Float32Array.from({length:ue*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}),J=new TextEncoder,ge={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,Y(e,`idx`),`idx`)})),extent:{e:[44e4,9e5],n:[605e4,641e4],h:[0,80]}},_e=J.encode(JSON.stringify(ge));function ve(){return async(t,n)=>{if(t.endsWith(`world.json`))return be(_e,n);let r=g(t),i=t.slice(t.lastIndexOf(`.`)+1);if(!r||i!==`idx`&&i!==`pack`||!xe(r)||r.hash!==Y(r,i))throw new e(`no file ${t}`);return i===`idx`?be(await De(r),n):Oe(r,n,t)}}function ye(e,t){let n=30;for(let[r,i,a,o,s]of pe)n+=r*Math.sin(i*e+a)*Math.sin(o*t+s);return n}function be(e,t){return t?e.slice(t[0],t[1]):e.slice()}function Y(e,t){return V(J.encode(`${e.level}/${e.e}/${e.n}.${t}`))}function X(e,t,n){let{e:r,n:i}=ge.extent;return e<r[1]&&e+n>r[0]&&t<i[1]&&t+n>i[0]}function xe({level:e,e:t,n}){let r=250*2**e;return e<=12&&t%r===0&&n%r===0&&X(t,n,r)}function Se(e){return e===0?[1,0]:e===12?[16,15,14,13]:[e+1]}function Ce(e){let t=0;for(let n=0;n<8;n++)t|=(e>>2*n&1)<<n;return t}function we(e){let t=[];for(let n of Se(e.level)){let i=r*2**n,a=250*2**e.level/i;for(let r=0;r<a*a;r++){let a=Ce(r),o=Ce(r>>1);X(e.e+a*i,e.n+o*i,i)&&t.push({g:n,i:a,j:o})}}return t}function Te(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};X(t.e,t.n,r)&&i.push({column:o,row:a,unit:t})}return i}function Ee(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=ye(e.e+(n+.5)*o,e.n+(i+.5)*o),d=me*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=K/4;return{g:t,i:n,j:i,count:K,quadrants:[p,2*p,3*p],box:f,offset:a,length:q}}function De(e){let t=we(e),n=[];for(let{column:t,row:r,unit:i}of Te(e,1))n.push({quadrant:t+2*r,idx:Y(i,`idx`)});let r=[];for(let t of[2,3])for(let{column:n,row:i,unit:a}of Te(e,t))r.push({depth:t,column:n,row:i,idx:Y(a,`idx`)});return B({level:e.level,e:e.e,n:e.n,pack:Y(e,`pack`),packSize:t.length*324173+16,col:null,rows:t.map((t,n)=>Ee(e,t,n*q)),children:n,descendants:r})}function Oe(e,t,n){let r=we(e);if(!t||t[0]%q!=0||t[1]%q!=0||t[0]>=t[1]||t[1]>r.length*q)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+=q)ke(je(e,r[(t[0]+n)/q]),i,n);return i}function ke(e,t,n){let r=n;for(let n=0;n<e.length;n+=de){let i=Math.min(de,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 Ae=e=>H(parseInt(V(J.encode(e)).slice(8),16));function je(e,{g:t,i,j:a}){let o=K,s=r*2**t/128,c=Ae(`${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+fe*(2*c()-1))*s,o=(a*128+Math.floor(t/128)+.5+fe*(2*c()-1))*s,h=ye(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%ue;m.set(he.subarray(9*b,9*(b+1)),9*t)}return F({count:o,position:l,rotation:u,scale:d,alpha:f,dc:p,sh:m},{g:t,i,j:a}).payload}let Z=2**20,Q=self,$,Me=/* @__PURE__ */ new Map,Ne=/* @__PURE__ */ new Map,Pe=le(e=>Q.postMessage(e,[]));Q.onmessage=({data:e})=>{`fetched`in e?Pe.take(e):e.type===`init`?($=Fe(e),$.catch(()=>void 0)):e.type===`abort`?Ne.get(e.id)?.abort():Re(e)};async function Fe(e){return e.source===`synthetic`?{fetch:ve(),cache:await Ie({...e,cache:`none`}),base:e.base}:{fetch:e.source===`page`?Pe.fetch:t,cache:await Ie(e),base:e.base}}async function Ie({cache:e,shard:t,shards:n}){return e===`memory`?ne(256*Z):e===`none`?{get:async()=>void 0,put:async()=>void 0}:(t===0&&ie(n),await re(await Le()/n,t)??ne(256*Z))}async function Le(){try{let{quota:e}=await navigator.storage.estimate();return Math.min(4096*Z,e===void 0?1/0:e/2)}catch{return 4096*Z}}async function Re(t){let{id:n}=t,r=new AbortController;Ne.set(n,r);try{if(!$)throw Error(`stream worker used before init`);let e=await $;if(t.type===`idx`)Q.postMessage({id:n,value:await U(e,t.path)},[]);else{for await(let i of W(e,t.batch,Me,r.signal))Q.postMessage({id:n,page:i},ze(i));Q.postMessage({id:n,done:!0},[])}}catch(t){let r=t instanceof Error?t.message:String(t);Q.postMessage({id:n,error:r,missing:t instanceof e},[])}finally{Ne.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]}})();", Gt = typeof self < "u" && self.Blob && new Blob(["(self.URL || self.webkitURL).revokeObjectURL(self.location.href);", Wt], { type: "text/javascript;charset=utf-8" });
2407
+ function Kt(e) {
2354
2408
  let t;
2355
2409
  try {
2356
- if (t = Bt && (self.URL || self.webkitURL).createObjectURL(Bt), !t) throw "";
2410
+ if (t = Gt && (self.URL || self.webkitURL).createObjectURL(Gt), !t) throw "";
2357
2411
  let n = new Worker(t, { name: e?.name });
2358
2412
  return n.addEventListener("error", () => {
2359
2413
  (self.URL || self.webkitURL).revokeObjectURL(t);
2360
2414
  }), n;
2361
2415
  } catch {
2362
- return new Worker("data:text/javascript;charset=utf-8," + encodeURIComponent(zt), { name: e?.name });
2416
+ return new Worker("data:text/javascript;charset=utf-8," + encodeURIComponent(Wt), { name: e?.name });
2363
2417
  }
2364
2418
  }
2365
2419
  //#endregion
2366
2420
  //#region src/engine/stream/loader.ts
2367
- var Ht = class {
2421
+ var qt = class {
2368
2422
  #e;
2369
2423
  #t = /* @__PURE__ */ new Map();
2370
2424
  #n = 0;
2371
2425
  constructor(e) {
2372
2426
  let { base: t, cache: n, source: r, workers: i } = e;
2373
2427
  this.#e = Array.from({ length: i }, (e, a) => {
2374
- let o = new Vt(), s = { worker: o }, c = typeof r == "function" ? Rt(r, (e, t) => o.postMessage(e, t)) : void 0;
2428
+ let o = new Kt(), s = { worker: o }, c = typeof r == "function" ? Ut(r, (e, t) => o.postMessage(e, t)) : void 0;
2375
2429
  o.onmessage = ({ data: e }) => {
2376
2430
  "id" in e ? this.#i(e) : c?.(e);
2377
2431
  }, o.onerror = () => this.#a(s);
@@ -2395,8 +2449,8 @@ var Ht = class {
2395
2449
  return this.#r(this.#e[0], t);
2396
2450
  }
2397
2451
  batch(e, t, n) {
2398
- if (t.aborted) return Promise.reject(Wt());
2399
- let r = this.#e[Ut(`${e.pack}#${e.window}`, this.#e.length)], i = {
2452
+ if (t.aborted) return Promise.reject(Yt());
2453
+ let r = this.#e[Jt(`${e.pack}#${e.window}`, this.#e.length)], i = {
2400
2454
  type: "batch",
2401
2455
  id: ++this.#n,
2402
2456
  batch: e
@@ -2405,7 +2459,7 @@ var Ht = class {
2405
2459
  }
2406
2460
  destroy() {
2407
2461
  for (let { worker: e } of this.#e) e.terminate();
2408
- for (let e of this.#t.values()) e.reject(Wt());
2462
+ for (let e of this.#t.values()) e.reject(Yt());
2409
2463
  }
2410
2464
  #r(e, t, n, r) {
2411
2465
  if (e.error) return Promise.reject(e.error);
@@ -2417,7 +2471,7 @@ var Ht = class {
2417
2471
  s(), e.worker.postMessage({
2418
2472
  type: "abort",
2419
2473
  id: i
2420
- }), o(Wt());
2474
+ }), o(Yt());
2421
2475
  };
2422
2476
  this.#t.set(i, {
2423
2477
  slot: e,
@@ -2440,90 +2494,90 @@ var Ht = class {
2440
2494
  for (let t of this.#t.values()) t.slot === e && t.reject(e.error);
2441
2495
  }
2442
2496
  };
2443
- function Ut(e, t) {
2497
+ function Jt(e, t) {
2444
2498
  let n = 2166136261;
2445
2499
  for (let t = 0; t < e.length; t++) n = Math.imul(n ^ e.charCodeAt(t), 16777619);
2446
2500
  return (n >>> 0) % t;
2447
2501
  }
2448
- function Wt() {
2502
+ function Yt() {
2449
2503
  return new DOMException("The request was aborted.", "AbortError");
2450
2504
  }
2451
2505
  //#endregion
2452
2506
  //#region src/engine/engine.ts
2453
- var Gt = class extends Error {
2507
+ var Xt = class extends Error {
2454
2508
  constructor() {
2455
2509
  super("This viewer needs WebGPU. Update to the latest Chrome, Edge, Safari or Firefox."), this.name = "NoWebGpu";
2456
2510
  }
2457
2511
  };
2458
- async function Kt(e, t) {
2512
+ async function Zt(e, t) {
2459
2513
  let n = await g();
2460
- if (!n) throw new Gt();
2514
+ if (!n) throw new Xt();
2461
2515
  let r = e.getContext("webgpu");
2462
- if (!r) throw n.device.destroy(), new Gt();
2516
+ if (!r) throw n.device.destroy(), new Xt();
2463
2517
  r.configure({
2464
2518
  device: n.device,
2465
2519
  format: n.format,
2466
2520
  alphaMode: "opaque"
2467
2521
  }), (t.cache ?? "opfs") === "opfs" && navigator.storage?.persist().catch(() => !1);
2468
2522
  let { source: i = "http" } = t;
2469
- return new vn(e, n, r, t, i === "synthetic" ? (await import("./synthetic-DO8oIw_x.js")).synthetic() : i === "http" ? u : i);
2523
+ return new Cn(e, n, r, t, i === "synthetic" ? (await import("./synthetic-DO8oIw_x.js")).synthetic() : i === "http" ? u : i);
2470
2524
  }
2471
- var W = .2, qt = 25165824, Jt = 3.25, Yt = 2, Xt = 1024, Zt = 2048, Qt = 100, $t = 2, en = 300, tn = 100, nn = 250, rn = 300, an = 1e3, on = 400, sn = 5e3, cn = 60, G = Math.PI / 180, K = "The viewer was closed.", ln = "The layers hold more splats than this device can.", un = [
2525
+ var G = .2, Qt = 25165824, $t = 3.25, en = 2, tn = 1024, nn = 2048, rn = 100, an = 2, on = 300, sn = 100, cn = 250, ln = 300, un = 1e3, dn = 400, fn = 5e3, pn = 60, K = Math.PI / 180, q = "The viewer was closed.", mn = "The layers hold more splats than this device can.", hn = [
2472
2526
  1,
2473
2527
  1,
2474
2528
  1,
2475
2529
  1
2476
- ], dn = "Another world was opened.";
2477
- function q(e, t) {
2530
+ ], gn = "Another world was opened.";
2531
+ function J(e, t) {
2478
2532
  let n = Math.min(t.maxStorageBufferBindingSize, t.maxBufferSize), r = (t, r) => {
2479
2533
  let i = Math.ceil(e * t / 256) * 256;
2480
2534
  return Math.min(i, Math.floor(n / r / 256) * 256);
2481
2535
  };
2482
2536
  return {
2483
- pool: r(Jt, 16),
2484
- frame: r(Yt, 24)
2537
+ pool: r($t, 16),
2538
+ frame: r(en, 24)
2485
2539
  };
2486
2540
  }
2487
- function fn(e, t) {
2541
+ function _n(e, t) {
2488
2542
  let [n, r, i] = t;
2489
- if (Math.hypot(n - e[0], r - e[1], i - e[2]) <= Zt) return e;
2490
- let a = (e) => Math.round(e / Xt) * Xt;
2543
+ if (Math.hypot(n - e[0], r - e[1], i - e[2]) <= nn) return e;
2544
+ let a = (e) => Math.round(e / tn) * tn;
2491
2545
  return [
2492
2546
  a(n),
2493
2547
  a(r),
2494
2548
  a(i)
2495
2549
  ];
2496
2550
  }
2497
- function pn(e, t, n, r, i, a) {
2551
+ function vn(e, t, n, r, i, a) {
2498
2552
  let o = 2 * e[0] / t[0] - 1, s = 1 - 2 * e[1] / t[1], c = [
2499
2553
  n * o / r[0],
2500
2554
  n * s / r[5],
2501
2555
  -n
2502
- ], [l, u, d] = oe(ae(/* @__PURE__ */ new Float64Array(16), i), c);
2556
+ ], [l, u, d] = ce(se(/* @__PURE__ */ new Float64Array(16), i), c);
2503
2557
  return [
2504
2558
  l + a[0],
2505
2559
  u + a[1],
2506
2560
  d + a[2]
2507
2561
  ];
2508
2562
  }
2509
- function mn(e) {
2563
+ function yn(e) {
2510
2564
  if (!e.length || !e.every((e) => e.length === 3 && e.every(Number.isFinite))) throw Error("Give at least one point, each three finite numbers.");
2511
2565
  return e;
2512
2566
  }
2513
- function hn(e, t) {
2567
+ function bn(e, t) {
2514
2568
  return [
2515
2569
  e.e - t[0],
2516
2570
  e.n - t[1],
2517
2571
  e.h - t[2]
2518
2572
  ];
2519
2573
  }
2520
- function gn(e, t) {
2521
- e.push(t), e.length > cn && e.shift();
2574
+ function xn(e, t) {
2575
+ e.push(t), e.length > pn && e.shift();
2522
2576
  }
2523
- function _n({ visible: e, opacity: t }) {
2577
+ function Sn({ visible: e, opacity: t }) {
2524
2578
  return e ? Math.round(t * 255) * 16843009 >>> 0 : 0;
2525
2579
  }
2526
- var vn = class {
2580
+ var Cn = class {
2527
2581
  #e;
2528
2582
  #t;
2529
2583
  #n;
@@ -2534,8 +2588,8 @@ var vn = class {
2534
2588
  #s;
2535
2589
  #c;
2536
2590
  #l;
2537
- #u = new ht();
2538
- #d = new et();
2591
+ #u = new yt();
2592
+ #d = new it();
2539
2593
  #f = (e) => this.#s.has(e);
2540
2594
  #p = null;
2541
2595
  #m = null;
@@ -2617,8 +2671,8 @@ var vn = class {
2617
2671
  e.height,
2618
2672
  1
2619
2673
  ], this.#R = [Math.max(1, e.width), Math.max(1, e.height)];
2620
- let { pool: a, frame: o } = q(this.#me, t.device.limits);
2621
- this.#s = new ee(t.device, a), this.#c = new Ze(t, n, this.#s, o), this.#l = o, t.device.lost.then((e) => {
2674
+ let { pool: a, frame: o } = J(this.#me, t.device.limits);
2675
+ this.#s = new ne(t.device, a), this.#c = new tt(t, n, this.#s, o), this.#l = o, t.device.lost.then((e) => {
2622
2676
  if (!this.#fe) {
2623
2677
  this.#pe = !0, cancelAnimationFrame(this.#z);
2624
2678
  for (let t of this.#se) t(e.message || e.reason);
@@ -2626,34 +2680,34 @@ var vn = class {
2626
2680
  });
2627
2681
  }
2628
2682
  async open(e) {
2629
- if (this.#fe) throw Error(K);
2683
+ if (this.#fe) throw Error(q);
2630
2684
  let t = ++this.#_, r = () => {
2631
- if (this.#fe) throw Error(K);
2632
- if (t !== this.#_) throw Error(dn);
2685
+ if (this.#fe) throw Error(q);
2686
+ if (t !== this.#_) throw Error(gn);
2633
2687
  }, { cache: i = "opfs", source: o = "http" } = this.#r;
2634
2688
  o === "http" && (e = new URL(e, document.baseURI).href);
2635
2689
  let s = await this.#i(e, null), c = a(JSON.parse(new TextDecoder().decode(s)));
2636
2690
  r();
2637
- let l = new Ht({
2691
+ let l = new qt({
2638
2692
  base: n(e),
2639
2693
  workers: Math.min(6, Math.max(2, navigator.hardwareConcurrency - 2)),
2640
2694
  cache: i,
2641
2695
  source: o
2642
- }), u = new ut(c);
2696
+ }), u = new mt(c);
2643
2697
  try {
2644
2698
  let e = await Promise.all(c.roots.map((e) => l.idx(e.idx)));
2645
2699
  r(), e.forEach((e, t) => u.add(e, c.roots[t].idx));
2646
2700
  } catch (e) {
2647
2701
  throw l.destroy(), e;
2648
2702
  }
2649
- return this.#g?.destroy(), this.#g = null, this.#h?.destroy(), this.#p = e, this.#m = u, this.#h = l, this.#H = null, this.#u = new ht(), this.#d = new et(), this.#s.clear(), this.#g = this.#ve(u, l), this.#G = !0, this.requestFrame(), c;
2703
+ return this.#g?.destroy(), this.#g = null, this.#h?.destroy(), this.#p = e, this.#m = u, this.#h = l, this.#H = null, this.#u = new yt(), this.#d = new it(), this.#s.clear(), this.#g = this.#ve(u, l), this.#G = !0, this.requestFrame(), c;
2650
2704
  }
2651
2705
  async addLayer(e, t) {
2652
- if (this.#fe) throw Error(K);
2653
- let n = await Qe("bytes" in e ? e.bytes : await this.#i(e.url, null), t);
2654
- if (this.#fe) throw Error(K);
2706
+ if (this.#fe) throw Error(q);
2707
+ let n = await nt("bytes" in e ? e.bytes : await this.#i(e.url, null), t);
2708
+ if (this.#fe) throw Error(q);
2655
2709
  let r = n.reduce((e, { page: t }) => e + d(t.count), 0), i = this.#t.device.limits;
2656
- if (q(this.#me, i).pool + this.#S + r > q(Infinity, i).pool) throw Error(ln);
2710
+ if (J(this.#me, i).pool + this.#S + r > J(Infinity, i).pool) throw Error(mn);
2657
2711
  this.#S += r, this.#ge();
2658
2712
  let a = ++this.#b, o = (e) => this.#g?.protects(e) ?? !1, s = () => this.#be(), c = !0, l = 1, u = () => {
2659
2713
  if (!(this.#fe || !this.#y.delete(a))) {
@@ -2662,7 +2716,7 @@ var vn = class {
2662
2716
  }
2663
2717
  }, f = {
2664
2718
  splats: n.reduce((e, { page: t }) => e + t.count, 0),
2665
- box: $e(n.map(({ box: e }) => e)),
2719
+ box: rt(n.map(({ box: e }) => e)),
2666
2720
  get visible() {
2667
2721
  return c;
2668
2722
  },
@@ -2683,7 +2737,7 @@ var vn = class {
2683
2737
  this.#y.set(a, p);
2684
2738
  for (let { page: e, box: r } of n) {
2685
2739
  let n = --this.#x;
2686
- if (!this.#s.add(n, e, t, o, a)) throw u(), Error(ln);
2740
+ if (!this.#s.add(n, e, t, o, a)) throw u(), Error(mn);
2687
2741
  p.pages.push({
2688
2742
  id: n,
2689
2743
  count: e.count,
@@ -2693,7 +2747,7 @@ var vn = class {
2693
2747
  return s(), this.#C.set(f, a), f;
2694
2748
  }
2695
2749
  addMask({ polygon: e, z: t = [-Infinity, Infinity], targets: n }) {
2696
- if (this.#fe) throw Error(K);
2750
+ if (this.#fe) throw Error(q);
2697
2751
  if (e.length < 3 || !e.flat().every(Number.isFinite)) throw Error("A mask needs three or more corners, each two finite numbers.");
2698
2752
  let r = new Set(n.map((e) => e === "world" ? 0 : this.#C.get(e) ?? -1)), i = this.#s, a = {
2699
2753
  polygon: Float64Array.from(e.flat()),
@@ -2714,8 +2768,8 @@ var vn = class {
2714
2768
  };
2715
2769
  }
2716
2770
  addLine(e, t = {}) {
2717
- let { colour: n = un, width: r = 2, closed: i = !1, occlude: a = !0 } = t, o = (e) => {
2718
- mn(e);
2771
+ let { colour: n = hn, width: r = 2, closed: i = !1, occlude: a = !0 } = t, o = (e) => {
2772
+ yn(e);
2719
2773
  let t = i && e.length > 2 ? [...e, e[0]] : e;
2720
2774
  return (t.length > 1 ? t.slice(1).map((e, n) => [t[n], e]) : [[t[0], t[0]]]).map(([e, t]) => ({
2721
2775
  a: e,
@@ -2748,7 +2802,7 @@ var vn = class {
2748
2802
  };
2749
2803
  }
2750
2804
  toScreen([e, t, n]) {
2751
- let r = this.#O, [i, a] = this.#L, o = this.#j, s = ne(/* @__PURE__ */ new Float64Array(16), hn(r, o), r.yaw * G, r.pitch * G), c = re(/* @__PURE__ */ new Float64Array(16), r.fov * G, i / Math.max(1, a), W, this.#a.viewDistance), [l, u, , d] = oe(N(/* @__PURE__ */ new Float64Array(16), c, s), [
2805
+ let r = this.#O, [i, a] = this.#L, o = this.#j, s = ie(/* @__PURE__ */ new Float64Array(16), bn(r, o), r.yaw * K, r.pitch * K), c = ae(/* @__PURE__ */ new Float64Array(16), r.fov * K, i / Math.max(1, a), G, this.#a.viewDistance), [l, u, , d] = ce(P(/* @__PURE__ */ new Float64Array(16), c, s), [
2752
2806
  e - o[0],
2753
2807
  t - o[1],
2754
2808
  n - o[2]
@@ -2758,9 +2812,9 @@ var vn = class {
2758
2812
  setCamera(e) {
2759
2813
  if (this.#fe) return;
2760
2814
  let t = performance.now(), n = t - this.#k, r = this.#O, i = this.#A;
2761
- if (n > nn) i.fill(0);
2815
+ if (n > cn) i.fill(0);
2762
2816
  else if (n > 0) {
2763
- let t = 1 - Math.exp(-n / tn);
2817
+ let t = 1 - Math.exp(-n / sn);
2764
2818
  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]);
2765
2819
  }
2766
2820
  this.#k = t, this.#O = { ...e }, this.#W = !0, this.#de || this.requestFrame();
@@ -2811,8 +2865,8 @@ var vn = class {
2811
2865
  stats() {
2812
2866
  let e = this.#s, t = this.#g, n = this.#c.stats();
2813
2867
  return {
2814
- frameMs: kt(this.#$, .5),
2815
- cpuMs: kt(this.#ee, .5),
2868
+ frameMs: Pt(this.#$, .5),
2869
+ cpuMs: Pt(this.#ee, .5),
2816
2870
  gpuMs: n.gpuMs,
2817
2871
  passes: n.passes,
2818
2872
  drawn: n.drawn,
@@ -2849,7 +2903,7 @@ var vn = class {
2849
2903
  }
2850
2904
  warm() {
2851
2905
  let e = performance.now();
2852
- e - this.#X < an || (this.#Z = e + on, this.requestFrame());
2906
+ e - this.#X < un || (this.#Z = e + dn, this.requestFrame());
2853
2907
  }
2854
2908
  onFrame(e) {
2855
2909
  return this.#ce.add(e), () => this.#ce.delete(e);
@@ -2891,30 +2945,30 @@ var vn = class {
2891
2945
  return this.#o.budget;
2892
2946
  }
2893
2947
  #he() {
2894
- let { budget: e, budgetRange: t = [e, e] } = this.#a, n = Math.floor(q(Infinity, this.#t.device.limits).frame / Yt), r = (e) => Math.max(1, Math.min(e, n));
2895
- return new At(r(e), [r(t[0]), r(t[1])]);
2948
+ let { budget: e, budgetRange: t = [e, e] } = this.#a, n = Math.floor(J(Infinity, this.#t.device.limits).frame / en), r = (e) => Math.max(1, Math.min(e, n));
2949
+ return new Ft(r(e), [r(t[0]), r(t[1])]);
2896
2950
  }
2897
2951
  #ge() {
2898
- let { pool: e, frame: t } = q(this.#me, this.#t.device.limits), n = e + this.#S;
2952
+ let { pool: e, frame: t } = J(this.#me, this.#t.device.limits), n = e + this.#S;
2899
2953
  (n > this.#s.capacity || t > this.#l) && this.#_e(n, t), this.#G = !0, this.requestFrame();
2900
2954
  }
2901
2955
  #_e(e, t) {
2902
2956
  this.#s.grow(e), this.#c.destroy();
2903
- let n = new Ze(this.#t, this.#n, this.#s, t);
2957
+ let n = new tt(this.#t, this.#n, this.#s, t);
2904
2958
  n.resize(...this.#R);
2905
2959
  for (let e of this.#te) e.off = n.shade(e.hook);
2906
2960
  for (let e of this.#ne) e.off = n.post(e.hook);
2907
2961
  this.#c = n, this.#l = t, this.#ie = null, this.#D = !0;
2908
2962
  }
2909
2963
  #ve(e, t) {
2910
- return new Lt(e, t, this.#s, () => {
2964
+ return new Ht(e, t, this.#s, () => {
2911
2965
  this.#q = !0, this.requestFrame();
2912
2966
  }, this.#ye);
2913
2967
  }
2914
2968
  #ye = () => {
2915
2969
  let e = this.#p, t = this.#m;
2916
2970
  this.#v || this.#fe || e === null || (this.#v = !0, this.open(e).then(() => this.#v = !1, () => {
2917
- this.#v = !1, this.#m === t && setTimeout(this.#ye, sn);
2971
+ this.#v = !1, this.#m === t && setTimeout(this.#ye, fn);
2918
2972
  }));
2919
2973
  };
2920
2974
  #be() {
@@ -2930,16 +2984,16 @@ var vn = class {
2930
2984
  0,
2931
2985
  0
2932
2986
  ], r = 0;
2933
- for (let { layer: i, pages: a } of this.#y.values()) if (_n(i)) for (let { count: i, box: o } of a) {
2987
+ for (let { layer: i, pages: a } of this.#y.values()) if (Sn(i)) for (let { count: i, box: o } of a) {
2934
2988
  for (let r = 0; r < 3; r++) t[r] = o[r] - e[r], n[r] = o[r + 3] - e[r];
2935
- je(this.#I, t, n) && (r += i);
2989
+ Ne(this.#I, t, n) && (r += i);
2936
2990
  }
2937
2991
  return r;
2938
2992
  }
2939
2993
  #Se() {
2940
2994
  let e = [];
2941
2995
  for (let { layer: t, pages: n } of this.#y.values()) {
2942
- let r = _n(t);
2996
+ let r = Sn(t);
2943
2997
  if (r) for (let { id: t } of n) e.push({
2944
2998
  id: t,
2945
2999
  factors: r
@@ -2958,12 +3012,12 @@ var vn = class {
2958
3012
  };
2959
3013
  }
2960
3014
  #we() {
2961
- let [e, t, n] = this.#L, r = Ot(e, t, n, this.#o.scale), i = Math.max(1, Math.round(e * r)), a = Math.max(1, Math.round(t * r));
3015
+ let [e, t, n] = this.#L, r = Nt(e, t, n, this.#o.scale), i = Math.max(1, Math.round(e * r)), a = Math.max(1, Math.round(t * r));
2962
3016
  (i !== this.#R[0] || a !== this.#R[1]) && (this.#R = [i, a], this.#e.width = i, this.#e.height = a, this.#c.resize(i, a), this.#G = !0, this.#D = !0, this.requestFrame());
2963
3017
  }
2964
3018
  #Te = (e) => {
2965
3019
  if (this.#z = 0, !(this.#fe || this.#pe)) {
2966
- if (this.#B >= $t) this.#V = !0;
3020
+ if (this.#B >= an) this.#V = !0;
2967
3021
  else {
2968
3022
  this.#de = !0;
2969
3023
  for (let t of this.#ce) t(e);
@@ -2976,33 +3030,33 @@ var vn = class {
2976
3030
  #Ee(e) {
2977
3031
  let t = performance.now(), n = this.#o, r = this.#s, i = this.#O, [a, o] = this.#R, s = this.#a.viewDistance, c = this.#W;
2978
3032
  this.#W = !1;
2979
- let l = fn(this.#j, [
3033
+ let l = _n(this.#j, [
2980
3034
  i.e,
2981
3035
  i.n,
2982
3036
  i.h
2983
3037
  ]);
2984
3038
  l !== this.#j && (this.#j = l, r.setOrigin(l), this.#D = !0);
2985
- let u = hn(i, l);
2986
- ne(this.#M, u, i.yaw * G, i.pitch * G), re(this.#N, i.fov * G, a / o, W, s);
3039
+ let u = bn(i, l);
3040
+ ie(this.#M, u, i.yaw * K, i.pitch * K), ae(this.#N, i.fov * K, a / o, G, s);
2987
3041
  let d = {
2988
3042
  time: t,
2989
3043
  width: a,
2990
3044
  height: o,
2991
3045
  view: new Float32Array(this.#M),
2992
3046
  proj: new Float32Array(this.#N),
2993
- near: W,
3047
+ near: G,
2994
3048
  far: s,
2995
3049
  camera: Float32Array.from(u),
2996
3050
  origin: l
2997
3051
  };
2998
- Ae(this.#I, N(this.#F, d.proj, d.view));
3052
+ Me(this.#I, P(this.#F, d.proj, d.view));
2999
3053
  let f = this.#m, p = this.#g, m = this.#q || this.#G || this.#J, h = this.#H, g = h;
3000
3054
  if (f && p) {
3001
- let e = !p.idle && t - this.#U >= Qt, n = this.#G || this.#q || this.#J || this.#K;
3055
+ let e = !p.idle && t - this.#U >= rn, n = this.#G || this.#q || this.#J || this.#K;
3002
3056
  (!g || c || e || n) && (g = this.#De(f, t, c));
3003
3057
  }
3004
3058
  let _ = this.#Y, v = this.#J;
3005
- if (g && p && (g !== h && (m || !h || g.cut.length !== h.cut.length || g.cut.some((e, t) => e !== h.cut[t])) && ({drawn: _, fading: v} = this.#d.update(g.cut, this.#f, t, this.#me)), p.update(g, new Set(_.map((e) => e.id)), t)), r.upload(qt) > 0 && (this.#q = !0), _ !== this.#Y || this.#q || this.#w) {
3059
+ if (g && p && (g !== h && (m || !h || g.cut.length !== h.cut.length || g.cut.some((e, t) => e !== h.cut[t])) && ({drawn: _, fading: v} = this.#d.update(g.cut, this.#f, t, this.#me)), p.update(g, new Set(_.map((e) => e.id)), t)), r.upload(Qt) > 0 && (this.#q = !0), _ !== this.#Y || this.#q || this.#w) {
3006
3060
  this.#w = !1;
3007
3061
  let e = this.#Se();
3008
3062
  r.draw(e.length ? _.concat(e) : _);
@@ -3034,8 +3088,8 @@ var vn = class {
3034
3088
  origin: this.#j,
3035
3089
  width: a / s,
3036
3090
  height: o / s,
3037
- tan: Math.tan(r.fov * G / 2),
3038
- near: W,
3091
+ tan: Math.tan(r.fov * K / 2),
3092
+ near: G,
3039
3093
  far: this.#a.viewDistance
3040
3094
  }, u = {
3041
3095
  ...l,
@@ -3052,20 +3106,20 @@ var vn = class {
3052
3106
  let t = this.#A;
3053
3107
  if (t.every((e) => e === 0)) return;
3054
3108
  let n = this.#O, r = [
3055
- n.e + t[0] * en - e.origin[0],
3056
- n.n + t[1] * en - e.origin[1],
3057
- n.h + t[2] * en - e.origin[2]
3109
+ n.e + t[0] * on - e.origin[0],
3110
+ n.n + t[1] * on - e.origin[1],
3111
+ n.h + t[2] * on - e.origin[2]
3058
3112
  ];
3059
3113
  return {
3060
3114
  ...e,
3061
- view: ne(this.#P, r, n.yaw * G, n.pitch * G)
3115
+ view: ie(this.#P, r, n.yaw * K, n.pitch * K)
3062
3116
  };
3063
3117
  }
3064
3118
  #ke() {
3065
3119
  let e = this.#ie, t = this.#M.slice(), [n, r] = this.#L, i = [e.width, e.height];
3066
3120
  for (let { x: a, y: o, resolve: s } of this.#re.splice(0)) {
3067
3121
  let c = [a * i[0] / Math.max(1, n), o * i[1] / Math.max(1, r)], l = (n) => n && {
3068
- point: pn(c, i, n.depth, e.proj, t, e.origin),
3122
+ point: vn(c, i, n.depth, e.proj, t, e.origin),
3069
3123
  normal: n.normal,
3070
3124
  layer: this.#y.get(n.layer)?.layer ?? null
3071
3125
  };
@@ -3099,22 +3153,22 @@ var vn = class {
3099
3153
  };
3100
3154
  }
3101
3155
  #Ne(e, t, n) {
3102
- let r = this.#o, { gpuMs: i } = this.#c.stats(), a = e - this.#X, o = a <= Math.max(nn, 2 * i, 2 * t);
3103
- o && gn(this.#$, a), gn(this.#ee, t), this.#X = e;
3156
+ let r = this.#o, { gpuMs: i } = this.#c.stats(), a = e - this.#X, o = a <= Math.max(cn, 2 * i, 2 * t);
3157
+ o && xn(this.#$, a), xn(this.#ee, t), this.#X = e;
3104
3158
  let s = r.budget;
3105
- r.sample(a, e, o && n, this.#H?.planned ?? 0) && (this.#we(), r.budget !== s && this.#ge()), n ? this.#Q = e : r.scale < 1 && e - this.#Q > rn && (r.full(), this.#we());
3159
+ r.sample(a, e, o && n, this.#H?.planned ?? 0) && (this.#we(), r.budget !== s && this.#ge()), n ? this.#Q = e : r.scale < 1 && e - this.#Q > ln && (r.full(), this.#we());
3106
3160
  }
3107
- }, yn = 45, bn = {
3161
+ }, wn = 45, Tn = {
3108
3162
  yaw: 0,
3109
3163
  pitch: -35,
3110
3164
  dist: 300
3111
- }, J = {
3165
+ }, Y = {
3112
3166
  pitch: [-90, -20],
3113
3167
  dist: [1, 2485],
3114
3168
  clearance: 10,
3115
3169
  floor: 50
3116
- }, xn = .1, Y = Math.PI / 180, Sn = 1.1, Cn = [600, 2500], wn = 300, Tn = .5, En = (e, [t, n]) => Math.min(n, Math.max(t, e)), Dn = (e) => (e % 360 + 360) % 360, On = (e, t) => (t - e + 540) % 360 - 180;
3117
- function kn({ leaf: e, roots: t, extent: n }) {
3170
+ }, En = .1, X = Math.PI / 180, Dn = 1.1, On = [600, 2500], kn = 300, An = .5, jn = (e, [t, n]) => Math.min(n, Math.max(t, e)), Mn = (e) => (e % 360 + 360) % 360, Nn = (e, t) => (t - e + 540) % 360 - 180;
3171
+ function Pn({ leaf: e, roots: t, extent: n }) {
3118
3172
  let r = {
3119
3173
  e: (n.e[0] + n.e[1]) / 2,
3120
3174
  n: (n.n[0] + n.n[1]) / 2,
@@ -3131,7 +3185,7 @@ function kn({ leaf: e, roots: t, extent: n }) {
3131
3185
  }
3132
3186
  return i;
3133
3187
  }
3134
- function An(e) {
3188
+ function Fn(e) {
3135
3189
  let t = e.split(",");
3136
3190
  if (t.length !== 6 || t.some((e) => e.trim() === "")) return null;
3137
3191
  let [n, r, i, a, o, s] = t.map(Number);
@@ -3151,7 +3205,7 @@ function An(e) {
3151
3205
  dist: s
3152
3206
  };
3153
3207
  }
3154
- function jn(e) {
3208
+ function In(e) {
3155
3209
  let t = (e, t) => +e.toFixed(t);
3156
3210
  return [
3157
3211
  t(e.e, 2),
@@ -3162,19 +3216,19 @@ function jn(e) {
3162
3216
  t(e.dist, 1)
3163
3217
  ].join(",");
3164
3218
  }
3165
- function X(e, t, n = J) {
3219
+ function Z(e, t, n = Y) {
3166
3220
  let r = {
3167
3221
  e: e.e,
3168
3222
  n: e.n,
3169
3223
  h: e.h,
3170
- yaw: Dn(e.yaw),
3171
- pitch: En(e.pitch, n.pitch),
3172
- dist: En(e.dist, n.dist)
3224
+ yaw: Mn(e.yaw),
3225
+ pitch: jn(e.pitch, n.pitch),
3226
+ dist: jn(e.dist, n.dist)
3173
3227
  };
3174
3228
  if (t) {
3175
- let e = Z(r), i = Math.max(n.floor, t(e.e, e.n) + n.clearance);
3229
+ let e = Q(r), i = Math.max(n.floor, t(e.e, e.n) + n.clearance);
3176
3230
  if (e.h < i) return {
3177
- ...Fn({
3231
+ ...Bn({
3178
3232
  ...e,
3179
3233
  h: i
3180
3234
  }, r),
@@ -3183,42 +3237,42 @@ function X(e, t, n = J) {
3183
3237
  }
3184
3238
  return r;
3185
3239
  }
3186
- function Mn(e, t) {
3187
- let n = Math.cos(t * Y);
3240
+ function Ln(e, t) {
3241
+ let n = Math.cos(t * X);
3188
3242
  return {
3189
- e: Math.sin(e * Y) * n,
3190
- n: Math.cos(e * Y) * n,
3191
- h: Math.sin(t * Y)
3243
+ e: Math.sin(e * X) * n,
3244
+ n: Math.cos(e * X) * n,
3245
+ h: Math.sin(t * X)
3192
3246
  };
3193
3247
  }
3194
- function Z(e) {
3195
- let t = Mn(e.yaw, e.pitch);
3248
+ function Q(e) {
3249
+ let t = Ln(e.yaw, e.pitch);
3196
3250
  return {
3197
3251
  e: e.e - t.e * e.dist,
3198
3252
  n: e.n - t.n * e.dist,
3199
3253
  h: e.h - t.h * e.dist
3200
3254
  };
3201
3255
  }
3202
- function Nn(e) {
3256
+ function Rn(e) {
3203
3257
  return {
3204
- ...Z(e),
3258
+ ...Q(e),
3205
3259
  yaw: e.yaw,
3206
3260
  pitch: e.pitch,
3207
3261
  fov: 45
3208
3262
  };
3209
3263
  }
3210
- function Pn(e, t, n) {
3211
- let r = Z(e), [i, a, o] = [
3264
+ function zn(e, t, n) {
3265
+ let r = Q(e), [i, a, o] = [
3212
3266
  n.e - r.e,
3213
3267
  n.n - r.n,
3214
3268
  n.h - r.h
3215
- ], [s, c] = [Math.sin(e.yaw * Y), Math.cos(e.yaw * Y)], [l, u] = [Math.sin(e.pitch * Y), Math.cos(e.pitch * Y)], d = i * s + a * c, f = 2 * Math.tan(t * Y / 2) * (d * u + o * l);
3269
+ ], [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);
3216
3270
  return {
3217
3271
  x: (i * c - a * s) / f,
3218
3272
  y: (d * l - o * u) / f
3219
3273
  };
3220
3274
  }
3221
- function Fn(e, t) {
3275
+ function Bn(e, t) {
3222
3276
  let [n, r, i] = [
3223
3277
  t.e - e.e,
3224
3278
  t.n - e.n,
@@ -3228,17 +3282,17 @@ function Fn(e, t) {
3228
3282
  e: t.e,
3229
3283
  n: t.n,
3230
3284
  h: t.h,
3231
- yaw: Dn(Math.atan2(n, r) / Y),
3232
- pitch: Math.asin(i / a) / Y,
3285
+ yaw: Mn(Math.atan2(n, r) / X),
3286
+ pitch: Math.asin(i / a) / X,
3233
3287
  dist: a
3234
3288
  };
3235
3289
  }
3236
- function In(e, t, n, r = J) {
3237
- let i = Z(e), a = X({
3290
+ function Vn(e, t, n, r = Y) {
3291
+ let i = Q(e), a = Z({
3238
3292
  ...e,
3239
3293
  yaw: t,
3240
3294
  pitch: n
3241
- }, void 0, r), o = Mn(a.yaw, a.pitch);
3295
+ }, void 0, r), o = Ln(a.yaw, a.pitch);
3242
3296
  return {
3243
3297
  ...a,
3244
3298
  e: i.e + o.e * a.dist,
@@ -3246,11 +3300,11 @@ function In(e, t, n, r = J) {
3246
3300
  h: i.h + o.h * a.dist
3247
3301
  };
3248
3302
  }
3249
- function Ln(e) {
3250
- return e.dist * Math.max(Math.sin(-e.pitch * Y), xn);
3303
+ function Hn(e) {
3304
+ return e.dist * Math.max(Math.sin(-e.pitch * X), En);
3251
3305
  }
3252
- function Rn(e, t, n, r) {
3253
- let [i, a] = [Math.sin(e.yaw * Y), Math.cos(e.yaw * Y)];
3306
+ function Un(e, t, n, r) {
3307
+ let [i, a] = [Math.sin(e.yaw * X), Math.cos(e.yaw * X)];
3254
3308
  return {
3255
3309
  ...e,
3256
3310
  e: e.e + t * a + n * i,
@@ -3258,20 +3312,20 @@ function Rn(e, t, n, r) {
3258
3312
  h: e.h + r
3259
3313
  };
3260
3314
  }
3261
- function zn(e, t, n) {
3262
- return Rn(e, t, n * e.dist / Ln(e), 0);
3315
+ function Wn(e, t, n) {
3316
+ return Un(e, t, n * e.dist / Hn(e), 0);
3263
3317
  }
3264
- function Q(e, t, n) {
3318
+ function Gn(e, t, n) {
3265
3319
  return {
3266
3320
  e: e.e + (t.e - e.e) * n,
3267
3321
  n: e.n + (t.n - e.n) * n,
3268
3322
  h: e.h + (t.h - e.h) * n,
3269
- yaw: Dn(e.yaw + On(e.yaw, t.yaw) * n),
3323
+ yaw: Mn(e.yaw + Nn(e.yaw, t.yaw) * n),
3270
3324
  pitch: e.pitch + (t.pitch - e.pitch) * n,
3271
3325
  dist: e.dist * (t.dist / e.dist) ** n
3272
3326
  };
3273
3327
  }
3274
- function Bn(e, t) {
3328
+ function Kn(e, t) {
3275
3329
  let n = ([e, t]) => (e + t) / 2, r = Math.hypot(e.e[1] - e.e[0], e.n[1] - e.n[0], e.h[1] - e.h[0]) / 2;
3276
3330
  return {
3277
3331
  e: n(e.e),
@@ -3279,17 +3333,17 @@ function Bn(e, t) {
3279
3333
  h: n(e.h),
3280
3334
  yaw: t.yaw,
3281
3335
  pitch: t.pitch,
3282
- dist: Sn * r / Math.sin(45 * Y / 2)
3336
+ dist: Dn * r / Math.sin(45 * X / 2)
3283
3337
  };
3284
3338
  }
3285
- function Vn(e, t) {
3286
- let n = Math.hypot(t.e - e.e, t.n - e.n), r = Math.log1p(n / Math.min(e.dist, t.dist)) + Math.abs(Math.log(t.dist / e.dist)), i = Math.log1p(Tn * n / Math.max(e.dist, t.dist));
3339
+ function qn(e, t) {
3340
+ let n = Math.hypot(t.e - e.e, t.n - e.n), r = Math.log1p(n / Math.min(e.dist, t.dist)) + Math.abs(Math.log(t.dist / e.dist)), i = Math.log1p(An * n / Math.max(e.dist, t.dist));
3287
3341
  return {
3288
- ms: En(Cn[0] + wn * r, Cn),
3342
+ ms: jn(On[0] + kn * r, On),
3289
3343
  at(n) {
3290
3344
  if (n <= 0) return e;
3291
3345
  if (n >= 1) return t;
3292
- let r = n * n * (3 - 2 * n), a = Q(e, t, r);
3346
+ let r = n * n * (3 - 2 * n), a = Gn(e, t, r);
3293
3347
  return {
3294
3348
  ...a,
3295
3349
  dist: a.dist * Math.exp(4 * i * r * (1 - r))
@@ -3297,17 +3351,17 @@ function Vn(e, t) {
3297
3351
  }
3298
3352
  };
3299
3353
  }
3300
- function Hn(e, t) {
3354
+ function Jn(e, t) {
3301
3355
  let n = e.dist * 1e-5;
3302
- 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(On(e.yaw, t.yaw)) < .001 && Math.abs(e.pitch - t.pitch) < .001;
3356
+ 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(Nn(e.yaw, t.yaw)) < .001 && Math.abs(e.pitch - t.pitch) < .001;
3303
3357
  }
3304
3358
  //#endregion
3305
3359
  //#region src/controls/controls.ts
3306
- var Un = .2, Wn = .002, Gn = .005, Kn = .5, qn = .05;
3307
- function Jn(e, t) {
3360
+ var Yn = .2, Xn = .002, Zn = .005, Qn = .5, $n = .05;
3361
+ function er(e, t) {
3308
3362
  return 2 * e * Math.tan(45 * Math.PI / 360) / Math.max(1, t);
3309
3363
  }
3310
- function Yn(e) {
3364
+ function tr(e) {
3311
3365
  let t = (t) => +!!e.has(t);
3312
3366
  return [
3313
3367
  t("KeyD") - t("KeyA") + t("ArrowRight") - t("ArrowLeft"),
@@ -3315,10 +3369,10 @@ function Yn(e) {
3315
3369
  t("KeyE") - t("KeyQ")
3316
3370
  ];
3317
3371
  }
3318
- function Xn(e, t, n, r, i = J) {
3319
- return Hn(e, t) ? t : X(Q(e, t, 1 - Math.exp(-n / qn)), r, i);
3372
+ function nr(e, t, n, r, i = Y) {
3373
+ return Jn(e, t) ? t : Z(Gn(e, t, 1 - Math.exp(-n / $n)), r, i);
3320
3374
  }
3321
- var Zn = class {
3375
+ var rr = class {
3322
3376
  enabled = !0;
3323
3377
  #e;
3324
3378
  #t;
@@ -3337,7 +3391,7 @@ var Zn = class {
3337
3391
  #m = /* @__PURE__ */ new Set();
3338
3392
  #h;
3339
3393
  #g = null;
3340
- constructor(e, t, n, r, i = J) {
3394
+ constructor(e, t, n, r, i = Y) {
3341
3395
  this.#e = e, this.#t = t, this.#n = n, this.#r = i, this.#d = this.#j(r), this.#f = this.#d, this.#h = t.onFrame(this.#D);
3342
3396
  let a = this.#i.signal;
3343
3397
  e.addEventListener("pointerdown", this.#_, { signal: a }), e.addEventListener("pointermove", this.#v, { signal: a });
@@ -3358,7 +3412,7 @@ var Zn = class {
3358
3412
  return this.#m.add(e), () => this.#m.delete(e);
3359
3413
  }
3360
3414
  moveTo(e, t) {
3361
- let n = this.#d, r = Math.min(n.dist, bn.dist);
3415
+ let n = this.#d, r = Math.min(n.dist, Tn.dist);
3362
3416
  this.#O(this.#j({
3363
3417
  ...n,
3364
3418
  e,
@@ -3382,7 +3436,7 @@ var Zn = class {
3382
3436
  let i = () => this.#k(!1);
3383
3437
  return new Promise((t) => {
3384
3438
  this.#p = {
3385
- path: Vn(r, this.#j({
3439
+ path: qn(r, this.#j({
3386
3440
  ...r,
3387
3441
  ...e
3388
3442
  })),
@@ -3412,7 +3466,7 @@ var Zn = class {
3412
3466
  e.buttons & 6 || t && e.shiftKey ? $(this.#c, r, i) : t && $(this.#s, r, i);
3413
3467
  } else if (n) {
3414
3468
  let e = this.#T();
3415
- $(this.#c, e.x - n.x, e.y - n.y), this.#l += (n.d - e.d) * Gn;
3469
+ $(this.#c, e.x - n.x, e.y - n.y), this.#l += (n.d - e.d) * Zn;
3416
3470
  } else $(this.#s, r, i);
3417
3471
  this.#E();
3418
3472
  };
@@ -3420,7 +3474,7 @@ var Zn = class {
3420
3474
  this.#a.delete(e.pointerId);
3421
3475
  };
3422
3476
  #b = (e) => {
3423
- this.#w(e) && (e.preventDefault(), this.#l += e.deltaY * Wn, this.#E());
3477
+ this.#w(e) && (e.preventDefault(), this.#l += e.deltaY * Xn, this.#E());
3424
3478
  };
3425
3479
  #x = (e) => {
3426
3480
  this.#w(e) && (e.code === "KeyF" && !e.repeat && (this.#u = !this.#u), this.#o.add(e.code), this.#u && this.#E());
@@ -3432,12 +3486,12 @@ var Zn = class {
3432
3486
  if (!this.#w(e)) return;
3433
3487
  let t = await this.#t.pick(e.offsetX, e.offsetY);
3434
3488
  if (!t || this.#i.signal.aborted) return;
3435
- let [n, r, i] = t.point, a = Fn(Z(this.#f), {
3489
+ let [n, r, i] = t.point, a = Bn(Q(this.#f), {
3436
3490
  e: n,
3437
3491
  n: r,
3438
3492
  h: i
3439
3493
  });
3440
- this.#O(X(a, void 0, this.#r));
3494
+ this.#O(Z(a, void 0, this.#r));
3441
3495
  };
3442
3496
  #w(e) {
3443
3497
  return this.enabled && !e.defaultPrevented;
@@ -3459,26 +3513,26 @@ var Zn = class {
3459
3513
  this.#g = e;
3460
3514
  let n = this.#d, [r, i] = this.#c;
3461
3515
  if (r || i) {
3462
- let e = Jn(n.dist, this.#e.clientHeight);
3463
- n = zn(n, -r * e, i * e);
3516
+ let e = er(n.dist, this.#e.clientHeight);
3517
+ n = Wn(n, -r * e, i * e);
3464
3518
  }
3465
3519
  let [a, o] = this.#s;
3466
3520
  if (a || o) {
3467
- let [e, t] = [n.yaw + a * Un, n.pitch - o * Un];
3468
- n = this.#u ? In(n, e, t, this.#r) : X({
3521
+ let [e, t] = [n.yaw + a * Yn, n.pitch - o * Yn];
3522
+ n = this.#u ? Vn(n, e, t, this.#r) : Z({
3469
3523
  ...n,
3470
3524
  yaw: e,
3471
3525
  pitch: t
3472
3526
  }, void 0, this.#r);
3473
3527
  }
3474
- this.#l && (n = X({
3528
+ this.#l && (n = Z({
3475
3529
  ...n,
3476
3530
  dist: n.dist * Math.exp(this.#l)
3477
3531
  }, void 0, this.#r)), this.#c = [0, 0], this.#s = [0, 0], this.#l = 0;
3478
- let [s, c, l] = Yn(this.#o), u = this.enabled && this.#u && (s !== 0 || l !== 0 || c !== 0);
3532
+ let [s, c, l] = tr(this.#o), u = this.enabled && this.#u && (s !== 0 || l !== 0 || c !== 0);
3479
3533
  if (u) {
3480
- let e = Kn * Ln(n) * t;
3481
- n = Rn(n, s * e, c * e, l * e);
3534
+ let e = Qn * Hn(n) * t;
3535
+ n = Un(n, s * e, c * e, l * e);
3482
3536
  }
3483
3537
  let d = this.#f;
3484
3538
  n !== this.#d && this.#k(!1);
@@ -3487,7 +3541,7 @@ var Zn = class {
3487
3541
  f.start ??= e;
3488
3542
  let t = Math.min(1, (e - f.start) / f.path.ms);
3489
3543
  this.#d = this.#f = this.#j(f.path.at(t)), t === 1 && this.#k(!0);
3490
- } else d !== n && (this.#d = n = this.#j(n), this.#f = Xn(d, n, t, this.#n, this.#r));
3544
+ } else d !== n && (this.#d = n = this.#j(n), this.#f = nr(d, n, t, this.#n, this.#r));
3491
3545
  this.#f !== d && this.#A(), u || this.#p || this.#f !== this.#d ? this.#E() : this.#g = null;
3492
3546
  };
3493
3547
  #O(e) {
@@ -3503,14 +3557,14 @@ var Zn = class {
3503
3557
  for (let t of this.#m) t(e);
3504
3558
  }
3505
3559
  #j(e) {
3506
- return X(e, this.#n, this.#r);
3560
+ return Z(e, this.#n, this.#r);
3507
3561
  }
3508
3562
  #M() {
3509
- this.#t.setCamera(Nn(this.#f));
3563
+ this.#t.setCamera(Rn(this.#f));
3510
3564
  }
3511
3565
  };
3512
3566
  function $(e, t, n) {
3513
3567
  e[0] += t, e[1] += n;
3514
3568
  }
3515
3569
  //#endregion
3516
- export { yt as C, Kt as S, An as _, Z as a, Nn as b, Bn as c, jn as d, Ln as f, zn as g, kn as h, Q as i, Vn as l, Fn as m, yn as n, X as o, In as p, J as r, bn as s, Zn as t, Rn as u, Pn as v, ve as w, Gt as x, Hn as y };
3570
+ export { wt as C, Zt as S, Fn as _, Q as a, Rn as b, Kn as c, In as d, Hn as f, Wn as g, Pn as h, Gn as i, qn as l, Bn as m, wn as n, Z as o, Vn as p, Y as r, Tn as s, rr as t, Un as u, zn as v, be as w, Xt as x, Jn as y };