loko/streetup/panoramax/static/panoramax/js/pmtiles.js
2026-07-22 14:48:40 +02:00

1139 lines
34 KiB
JavaScript

var M = Math.pow, g = (e, t, r) => new Promise((n, i) => {
var o = (u) => {
try {
c(r.next(u));
} catch (f) {
i(f);
}
}, s = (u) => {
try {
c(r.throw(u));
} catch (f) {
i(f);
}
}, c = (u) => u.done ? n(u.value) : Promise.resolve(u.value).then(o, s);
c((r = r.apply(e, t)).next());
}), w = Uint8Array, O = Uint16Array, Oe = Int32Array, ve = new w([
0,
0,
0,
0,
0,
0,
0,
0,
1,
1,
1,
1,
2,
2,
2,
2,
3,
3,
3,
3,
4,
4,
4,
4,
5,
5,
5,
5,
0,
/* unused */
0,
0,
/* impossible */
0
]), ye = new w([
0,
0,
0,
0,
1,
1,
2,
2,
3,
3,
4,
4,
5,
5,
6,
6,
7,
7,
8,
8,
9,
9,
10,
10,
11,
11,
12,
12,
13,
13,
/* unused */
0,
0
]), Ke = new w([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]), me = function(e, t) {
for (var r = new O(31), n = 0; n < 31; ++n)
r[n] = t += 1 << e[n - 1];
for (var i = new Oe(r[30]), n = 1; n < 30; ++n)
for (var o = r[n]; o < r[n + 1]; ++o)
i[o] = o - r[n] << 5 | n;
return { b: r, r: i };
}, pe = me(ve, 2), we = pe.b, Se = pe.r;
we[28] = 258, Se[258] = 28;
var Pe = me(ye, 0), Re = Pe.b, xe = new O(32768);
for (h = 0; h < 32768; ++h)
z = (h & 43690) >> 1 | (h & 21845) << 1, z = (z & 52428) >> 2 | (z & 13107) << 2, z = (z & 61680) >> 4 | (z & 3855) << 4, xe[h] = ((z & 65280) >> 8 | (z & 255) << 8) >> 1;
var z, h, K = function(e, t, r) {
for (var n = e.length, i = 0, o = new O(t); i < n; ++i)
e[i] && ++o[e[i] - 1];
var s = new O(t);
for (i = 1; i < t; ++i)
s[i] = s[i - 1] + o[i - 1] << 1;
var c;
{
c = new O(1 << t);
var u = 15 - t;
for (i = 0; i < n; ++i)
if (e[i])
for (var f = i << 4 | e[i], a = t - e[i], l = s[e[i] - 1]++ << a, d = l | (1 << a) - 1; l <= d; ++l)
c[xe[l] >> u] = f;
}
return c;
}, S = new w(288);
for (h = 0; h < 144; ++h)
S[h] = 8;
var h;
for (h = 144; h < 256; ++h)
S[h] = 9;
var h;
for (h = 256; h < 280; ++h)
S[h] = 7;
var h;
for (h = 280; h < 288; ++h)
S[h] = 8;
var h, Ue = new w(32);
for (h = 0; h < 32; ++h)
Ue[h] = 5;
var h, ke = /* @__PURE__ */ K(S, 9), Ie = /* @__PURE__ */ K(Ue, 5), G = function(e) {
for (var t = e[0], r = 1; r < e.length; ++r)
e[r] > t && (t = e[r]);
return t;
}, b = function(e, t, r) {
var n = t / 8 | 0;
return (e[n] | e[n + 1] << 8) >> (t & 7) & r;
}, Y = function(e, t) {
var r = t / 8 | 0;
return (e[r] | e[r + 1] << 8 | e[r + 2] << 16) >> (t & 7);
}, _e = function(e) {
return (e + 7) / 8 | 0;
}, je = function(e, t, r) {
(r == null || r > e.length) && (r = e.length);
var n = new w(r - t);
return n.set(e.subarray(t, r)), n;
}, We = [
"unexpected EOF",
"invalid block type",
"invalid length/literal",
"invalid distance",
"stream finished",
"no stream handler",
,
"no callback",
"invalid UTF-8 data",
"extra field too long",
"date not in range 1980-2099",
"filename too long",
"stream finishing",
"invalid zip data"
// determined by unknown compression method
], p = function(e, t, r) {
var n = new Error(t || We[e]);
if (n.code = e, Error.captureStackTrace && Error.captureStackTrace(n, p), !r)
throw n;
return n;
}, ee = function(e, t, r, n) {
var i = e.length, o = 0;
if (!i || t.f && !t.l)
return r || new w(0);
var s = !r || t.i != 2, c = t.i;
r || (r = new w(i * 3));
var u = function(le) {
var ue = r.length;
if (le > ue) {
var fe = new w(Math.max(ue * 2, le));
fe.set(r), r = fe;
}
}, f = t.f || 0, a = t.p || 0, l = t.b || 0, d = t.l, m = t.d, v = t.m, U = t.n, T = i * 8;
do {
if (!d) {
f = b(e, a, 1);
var P = b(e, a + 1, 3);
if (a += 3, P)
if (P == 1)
d = ke, m = Ie, v = 9, U = 5;
else if (P == 2) {
var j = b(e, a, 31) + 257, re = b(e, a + 10, 15) + 4, ne = j + b(e, a + 5, 31) + 1;
a += 14;
for (var B = new w(ne), W = new w(19), x = 0; x < re; ++x)
W[Ke[x]] = b(e, a + x * 3, 7);
a += re * 3;
for (var ie = G(W), $e = (1 << ie) - 1, Be = K(W, ie), x = 0; x < ne; ) {
var oe = Be[b(e, a, $e)];
a += oe & 15;
var y = oe >> 4;
if (y < 16)
B[x++] = y;
else {
var A = 0, R = 0;
for (y == 16 ? (R = 3 + b(e, a, 3), a += 2, A = B[x - 1]) : y == 17 ? (R = 3 + b(e, a, 7), a += 3) : y == 18 && (R = 11 + b(e, a, 127), a += 7); R--; )
B[x++] = A;
}
}
var se = B.subarray(0, j), D = B.subarray(j);
v = G(se), U = G(D), d = K(se, v), m = K(D, U);
} else
p(1);
else {
var y = _e(a) + 4, I = e[y - 4] | e[y - 3] << 8, _ = y + I;
if (_ > i) {
c && p(0);
break;
}
s && u(l + I), r.set(e.subarray(y, _), l), t.b = l += I, t.p = a = _ * 8, t.f = f;
continue;
}
if (a > T) {
c && p(0);
break;
}
}
s && u(l + 131072);
for (var Ve = (1 << v) - 1, Ze = (1 << U) - 1, N = a; ; N = a) {
var A = d[Y(e, a) & Ve], C = A >> 4;
if (a += A & 15, a > T) {
c && p(0);
break;
}
if (A || p(2), C < 256)
r[l++] = C;
else if (C == 256) {
N = a, d = null;
break;
} else {
var ae = C - 254;
if (C > 264) {
var x = C - 257, V = ve[x];
ae = b(e, a, (1 << V) - 1) + we[x], a += V;
}
var J = m[Y(e, a) & Ze], F = J >> 4;
J || p(3), a += J & 15;
var D = Re[F];
if (F > 3) {
var V = ye[F];
D += Y(e, a) & (1 << V) - 1, a += V;
}
if (a > T) {
c && p(0);
break;
}
s && u(l + 131072);
var q = l + ae;
if (l < D) {
var ce = o - D, He = Math.min(D, q);
for (ce + l < 0 && p(3); l < He; ++l)
r[l] = n[ce + l];
}
for (; l < q; l += 4)
r[l] = r[l - D], r[l + 1] = r[l + 1 - D], r[l + 2] = r[l + 2 - D], r[l + 3] = r[l + 3 - D];
l = q;
}
}
t.l = d, t.p = N, t.b = l, t.f = f, d && (f = 1, t.m = v, t.d = m, t.n = U);
} while (!f);
return l == r.length ? r : je(r, 0, l);
}, Ne = /* @__PURE__ */ new w(0), Je = function(e) {
(e[0] != 31 || e[1] != 139 || e[2] != 8) && p(6, "invalid gzip data");
var t = e[3], r = 10;
t & 4 && (r += (e[10] | e[11] << 8) + 2);
for (var n = (t >> 3 & 1) + (t >> 4 & 1); n > 0; n -= !e[r++])
;
return r + (t & 2);
}, Fe = function(e) {
var t = e.length;
return (e[t - 4] | e[t - 3] << 8 | e[t - 2] << 16 | e[t - 1] << 24) >>> 0;
}, qe = function(e, t) {
return ((e[0] & 15) != 8 || e[0] >> 4 > 7 || (e[0] << 8 | e[1]) % 31) && p(6, "invalid zlib data"), (e[1] >> 5 & 1) == 1 && p(6, "invalid zlib data: " + (e[1] & 32 ? "need" : "unexpected") + " dictionary"), (e[1] >> 3 & 4) + 2;
};
function Ge(e, t) {
return ee(e, { i: 2 }, t, t);
}
function Ye(e, t) {
var r = Je(e);
return r + 8 > e.length && p(6, "invalid gzip data"), ee(e.subarray(r, -8), { i: 2 }, new w(Fe(e)), t);
}
function Xe(e, t) {
return ee(e.subarray(qe(e), -4), { i: 2 }, t, t);
}
function X(e, t) {
return e[0] == 31 && e[1] == 139 && e[2] == 8 ? Ye(e, t) : (e[0] & 15) != 8 || e[0] >> 4 > 7 || (e[0] << 8 | e[1]) % 31 ? Ge(e, t) : Xe(e, t);
}
var Qe = typeof TextDecoder < "u" && /* @__PURE__ */ new TextDecoder(), et = 0;
try {
Qe.decode(Ne, { stream: !0 }), et = 1;
} catch {
}
var De = (e, t) => e * M(2, t), Z = (e, t) => Math.floor(e / M(2, t)), k = (e, t) => De(e.getUint16(t + 1, !0), 8) + e.getUint8(t), be = (e, t) => De(e.getUint32(t + 2, !0), 16) + e.getUint16(t, !0), tt = (e, t, r, n, i) => {
if (e !== n.getUint8(i))
return e - n.getUint8(i);
const o = k(n, i + 1);
if (t !== o)
return t - o;
const s = k(n, i + 4);
return r !== s ? r - s : 0;
}, rt = (e, t, r, n) => {
const i = Le(e, t | 128, r, n);
return i ? {
z: t,
x: r,
y: n,
offset: i[0],
length: i[1],
isDir: !0
} : null;
}, he = (e, t, r, n) => {
const i = Le(e, t, r, n);
return i ? {
z: t,
x: r,
y: n,
offset: i[0],
length: i[1],
isDir: !1
} : null;
}, Le = (e, t, r, n) => {
let i = 0, o = e.byteLength / 17 - 1;
for (; i <= o; ) {
const s = o + i >> 1, c = tt(t, r, n, e, s * 17);
if (c > 0)
i = s + 1;
else if (c < 0)
o = s - 1;
else
return [be(e, s * 17 + 7), e.getUint32(s * 17 + 13, !0)];
}
return null;
}, nt = (e, t) => e.isDir && !t.isDir ? 1 : !e.isDir && t.isDir ? -1 : e.z !== t.z ? e.z - t.z : e.x !== t.x ? e.x - t.x : e.y - t.y, Ee = (e, t) => {
const r = e.getUint8(t * 17);
return {
z: r & 127,
x: k(e, t * 17 + 1),
y: k(e, t * 17 + 4),
offset: be(e, t * 17 + 7),
length: e.getUint32(t * 17 + 13, !0),
isDir: r >> 7 === 1
};
}, de = (e) => {
const t = [], r = new DataView(e);
for (let n = 0; n < r.byteLength / 17; n++)
t.push(Ee(r, n));
return it(t);
}, it = (e) => {
e.sort(nt);
const t = new ArrayBuffer(17 * e.length), r = new Uint8Array(t);
for (let n = 0; n < e.length; n++) {
const i = e[n];
let o = i.z;
i.isDir && (o = o | 128), r[n * 17] = o, r[n * 17 + 1] = i.x & 255, r[n * 17 + 2] = i.x >> 8 & 255, r[n * 17 + 3] = i.x >> 16 & 255, r[n * 17 + 4] = i.y & 255, r[n * 17 + 5] = i.y >> 8 & 255, r[n * 17 + 6] = i.y >> 16 & 255, r[n * 17 + 7] = i.offset & 255, r[n * 17 + 8] = Z(i.offset, 8) & 255, r[n * 17 + 9] = Z(i.offset, 16) & 255, r[n * 17 + 10] = Z(i.offset, 24) & 255, r[n * 17 + 11] = Z(i.offset, 32) & 255, r[n * 17 + 12] = Z(i.offset, 48) & 255, r[n * 17 + 13] = i.length & 255, r[n * 17 + 14] = i.length >> 8 & 255, r[n * 17 + 15] = i.length >> 16 & 255, r[n * 17 + 16] = i.length >> 24 & 255;
}
return t;
}, ot = (e, t) => {
if (e.byteLength < 17)
return null;
const r = e.byteLength / 17, n = Ee(e, r - 1);
if (n.isDir) {
const i = n.z, o = t.z - i, s = Math.trunc(t.x / (1 << o)), c = Math.trunc(t.y / (1 << o));
return { z: i, x: s, y: c };
}
return null;
};
function st(e) {
return g(this, null, function* () {
const t = yield e.getBytes(0, 512e3), r = new DataView(t.data), n = r.getUint32(4, !0), i = r.getUint16(8, !0), o = new TextDecoder("utf-8"), s = JSON.parse(
o.decode(new DataView(t.data, 10, n))
);
let c = 0;
s.compression === "gzip" && (c = 2);
let u = 0;
"minzoom" in s && (u = +s.minzoom);
let f = 0;
"maxzoom" in s && (f = +s.maxzoom);
let a = 0, l = 0, d = 0, m = -180, v = -85, U = 180, T = 85;
if (s.bounds) {
const y = s.bounds.split(",");
m = +y[0], v = +y[1], U = +y[2], T = +y[3];
}
if (s.center) {
const y = s.center.split(",");
a = +y[0], l = +y[1], d = +y[2];
}
return {
specVersion: r.getUint16(2, !0),
rootDirectoryOffset: 10 + n,
rootDirectoryLength: i * 17,
jsonMetadataOffset: 10,
jsonMetadataLength: n,
leafDirectoryOffset: 0,
leafDirectoryLength: void 0,
tileDataOffset: 0,
tileDataLength: void 0,
numAddressedTiles: 0,
numTileEntries: 0,
numTileContents: 0,
clustered: !1,
internalCompression: 1,
tileCompression: c,
tileType: 1,
minZoom: u,
maxZoom: f,
minLon: m,
minLat: v,
maxLon: U,
maxLat: T,
centerZoom: d,
centerLon: a,
centerLat: l,
etag: t.etag
};
});
}
function at(e, t, r, n, i, o, s) {
return g(this, null, function* () {
let c = yield r.getArrayBuffer(
t,
e.rootDirectoryOffset,
e.rootDirectoryLength,
e
);
e.specVersion === 1 && (c = de(c));
const u = he(new DataView(c), n, i, o);
if (u) {
let l = (yield t.getBytes(u.offset, u.length, s)).data;
const d = new DataView(l);
return d.getUint8(0) === 31 && d.getUint8(1) === 139 && (l = X(new Uint8Array(l))), {
data: l
};
}
const f = ot(new DataView(c), { z: n, x: i, y: o });
if (f) {
const a = rt(
new DataView(c),
f.z,
f.x,
f.y
);
if (a) {
let l = yield r.getArrayBuffer(
t,
a.offset,
a.length,
e
);
e.specVersion === 1 && (l = de(l));
const d = he(new DataView(l), n, i, o);
if (d) {
let v = (yield t.getBytes(
d.offset,
d.length,
s
)).data;
const U = new DataView(v);
return U.getUint8(0) === 31 && U.getUint8(1) === 139 && (v = X(new Uint8Array(v))), {
data: v
};
}
}
}
});
}
var ze = {
getHeader: st,
getZxy: at
}, Dt = (e, t) => {
let r = !1, n = "";
const i = L.GridLayer.extend({
createTile: (o, s) => {
const c = document.createElement("img"), u = new AbortController(), f = u.signal;
return c.cancel = () => {
u.abort();
}, r || (e.getHeader().then((a) => {
a.tileType === 1 ? console.error(
"Error: archive contains MVT vector tiles, but leafletRasterLayer is for displaying raster tiles. See https://github.com/protomaps/PMTiles/tree/main/js for details."
) : a.tileType === 2 ? n = "image/png" : a.tileType === 3 ? n = "image/jpeg" : a.tileType === 4 ? n = "image/webp" : a.tileType === 5 && (n = "image/avif");
}), r = !0), e.getZxy(o.z, o.x, o.y, f).then((a) => {
if (a) {
const l = new Blob([a.data], { type: n }), d = window.URL.createObjectURL(l);
c.src = d, c.cancel = void 0, s(void 0, c);
}
}).catch((a) => {
if (a.name !== "AbortError")
throw a;
}), c;
},
_removeTile: function(o) {
const s = this._tiles[o];
s && (s.el.cancel && s.el.cancel(), s.el.width = 0, s.el.height = 0, s.el.deleted = !0, L.DomUtil.remove(s.el), delete this._tiles[o], this.fire("tileunload", {
tile: s.el,
coords: this._keyToTileCoords(o)
}));
}
});
return new i(t);
}, ct = (e) => (t, r) => {
if (r instanceof AbortController)
return e(t, r);
const n = new AbortController();
return e(t, n).then(
(i) => r(
void 0,
i.data,
i.cacheControl || "",
i.expires || ""
),
(i) => r(i)
).catch((i) => r(i)), { cancel: () => n.abort() };
}, bt = class {
/**
* Initialize the MapLibre PMTiles protocol.
*
* * metadata: also load the metadata section of the PMTiles. required for some "inspect" functionality
* and to automatically populate the map attribution. Requires an extra HTTP request.
*/
constructor(e) {
this.tilev4 = (t, r) => g(this, null, function* () {
if (t.type === "json") {
const d = t.url.substr(10);
let m = this.tiles.get(d);
if (m || (m = new ge(d), this.tiles.set(d, m)), this.metadata)
return {
data: yield m.getTileJson(t.url)
};
const v = yield m.getHeader();
return {
data: {
tiles: [`${t.url}/{z}/{x}/{y}`],
minzoom: v.minZoom,
maxzoom: v.maxZoom,
bounds: [v.minLon, v.minLat, v.maxLon, v.maxLat]
}
};
}
const n = new RegExp(/pmtiles:\/\/(.+)\/(\d+)\/(\d+)\/(\d+)/), i = t.url.match(n);
if (!i)
throw new Error("Invalid PMTiles protocol URL");
const o = i[1];
let s = this.tiles.get(o);
s || (s = new ge(o), this.tiles.set(o, s));
const c = i[2], u = i[3], f = i[4], a = yield s.getHeader(), l = yield s?.getZxy(+c, +u, +f, r.signal);
return l ? {
data: new Uint8Array(l.data),
cacheControl: l.cacheControl,
expires: l.expires
} : a.tileType === 1 ? { data: new Uint8Array() } : { data: null };
}), this.tile = ct(this.tilev4), this.tiles = /* @__PURE__ */ new Map(), this.metadata = e?.metadata || !1;
}
/**
* Add a {@link PMTiles} instance to the global protocol instance.
*
* For remote fetch sources, references in MapLibre styles like pmtiles://http://...
* will resolve to the same instance if the URLs match.
*/
add(e) {
this.tiles.set(e.source.getKey(), e);
}
/**
* Fetch a {@link PMTiles} instance by URL, for remote PMTiles instances.
*/
get(e) {
return this.tiles.get(e);
}
};
function $(e, t) {
return (t >>> 0) * 4294967296 + (e >>> 0);
}
function lt(e, t) {
const r = t.buf;
let n = r[t.pos++], i = (n & 112) >> 4;
if (n < 128 || (n = r[t.pos++], i |= (n & 127) << 3, n < 128) || (n = r[t.pos++], i |= (n & 127) << 10, n < 128) || (n = r[t.pos++], i |= (n & 127) << 17, n < 128) || (n = r[t.pos++], i |= (n & 127) << 24, n < 128) || (n = r[t.pos++], i |= (n & 1) << 31, n < 128))
return $(e, i);
throw new Error("Expected varint not more than 10 bytes");
}
function H(e) {
const t = e.buf;
let r = t[e.pos++], n = r & 127;
return r < 128 || (r = t[e.pos++], n |= (r & 127) << 7, r < 128) || (r = t[e.pos++], n |= (r & 127) << 14, r < 128) || (r = t[e.pos++], n |= (r & 127) << 21, r < 128) ? n : (r = t[e.pos], n |= (r & 15) << 28, lt(n, e));
}
function Me(e, t, r, n) {
if (n === 0) {
r === 1 && (t[0] = e - 1 - t[0], t[1] = e - 1 - t[1]);
const i = t[0];
t[0] = t[1], t[1] = i;
}
}
function ut(e, t) {
const r = M(2, e);
let n = t, i = t, o = t;
const s = [0, 0];
let c = 1;
for (; c < r; )
n = 1 & o / 2, i = 1 & (o ^ n), Me(c, s, n, i), s[0] += c * n, s[1] += c * i, o = o / 4, c *= 2;
return [e, s[0], s[1]];
}
var ft = [
0,
1,
5,
21,
85,
341,
1365,
5461,
21845,
87381,
349525,
1398101,
5592405,
22369621,
89478485,
357913941,
1431655765,
5726623061,
22906492245,
91625968981,
366503875925,
1466015503701,
5864062014805,
23456248059221,
93824992236885,
375299968947541,
1501199875790165
];
function ht(e, t, r) {
if (e > 26)
throw Error("Tile zoom level exceeds max safe number limit (26)");
if (t > M(2, e) - 1 || r > M(2, e) - 1)
throw Error("tile x/y outside zoom level bounds");
const n = ft[e], i = M(2, e);
let o = 0, s = 0, c = 0;
const u = [t, r];
let f = i / 2;
for (; f > 0; )
o = (u[0] & f) > 0 ? 1 : 0, s = (u[1] & f) > 0 ? 1 : 0, c += f * f * (3 * o ^ s), Me(f, u, o, s), f = f / 2;
return n + c;
}
function Lt(e) {
let t = 0;
for (let r = 0; r < 27; r++) {
const n = (1 << r) * (1 << r);
if (t + n > e)
return ut(r, e - t);
t += n;
}
throw Error("Tile zoom level exceeds max safe number limit (26)");
}
var dt = /* @__PURE__ */ ((e) => (e[e.Unknown = 0] = "Unknown", e[e.None = 1] = "None", e[e.Gzip = 2] = "Gzip", e[e.Brotli = 3] = "Brotli", e[e.Zstd = 4] = "Zstd", e))(dt || {});
function te(e, t) {
return g(this, null, function* () {
if (t === 1 || t === 0)
return e;
if (t === 2) {
if (typeof globalThis.DecompressionStream > "u")
return X(new Uint8Array(e));
const r = new Response(e).body;
if (!r)
throw Error("Failed to read response stream");
const n = r.pipeThrough(
// biome-ignore lint: needed to detect DecompressionStream in browser+node+cloudflare workers
new globalThis.DecompressionStream("gzip")
);
return new Response(n).arrayBuffer();
}
throw Error("Compression method not supported");
});
}
var gt = /* @__PURE__ */ ((e) => (e[e.Unknown = 0] = "Unknown", e[e.Mvt = 1] = "Mvt", e[e.Png = 2] = "Png", e[e.Jpeg = 3] = "Jpeg", e[e.Webp = 4] = "Webp", e[e.Avif = 5] = "Avif", e))(gt || {});
function vt(e) {
return e === 1 ? ".mvt" : e === 2 ? ".png" : e === 3 ? ".jpg" : e === 4 ? ".webp" : e === 5 ? ".avif" : "";
}
var yt = 127;
function mt(e, t) {
let r = 0, n = e.length - 1;
for (; r <= n; ) {
const i = n + r >> 1, o = t - e[i].tileId;
if (o > 0)
r = i + 1;
else if (o < 0)
n = i - 1;
else
return e[i];
}
return n >= 0 && (e[n].runLength === 0 || t - e[n].tileId < e[n].runLength) ? e[n] : null;
}
var Et = class {
constructor(e) {
this.file = e;
}
getKey() {
return this.file.name;
}
getBytes(e, t) {
return g(this, null, function* () {
return { data: yield this.file.slice(e, e + t).arrayBuffer() };
});
}
}, pt = class {
constructor(e, t = new Headers()) {
this.url = e, this.customHeaders = t, this.mustReload = !1;
let r = "";
"navigator" in globalThis && (r = globalThis.navigator.userAgent || "");
const n = r.indexOf("Windows") > -1, i = /Chrome|Chromium|Edg|OPR|Brave/.test(r);
this.chromeWindowsNoCache = !1, n && i && (this.chromeWindowsNoCache = !0);
}
getKey() {
return this.url;
}
/**
* Mutate the custom [Headers](https://developer.mozilla.org/en-US/docs/Web/API/Headers) set for all requests to the remote archive.
*/
setHeaders(e) {
this.customHeaders = e;
}
getBytes(e, t, r, n) {
return g(this, null, function* () {
let i, o;
r ? o = r : (i = new AbortController(), o = i.signal);
const s = new Headers(this.customHeaders);
s.set("range", `bytes=${e}-${e + t - 1}`);
let c;
this.mustReload ? c = "reload" : this.chromeWindowsNoCache && (c = "no-store");
let u = yield fetch(this.url, {
signal: o,
cache: c,
headers: s
//biome-ignore lint: "cache" is incompatible between cloudflare workers and browser
});
if (e === 0 && u.status === 416) {
const d = u.headers.get("Content-Range");
if (!d || !d.startsWith("bytes */"))
throw Error("Missing content-length on 416 response");
const m = +d.substr(8);
u = yield fetch(this.url, {
signal: o,
cache: "reload",
headers: { range: `bytes=0-${m - 1}` }
//biome-ignore lint: "cache" is incompatible between cloudflare workers and browser
});
}
let f = u.headers.get("Etag");
if (f?.startsWith("W/") && (f = null), u.status === 416 || n && f && f !== n)
throw this.mustReload = !0, new Q(
`Server returned non-matching ETag ${n} after one retry. Check browser extensions and servers for issues that may affect correct ETag headers.`
);
if (u.status >= 300)
throw Error(`Bad response code: ${u.status}`);
const a = u.headers.get("Content-Length");
if (u.status === 200 && (!a || +a > t))
throw i && i.abort(), Error(
"Server returned no content-length header or content-length exceeding request. Check that your storage backend supports HTTP Byte Serving."
);
return {
data: yield u.arrayBuffer(),
etag: f || void 0,
cacheControl: u.headers.get("Cache-Control") || void 0,
expires: u.headers.get("Expires") || void 0
};
});
}
};
function E(e, t) {
const r = e.getUint32(t + 4, !0), n = e.getUint32(t + 0, !0);
return r * M(2, 32) + n;
}
function wt(e, t) {
const r = new DataView(e), n = r.getUint8(7);
if (n > 3)
throw Error(
`Archive is spec version ${n} but this library supports up to spec version 3`
);
return {
specVersion: n,
rootDirectoryOffset: E(r, 8),
rootDirectoryLength: E(r, 16),
jsonMetadataOffset: E(r, 24),
jsonMetadataLength: E(r, 32),
leafDirectoryOffset: E(r, 40),
leafDirectoryLength: E(r, 48),
tileDataOffset: E(r, 56),
tileDataLength: E(r, 64),
numAddressedTiles: E(r, 72),
numTileEntries: E(r, 80),
numTileContents: E(r, 88),
clustered: r.getUint8(96) === 1,
internalCompression: r.getUint8(97),
tileCompression: r.getUint8(98),
tileType: r.getUint8(99),
minZoom: r.getUint8(100),
maxZoom: r.getUint8(101),
minLon: r.getInt32(102, !0) / 1e7,
minLat: r.getInt32(106, !0) / 1e7,
maxLon: r.getInt32(110, !0) / 1e7,
maxLat: r.getInt32(114, !0) / 1e7,
centerZoom: r.getUint8(118),
centerLon: r.getInt32(119, !0) / 1e7,
centerLat: r.getInt32(123, !0) / 1e7,
etag: t
};
}
function Te(e) {
const t = { buf: new Uint8Array(e), pos: 0 }, r = H(t), n = [];
let i = 0;
for (let o = 0; o < r; o++) {
const s = H(t);
n.push({ tileId: i + s, offset: 0, length: 0, runLength: 1 }), i += s;
}
for (let o = 0; o < r; o++)
n[o].runLength = H(t);
for (let o = 0; o < r; o++)
n[o].length = H(t);
for (let o = 0; o < r; o++) {
const s = H(t);
s === 0 && o > 0 ? n[o].offset = n[o - 1].offset + n[o - 1].length : n[o].offset = s - 1;
}
return n;
}
function xt(e) {
const t = new DataView(e);
return t.getUint16(2, !0) === 2 ? (console.warn(
"PMTiles spec version 2 has been deprecated; please see github.com/protomaps/PMTiles for tools to upgrade"
), 2) : t.getUint16(2, !0) === 1 ? (console.warn(
"PMTiles spec version 1 has been deprecated; please see github.com/protomaps/PMTiles for tools to upgrade"
), 1) : 3;
}
var Q = class extends Error {
};
function Ae(e, t) {
return g(this, null, function* () {
const r = yield e.getBytes(0, 16384);
if (new DataView(r.data).getUint16(0, !0) !== 19792)
throw new Error("Wrong magic number for PMTiles archive");
if (xt(r.data) < 3)
return [yield ze.getHeader(e)];
const i = r.data.slice(0, yt), o = wt(i, r.etag), s = r.data.slice(
o.rootDirectoryOffset,
o.rootDirectoryOffset + o.rootDirectoryLength
), c = `${e.getKey()}|${o.etag || ""}|${o.rootDirectoryOffset}|${o.rootDirectoryLength}`, u = Te(
yield t(s, o.internalCompression)
);
return [o, [c, u.length, u]];
});
}
function Ce(e, t, r, n, i) {
return g(this, null, function* () {
const o = yield e.getBytes(r, n, void 0, i.etag), s = yield t(o.data, i.internalCompression), c = Te(s);
if (c.length === 0)
throw new Error("Empty directory is invalid");
return c;
});
}
var zt = class {
constructor(e = 100, t = !0, r = te) {
this.cache = /* @__PURE__ */ new Map(), this.maxCacheEntries = e, this.counter = 1, this.decompress = r;
}
getHeader(e) {
return g(this, null, function* () {
const t = e.getKey(), r = this.cache.get(t);
if (r)
return r.lastUsed = this.counter++, r.data;
const n = yield Ae(e, this.decompress);
return n[1] && this.cache.set(n[1][0], {
lastUsed: this.counter++,
data: n[1][2]
}), this.cache.set(t, {
lastUsed: this.counter++,
data: n[0]
}), this.prune(), n[0];
});
}
getDirectory(e, t, r, n) {
return g(this, null, function* () {
const i = `${e.getKey()}|${n.etag || ""}|${t}|${r}`, o = this.cache.get(i);
if (o)
return o.lastUsed = this.counter++, o.data;
const s = yield Ce(
e,
this.decompress,
t,
r,
n
);
return this.cache.set(i, {
lastUsed: this.counter++,
data: s
}), this.prune(), s;
});
}
// for v2 backwards compatibility
getArrayBuffer(e, t, r, n) {
return g(this, null, function* () {
const i = `${e.getKey()}|${n.etag || ""}|${t}|${r}`, o = this.cache.get(i);
if (o)
return o.lastUsed = this.counter++, yield o.data;
const s = yield e.getBytes(t, r, void 0, n.etag);
return this.cache.set(i, {
lastUsed: this.counter++,
data: s.data
}), this.prune(), s.data;
});
}
prune() {
if (this.cache.size > this.maxCacheEntries) {
let e = 1 / 0, t;
this.cache.forEach((r, n) => {
r.lastUsed < e && (e = r.lastUsed, t = n);
}), t && this.cache.delete(t);
}
}
invalidate(e) {
return g(this, null, function* () {
this.cache.delete(e.getKey());
});
}
}, Ut = class {
constructor(e = 100, t = !0, r = te) {
this.cache = /* @__PURE__ */ new Map(), this.invalidations = /* @__PURE__ */ new Map(), this.maxCacheEntries = e, this.counter = 1, this.decompress = r;
}
getHeader(e) {
return g(this, null, function* () {
const t = e.getKey(), r = this.cache.get(t);
if (r)
return r.lastUsed = this.counter++, yield r.data;
const n = new Promise((i, o) => {
Ae(e, this.decompress).then((s) => {
s[1] && this.cache.set(s[1][0], {
lastUsed: this.counter++,
data: Promise.resolve(s[1][2])
}), i(s[0]), this.prune();
}).catch((s) => {
o(s);
});
});
return this.cache.set(t, { lastUsed: this.counter++, data: n }), n;
});
}
getDirectory(e, t, r, n) {
return g(this, null, function* () {
const i = `${e.getKey()}|${n.etag || ""}|${t}|${r}`, o = this.cache.get(i);
if (o)
return o.lastUsed = this.counter++, yield o.data;
const s = new Promise((c, u) => {
Ce(e, this.decompress, t, r, n).then((f) => {
c(f), this.prune();
}).catch((f) => {
u(f);
});
});
return this.cache.set(i, { lastUsed: this.counter++, data: s }), s;
});
}
// for v2 backwards compatibility
getArrayBuffer(e, t, r, n) {
return g(this, null, function* () {
const i = `${e.getKey()}|${n.etag || ""}|${t}|${r}`, o = this.cache.get(i);
if (o)
return o.lastUsed = this.counter++, yield o.data;
const s = new Promise((c, u) => {
e.getBytes(t, r, void 0, n.etag).then((f) => {
c(f.data), this.cache.has(i), this.prune();
}).catch((f) => {
u(f);
});
});
return this.cache.set(i, { lastUsed: this.counter++, data: s }), s;
});
}
prune() {
if (this.cache.size >= this.maxCacheEntries) {
let e = 1 / 0, t;
this.cache.forEach((r, n) => {
r.lastUsed < e && (e = r.lastUsed, t = n);
}), t && this.cache.delete(t);
}
}
invalidate(e) {
return g(this, null, function* () {
const t = e.getKey();
if (this.invalidations.get(t))
return yield this.invalidations.get(t);
this.cache.delete(e.getKey());
const r = new Promise((n, i) => {
this.getHeader(e).then((o) => {
n(), this.invalidations.delete(t);
}).catch((o) => {
i(o);
});
});
this.invalidations.set(t, r);
});
}
}, ge = class {
constructor(e, t, r) {
typeof e == "string" ? this.source = new pt(e) : this.source = e, r ? this.decompress = r : this.decompress = te, t ? this.cache = t : this.cache = new Ut();
}
/**
* Return the header of the archive,
* including information such as tile type, min/max zoom, bounds, and summary statistics.
*/
getHeader() {
return g(this, null, function* () {
return yield this.cache.getHeader(this.source);
});
}
/** @hidden */
getZxyAttempt(e, t, r, n) {
return g(this, null, function* () {
const i = ht(e, t, r), o = yield this.cache.getHeader(this.source);
if (o.specVersion < 3)
return ze.getZxy(o, this.source, this.cache, e, t, r, n);
if (e < o.minZoom || e > o.maxZoom)
return;
let s = o.rootDirectoryOffset, c = o.rootDirectoryLength;
for (let u = 0; u <= 3; u++) {
const f = yield this.cache.getDirectory(
this.source,
s,
c,
o
), a = mt(f, i);
if (a) {
if (a.runLength > 0) {
const l = yield this.source.getBytes(
o.tileDataOffset + a.offset,
a.length,
n,
o.etag
);
return {
data: yield this.decompress(l.data, o.tileCompression),
cacheControl: l.cacheControl,
expires: l.expires
};
}
s = o.leafDirectoryOffset + a.offset, c = a.length;
} else
return;
}
throw Error("Maximum directory depth exceeded");
});
}
/**
* Primary method to get a single tile's bytes from an archive.
*
* Returns undefined if the tile does not exist in the archive.
*/
getZxy(e, t, r, n) {
return g(this, null, function* () {
try {
return yield this.getZxyAttempt(e, t, r, n);
} catch (i) {
if (i instanceof Q)
return this.cache.invalidate(this.source), yield this.getZxyAttempt(e, t, r, n);
throw i;
}
});
}
/** @hidden */
getMetadataAttempt() {
return g(this, null, function* () {
const e = yield this.cache.getHeader(this.source), t = yield this.source.getBytes(
e.jsonMetadataOffset,
e.jsonMetadataLength,
void 0,
e.etag
), r = yield this.decompress(
t.data,
e.internalCompression
), n = new TextDecoder("utf-8");
return JSON.parse(n.decode(r));
});
}
/**
* Return the arbitrary JSON metadata of the archive.
*/
getMetadata() {
return g(this, null, function* () {
try {
return yield this.getMetadataAttempt();
} catch (e) {
if (e instanceof Q)
return this.cache.invalidate(this.source), yield this.getMetadataAttempt();
throw e;
}
});
}
/**
* Construct a [TileJSON](https://github.com/mapbox/tilejson-spec) object.
*
* baseTilesUrl is the desired tiles URL, excluding the suffix `/{z}/{x}/{y}.{ext}`.
* For example, if the desired URL is `http://example.com/tileset/{z}/{x}/{y}.mvt`,
* the baseTilesUrl should be `https://example.com/tileset`.
*/
getTileJson(e) {
return g(this, null, function* () {
const t = yield this.getHeader(), r = yield this.getMetadata(), n = vt(t.tileType);
return {
tilejson: "3.0.0",
scheme: "xyz",
tiles: [`${e}/{z}/{x}/{y}${n}`],
// biome-ignore lint: TileJSON spec
vector_layers: r.vector_layers,
attribution: r.attribution,
description: r.description,
name: r.name,
version: r.version,
bounds: [t.minLon, t.minLat, t.maxLon, t.maxLat],
center: [t.centerLon, t.centerLat, t.centerZoom],
minzoom: t.minZoom,
maxzoom: t.maxZoom
};
});
}
};
export {
dt as Compression,
Q as EtagMismatch,
pt as FetchSource,
Et as FileSource,
ge as PMTiles,
bt as Protocol,
zt as ResolvedValueCache,
Ut as SharedPromiseCache,
gt as TileType,
wt as bytesToHeader,
mt as findTile,
E as getUint64,
Dt as leafletRasterLayer,
H as readVarint,
Lt as tileIdToZxy,
vt as tileTypeExt,
ht as zxyToTileId
};