@fxi/zartigl 0.6.0 → 0.7.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.
- package/README.md +79 -39
- package/dist/backdrop-DctkJ45Q.js +79 -0
- package/dist/catalog.d.ts +136 -15
- package/dist/catalog.js +246 -90
- package/dist/engine.d.ts +324 -22
- package/dist/engine.js +78 -25
- package/dist/{geovideo-index-CD5wflJT.js → geovideo-index-CMGVia5M.js} +567 -252
- package/dist/zartigl.d.ts +168 -18
- package/dist/zartigl.js +2057 -1890
- package/package.json +8 -20
- package/dist/GeoVideoScalarSource-DoQAnyTy.js +0 -38
- package/dist/land-50m-BX3pQS4x.js +0 -15
- package/dist/projversor.d.ts +0 -919
- package/dist/projversor.js +0 -2374
- package/dist/scalar-color-domain-PEK8Hxg1.js +0 -12
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
const
|
|
2
|
-
thermal:
|
|
1
|
+
const $ = { label: "Thermal", tags: ["sequential", "temperature"], colors: ["#042333", "#2c3395", "#744796", "#b15f82", "#eb7958", "#fbb43d", "#e8fa5b"] }, W = { label: "Haline", tags: ["sequential", "salinity"], colors: ["#2a186c", "#17568b", "#1a7e8f", "#22a785", "#55c666", "#aadc32", "#fde333"] }, H = { label: "Solar", tags: ["sequential", "irradiance"], colors: ["#330f0b", "#6b2313", "#a83c12", "#d6621a", "#f3951e", "#f7c741", "#f9f871"] }, Y = { label: "Ice", tags: ["sequential"], colors: ["#040d1a", "#123365", "#1c5f9e", "#2b8ece", "#62bde3", "#aaddf2", "#f2faff"] }, z = { label: "Deep", tags: ["sequential", "depth"], colors: ["#fdfecc", "#c8e59b", "#74c8a3", "#3194b0", "#2a5b8e", "#281a5e", "#0c0820"] }, j = { label: "RdYlBu", tags: ["diverging"], colors: ["#3288bd", "#66c2a5", "#abdda4", "#e6f598", "#fee08b", "#fdae61", "#f46d43", "#d53e4f"] }, K = { label: "Dense", tags: ["sequential"], colors: ["#e6f1f1", "#92c4ca", "#44929a", "#20627a", "#1a3c6a", "#211a50", "#0d0621"] }, J = { label: "Algae", tags: ["sequential", "biology", "log"], colors: ["#d7f9d0", "#a2d595", "#64b463", "#129450", "#126e45", "#1a482f", "#122414"] }, Q = { label: "Oxygen", tags: ["sequential", "biology", "hypoxia"], colors: ["#09060f", "#5b1028", "#d43d2f", "#f39b3d", "#f3e7b3", "#79cbd1", "#176b9c"] }, Z = { label: "Matter", tags: ["sequential", "biology"], colors: ["#fdfecc", "#f2c98a", "#e07c4e", "#bc3754", "#8d1a6d", "#51156b", "#1c0c3f"] }, ee = { label: "Viridis", tags: ["sequential", "perceptual"], colors: ["#440154", "#443983", "#31688e", "#21918c", "#35b779", "#90d743", "#fde725"] }, te = { label: "Plasma", tags: ["sequential", "perceptual"], colors: ["#0d0887", "#5e01a6", "#9c179e", "#cc4778", "#ed7953", "#fdb42f", "#f0f921"] }, re = { label: "Cyclic", tags: ["cyclic", "direction"], colors: ["#2e22ea", "#b541fb", "#fc93c0", "#f1ee35", "#77c80d", "#458776", "#2c24e9"] }, ne = { label: "Tempo", tags: ["sequential"], colors: ["#fff6f4", "#c2d1b9", "#7db390", "#2a937f", "#156d73", "#1c455b", "#151d44"] }, ae = { label: "Turbid", tags: ["sequential", "biology", "log"], colors: ["#e9f5a0", "#c8c86e", "#a09845", "#786031", "#533324", "#341423", "#150d17"] }, ie = { label: "Speed", tags: ["sequential", "velocity"], colors: ["#fcfea4", "#d5e429", "#94c63e", "#52a657", "#2d8169", "#1d5b6d", "#0d3361"] }, oe = { label: "Amp", tags: ["sequential"], colors: ["#f2f2f2", "#c0b8db", "#9180b6", "#6c4e9e", "#4e2e83", "#32185d", "#110a35"] }, se = { label: "Balance", tags: ["diverging"], colors: ["#181c43", "#3066af", "#9bbcdd", "#f2f2f2", "#e07d53", "#b13626", "#2c0b0e"] }, ce = { label: "Delta", tags: ["diverging"], colors: ["#0e3f31", "#20877b", "#99d4c1", "#f2f2f2", "#a1b0d4", "#3c5b9e", "#0d1938"] }, de = { label: "Curl", tags: ["diverging"], colors: ["#152237", "#2471b3", "#8dbac4", "#f2f2f2", "#c79f84", "#a63827", "#270b17"] }, ue = { label: "Gray", tags: ["sequential"], colors: ["#000000", "#252525", "#4d4d4d", "#7a7a7a", "#a8a8a8", "#d4d4d4", "#ffffff"] }, g = {
|
|
2
|
+
thermal: $,
|
|
3
3
|
"thermal-alt": { label: "Thermal Alt", tags: ["sequential", "temperature"], colors: ["#176b9c", "#79cbd1", "#f3e7b3", "#f39b3d", "#d43d2f", "#5b1028", "#09060f"] },
|
|
4
|
-
haline:
|
|
5
|
-
solar:
|
|
6
|
-
ice:
|
|
7
|
-
deep:
|
|
8
|
-
rdylbu:
|
|
9
|
-
dense:
|
|
10
|
-
algae:
|
|
11
|
-
oxygen:
|
|
12
|
-
matter:
|
|
13
|
-
viridis:
|
|
14
|
-
plasma:
|
|
15
|
-
cyclic:
|
|
16
|
-
tempo:
|
|
17
|
-
turbid:
|
|
18
|
-
speed:
|
|
19
|
-
amp:
|
|
20
|
-
balance:
|
|
21
|
-
delta:
|
|
22
|
-
curl:
|
|
4
|
+
haline: W,
|
|
5
|
+
solar: H,
|
|
6
|
+
ice: Y,
|
|
7
|
+
deep: z,
|
|
8
|
+
rdylbu: j,
|
|
9
|
+
dense: K,
|
|
10
|
+
algae: J,
|
|
11
|
+
oxygen: Q,
|
|
12
|
+
matter: Z,
|
|
13
|
+
viridis: ee,
|
|
14
|
+
plasma: te,
|
|
15
|
+
cyclic: re,
|
|
16
|
+
tempo: ne,
|
|
17
|
+
turbid: ae,
|
|
18
|
+
speed: ie,
|
|
19
|
+
amp: oe,
|
|
20
|
+
balance: se,
|
|
21
|
+
delta: ce,
|
|
22
|
+
curl: de,
|
|
23
23
|
"mono-black": { label: "Black", tags: ["monochrome", "particles"], colors: ["#000000", "#000000"] },
|
|
24
24
|
"mono-white": { label: "White", tags: ["monochrome", "particles"], colors: ["#ffffff", "#ffffff"] },
|
|
25
25
|
"mono-pink": { label: "Pink", tags: ["monochrome", "particles"], colors: ["#ff2aa1", "#ff2aa1"] },
|
|
26
|
-
gray:
|
|
26
|
+
gray: ue
|
|
27
27
|
};
|
|
28
|
-
function
|
|
28
|
+
function I(e) {
|
|
29
29
|
const t = {}, r = e.length - 1;
|
|
30
30
|
return e.forEach((n, a) => {
|
|
31
31
|
t[r === 0 ? 0 : a / r] = n;
|
|
32
32
|
}), t;
|
|
33
33
|
}
|
|
34
|
-
function
|
|
35
|
-
const r =
|
|
34
|
+
function fe(e, t) {
|
|
35
|
+
const r = g;
|
|
36
36
|
if (typeof e == "string") {
|
|
37
37
|
const n = r[e];
|
|
38
38
|
if (!n)
|
|
@@ -42,18 +42,18 @@ function ee(e, t) {
|
|
|
42
42
|
).join(", ")}`
|
|
43
43
|
);
|
|
44
44
|
const a = t?.reverse ? [...n.colors].reverse() : n.colors;
|
|
45
|
-
return
|
|
45
|
+
return I(a);
|
|
46
46
|
}
|
|
47
47
|
if (Array.isArray(e)) {
|
|
48
48
|
const n = t?.reverse ? [...e].reverse() : e;
|
|
49
|
-
return
|
|
49
|
+
return I(n);
|
|
50
50
|
}
|
|
51
51
|
return e;
|
|
52
52
|
}
|
|
53
|
-
function
|
|
54
|
-
return Object.entries(
|
|
53
|
+
function Ye() {
|
|
54
|
+
return Object.entries(g).map(([t, r]) => ({ id: t, ...r }));
|
|
55
55
|
}
|
|
56
|
-
function
|
|
56
|
+
function N(e, t, r) {
|
|
57
57
|
const n = e.createShader(t);
|
|
58
58
|
if (!n)
|
|
59
59
|
throw new Error("Failed to create shader");
|
|
@@ -63,18 +63,18 @@ function x(e, t, r) {
|
|
|
63
63
|
}
|
|
64
64
|
return n;
|
|
65
65
|
}
|
|
66
|
-
function
|
|
66
|
+
function ze(e, t, r) {
|
|
67
67
|
const n = e.createProgram();
|
|
68
68
|
if (!n)
|
|
69
69
|
throw new Error("Failed to create program");
|
|
70
|
-
const a =
|
|
70
|
+
const a = N(e, e.VERTEX_SHADER, t), i = N(e, e.FRAGMENT_SHADER, r);
|
|
71
71
|
if (e.attachShader(n, a), e.attachShader(n, i), e.linkProgram(n), !e.getProgramParameter(n, e.LINK_STATUS)) {
|
|
72
72
|
const s = e.getProgramInfoLog(n);
|
|
73
73
|
throw e.deleteProgram(n), new Error(`Program link error: ${s}`);
|
|
74
74
|
}
|
|
75
75
|
return e.deleteShader(a), e.deleteShader(i), n;
|
|
76
76
|
}
|
|
77
|
-
function
|
|
77
|
+
function je(e, t, r, n, a) {
|
|
78
78
|
const i = e.createTexture();
|
|
79
79
|
if (!i)
|
|
80
80
|
throw new Error("Failed to create texture");
|
|
@@ -90,7 +90,7 @@ function Ae(e, t, r, n, a) {
|
|
|
90
90
|
r
|
|
91
91
|
), e.bindTexture(e.TEXTURE_2D, null), i;
|
|
92
92
|
}
|
|
93
|
-
function
|
|
93
|
+
function le(e, t, r) {
|
|
94
94
|
const n = e.getParameter(
|
|
95
95
|
e.TEXTURE_BINDING_2D
|
|
96
96
|
), a = e.getParameter(
|
|
@@ -122,19 +122,19 @@ function te(e, t, r) {
|
|
|
122
122
|
}
|
|
123
123
|
return o;
|
|
124
124
|
}
|
|
125
|
-
function
|
|
125
|
+
function he(e) {
|
|
126
126
|
return {
|
|
127
127
|
kind: "rgba8-packed",
|
|
128
128
|
internalFormat: e.RGBA,
|
|
129
129
|
type: e.UNSIGNED_BYTE
|
|
130
130
|
};
|
|
131
131
|
}
|
|
132
|
-
function
|
|
132
|
+
function Ke(e) {
|
|
133
133
|
if (typeof WebGL2RenderingContext > "u" || !(e instanceof WebGL2RenderingContext))
|
|
134
134
|
throw new Error("zartigl requires WebGL2");
|
|
135
135
|
return e;
|
|
136
136
|
}
|
|
137
|
-
function
|
|
137
|
+
function Je(e) {
|
|
138
138
|
const t = [];
|
|
139
139
|
e.getExtension("EXT_color_buffer_float") ? t.push(
|
|
140
140
|
{ kind: "float32", internalFormat: e.RGBA32F, type: e.FLOAT },
|
|
@@ -145,15 +145,15 @@ function De(e) {
|
|
|
145
145
|
type: e.HALF_FLOAT
|
|
146
146
|
});
|
|
147
147
|
for (const r of t)
|
|
148
|
-
if (
|
|
148
|
+
if (le(
|
|
149
149
|
e,
|
|
150
150
|
r.internalFormat,
|
|
151
151
|
r.type
|
|
152
152
|
))
|
|
153
153
|
return r;
|
|
154
|
-
return
|
|
154
|
+
return he(e);
|
|
155
155
|
}
|
|
156
|
-
function
|
|
156
|
+
function Qe(e, t, r, n, a, i, s) {
|
|
157
157
|
const o = e.createTexture();
|
|
158
158
|
if (!o)
|
|
159
159
|
throw new Error("Failed to create texture");
|
|
@@ -169,10 +169,10 @@ function Ue(e, t, r, n, a, i, s) {
|
|
|
169
169
|
r
|
|
170
170
|
), e.bindTexture(e.TEXTURE_2D, null), o;
|
|
171
171
|
}
|
|
172
|
-
function
|
|
172
|
+
function Ze(e, t, r) {
|
|
173
173
|
e.activeTexture(e.TEXTURE0 + r), e.bindTexture(e.TEXTURE_2D, t);
|
|
174
174
|
}
|
|
175
|
-
function
|
|
175
|
+
function et(e, t) {
|
|
176
176
|
const r = e.createFramebuffer();
|
|
177
177
|
if (!r)
|
|
178
178
|
throw new Error("Failed to create framebuffer");
|
|
@@ -184,7 +184,7 @@ function Me(e, t) {
|
|
|
184
184
|
0
|
|
185
185
|
), e.bindFramebuffer(e.FRAMEBUFFER, null), r;
|
|
186
186
|
}
|
|
187
|
-
function
|
|
187
|
+
function tt(e) {
|
|
188
188
|
const t = e.createBuffer();
|
|
189
189
|
if (!t)
|
|
190
190
|
throw new Error("Failed to create buffer");
|
|
@@ -194,7 +194,7 @@ function ye(e) {
|
|
|
194
194
|
e.STATIC_DRAW
|
|
195
195
|
), t;
|
|
196
196
|
}
|
|
197
|
-
const
|
|
197
|
+
const me = {
|
|
198
198
|
0: "#3288bd",
|
|
199
199
|
0.1: "#66c2a5",
|
|
200
200
|
0.2: "#abdda4",
|
|
@@ -204,19 +204,19 @@ const ae = {
|
|
|
204
204
|
0.6: "#f46d43",
|
|
205
205
|
1: "#d53e4f"
|
|
206
206
|
};
|
|
207
|
-
function
|
|
208
|
-
const r = t != null ?
|
|
207
|
+
function rt(e, t) {
|
|
208
|
+
const r = t != null ? fe(t) : me, n = document.createElement("canvas");
|
|
209
209
|
n.width = 256, n.height = 1;
|
|
210
210
|
const a = n.getContext("2d"), i = a.createLinearGradient(0, 0, 256, 0);
|
|
211
|
-
for (const [o,
|
|
212
|
-
i.addColorStop(Number(o),
|
|
211
|
+
for (const [o, c] of Object.entries(r))
|
|
212
|
+
i.addColorStop(Number(o), c);
|
|
213
213
|
a.fillStyle = i, a.fillRect(0, 0, 256, 1);
|
|
214
214
|
const s = e.createTexture();
|
|
215
215
|
if (!s)
|
|
216
216
|
throw new Error("Failed to create color ramp texture");
|
|
217
217
|
return e.bindTexture(e.TEXTURE_2D, s), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_S, e.CLAMP_TO_EDGE), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_WRAP_T, e.CLAMP_TO_EDGE), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MIN_FILTER, e.LINEAR), e.texParameteri(e.TEXTURE_2D, e.TEXTURE_MAG_FILTER, e.LINEAR), e.texImage2D(e.TEXTURE_2D, 0, e.RGBA, e.RGBA, e.UNSIGNED_BYTE, n), e.bindTexture(e.TEXTURE_2D, null), s;
|
|
218
218
|
}
|
|
219
|
-
function
|
|
219
|
+
function nt(e) {
|
|
220
220
|
const t = e.getExtension("WEBGL_debug_renderer_info");
|
|
221
221
|
return {
|
|
222
222
|
vendor: String(e.getParameter(e.VENDOR) ?? ""),
|
|
@@ -226,7 +226,7 @@ function Se(e) {
|
|
|
226
226
|
version: String(e.getParameter(e.VERSION) ?? "")
|
|
227
227
|
};
|
|
228
228
|
}
|
|
229
|
-
function
|
|
229
|
+
function at(e) {
|
|
230
230
|
return {
|
|
231
231
|
program: e.getParameter(e.CURRENT_PROGRAM),
|
|
232
232
|
activeTexture: e.getParameter(e.ACTIVE_TEXTURE),
|
|
@@ -243,19 +243,19 @@ function Pe(e) {
|
|
|
243
243
|
]
|
|
244
244
|
};
|
|
245
245
|
}
|
|
246
|
-
function
|
|
246
|
+
function it(e, t) {
|
|
247
247
|
e.useProgram(t.program), e.activeTexture(t.activeTexture), e.bindBuffer(e.ARRAY_BUFFER, t.arrayBuffer), e.bindBuffer(e.ELEMENT_ARRAY_BUFFER, t.elementBuffer), e.bindFramebuffer(e.FRAMEBUFFER, t.framebuffer), t.blend ? e.enable(e.BLEND) : e.disable(e.BLEND), t.depthTest ? e.enable(e.DEPTH_TEST) : e.disable(e.DEPTH_TEST), t.stencilTest ? e.enable(e.STENCIL_TEST) : e.disable(e.STENCIL_TEST), e.viewport(t.viewport[0], t.viewport[1], t.viewport[2], t.viewport[3]), e.blendFunc(t.blendFunc[0], t.blendFunc[1]);
|
|
248
248
|
}
|
|
249
|
-
const
|
|
250
|
-
function
|
|
249
|
+
const L = 20, Ee = 600;
|
|
250
|
+
function Te(e) {
|
|
251
251
|
const t = Math.max(0, Math.min(1, e));
|
|
252
|
-
return
|
|
252
|
+
return L * Math.pow(Ee / L, t);
|
|
253
253
|
}
|
|
254
|
-
function
|
|
255
|
-
return Math.exp(-1 /
|
|
254
|
+
function ot(e) {
|
|
255
|
+
return Math.exp(-1 / Te(e));
|
|
256
256
|
}
|
|
257
|
-
const
|
|
258
|
-
class
|
|
257
|
+
const pe = 0.8, be = 120, we = 300;
|
|
258
|
+
class st {
|
|
259
259
|
constructor(t) {
|
|
260
260
|
this.base = t, this.moving = !1, this.start = 0, this.duration = 0, this.from = t, this.to = t;
|
|
261
261
|
}
|
|
@@ -264,7 +264,7 @@ class Le {
|
|
|
264
264
|
this.base = t, this.moving || (this.from = t, this.to = t, this.duration = 0);
|
|
265
265
|
}
|
|
266
266
|
setMoving(t, r) {
|
|
267
|
-
t !== this.moving && (this.from = this.value(r), this.moving = t, this.to = t ?
|
|
267
|
+
t !== this.moving && (this.from = this.value(r), this.moving = t, this.to = t ? pe : this.base, this.start = r, this.duration = t ? be : we);
|
|
268
268
|
}
|
|
269
269
|
value(t) {
|
|
270
270
|
if (this.duration === 0)
|
|
@@ -273,48 +273,21 @@ class Le {
|
|
|
273
273
|
return r === 1 ? (this.duration = 0, this.from = this.to, this.to) : this.from + (this.to - this.from) * r * r * (3 - 2 * r);
|
|
274
274
|
}
|
|
275
275
|
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
}), fe = Object.freeze({
|
|
285
|
-
enabled: !0,
|
|
286
|
-
...S
|
|
287
|
-
}), U = {
|
|
288
|
-
exposure: [0, 4],
|
|
289
|
-
contrast: [0, 1],
|
|
290
|
-
saturation: [-1, 1],
|
|
291
|
-
highlights: [0, 1]
|
|
292
|
-
};
|
|
293
|
-
function Ve(e) {
|
|
294
|
-
if (!e)
|
|
295
|
-
return { ...ce };
|
|
296
|
-
const t = {
|
|
297
|
-
...fe,
|
|
298
|
-
enabled: e.enabled ?? !0
|
|
299
|
-
};
|
|
300
|
-
for (const r of Object.keys(U)) {
|
|
301
|
-
const n = e[r];
|
|
302
|
-
if (typeof n == "number" && Number.isFinite(n)) {
|
|
303
|
-
const [a, i] = U[r];
|
|
304
|
-
t[r] = Math.min(i, Math.max(a, n));
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
return t;
|
|
308
|
-
}
|
|
309
|
-
function Be(e) {
|
|
310
|
-
return [e.exposure, e.contrast, e.saturation, e.highlights];
|
|
276
|
+
function ct(e) {
|
|
277
|
+
if (e == null)
|
|
278
|
+
return null;
|
|
279
|
+
if (!Number.isFinite(e[0]) || !Number.isFinite(e[1]) || e[0] >= e[1])
|
|
280
|
+
throw new RangeError(
|
|
281
|
+
"colorDomain must contain two finite, increasing values"
|
|
282
|
+
);
|
|
283
|
+
return [e[0], e[1]];
|
|
311
284
|
}
|
|
312
|
-
function
|
|
285
|
+
function m(e, t) {
|
|
313
286
|
if (typeof e != "number" || !Number.isFinite(e))
|
|
314
287
|
throw new Error(`Invalid GeoVideo manifest ${t}`);
|
|
315
288
|
return e;
|
|
316
289
|
}
|
|
317
|
-
function
|
|
290
|
+
function F(e, t) {
|
|
318
291
|
if (typeof e != "string")
|
|
319
292
|
throw new Error(`Invalid GeoVideo manifest ${t}`);
|
|
320
293
|
const r = new Date(e).getTime();
|
|
@@ -322,12 +295,12 @@ function b(e, t) {
|
|
|
322
295
|
throw new Error(`Invalid GeoVideo manifest ${t}`);
|
|
323
296
|
return r;
|
|
324
297
|
}
|
|
325
|
-
function
|
|
298
|
+
function D(e) {
|
|
326
299
|
return typeof e == "string" && /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(
|
|
327
300
|
e
|
|
328
301
|
);
|
|
329
302
|
}
|
|
330
|
-
function
|
|
303
|
+
function V(e) {
|
|
331
304
|
if (!e || typeof e != "object")
|
|
332
305
|
throw new Error("Invalid GeoVideo manifest");
|
|
333
306
|
const t = e;
|
|
@@ -340,50 +313,50 @@ function v(e) {
|
|
|
340
313
|
if (!Array.isArray(t.bounds) || t.bounds.length !== 4)
|
|
341
314
|
throw new Error("Invalid GeoVideo manifest bounds");
|
|
342
315
|
const [r, n, a, i] = t.bounds.map(
|
|
343
|
-
(
|
|
316
|
+
(f, T) => m(f, `bounds[${T}]`)
|
|
344
317
|
);
|
|
345
318
|
if (n < -90 || i > 90 || n >= i || r === a)
|
|
346
319
|
throw new Error("Invalid GeoVideo geographic bounds");
|
|
347
320
|
const s = t.media;
|
|
348
321
|
if (!s || typeof s.url != "string" || !s.url)
|
|
349
322
|
throw new Error("Invalid GeoVideo media");
|
|
350
|
-
for (const
|
|
351
|
-
if (
|
|
352
|
-
throw new Error(`Invalid GeoVideo media.${
|
|
323
|
+
for (const f of ["width", "height", "fps", "durationSeconds"])
|
|
324
|
+
if (m(s[f], `media.${f}`) <= 0)
|
|
325
|
+
throw new Error(`Invalid GeoVideo media.${f}`);
|
|
353
326
|
const o = t.encoding;
|
|
354
327
|
if (!o || o.bits !== 8 || o.colorSpace !== "bt709" || o.colorRange !== "limited" && o.colorRange !== "full")
|
|
355
328
|
throw new Error("Invalid GeoVideo encoding");
|
|
356
|
-
const
|
|
357
|
-
if (
|
|
329
|
+
const c = m(o.codeMin, "encoding.codeMin"), d = m(o.codeMax, "encoding.codeMax");
|
|
330
|
+
if (c < 0 || d > 255 || c >= d)
|
|
358
331
|
throw new Error("Invalid GeoVideo code range");
|
|
359
|
-
let
|
|
332
|
+
let h = s.height;
|
|
360
333
|
if (o.kind === "scalar-luma") {
|
|
361
|
-
if (o.transfer !== "linear" ||
|
|
334
|
+
if (o.transfer !== "linear" || m(o.valueMin, "encoding.valueMin") >= m(o.valueMax, "encoding.valueMax"))
|
|
362
335
|
throw new Error("Invalid GeoVideo scalar-luma encoding");
|
|
363
336
|
} else if (o.kind === "vector-luma") {
|
|
364
|
-
if (o.transfer !== "linear" && o.transfer !== "sqrt" || o.layout !== "stacked-uv" ||
|
|
337
|
+
if (o.transfer !== "linear" && o.transfer !== "sqrt" || o.layout !== "stacked-uv" || m(o.valueDomain, "encoding.valueDomain") <= 0 || s.height % 2 !== 0)
|
|
365
338
|
throw new Error("Invalid GeoVideo vector-luma encoding");
|
|
366
|
-
|
|
339
|
+
h = s.height / 2;
|
|
367
340
|
} else
|
|
368
341
|
throw new Error("Unsupported GeoVideo encoding");
|
|
369
|
-
const
|
|
370
|
-
if (!
|
|
342
|
+
const u = t.mask;
|
|
343
|
+
if (!u || u.kind !== "static-validity" || typeof u.url != "string" || !u.url || m(u.width, "mask.width") !== s.width || m(u.height, "mask.height") !== h || m(u.threshold, "mask.threshold") < 0 || u.threshold > 1)
|
|
371
344
|
throw new Error("Invalid GeoVideo static mask");
|
|
372
345
|
if (t.timeline?.kind === "range") {
|
|
373
|
-
const
|
|
374
|
-
if (
|
|
346
|
+
const f = F(t.timeline.dateStart, "timeline.dateStart");
|
|
347
|
+
if (F(t.timeline.dateEnd, "timeline.dateEnd") <= f)
|
|
375
348
|
throw new Error("GeoVideo timeline end must follow start");
|
|
376
349
|
if (t.timeline.interpolation !== "linear" && t.timeline.interpolation !== "nearest")
|
|
377
350
|
throw new Error("Invalid GeoVideo interpolation");
|
|
378
351
|
} else if (t.timeline?.kind === "snapshot-loop")
|
|
379
|
-
|
|
352
|
+
F(t.timeline.date, "timeline.date");
|
|
380
353
|
else if (t.timeline?.kind === "sample-sequence") {
|
|
381
354
|
if (!Array.isArray(t.timeline.values) || t.timeline.values.length === 0)
|
|
382
355
|
throw new Error("GeoVideo sample sequence must contain values");
|
|
383
|
-
const
|
|
384
|
-
(
|
|
356
|
+
const f = t.timeline.values.map(
|
|
357
|
+
(T, b) => F(T, `timeline.values[${b}]`)
|
|
385
358
|
);
|
|
386
|
-
if (
|
|
359
|
+
if (f.some((T, b) => b > 0 && T <= f[b - 1]))
|
|
387
360
|
throw new Error(
|
|
388
361
|
"GeoVideo sample sequence values must be strictly increasing"
|
|
389
362
|
);
|
|
@@ -392,26 +365,26 @@ function v(e) {
|
|
|
392
365
|
const E = t.style?.colorDomain;
|
|
393
366
|
if (!Array.isArray(E) || E.length !== 2 || !E.every(Number.isFinite) || E[0] >= E[1])
|
|
394
367
|
throw new Error("Invalid GeoVideo color domain");
|
|
395
|
-
if (!
|
|
368
|
+
if (!D(t.id) || !t.provenance || !D(t.provenance.catalogEntryId) || !D(t.provenance.inputSourceId) || !Array.isArray(t.provenance.variables) || t.provenance.variables.length === 0)
|
|
396
369
|
throw new Error("Invalid GeoVideo provenance");
|
|
397
370
|
return { ...t, bounds: [r, n, a, i] };
|
|
398
371
|
}
|
|
399
|
-
async function
|
|
372
|
+
async function Re(e, t) {
|
|
400
373
|
if (typeof e != "string")
|
|
401
|
-
return
|
|
374
|
+
return V(e);
|
|
402
375
|
const r = await fetch(e, { signal: t });
|
|
403
376
|
if (!r.ok)
|
|
404
377
|
throw new Error(
|
|
405
378
|
`GeoVideo manifest request failed (${r.status}): ${e}`
|
|
406
379
|
);
|
|
407
|
-
const n = await r.json(), a =
|
|
380
|
+
const n = await r.json(), a = V(n), i = typeof document < "u" ? new URL(e, document.baseURI).href : e;
|
|
408
381
|
return {
|
|
409
382
|
...a,
|
|
410
383
|
media: { ...a.media, url: new URL(a.media.url, i).href },
|
|
411
384
|
mask: { ...a.mask, url: new URL(a.mask.url, i).href }
|
|
412
385
|
};
|
|
413
386
|
}
|
|
414
|
-
function
|
|
387
|
+
function _(e) {
|
|
415
388
|
if (e.timeline.kind === "snapshot-loop")
|
|
416
389
|
return [new Date(e.timeline.date).getTime()];
|
|
417
390
|
if (e.timeline.kind === "sample-sequence")
|
|
@@ -425,40 +398,40 @@ function F(e) {
|
|
|
425
398
|
(a, i) => t + (r - t) * i / (n - 1)
|
|
426
399
|
);
|
|
427
400
|
}
|
|
428
|
-
function
|
|
401
|
+
function _e(e) {
|
|
429
402
|
return e.timeline.kind === "sample-sequence" ? e.timeline.values.length / e.media.durationSeconds : e.media.fps;
|
|
430
403
|
}
|
|
431
|
-
function
|
|
432
|
-
return t /
|
|
404
|
+
function dt(e, t) {
|
|
405
|
+
return t / _e(e);
|
|
433
406
|
}
|
|
434
|
-
function
|
|
407
|
+
function Ae(e, t) {
|
|
435
408
|
if (e.timeline.kind === "snapshot-loop")
|
|
436
409
|
return 0;
|
|
437
410
|
if (e.timeline.kind === "sample-sequence") {
|
|
438
|
-
const i =
|
|
411
|
+
const i = _(e);
|
|
439
412
|
let s = 0;
|
|
440
|
-
for (let
|
|
441
|
-
Math.abs(i[
|
|
413
|
+
for (let c = 1; c < i.length; c += 1)
|
|
414
|
+
Math.abs(i[c] - t) < Math.abs(i[s] - t) && (s = c);
|
|
442
415
|
const o = e.media.durationSeconds / i.length;
|
|
443
416
|
return s * o + Math.min(o / 2, 0.5 / e.media.fps);
|
|
444
417
|
}
|
|
445
418
|
const r = new Date(e.timeline.dateStart).getTime(), n = new Date(e.timeline.dateEnd).getTime();
|
|
446
|
-
return Math.max(0, Math.min(1, (t - r) / (n - r))) *
|
|
419
|
+
return Math.max(0, Math.min(1, (t - r) / (n - r))) * X(e);
|
|
447
420
|
}
|
|
448
|
-
function
|
|
421
|
+
function ut(e, t) {
|
|
449
422
|
if (e.timeline.kind === "snapshot-loop")
|
|
450
423
|
return new Date(e.timeline.date).getTime();
|
|
451
424
|
if (e.timeline.kind === "sample-sequence") {
|
|
452
|
-
const s =
|
|
453
|
-
return s[Math.max(0, Math.min(s.length - 1,
|
|
425
|
+
const s = _(e), o = e.media.durationSeconds / s.length, c = Math.floor((t + 0.25 / e.media.fps) / o);
|
|
426
|
+
return s[Math.max(0, Math.min(s.length - 1, c))];
|
|
454
427
|
}
|
|
455
|
-
const r = new Date(e.timeline.dateStart).getTime(), n = new Date(e.timeline.dateEnd).getTime(), a =
|
|
428
|
+
const r = new Date(e.timeline.dateStart).getTime(), n = new Date(e.timeline.dateEnd).getTime(), a = X(e), i = a > 0 ? Math.max(0, Math.min(1, t / a)) : 0;
|
|
456
429
|
return r + (n - r) * i;
|
|
457
430
|
}
|
|
458
|
-
function
|
|
431
|
+
function X(e) {
|
|
459
432
|
return Math.max(0, e.media.durationSeconds - 1 / e.media.fps);
|
|
460
433
|
}
|
|
461
|
-
function
|
|
434
|
+
function Fe(e, t) {
|
|
462
435
|
const r = new Uint8Array(e.length / 4);
|
|
463
436
|
for (let n = 0; n < r.length; n++) {
|
|
464
437
|
const a = e[n * 4];
|
|
@@ -466,7 +439,7 @@ function le(e, t) {
|
|
|
466
439
|
}
|
|
467
440
|
return r;
|
|
468
441
|
}
|
|
469
|
-
class
|
|
442
|
+
class xe {
|
|
470
443
|
constructor() {
|
|
471
444
|
this.gl = null, this.texture = null, this.framebuffer = null;
|
|
472
445
|
}
|
|
@@ -497,62 +470,105 @@ class me {
|
|
|
497
470
|
return this.gl = n, this.texture = n.createTexture(), this.framebuffer = n.createFramebuffer(), n;
|
|
498
471
|
}
|
|
499
472
|
}
|
|
500
|
-
function
|
|
473
|
+
function C(e) {
|
|
501
474
|
const t = Math.max(4, Math.floor(e.length / 4 / 997) * 4);
|
|
502
475
|
for (let r = 3; r < e.length; r += t)
|
|
503
476
|
if (e[r] !== 0)
|
|
504
477
|
return !1;
|
|
505
478
|
return !0;
|
|
506
479
|
}
|
|
507
|
-
function
|
|
480
|
+
function l() {
|
|
508
481
|
return new DOMException("GeoVideo frame request was cancelled", "AbortError");
|
|
509
482
|
}
|
|
510
|
-
function
|
|
483
|
+
function R(e, t, r) {
|
|
484
|
+
return t ? t.aborted ? (e.catch(() => {
|
|
485
|
+
}), r?.(), Promise.reject(l())) : new Promise((n, a) => {
|
|
486
|
+
const i = () => {
|
|
487
|
+
r?.(), a(l());
|
|
488
|
+
};
|
|
489
|
+
t.addEventListener("abort", i, { once: !0 }), e.then(n, a).finally(() => {
|
|
490
|
+
t.removeEventListener("abort", i);
|
|
491
|
+
});
|
|
492
|
+
}) : e;
|
|
493
|
+
}
|
|
494
|
+
function M(e, t) {
|
|
511
495
|
return new Promise(
|
|
512
496
|
(r) => e.addEventListener(t, () => r(), { once: !0 })
|
|
513
497
|
);
|
|
514
498
|
}
|
|
515
|
-
const
|
|
516
|
-
function
|
|
499
|
+
const ve = 250;
|
|
500
|
+
function ye(e) {
|
|
517
501
|
return "requestVideoFrameCallback" in e ? Promise.race([
|
|
518
502
|
new Promise(
|
|
519
503
|
(t) => e.requestVideoFrameCallback(() => t())
|
|
520
504
|
),
|
|
521
|
-
new Promise((t) => setTimeout(t,
|
|
505
|
+
new Promise((t) => setTimeout(t, ve))
|
|
522
506
|
]) : Promise.resolve();
|
|
523
507
|
}
|
|
524
|
-
class
|
|
508
|
+
class O {
|
|
525
509
|
constructor(t, r, n = {}) {
|
|
526
|
-
this.reader = new
|
|
510
|
+
this.reader = new xe(), this.video = null, this.mask = null, this.initPromise = null, this.presented = !1, this.primed = !1, this.queue = Promise.resolve(), this.frames = /* @__PURE__ */ new Map(), this.pending = /* @__PURE__ */ new Set(), this.manifest = t, this.planes = r, this.cacheSize = Math.max(1, n.cacheSize ?? 3), this.width = t.media.width, this.height = t.media.height / r, this.times = Float64Array.from(_(t));
|
|
527
511
|
}
|
|
528
512
|
init() {
|
|
529
513
|
return this.initPromise ??= this.load().catch((t) => {
|
|
530
514
|
throw this.initPromise = null, t;
|
|
531
515
|
}), this.initPromise;
|
|
532
516
|
}
|
|
533
|
-
/** Abort
|
|
517
|
+
/** Abort every pending frame decode; frames already decoded stay cached. */
|
|
534
518
|
cancelAll() {
|
|
535
|
-
this.
|
|
536
|
-
|
|
537
|
-
r.catch(() => this.frames.delete(t));
|
|
519
|
+
for (const t of [...this.pending])
|
|
520
|
+
this.drop(t);
|
|
538
521
|
}
|
|
539
522
|
/** Release the video element and GL context; a later init() reloads them. */
|
|
540
523
|
release() {
|
|
541
524
|
this.cancelAll(), this.frames.clear(), this.video && (this.video.removeAttribute("src"), this.video.load()), this.video = null, this.mask = null, this.presented = !1, this.primed = !1, this.initPromise = null, this.reader.release();
|
|
542
525
|
}
|
|
543
|
-
/**
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
526
|
+
/**
|
|
527
|
+
* One decode per time step, cached and shared by concurrent requests.
|
|
528
|
+
* Aborting `request.signal` rejects this request with an AbortError; the
|
|
529
|
+
* decode goes on while another request waits for it.
|
|
530
|
+
*/
|
|
531
|
+
frame(t, r = {}) {
|
|
532
|
+
const { signal: n } = r;
|
|
533
|
+
if (n?.aborted)
|
|
534
|
+
return Promise.reject(l());
|
|
535
|
+
let a = this.frames.get(t);
|
|
536
|
+
if (a ? (this.frames.delete(t), this.frames.set(t, a)) : a = this.enqueue(t), a.settled)
|
|
537
|
+
return a.promise;
|
|
538
|
+
const i = a;
|
|
539
|
+
return i.waiters++, R(i.promise, n, () => this.leave(i));
|
|
540
|
+
}
|
|
541
|
+
enqueue(t) {
|
|
542
|
+
const r = new AbortController(), n = this.queue.then(
|
|
543
|
+
() => r.signal.aborted ? Promise.reject(l()) : this.decode(t, r.signal)
|
|
544
|
+
);
|
|
545
|
+
this.queue = n.catch(() => {
|
|
546
|
+
});
|
|
547
|
+
const a = {
|
|
548
|
+
index: t,
|
|
549
|
+
controller: r,
|
|
550
|
+
promise: R(n, r.signal),
|
|
551
|
+
waiters: 0,
|
|
552
|
+
settled: !1
|
|
553
|
+
};
|
|
554
|
+
for (this.pending.add(a), a.promise.then(
|
|
555
|
+
() => {
|
|
556
|
+
a.settled = !0, this.pending.delete(a);
|
|
557
|
+
},
|
|
558
|
+
() => {
|
|
559
|
+
a.settled = !0, this.pending.delete(a), this.frames.get(t) === a && this.frames.delete(t);
|
|
560
|
+
}
|
|
561
|
+
), this.frames.set(t, a); this.frames.size > this.cacheSize; )
|
|
553
562
|
this.frames.delete(this.frames.keys().next().value);
|
|
554
563
|
return a;
|
|
555
564
|
}
|
|
565
|
+
/** A request left; drop the decode when it was the last one waiting. */
|
|
566
|
+
leave(t) {
|
|
567
|
+
t.waiters--, t.waiters <= 0 && !t.settled && this.drop(t);
|
|
568
|
+
}
|
|
569
|
+
drop(t) {
|
|
570
|
+
t.controller.abort(), this.pending.delete(t), this.frames.get(t.index) === t && this.frames.delete(t.index);
|
|
571
|
+
}
|
|
556
572
|
async load() {
|
|
557
573
|
const [t] = await Promise.all([this.loadMask(), this.loadVideo()]);
|
|
558
574
|
this.mask = t;
|
|
@@ -594,8 +610,8 @@ class be {
|
|
|
594
610
|
async presentFrame(t, r) {
|
|
595
611
|
if (this.presented && Math.abs(t.currentTime - r) <= 1e-3 && !t.seeking)
|
|
596
612
|
return;
|
|
597
|
-
const n =
|
|
598
|
-
t.currentTime = r, await a, t.readyState < HTMLMediaElement.HAVE_CURRENT_DATA && await Promise.race([
|
|
613
|
+
const n = ye(t), a = M(t, "seeked");
|
|
614
|
+
t.currentTime = r, await a, t.readyState < HTMLMediaElement.HAVE_CURRENT_DATA && await Promise.race([M(t, "loadeddata"), M(t, "canplay")]), await n, this.presented = !0;
|
|
599
615
|
}
|
|
600
616
|
/**
|
|
601
617
|
* Some mobile browsers expose no decoded pixels to WebGL until playback
|
|
@@ -610,63 +626,69 @@ class be {
|
|
|
610
626
|
}
|
|
611
627
|
t.pause(), this.presented = !1;
|
|
612
628
|
}
|
|
629
|
+
/**
|
|
630
|
+
* Seek, read back and decode one step. `signal` aborts it between steps;
|
|
631
|
+
* a seek already started completes first, keeping the queue serial.
|
|
632
|
+
*/
|
|
613
633
|
async decode(t, r) {
|
|
634
|
+
if (r.aborted)
|
|
635
|
+
throw l();
|
|
614
636
|
await this.init();
|
|
615
637
|
const n = this.video, a = this.mask;
|
|
616
|
-
if (r
|
|
617
|
-
throw
|
|
618
|
-
const i =
|
|
619
|
-
if (await this.presentFrame(n, i), r
|
|
620
|
-
throw
|
|
638
|
+
if (r.aborted || !n || !a)
|
|
639
|
+
throw l();
|
|
640
|
+
const i = Ae(this.manifest, this.times[t]);
|
|
641
|
+
if (await this.presentFrame(n, i), r.aborted || n !== this.video)
|
|
642
|
+
throw l();
|
|
621
643
|
const s = this.height * this.planes;
|
|
622
644
|
let o = this.reader.read(n, this.width, s);
|
|
623
|
-
if (
|
|
624
|
-
if (await this.primeDecoder(n), await this.presentFrame(n, i), r
|
|
625
|
-
throw
|
|
645
|
+
if (C(o) && !this.primed) {
|
|
646
|
+
if (await this.primeDecoder(n), await this.presentFrame(n, i), r.aborted || n !== this.video)
|
|
647
|
+
throw l();
|
|
626
648
|
o = this.reader.read(n, this.width, s);
|
|
627
649
|
}
|
|
628
|
-
if (
|
|
650
|
+
if (C(o))
|
|
629
651
|
throw new Error("GeoVideo frame could not be read back from the decoder");
|
|
630
|
-
const
|
|
631
|
-
return this.decodeCodes(
|
|
652
|
+
const c = Fe(o, this.manifest.encoding.colorRange);
|
|
653
|
+
return this.decodeCodes(c, a, this.manifest.mask.threshold);
|
|
632
654
|
}
|
|
633
655
|
}
|
|
634
|
-
function
|
|
656
|
+
function De(e, t) {
|
|
635
657
|
let r = (e - t.codeMin) / (t.codeMax - t.codeMin) * 2 - 1;
|
|
636
658
|
return r = Math.max(-1, Math.min(1, r)), t.transfer === "sqrt" && (r = Math.sign(r) * r * r), r * t.valueDomain;
|
|
637
659
|
}
|
|
638
|
-
function
|
|
660
|
+
function Me(e, t, r, n) {
|
|
639
661
|
const a = t.length;
|
|
640
662
|
if (e.length !== 2 * a)
|
|
641
663
|
throw new Error(
|
|
642
664
|
`GeoVideo vector frame has ${e.length} codes, expected ${2 * a}`
|
|
643
665
|
);
|
|
644
666
|
const i = new Float32Array(256);
|
|
645
|
-
for (let
|
|
646
|
-
i[
|
|
647
|
-
const s = r * 255, o = new Float32Array(a),
|
|
648
|
-
for (let
|
|
649
|
-
const
|
|
650
|
-
o[
|
|
667
|
+
for (let d = 0; d < 256; d++)
|
|
668
|
+
i[d] = De(d, n);
|
|
669
|
+
const s = r * 255, o = new Float32Array(a), c = new Float32Array(a);
|
|
670
|
+
for (let d = 0; d < a; d++) {
|
|
671
|
+
const h = t[d] >= s;
|
|
672
|
+
o[d] = h ? i[e[d]] : NaN, c[d] = h ? i[e[a + d]] : NaN;
|
|
651
673
|
}
|
|
652
|
-
return { u: o, v:
|
|
674
|
+
return { u: o, v: c };
|
|
653
675
|
}
|
|
654
|
-
class
|
|
676
|
+
class Ue extends O {
|
|
655
677
|
constructor(t, r = {}) {
|
|
656
678
|
if (t.encoding.kind !== "vector-luma")
|
|
657
679
|
throw new Error("GeoVideoVectorSource requires a vector-luma manifest");
|
|
658
680
|
super(t, 2, r), this.encoding = t.encoding;
|
|
659
|
-
const [n, a, i, s] = t.bounds, o = (i - n) / this.width,
|
|
681
|
+
const [n, a, i, s] = t.bounds, o = (i - n) / this.width, c = (s - a) / this.height;
|
|
660
682
|
this.coords = {
|
|
661
683
|
time: this.times,
|
|
662
684
|
vertical: new Float32Array([0]),
|
|
663
685
|
latitude: Float32Array.from(
|
|
664
686
|
{ length: this.height },
|
|
665
|
-
(
|
|
687
|
+
(d, h) => s - (h + 0.5) * c
|
|
666
688
|
),
|
|
667
689
|
longitude: Float32Array.from(
|
|
668
690
|
{ length: this.width },
|
|
669
|
-
(
|
|
691
|
+
(d, h) => n + (h + 0.5) * o
|
|
670
692
|
)
|
|
671
693
|
};
|
|
672
694
|
}
|
|
@@ -716,67 +738,354 @@ class Oe extends be {
|
|
|
716
738
|
};
|
|
717
739
|
}
|
|
718
740
|
decodeCodes(t, r, n) {
|
|
719
|
-
return
|
|
741
|
+
return Me(t, r, n, this.encoding);
|
|
720
742
|
}
|
|
721
743
|
}
|
|
722
|
-
function
|
|
723
|
-
const
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
744
|
+
function Se(e, t) {
|
|
745
|
+
const r = Math.max(
|
|
746
|
+
0,
|
|
747
|
+
Math.min(
|
|
748
|
+
1,
|
|
749
|
+
(e - t.codeMin) / (t.codeMax - t.codeMin)
|
|
750
|
+
)
|
|
751
|
+
);
|
|
752
|
+
return t.valueMin + r * (t.valueMax - t.valueMin);
|
|
753
|
+
}
|
|
754
|
+
function Ge(e, t, r, n) {
|
|
755
|
+
const a = t.length;
|
|
756
|
+
if (e.length !== a)
|
|
757
|
+
throw new Error(
|
|
758
|
+
`GeoVideo scalar frame has ${e.length} codes, expected ${a}`
|
|
759
|
+
);
|
|
760
|
+
const i = new Float32Array(256);
|
|
761
|
+
for (let c = 0; c < 256; c++)
|
|
762
|
+
i[c] = Se(c, n);
|
|
763
|
+
const s = r * 255, o = new Float32Array(a);
|
|
764
|
+
for (let c = 0; c < a; c++)
|
|
765
|
+
o[c] = t[c] >= s ? i[e[c]] : NaN;
|
|
766
|
+
return o;
|
|
767
|
+
}
|
|
768
|
+
class Pe extends O {
|
|
769
|
+
constructor(t, r = {}) {
|
|
770
|
+
if (t.encoding.kind !== "scalar-luma")
|
|
771
|
+
throw new Error("GeoVideoScalarSource requires a scalar-luma manifest");
|
|
772
|
+
super(t, 1, r), this.encoding = t.encoding;
|
|
773
|
+
}
|
|
774
|
+
decodeCodes(t, r, n) {
|
|
775
|
+
return Ge(t, r, n, this.encoding);
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
function ke(e, t, r = {}) {
|
|
779
|
+
const [n, a] = r.range ?? [-1 / 0, 1 / 0], i = [...e].sort((o, c) => o.start - c.start), s = i.find(
|
|
780
|
+
(o) => o.start > t && o.start <= a
|
|
732
781
|
) ?? (r.loop ? i.find(
|
|
733
|
-
(
|
|
782
|
+
(o) => o.end >= n && o.start <= a
|
|
734
783
|
) : void 0);
|
|
735
|
-
return
|
|
784
|
+
return s ? { chunk: s, time: Math.max(s.start, n) } : null;
|
|
736
785
|
}
|
|
737
|
-
function
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
Number.isFinite(c) && c >= 0 && c > i && (a = s, i = c);
|
|
786
|
+
function Ie(e, t) {
|
|
787
|
+
let r = null, n = -1 / 0;
|
|
788
|
+
for (const a of t) {
|
|
789
|
+
const i = Math.min(e.end, a.end) - Math.max(e.start, a.start);
|
|
790
|
+
Number.isFinite(i) && i >= 0 && i > n && (r = a, n = i);
|
|
743
791
|
}
|
|
744
|
-
return
|
|
792
|
+
return r;
|
|
793
|
+
}
|
|
794
|
+
function Ne(e) {
|
|
795
|
+
return {
|
|
796
|
+
width: e.mask.width,
|
|
797
|
+
height: e.mask.height,
|
|
798
|
+
bounds: e.bounds,
|
|
799
|
+
rowOrder: "north-to-south"
|
|
800
|
+
};
|
|
801
|
+
}
|
|
802
|
+
function Le(e, t = {}) {
|
|
803
|
+
return e.encoding.kind === "vector-luma" ? new Ue(e, t) : new Pe(e, t);
|
|
745
804
|
}
|
|
746
|
-
|
|
805
|
+
const Ve = 3, Ce = 3, Be = 0.6, ge = 1.5;
|
|
806
|
+
function Xe(e, t) {
|
|
807
|
+
const r = e.length - 1;
|
|
808
|
+
if (t <= e[0])
|
|
809
|
+
return { step: 0, fraction: 0 };
|
|
810
|
+
if (t >= e[r])
|
|
811
|
+
return { step: r, fraction: 0 };
|
|
812
|
+
let n = 0, a = r;
|
|
813
|
+
for (; a - n > 1; ) {
|
|
814
|
+
const i = n + a >> 1;
|
|
815
|
+
e[i] <= t ? n = i : a = i;
|
|
816
|
+
}
|
|
817
|
+
return { step: n, fraction: (t - e[n]) / (e[a] - e[n]) };
|
|
818
|
+
}
|
|
819
|
+
function Oe(e) {
|
|
820
|
+
const t = new AbortController();
|
|
821
|
+
if (!e)
|
|
822
|
+
return { controller: t, unlink: () => {
|
|
823
|
+
} };
|
|
824
|
+
const r = () => t.abort();
|
|
825
|
+
return e.aborted && r(), e.addEventListener("abort", r, { once: !0 }), {
|
|
826
|
+
controller: t,
|
|
827
|
+
unlink: () => e.removeEventListener("abort", r)
|
|
828
|
+
};
|
|
829
|
+
}
|
|
830
|
+
class ft {
|
|
831
|
+
constructor(t) {
|
|
832
|
+
this.manifests = /* @__PURE__ */ new Map(), this.open = /* @__PURE__ */ new Map(), this.id = t.id, this.chunks = t.chunks.filter(
|
|
833
|
+
(r) => Number.isFinite(r.start) && Number.isFinite(r.end) && r.end >= r.start
|
|
834
|
+
).sort((r, n) => r.start - n.start), this.maxOpenChunks = Math.max(2, t.maxOpenChunks ?? Ve), this.frameCacheSize = Math.max(
|
|
835
|
+
1,
|
|
836
|
+
t.frameCacheSize ?? Ce
|
|
837
|
+
), this.prefetchAt = t.prefetchAt ?? Be, this.maxGap = t.maxGap, this.loadManifest = t.loadManifest ?? Re, this.createFrameSource = t.createFrameSource ?? ((r, n) => Le(
|
|
838
|
+
r,
|
|
839
|
+
n
|
|
840
|
+
));
|
|
841
|
+
}
|
|
842
|
+
/** First and last sample of the archive, or null without chunks. */
|
|
843
|
+
get range() {
|
|
844
|
+
const { chunks: t } = this;
|
|
845
|
+
return t.length ? [t[0].start, Math.max(...t.map((r) => r.end))] : null;
|
|
846
|
+
}
|
|
847
|
+
/** The chunk whose sample range holds `time`, or null. */
|
|
848
|
+
chunkAt(t) {
|
|
849
|
+
const r = this.chunkIndexAt(t), n = r >= 0 ? this.chunks[r] : null;
|
|
850
|
+
return n && t <= n.end ? n : null;
|
|
851
|
+
}
|
|
852
|
+
/** Every step time of the archive; loads all chunk manifests. */
|
|
853
|
+
async steps(t = {}) {
|
|
854
|
+
if (t.signal?.aborted)
|
|
855
|
+
throw l();
|
|
856
|
+
const r = await R(
|
|
857
|
+
Promise.all(this.chunks.map((n) => this.manifest(n))),
|
|
858
|
+
t.signal
|
|
859
|
+
);
|
|
860
|
+
return Float64Array.from(r.flatMap(_));
|
|
861
|
+
}
|
|
862
|
+
/**
|
|
863
|
+
* The frames bracketing `time`, decoded; null out of coverage (before the
|
|
864
|
+
* first step, after the last, or in a gap wider than `maxGap`).
|
|
865
|
+
*/
|
|
866
|
+
async sample(t, r = {}) {
|
|
867
|
+
const { signal: n } = r, a = r.mode ?? "interpolate";
|
|
868
|
+
if (n?.aborted)
|
|
869
|
+
throw l();
|
|
870
|
+
const i = this.chunkIndexAt(t);
|
|
871
|
+
if (i < 0)
|
|
872
|
+
return null;
|
|
873
|
+
const s = [], { controller: o, unlink: c } = Oe(n);
|
|
874
|
+
try {
|
|
875
|
+
const d = this.acquire(this.chunks[i], s), h = await R(d.ready, o.signal), { times: u } = h;
|
|
876
|
+
let E;
|
|
877
|
+
if (t <= u[u.length - 1]) {
|
|
878
|
+
const { step: p, fraction: w } = Xe(u, t);
|
|
879
|
+
E = a === "discrete" || w === 0 ? [d, p, d, p, 0] : [d, p, d, p + 1, w];
|
|
880
|
+
} else {
|
|
881
|
+
const p = this.chunks[i + 1];
|
|
882
|
+
if (!p)
|
|
883
|
+
return null;
|
|
884
|
+
const w = this.acquire(p, s), k = await R(w.ready, o.signal), A = u.length - 1, v = u[A], y = k.times[0];
|
|
885
|
+
if (y - v > this.gapLimit(u, k.times))
|
|
886
|
+
return null;
|
|
887
|
+
E = a === "discrete" ? [d, A, d, A, 0] : t >= y ? [w, 0, w, 0, 0] : [d, A, w, 0, (t - v) / (y - v)];
|
|
888
|
+
}
|
|
889
|
+
const [f, T, b, S, q] = E, G = f === b && T === S, P = [this.frame(f, T, o.signal)];
|
|
890
|
+
G || P.push(this.frame(b, S, o.signal));
|
|
891
|
+
let x;
|
|
892
|
+
try {
|
|
893
|
+
x = await Promise.all(P);
|
|
894
|
+
} catch (p) {
|
|
895
|
+
throw o.abort(), p;
|
|
896
|
+
}
|
|
897
|
+
return this.prefetchAfter(i, t), {
|
|
898
|
+
time: t,
|
|
899
|
+
a: x[0],
|
|
900
|
+
b: x[G ? 0 : 1],
|
|
901
|
+
mix: q
|
|
902
|
+
};
|
|
903
|
+
} finally {
|
|
904
|
+
c();
|
|
905
|
+
for (const d of s)
|
|
906
|
+
d.users--;
|
|
907
|
+
this.trim();
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
/** Open `chunk` and decode its first frame ahead of a request. */
|
|
911
|
+
prefetch(t) {
|
|
912
|
+
if (this.open.has(t.key))
|
|
913
|
+
return;
|
|
914
|
+
const r = this.touch(t), n = new AbortController();
|
|
915
|
+
r.prefetch = n, r.ready.then(({ source: a }) => a.frame(0, { signal: n.signal })).catch(() => {
|
|
916
|
+
}).finally(() => {
|
|
917
|
+
r.prefetch === n && (r.prefetch = null);
|
|
918
|
+
}), this.trim();
|
|
919
|
+
}
|
|
920
|
+
/** Release every open chunk source; later requests reopen them. */
|
|
921
|
+
release() {
|
|
922
|
+
for (const t of [...this.open.values()])
|
|
923
|
+
this.close(t);
|
|
924
|
+
}
|
|
925
|
+
chunkIndexAt(t) {
|
|
926
|
+
let r = 0, n = this.chunks.length - 1, a = -1;
|
|
927
|
+
for (; r <= n; ) {
|
|
928
|
+
const i = r + n >> 1;
|
|
929
|
+
this.chunks[i].start <= t ? (a = i, r = i + 1) : n = i - 1;
|
|
930
|
+
}
|
|
931
|
+
return a;
|
|
932
|
+
}
|
|
933
|
+
gapLimit(t, r) {
|
|
934
|
+
if (this.maxGap !== void 0)
|
|
935
|
+
return this.maxGap;
|
|
936
|
+
const n = [
|
|
937
|
+
t.length > 1 ? t[t.length - 1] - t[t.length - 2] : 0,
|
|
938
|
+
r.length > 1 ? r[1] - r[0] : 0
|
|
939
|
+
], a = Math.max(...n);
|
|
940
|
+
return a > 0 ? a * ge : -1 / 0;
|
|
941
|
+
}
|
|
942
|
+
prefetchAfter(t, r) {
|
|
943
|
+
const n = this.chunks[t], a = this.chunks[t + 1], i = n.end - n.start, s = i > 0 ? (r - n.start) / i : 1;
|
|
944
|
+
a && s > this.prefetchAt && this.prefetch(a);
|
|
945
|
+
}
|
|
946
|
+
manifest(t) {
|
|
947
|
+
let r = this.manifests.get(t.manifestUrl);
|
|
948
|
+
return r || (r = this.loadManifest(t.manifestUrl), this.manifests.set(t.manifestUrl, r), r.catch(() => {
|
|
949
|
+
this.manifests.get(t.manifestUrl) === r && this.manifests.delete(t.manifestUrl);
|
|
950
|
+
})), r;
|
|
951
|
+
}
|
|
952
|
+
/** The open chunk, pinned for a running sample listed in `used`. */
|
|
953
|
+
acquire(t, r) {
|
|
954
|
+
const n = this.touch(t);
|
|
955
|
+
return n.users++, r.push(n), n;
|
|
956
|
+
}
|
|
957
|
+
/** The open chunk, opened when needed, most recently used; not pinned. */
|
|
958
|
+
touch(t) {
|
|
959
|
+
let r = this.open.get(t.key);
|
|
960
|
+
if (r)
|
|
961
|
+
this.open.delete(t.key);
|
|
962
|
+
else {
|
|
963
|
+
const n = {
|
|
964
|
+
chunk: t,
|
|
965
|
+
ready: null,
|
|
966
|
+
opened: null,
|
|
967
|
+
users: 0,
|
|
968
|
+
prefetch: null,
|
|
969
|
+
released: !1
|
|
970
|
+
};
|
|
971
|
+
n.ready = this.manifest(t).then((a) => {
|
|
972
|
+
if (n.released)
|
|
973
|
+
throw l();
|
|
974
|
+
return n.opened = {
|
|
975
|
+
manifest: a,
|
|
976
|
+
times: Float64Array.from(_(a)),
|
|
977
|
+
grid: Ne(a),
|
|
978
|
+
source: this.createFrameSource(a, {
|
|
979
|
+
cacheSize: this.frameCacheSize
|
|
980
|
+
})
|
|
981
|
+
}, n.opened;
|
|
982
|
+
}), n.ready.catch(() => {
|
|
983
|
+
this.open.get(t.key) === n && this.open.delete(t.key);
|
|
984
|
+
}), r = n;
|
|
985
|
+
}
|
|
986
|
+
return this.open.set(t.key, r), r;
|
|
987
|
+
}
|
|
988
|
+
async frame(t, r, n) {
|
|
989
|
+
const { manifest: a, times: i, grid: s, source: o } = await R(
|
|
990
|
+
t.ready,
|
|
991
|
+
n
|
|
992
|
+
);
|
|
993
|
+
if (t.released)
|
|
994
|
+
throw l();
|
|
995
|
+
const c = await o.frame(r, { signal: n });
|
|
996
|
+
return {
|
|
997
|
+
key: `${this.id}/${t.chunk.key}/${r}`,
|
|
998
|
+
chunk: t.chunk,
|
|
999
|
+
step: r,
|
|
1000
|
+
time: i[r],
|
|
1001
|
+
data: c,
|
|
1002
|
+
grid: s,
|
|
1003
|
+
manifest: a
|
|
1004
|
+
};
|
|
1005
|
+
}
|
|
1006
|
+
/** Release least recently used chunks beyond the bound, unless in use. */
|
|
1007
|
+
trim() {
|
|
1008
|
+
let t = this.open.size - this.maxOpenChunks;
|
|
1009
|
+
for (const r of [...this.open.values()]) {
|
|
1010
|
+
if (t <= 0)
|
|
1011
|
+
return;
|
|
1012
|
+
r.users === 0 && (this.close(r), t--);
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
close(t) {
|
|
1016
|
+
t.released = !0, t.prefetch?.abort(), t.prefetch = null, t.opened?.source.release(), t.opened = null, this.open.get(t.chunk.key) === t && this.open.delete(t.chunk.key);
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
function U(e) {
|
|
1020
|
+
const { start: t, end: r } = e.temporal ?? {};
|
|
1021
|
+
return {
|
|
1022
|
+
source: e,
|
|
1023
|
+
start: Date.parse(t ?? ""),
|
|
1024
|
+
end: Date.parse(r ?? t ?? "")
|
|
1025
|
+
};
|
|
1026
|
+
}
|
|
1027
|
+
function lt(e, t, r = {}) {
|
|
1028
|
+
const n = e.filter((i) => i.id === t.id && i.temporal?.start != null).map(U), a = ke(
|
|
1029
|
+
n,
|
|
1030
|
+
Date.parse(t.temporal?.end ?? ""),
|
|
1031
|
+
r
|
|
1032
|
+
);
|
|
1033
|
+
return a ? { source: a.chunk.source, time: a.time } : null;
|
|
1034
|
+
}
|
|
1035
|
+
function ht(e, t) {
|
|
1036
|
+
return Ie(U(e), t.map(U))?.source ?? null;
|
|
1037
|
+
}
|
|
1038
|
+
function mt(e) {
|
|
747
1039
|
return e.type === "geovideo" && typeof e.indexUrl == "string";
|
|
748
1040
|
}
|
|
749
|
-
function
|
|
1041
|
+
function Et(e, t) {
|
|
750
1042
|
return e.id === t.id && (e.type !== "geovideo" || t.type !== "geovideo" || e.manifestUrl === t.manifestUrl);
|
|
751
1043
|
}
|
|
752
|
-
function
|
|
1044
|
+
function B(e) {
|
|
753
1045
|
return typeof e == "string" && Number.isFinite(Date.parse(e));
|
|
754
1046
|
}
|
|
755
|
-
function
|
|
1047
|
+
function qe(e) {
|
|
756
1048
|
const t = e;
|
|
757
1049
|
if (!t || t.schemaVersion !== 1 || t.type !== "geovideo-index" || !Array.isArray(t.chunks))
|
|
758
1050
|
throw new Error("Unsupported GeoVideo index");
|
|
759
1051
|
for (const r of t.chunks)
|
|
760
|
-
if (!
|
|
1052
|
+
if (!B(r?.start) || !B(r.end) || Date.parse(r.end) < Date.parse(r.start) || typeof r.manifestUrl != "string")
|
|
761
1053
|
throw new Error("Invalid GeoVideo index chunk");
|
|
762
1054
|
return t;
|
|
763
1055
|
}
|
|
764
|
-
async function
|
|
1056
|
+
async function Tt(e, t) {
|
|
765
1057
|
const r = await fetch(e, { signal: t });
|
|
766
1058
|
if (!r.ok)
|
|
767
1059
|
throw new Error(
|
|
768
1060
|
`GeoVideo index request failed (${r.status}): ${e}`
|
|
769
1061
|
);
|
|
770
|
-
return
|
|
1062
|
+
return qe(await r.json());
|
|
771
1063
|
}
|
|
772
|
-
function
|
|
1064
|
+
function $e(e) {
|
|
1065
|
+
return typeof document < "u" ? new URL(e, document.baseURI).href : e;
|
|
1066
|
+
}
|
|
1067
|
+
function We(e, t) {
|
|
1068
|
+
const r = $e(t);
|
|
1069
|
+
return e.chunks.map((n) => ({
|
|
1070
|
+
key: n.key,
|
|
1071
|
+
manifestUrl: new URL(n.manifestUrl, r).href,
|
|
1072
|
+
start: Date.parse(n.start),
|
|
1073
|
+
end: Date.parse(n.end),
|
|
1074
|
+
samples: n.samples,
|
|
1075
|
+
...n.provisional ? { provisional: !0 } : {}
|
|
1076
|
+
}));
|
|
1077
|
+
}
|
|
1078
|
+
function He(e, t, r) {
|
|
773
1079
|
if (t.sourceId !== e.id || t.catalogEntryId !== r.id)
|
|
774
1080
|
throw new Error(
|
|
775
1081
|
`GeoVideo index identity does not match catalog entry/source: ${e.id}`
|
|
776
1082
|
);
|
|
777
|
-
|
|
1083
|
+
}
|
|
1084
|
+
function pt(e, t, r) {
|
|
1085
|
+
He(e, t, r);
|
|
1086
|
+
const n = We(t, e.indexUrl);
|
|
778
1087
|
return t.chunks.map(
|
|
779
|
-
(a) => ({
|
|
1088
|
+
(a, i) => ({
|
|
780
1089
|
id: e.id,
|
|
781
1090
|
type: "geovideo",
|
|
782
1091
|
title: e.title,
|
|
@@ -787,47 +1096,53 @@ function je(e, t, r) {
|
|
|
787
1096
|
start: a.start,
|
|
788
1097
|
end: a.end
|
|
789
1098
|
},
|
|
790
|
-
manifestUrl:
|
|
1099
|
+
manifestUrl: n[i].manifestUrl
|
|
791
1100
|
})
|
|
792
1101
|
);
|
|
793
1102
|
}
|
|
794
1103
|
export {
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
1104
|
+
Tt as A,
|
|
1105
|
+
pt as B,
|
|
1106
|
+
V as C,
|
|
1107
|
+
ft as D,
|
|
1108
|
+
O as E,
|
|
1109
|
+
Pe as F,
|
|
1110
|
+
Ue as G,
|
|
1111
|
+
He as H,
|
|
1112
|
+
Le as I,
|
|
1113
|
+
N as J,
|
|
1114
|
+
Te as K,
|
|
1115
|
+
Ne as L,
|
|
1116
|
+
We as M,
|
|
1117
|
+
ke as N,
|
|
1118
|
+
ht as O,
|
|
1119
|
+
Ie as P,
|
|
1120
|
+
qe as Q,
|
|
1121
|
+
st as T,
|
|
1122
|
+
tt as a,
|
|
1123
|
+
rt as b,
|
|
1124
|
+
ze as c,
|
|
1125
|
+
Je as d,
|
|
1126
|
+
Qe as e,
|
|
1127
|
+
et as f,
|
|
1128
|
+
nt as g,
|
|
814
1129
|
je as h,
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
1130
|
+
Ze as i,
|
|
1131
|
+
Ke as j,
|
|
1132
|
+
it as k,
|
|
1133
|
+
ot as l,
|
|
1134
|
+
Re as m,
|
|
1135
|
+
Ae as n,
|
|
1136
|
+
fe as o,
|
|
1137
|
+
ut as p,
|
|
1138
|
+
_ as q,
|
|
1139
|
+
he as r,
|
|
1140
|
+
at as s,
|
|
1141
|
+
Et as t,
|
|
1142
|
+
dt as u,
|
|
1143
|
+
ct as v,
|
|
1144
|
+
_e as w,
|
|
1145
|
+
Ye as x,
|
|
1146
|
+
mt as y,
|
|
1147
|
+
lt as z
|
|
833
1148
|
};
|