@india-boundary-corrector/maplibre-protocol 0.0.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.
@@ -0,0 +1,3167 @@
1
+ "use strict";
2
+ var IndiaBoundaryCorrector = (() => {
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/index.js
22
+ var index_exports = {};
23
+ __export(index_exports, {
24
+ CorrectionProtocol: () => CorrectionProtocol,
25
+ LayerConfig: () => LayerConfig,
26
+ fetchAndFixTile: () => fetchAndFixTile,
27
+ getPmtilesUrl: () => getPmtilesUrl,
28
+ layerConfigs: () => layerConfigs,
29
+ parseCorrectionsUrl: () => parseCorrectionsUrl,
30
+ registerCorrectionProtocol: () => registerCorrectionProtocol
31
+ });
32
+
33
+ // ../data/version.js
34
+ var packageVersion = "0.0.1";
35
+
36
+ // ../data/index.js
37
+ var import_meta = {};
38
+ var PACKAGE_NAME = "@india-boundary-corrector/data";
39
+ var PMTILES_FILENAME = "india_boundary_corrections.pmtiles";
40
+ var DEFAULT_CDN_URL = `https://unpkg.com/${PACKAGE_NAME}@${packageVersion}/${PMTILES_FILENAME}`;
41
+ function detectPmtilesUrl() {
42
+ try {
43
+ if (typeof import_meta !== "undefined" && import_meta.url) {
44
+ const moduleUrl = new URL(".", import_meta.url);
45
+ return new URL(PMTILES_FILENAME, moduleUrl).href;
46
+ }
47
+ } catch {
48
+ }
49
+ return DEFAULT_CDN_URL;
50
+ }
51
+ var cachedPmtilesUrl = null;
52
+ function getPmtilesUrl() {
53
+ if (cachedPmtilesUrl === null) {
54
+ cachedPmtilesUrl = detectPmtilesUrl();
55
+ }
56
+ return cachedPmtilesUrl;
57
+ }
58
+
59
+ // ../layer-configs/dist/index.js
60
+ var configs_default = [
61
+ {
62
+ id: "cartodb-dark",
63
+ zoomThreshold: 5,
64
+ tileUrlTemplates: [
65
+ "https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png",
66
+ "https://basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png",
67
+ "https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_all/{z}/{x}/{y}{r}.png",
68
+ "https://{s}.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}{r}.png",
69
+ "https://basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}{r}.png",
70
+ "https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_nolabels/{z}/{x}/{y}{r}.png"
71
+ ],
72
+ lineWidthStops: { "1": 0.5, "10": 2.5 },
73
+ lineStyles: [
74
+ { color: "rgb(40, 40, 40)" }
75
+ ]
76
+ },
77
+ {
78
+ id: "cartodb-light",
79
+ startZoom: 0,
80
+ zoomThreshold: 5,
81
+ tileUrlTemplates: [
82
+ "https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png",
83
+ "https://basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png",
84
+ "https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}{r}.png",
85
+ "https://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}{r}.png",
86
+ "https://basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}{r}.png",
87
+ "https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_nolabels/{z}/{x}/{y}{r}.png",
88
+ "https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png",
89
+ "https://basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png",
90
+ "https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}{r}.png",
91
+ "https://basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}{r}.png",
92
+ "https://{s}.basemaps.cartocdn.com/rastertiles/voyager_labels_under/{z}/{x}/{y}{r}.png",
93
+ "https://basemaps.cartocdn.com/rastertiles/voyager_labels_under/{z}/{x}/{y}{r}.png"
94
+ ],
95
+ lineWidthStops: { "1": 0.25, "2": 0.25, "3": 0.5, "4": 0.75, "5": 1 },
96
+ lineStyles: [
97
+ { color: "rgb(235, 214, 214)", alpha: 0.2, startZoom: 6, widthFraction: 5 },
98
+ { color: "rgb(235, 214, 214)" }
99
+ ]
100
+ },
101
+ {
102
+ id: "open-topo",
103
+ startZoom: 4,
104
+ zoomThreshold: 4,
105
+ tileUrlTemplates: [
106
+ "https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png",
107
+ "https://tile.opentopomap.org/{z}/{x}/{y}.png"
108
+ ],
109
+ lineWidthStops: { "4": 0.75, "5": 1, "6": 1.25, "7": 1.5, "8": 1.75, "9": 1.25, "10": 1.25, "13": 1.5 },
110
+ lineStyles: [
111
+ { color: "rgb(83, 83, 83)", startZoom: 7, endZoom: 8, alpha: 0.4, widthFraction: 4 },
112
+ { color: "rgb(83, 83, 83)", endZoom: 8 },
113
+ { color: "rgb(140, 20, 180)", startZoom: 9, widthFraction: 9, alpha: 0.2 },
114
+ { color: "rgb(140, 20, 180)", startZoom: 9 }
115
+ ]
116
+ },
117
+ {
118
+ id: "osm-carto",
119
+ startZoom: 1,
120
+ zoomThreshold: 1,
121
+ tileUrlTemplates: [
122
+ "https://tile.openstreetmap.org/{z}/{x}/{y}.png",
123
+ "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
124
+ ],
125
+ lineWidthStops: { "1": 0.5, "2": 0.6, "3": 0.7, "4": 1, "10": 3.75 },
126
+ lineStyles: [
127
+ { color: "rgb(200, 180, 200)" },
128
+ { color: "rgb(160, 120, 160)", widthFraction: 0.333, dashArray: [30, 2, 8, 2] }
129
+ ]
130
+ },
131
+ {
132
+ id: "osm-hot",
133
+ startZoom: 2,
134
+ zoomThreshold: 2,
135
+ tileUrlTemplates: [
136
+ "https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png"
137
+ ],
138
+ lineWidthStops: { "2": 3, "3": 3, "7": 3, "8": 3.5, "9": 3.5 },
139
+ lineStyles: [
140
+ { color: "rgb(149, 175, 180)" },
141
+ { color: "rgb(89, 117, 123)", widthFraction: 0.33 }
142
+ ]
143
+ }
144
+ ];
145
+ function templateToRegex(template) {
146
+ const groups = [];
147
+ let pattern = template.replace(/[.*+?^${}()|[\]\\]/g, (char) => {
148
+ if (char === "{" || char === "}") return char;
149
+ return "\\" + char;
150
+ }).replace(/^https:\/\//, "https?://").replace(/^http:\/\//, "https?://").replace(/\{[a-z0-9]-[a-z0-9]\}/gi, () => {
151
+ groups.push("s");
152
+ return "([a-z0-9]+)";
153
+ }).replace(/\{(z|x|y|s|r)\}/gi, (_2, name) => {
154
+ const lowerName = name.toLowerCase();
155
+ groups.push(lowerName);
156
+ if (lowerName === "s") {
157
+ return "([a-z0-9]+)";
158
+ }
159
+ if (lowerName === "r") {
160
+ return "(@\\d+x)?";
161
+ }
162
+ return "(\\d+)";
163
+ });
164
+ return { pattern: new RegExp("^" + pattern + "(\\?.*)?$", "i"), groups };
165
+ }
166
+ function templateToTemplateRegex(template) {
167
+ let pattern = template.replace(/[.*+?^${}()|[\]\\]/g, (char) => {
168
+ if (char === "{" || char === "}") return char;
169
+ return "\\" + char;
170
+ }).replace(/^https:\/\//, "https?://").replace(/^http:\/\//, "https?://").replace(/\{([a-z0-9])-([a-z0-9])\}/gi, (_2, start, end) => `(\\{${start}-${end}\\}|[a-z0-9]+)`).replace(/\{(z|x|y|s|r)\}/gi, (_2, name) => {
171
+ const lowerName = name.toLowerCase();
172
+ if (lowerName === "s") {
173
+ return "(\\{s\\}|[a-z0-9]+)";
174
+ }
175
+ if (lowerName === "r") {
176
+ return "(\\{r\\}|@\\d+x)?";
177
+ }
178
+ return `\\{${lowerName}\\}`;
179
+ });
180
+ return new RegExp("^" + pattern + "(\\?.*)?$", "i");
181
+ }
182
+ var LayerConfig = class _LayerConfig {
183
+ constructor({
184
+ id,
185
+ startZoom = 0,
186
+ zoomThreshold = 5,
187
+ // Tile URL templates for matching (e.g., "https://{s}.tile.example.com/{z}/{x}/{y}.png")
188
+ tileUrlTemplates = [],
189
+ // Line width stops: map of zoom level to line width (at least 2 entries)
190
+ lineWidthStops = { 1: 0.5, 10: 2.5 },
191
+ // Line styles array - each element describes a line to draw
192
+ // { color: string, widthFraction?: number, dashArray?: number[], startZoom?: number, endZoom?: number }
193
+ // Lines are drawn in array order. startZoom defaults to layerConfig startZoom, endZoom defaults to Infinity
194
+ lineStyles = [{ color: "green", widthFraction: 1 }],
195
+ // Factor to multiply line width for deletion blur (default 1.5)
196
+ // Higher values leave gaps where wiped lines meet existing lines
197
+ // Lower values mean wiped lines show through
198
+ delWidthFactor = 1.5,
199
+ // Factor to extend add lines by (multiplied by deletion line width)
200
+ // Helps cover gaps where deleted lines meet the new boundary
201
+ // Set to 0 to disable extension
202
+ lineExtensionFactor = 0.5
203
+ }) {
204
+ if (!id || typeof id !== "string") {
205
+ throw new Error("LayerConfig requires a non-empty string id");
206
+ }
207
+ this.id = id;
208
+ this.startZoom = startZoom;
209
+ this.zoomThreshold = zoomThreshold;
210
+ if (startZoom > zoomThreshold) {
211
+ throw new Error(`LayerConfig "${id}": startZoom (${startZoom}) must be <= zoomThreshold (${zoomThreshold})`);
212
+ }
213
+ const templates = Array.isArray(tileUrlTemplates) ? tileUrlTemplates : tileUrlTemplates ? [tileUrlTemplates] : [];
214
+ this.tileUrlTemplates = templates;
215
+ this._compiledPatterns = templates.map((t) => templateToRegex(t));
216
+ this._templatePatterns = templates.map((t) => templateToTemplateRegex(t));
217
+ if (!lineWidthStops || typeof lineWidthStops !== "object" || Array.isArray(lineWidthStops)) {
218
+ throw new Error(`LayerConfig "${id}": lineWidthStops must be an object`);
219
+ }
220
+ const stopKeys = Object.keys(lineWidthStops);
221
+ if (stopKeys.length < 2) {
222
+ throw new Error(`LayerConfig "${id}": lineWidthStops must have at least 2 entries`);
223
+ }
224
+ for (const key of stopKeys) {
225
+ const zoom = Number(key);
226
+ if (!Number.isInteger(zoom) || zoom < 0) {
227
+ throw new Error(`LayerConfig "${id}": lineWidthStops keys must be non-negative integers, got "${key}"`);
228
+ }
229
+ if (typeof lineWidthStops[key] !== "number" || lineWidthStops[key] <= 0) {
230
+ throw new Error(`LayerConfig "${id}": lineWidthStops values must be positive numbers`);
231
+ }
232
+ }
233
+ this.lineWidthStops = lineWidthStops;
234
+ if (!Array.isArray(lineStyles) || lineStyles.length === 0) {
235
+ throw new Error(`LayerConfig "${id}": lineStyles must be a non-empty array`);
236
+ }
237
+ for (let i2 = 0; i2 < lineStyles.length; i2++) {
238
+ const style = lineStyles[i2];
239
+ if (!style || typeof style !== "object") {
240
+ throw new Error(`LayerConfig "${id}": lineStyles[${i2}] must be an object`);
241
+ }
242
+ if (!style.color || typeof style.color !== "string") {
243
+ throw new Error(`LayerConfig "${id}": lineStyles[${i2}].color must be a non-empty string`);
244
+ }
245
+ }
246
+ this.lineStyles = lineStyles.map((style) => ({
247
+ ...style,
248
+ startZoom: style.startZoom ?? startZoom,
249
+ endZoom: style.endZoom ?? Infinity
250
+ }));
251
+ this.delWidthFactor = delWidthFactor;
252
+ this.lineExtensionFactor = lineExtensionFactor;
253
+ }
254
+ /**
255
+ * Get line styles active at a given zoom level
256
+ * @param {number} z - Zoom level
257
+ * @returns {Array<{color: string, widthFraction?: number, dashArray?: number[]}>}
258
+ */
259
+ getLineStylesForZoom(z2) {
260
+ return this.lineStyles.filter((style) => z2 >= style.startZoom && z2 <= style.endZoom);
261
+ }
262
+ /**
263
+ * Check if this config matches the given template URLs (with {z}/{x}/{y} placeholders)
264
+ * @param {string | string[]} templates - Single template URL or array of template URLs
265
+ * @returns {boolean}
266
+ */
267
+ matchTemplate(templates) {
268
+ if (this._templatePatterns.length === 0) return false;
269
+ const urls = Array.isArray(templates) ? templates : [templates];
270
+ if (urls.length === 0) return false;
271
+ return urls.some(
272
+ (url) => this._templatePatterns.some((pattern) => pattern.test(url))
273
+ );
274
+ }
275
+ /**
276
+ * Check if this config matches the given tile URLs (with actual coordinates)
277
+ * @param {string | string[]} tiles - Single tile URL or array of tile URLs
278
+ * @returns {boolean}
279
+ */
280
+ matchTileUrl(tiles) {
281
+ if (this._compiledPatterns.length === 0) return false;
282
+ const urls = Array.isArray(tiles) ? tiles : [tiles];
283
+ if (urls.length === 0) return false;
284
+ return urls.some(
285
+ (url) => this._compiledPatterns.some(({ pattern }) => pattern.test(url))
286
+ );
287
+ }
288
+ /**
289
+ * Extract tile coordinates (z, x, y) from a URL using this config's templates
290
+ * @param {string} url - Tile URL to extract coordinates from
291
+ * @returns {{ z: number, x: number, y: number } | null}
292
+ */
293
+ extractCoords(url) {
294
+ for (const { pattern, groups } of this._compiledPatterns) {
295
+ const match = url.match(pattern);
296
+ if (match) {
297
+ const result = {};
298
+ for (let i2 = 0; i2 < groups.length; i2++) {
299
+ const name = groups[i2];
300
+ const value = match[i2 + 1];
301
+ if (name === "z" || name === "x" || name === "y") {
302
+ result[name] = parseInt(value, 10);
303
+ }
304
+ }
305
+ if ("z" in result && "x" in result && "y" in result) {
306
+ return { z: result.z, x: result.x, y: result.y };
307
+ }
308
+ }
309
+ }
310
+ return null;
311
+ }
312
+ /**
313
+ * Serialize the config to a plain object for postMessage
314
+ * @returns {Object}
315
+ */
316
+ toJSON() {
317
+ return {
318
+ id: this.id,
319
+ startZoom: this.startZoom,
320
+ zoomThreshold: this.zoomThreshold,
321
+ tileUrlTemplates: this.tileUrlTemplates,
322
+ lineWidthStops: this.lineWidthStops,
323
+ lineStyles: this.lineStyles,
324
+ delWidthFactor: this.delWidthFactor,
325
+ lineExtensionFactor: this.lineExtensionFactor
326
+ };
327
+ }
328
+ /**
329
+ * Create a LayerConfig from a plain object (e.g., from postMessage)
330
+ * @param {Object} obj
331
+ * @returns {LayerConfig}
332
+ */
333
+ static fromJSON(obj) {
334
+ return new _LayerConfig(obj);
335
+ }
336
+ };
337
+ var LayerConfigRegistry = class _LayerConfigRegistry {
338
+ constructor() {
339
+ this.registry = {};
340
+ }
341
+ /**
342
+ * Get a layer config by id
343
+ */
344
+ get(id) {
345
+ return this.registry[id];
346
+ }
347
+ /**
348
+ * Register a new layer config
349
+ */
350
+ register(config) {
351
+ this.registry[config.id] = config;
352
+ }
353
+ /**
354
+ * Remove a layer config by id
355
+ */
356
+ remove(id) {
357
+ if (!this.registry[id]) return false;
358
+ delete this.registry[id];
359
+ return true;
360
+ }
361
+ /**
362
+ * Detect layer config from tile URL templates (with {z}/{x}/{y} placeholders)
363
+ * @param {string | string[]} templates - Single template URL or array of template URLs
364
+ */
365
+ detectFromTemplates(templates) {
366
+ if (!templates || Array.isArray(templates) && templates.length === 0) return void 0;
367
+ for (const config of Object.values(this.registry)) {
368
+ if (config.matchTemplate(templates)) {
369
+ return config;
370
+ }
371
+ }
372
+ return void 0;
373
+ }
374
+ /**
375
+ * Detect layer config from actual tile URLs (with numeric coordinates)
376
+ * @param {string | string[]} urls - Single tile URL or array of tile URLs
377
+ */
378
+ detectFromTileUrls(urls) {
379
+ if (!urls || Array.isArray(urls) && urls.length === 0) return void 0;
380
+ for (const config of Object.values(this.registry)) {
381
+ if (config.matchTileUrl(urls)) {
382
+ return config;
383
+ }
384
+ }
385
+ return void 0;
386
+ }
387
+ /**
388
+ * Get all available layer config ids
389
+ */
390
+ getAvailableIds() {
391
+ return Object.keys(this.registry);
392
+ }
393
+ /**
394
+ * Create a new registry with all configs from this registry plus extra configs.
395
+ * @param {LayerConfig[]} extraLayerConfigs - Additional configs to add
396
+ * @returns {LayerConfigRegistry} A new registry with merged configs
397
+ */
398
+ createMergedRegistry(extraLayerConfigs) {
399
+ const registry = new _LayerConfigRegistry();
400
+ for (const id of this.getAvailableIds()) {
401
+ registry.register(this.get(id));
402
+ }
403
+ if (extraLayerConfigs && extraLayerConfigs.length > 0) {
404
+ for (const config of extraLayerConfigs) {
405
+ registry.register(config);
406
+ }
407
+ }
408
+ return registry;
409
+ }
410
+ /**
411
+ * Parse a tile URL into its components: layer config and coordinates
412
+ * @param {string} url - Tile URL to parse
413
+ * @returns {{ layerConfig: LayerConfig, coords: { z: number, x: number, y: number } } | null}
414
+ */
415
+ parseTileUrl(url) {
416
+ const layerConfig = this.detectFromTileUrls([url]);
417
+ if (!layerConfig) return null;
418
+ const coords = layerConfig.extractCoords(url);
419
+ if (!coords) return null;
420
+ return { layerConfig, coords };
421
+ }
422
+ };
423
+ var layerConfigs = new LayerConfigRegistry();
424
+ for (const configData of configs_default) {
425
+ layerConfigs.register(new LayerConfig(configData));
426
+ }
427
+
428
+ // ../tilefixer/dist/index.js
429
+ var u8 = Uint8Array;
430
+ var u16 = Uint16Array;
431
+ var i32 = Int32Array;
432
+ var fleb = new u8([
433
+ 0,
434
+ 0,
435
+ 0,
436
+ 0,
437
+ 0,
438
+ 0,
439
+ 0,
440
+ 0,
441
+ 1,
442
+ 1,
443
+ 1,
444
+ 1,
445
+ 2,
446
+ 2,
447
+ 2,
448
+ 2,
449
+ 3,
450
+ 3,
451
+ 3,
452
+ 3,
453
+ 4,
454
+ 4,
455
+ 4,
456
+ 4,
457
+ 5,
458
+ 5,
459
+ 5,
460
+ 5,
461
+ 0,
462
+ /* unused */
463
+ 0,
464
+ 0,
465
+ /* impossible */
466
+ 0
467
+ ]);
468
+ var fdeb = new u8([
469
+ 0,
470
+ 0,
471
+ 0,
472
+ 0,
473
+ 1,
474
+ 1,
475
+ 2,
476
+ 2,
477
+ 3,
478
+ 3,
479
+ 4,
480
+ 4,
481
+ 5,
482
+ 5,
483
+ 6,
484
+ 6,
485
+ 7,
486
+ 7,
487
+ 8,
488
+ 8,
489
+ 9,
490
+ 9,
491
+ 10,
492
+ 10,
493
+ 11,
494
+ 11,
495
+ 12,
496
+ 12,
497
+ 13,
498
+ 13,
499
+ /* unused */
500
+ 0,
501
+ 0
502
+ ]);
503
+ var clim = new u8([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);
504
+ var freb = function(eb, start) {
505
+ var b2 = new u16(31);
506
+ for (var i2 = 0; i2 < 31; ++i2) {
507
+ b2[i2] = start += 1 << eb[i2 - 1];
508
+ }
509
+ var r = new i32(b2[30]);
510
+ for (var i2 = 1; i2 < 30; ++i2) {
511
+ for (var j2 = b2[i2]; j2 < b2[i2 + 1]; ++j2) {
512
+ r[j2] = j2 - b2[i2] << 5 | i2;
513
+ }
514
+ }
515
+ return { b: b2, r };
516
+ };
517
+ var _a = freb(fleb, 2);
518
+ var fl = _a.b;
519
+ var revfl = _a.r;
520
+ fl[28] = 258, revfl[258] = 28;
521
+ var _b = freb(fdeb, 0);
522
+ var fd = _b.b;
523
+ var revfd = _b.r;
524
+ var rev = new u16(32768);
525
+ for (i = 0; i < 32768; ++i) {
526
+ x2 = (i & 43690) >> 1 | (i & 21845) << 1;
527
+ x2 = (x2 & 52428) >> 2 | (x2 & 13107) << 2;
528
+ x2 = (x2 & 61680) >> 4 | (x2 & 3855) << 4;
529
+ rev[i] = ((x2 & 65280) >> 8 | (x2 & 255) << 8) >> 1;
530
+ }
531
+ var x2;
532
+ var i;
533
+ var hMap = (function(cd, mb, r) {
534
+ var s = cd.length;
535
+ var i2 = 0;
536
+ var l2 = new u16(mb);
537
+ for (; i2 < s; ++i2) {
538
+ if (cd[i2])
539
+ ++l2[cd[i2] - 1];
540
+ }
541
+ var le = new u16(mb);
542
+ for (i2 = 1; i2 < mb; ++i2) {
543
+ le[i2] = le[i2 - 1] + l2[i2 - 1] << 1;
544
+ }
545
+ var co;
546
+ if (r) {
547
+ co = new u16(1 << mb);
548
+ var rvb = 15 - mb;
549
+ for (i2 = 0; i2 < s; ++i2) {
550
+ if (cd[i2]) {
551
+ var sv = i2 << 4 | cd[i2];
552
+ var r_1 = mb - cd[i2];
553
+ var v2 = le[cd[i2] - 1]++ << r_1;
554
+ for (var m2 = v2 | (1 << r_1) - 1; v2 <= m2; ++v2) {
555
+ co[rev[v2] >> rvb] = sv;
556
+ }
557
+ }
558
+ }
559
+ } else {
560
+ co = new u16(s);
561
+ for (i2 = 0; i2 < s; ++i2) {
562
+ if (cd[i2]) {
563
+ co[i2] = rev[le[cd[i2] - 1]++] >> 15 - cd[i2];
564
+ }
565
+ }
566
+ }
567
+ return co;
568
+ });
569
+ var flt = new u8(288);
570
+ for (i = 0; i < 144; ++i)
571
+ flt[i] = 8;
572
+ var i;
573
+ for (i = 144; i < 256; ++i)
574
+ flt[i] = 9;
575
+ var i;
576
+ for (i = 256; i < 280; ++i)
577
+ flt[i] = 7;
578
+ var i;
579
+ for (i = 280; i < 288; ++i)
580
+ flt[i] = 8;
581
+ var i;
582
+ var fdt = new u8(32);
583
+ for (i = 0; i < 32; ++i)
584
+ fdt[i] = 5;
585
+ var i;
586
+ var flrm = /* @__PURE__ */ hMap(flt, 9, 1);
587
+ var fdrm = /* @__PURE__ */ hMap(fdt, 5, 1);
588
+ var max = function(a) {
589
+ var m2 = a[0];
590
+ for (var i2 = 1; i2 < a.length; ++i2) {
591
+ if (a[i2] > m2)
592
+ m2 = a[i2];
593
+ }
594
+ return m2;
595
+ };
596
+ var bits = function(d, p, m2) {
597
+ var o = p / 8 | 0;
598
+ return (d[o] | d[o + 1] << 8) >> (p & 7) & m2;
599
+ };
600
+ var bits16 = function(d, p) {
601
+ var o = p / 8 | 0;
602
+ return (d[o] | d[o + 1] << 8 | d[o + 2] << 16) >> (p & 7);
603
+ };
604
+ var shft = function(p) {
605
+ return (p + 7) / 8 | 0;
606
+ };
607
+ var slc = function(v2, s, e) {
608
+ if (s == null || s < 0)
609
+ s = 0;
610
+ if (e == null || e > v2.length)
611
+ e = v2.length;
612
+ return new u8(v2.subarray(s, e));
613
+ };
614
+ var ec = [
615
+ "unexpected EOF",
616
+ "invalid block type",
617
+ "invalid length/literal",
618
+ "invalid distance",
619
+ "stream finished",
620
+ "no stream handler",
621
+ ,
622
+ "no callback",
623
+ "invalid UTF-8 data",
624
+ "extra field too long",
625
+ "date not in range 1980-2099",
626
+ "filename too long",
627
+ "stream finishing",
628
+ "invalid zip data"
629
+ // determined by unknown compression method
630
+ ];
631
+ var err = function(ind, msg, nt) {
632
+ var e = new Error(msg || ec[ind]);
633
+ e.code = ind;
634
+ if (Error.captureStackTrace)
635
+ Error.captureStackTrace(e, err);
636
+ if (!nt)
637
+ throw e;
638
+ return e;
639
+ };
640
+ var inflt = function(dat, st, buf, dict) {
641
+ var sl = dat.length, dl = dict ? dict.length : 0;
642
+ if (!sl || st.f && !st.l)
643
+ return buf || new u8(0);
644
+ var noBuf = !buf;
645
+ var resize = noBuf || st.i != 2;
646
+ var noSt = st.i;
647
+ if (noBuf)
648
+ buf = new u8(sl * 3);
649
+ var cbuf = function(l3) {
650
+ var bl = buf.length;
651
+ if (l3 > bl) {
652
+ var nbuf = new u8(Math.max(bl * 2, l3));
653
+ nbuf.set(buf);
654
+ buf = nbuf;
655
+ }
656
+ };
657
+ var final = st.f || 0, pos = st.p || 0, bt = st.b || 0, lm = st.l, dm = st.d, lbt = st.m, dbt = st.n;
658
+ var tbts = sl * 8;
659
+ do {
660
+ if (!lm) {
661
+ final = bits(dat, pos, 1);
662
+ var type = bits(dat, pos + 1, 3);
663
+ pos += 3;
664
+ if (!type) {
665
+ var s = shft(pos) + 4, l2 = dat[s - 4] | dat[s - 3] << 8, t = s + l2;
666
+ if (t > sl) {
667
+ if (noSt)
668
+ err(0);
669
+ break;
670
+ }
671
+ if (resize)
672
+ cbuf(bt + l2);
673
+ buf.set(dat.subarray(s, t), bt);
674
+ st.b = bt += l2, st.p = pos = t * 8, st.f = final;
675
+ continue;
676
+ } else if (type == 1)
677
+ lm = flrm, dm = fdrm, lbt = 9, dbt = 5;
678
+ else if (type == 2) {
679
+ var hLit = bits(dat, pos, 31) + 257, hcLen = bits(dat, pos + 10, 15) + 4;
680
+ var tl = hLit + bits(dat, pos + 5, 31) + 1;
681
+ pos += 14;
682
+ var ldt = new u8(tl);
683
+ var clt = new u8(19);
684
+ for (var i2 = 0; i2 < hcLen; ++i2) {
685
+ clt[clim[i2]] = bits(dat, pos + i2 * 3, 7);
686
+ }
687
+ pos += hcLen * 3;
688
+ var clb = max(clt), clbmsk = (1 << clb) - 1;
689
+ var clm = hMap(clt, clb, 1);
690
+ for (var i2 = 0; i2 < tl; ) {
691
+ var r = clm[bits(dat, pos, clbmsk)];
692
+ pos += r & 15;
693
+ var s = r >> 4;
694
+ if (s < 16) {
695
+ ldt[i2++] = s;
696
+ } else {
697
+ var c = 0, n = 0;
698
+ if (s == 16)
699
+ n = 3 + bits(dat, pos, 3), pos += 2, c = ldt[i2 - 1];
700
+ else if (s == 17)
701
+ n = 3 + bits(dat, pos, 7), pos += 3;
702
+ else if (s == 18)
703
+ n = 11 + bits(dat, pos, 127), pos += 7;
704
+ while (n--)
705
+ ldt[i2++] = c;
706
+ }
707
+ }
708
+ var lt = ldt.subarray(0, hLit), dt = ldt.subarray(hLit);
709
+ lbt = max(lt);
710
+ dbt = max(dt);
711
+ lm = hMap(lt, lbt, 1);
712
+ dm = hMap(dt, dbt, 1);
713
+ } else
714
+ err(1);
715
+ if (pos > tbts) {
716
+ if (noSt)
717
+ err(0);
718
+ break;
719
+ }
720
+ }
721
+ if (resize)
722
+ cbuf(bt + 131072);
723
+ var lms = (1 << lbt) - 1, dms = (1 << dbt) - 1;
724
+ var lpos = pos;
725
+ for (; ; lpos = pos) {
726
+ var c = lm[bits16(dat, pos) & lms], sym = c >> 4;
727
+ pos += c & 15;
728
+ if (pos > tbts) {
729
+ if (noSt)
730
+ err(0);
731
+ break;
732
+ }
733
+ if (!c)
734
+ err(2);
735
+ if (sym < 256)
736
+ buf[bt++] = sym;
737
+ else if (sym == 256) {
738
+ lpos = pos, lm = null;
739
+ break;
740
+ } else {
741
+ var add = sym - 254;
742
+ if (sym > 264) {
743
+ var i2 = sym - 257, b2 = fleb[i2];
744
+ add = bits(dat, pos, (1 << b2) - 1) + fl[i2];
745
+ pos += b2;
746
+ }
747
+ var d = dm[bits16(dat, pos) & dms], dsym = d >> 4;
748
+ if (!d)
749
+ err(3);
750
+ pos += d & 15;
751
+ var dt = fd[dsym];
752
+ if (dsym > 3) {
753
+ var b2 = fdeb[dsym];
754
+ dt += bits16(dat, pos) & (1 << b2) - 1, pos += b2;
755
+ }
756
+ if (pos > tbts) {
757
+ if (noSt)
758
+ err(0);
759
+ break;
760
+ }
761
+ if (resize)
762
+ cbuf(bt + 131072);
763
+ var end = bt + add;
764
+ if (bt < dt) {
765
+ var shift = dl - dt, dend = Math.min(dt, end);
766
+ if (shift + bt < 0)
767
+ err(3);
768
+ for (; bt < dend; ++bt)
769
+ buf[bt] = dict[shift + bt];
770
+ }
771
+ for (; bt < end; ++bt)
772
+ buf[bt] = buf[bt - dt];
773
+ }
774
+ }
775
+ st.l = lm, st.p = lpos, st.b = bt, st.f = final;
776
+ if (lm)
777
+ final = 1, st.m = lbt, st.d = dm, st.n = dbt;
778
+ } while (!final);
779
+ return bt != buf.length && noBuf ? slc(buf, 0, bt) : buf.subarray(0, bt);
780
+ };
781
+ var et = /* @__PURE__ */ new u8(0);
782
+ var gzs = function(d) {
783
+ if (d[0] != 31 || d[1] != 139 || d[2] != 8)
784
+ err(6, "invalid gzip data");
785
+ var flg = d[3];
786
+ var st = 10;
787
+ if (flg & 4)
788
+ st += (d[10] | d[11] << 8) + 2;
789
+ for (var zs = (flg >> 3 & 1) + (flg >> 4 & 1); zs > 0; zs -= !d[st++])
790
+ ;
791
+ return st + (flg & 2);
792
+ };
793
+ var gzl = function(d) {
794
+ var l2 = d.length;
795
+ return (d[l2 - 4] | d[l2 - 3] << 8 | d[l2 - 2] << 16 | d[l2 - 1] << 24) >>> 0;
796
+ };
797
+ var zls = function(d, dict) {
798
+ if ((d[0] & 15) != 8 || d[0] >> 4 > 7 || (d[0] << 8 | d[1]) % 31)
799
+ err(6, "invalid zlib data");
800
+ if ((d[1] >> 5 & 1) == +!dict)
801
+ err(6, "invalid zlib data: " + (d[1] & 32 ? "need" : "unexpected") + " dictionary");
802
+ return (d[1] >> 3 & 4) + 2;
803
+ };
804
+ function inflateSync(data, opts) {
805
+ return inflt(data, { i: 2 }, opts && opts.out, opts && opts.dictionary);
806
+ }
807
+ function gunzipSync(data, opts) {
808
+ var st = gzs(data);
809
+ if (st + 8 > data.length)
810
+ err(6, "invalid gzip data");
811
+ return inflt(data.subarray(st, -8), { i: 2 }, opts && opts.out || new u8(gzl(data)), opts && opts.dictionary);
812
+ }
813
+ function unzlibSync(data, opts) {
814
+ return inflt(data.subarray(zls(data, opts && opts.dictionary), -4), { i: 2 }, opts && opts.out, opts && opts.dictionary);
815
+ }
816
+ function decompressSync(data, opts) {
817
+ return data[0] == 31 && data[1] == 139 && data[2] == 8 ? gunzipSync(data, opts) : (data[0] & 15) != 8 || data[0] >> 4 > 7 || (data[0] << 8 | data[1]) % 31 ? inflateSync(data, opts) : unzlibSync(data, opts);
818
+ }
819
+ var td = typeof TextDecoder != "undefined" && /* @__PURE__ */ new TextDecoder();
820
+ var tds = 0;
821
+ try {
822
+ td.decode(et, { stream: true });
823
+ tds = 1;
824
+ } catch (e) {
825
+ }
826
+ var z = Object.defineProperty;
827
+ var b = Math.pow;
828
+ var l = (i2, e) => z(i2, "name", { value: e, configurable: true });
829
+ var m = (i2, e, t) => new Promise((r, n) => {
830
+ var s = (u) => {
831
+ try {
832
+ a(t.next(u));
833
+ } catch (c) {
834
+ n(c);
835
+ }
836
+ }, o = (u) => {
837
+ try {
838
+ a(t.throw(u));
839
+ } catch (c) {
840
+ n(c);
841
+ }
842
+ }, a = (u) => u.done ? r(u.value) : Promise.resolve(u.value).then(s, o);
843
+ a((t = t.apply(i2, e)).next());
844
+ });
845
+ var re = l((i2, e) => {
846
+ let t = false, r = "", n = L.GridLayer.extend({ createTile: l((s, o) => {
847
+ let a = document.createElement("img"), u = new AbortController(), c = u.signal;
848
+ return a.cancel = () => {
849
+ u.abort();
850
+ }, t || (i2.getHeader().then((d) => {
851
+ d.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.") : d.tileType === 2 ? r = "image/png" : d.tileType === 3 ? r = "image/jpeg" : d.tileType === 4 ? r = "image/webp" : d.tileType === 5 && (r = "image/avif");
852
+ }), t = true), i2.getZxy(s.z, s.x, s.y, c).then((d) => {
853
+ if (d) {
854
+ let h = new Blob([d.data], { type: r }), p = window.URL.createObjectURL(h);
855
+ a.src = p, a.cancel = void 0, o(void 0, a);
856
+ }
857
+ }).catch((d) => {
858
+ if (d.name !== "AbortError") throw d;
859
+ }), a;
860
+ }, "createTile"), _removeTile: l(function(s) {
861
+ let o = this._tiles[s];
862
+ o && (o.el.cancel && o.el.cancel(), o.el.width = 0, o.el.height = 0, o.el.deleted = true, L.DomUtil.remove(o.el), delete this._tiles[s], this.fire("tileunload", { tile: o.el, coords: this._keyToTileCoords(s) }));
863
+ }, "_removeTile") });
864
+ return new n(e);
865
+ }, "leafletRasterLayer");
866
+ var j = l((i2) => (e, t) => {
867
+ if (t instanceof AbortController) return i2(e, t);
868
+ let r = new AbortController();
869
+ return i2(e, r).then((n) => t(void 0, n.data, n.cacheControl || "", n.expires || ""), (n) => t(n)).catch((n) => t(n)), { cancel: l(() => r.abort(), "cancel") };
870
+ }, "v3compat");
871
+ var T = class T2 {
872
+ constructor(e) {
873
+ this.tilev4 = l((e2, t) => m(this, null, function* () {
874
+ if (e2.type === "json") {
875
+ let p = e2.url.substr(10), y = this.tiles.get(p);
876
+ if (y || (y = new x(p), this.tiles.set(p, y)), this.metadata) return { data: yield y.getTileJson(e2.url) };
877
+ let f = yield y.getHeader();
878
+ return (f.minLon >= f.maxLon || f.minLat >= f.maxLat) && console.error(`Bounds of PMTiles archive ${f.minLon},${f.minLat},${f.maxLon},${f.maxLat} are not valid.`), { data: { tiles: [`${e2.url}/{z}/{x}/{y}`], minzoom: f.minZoom, maxzoom: f.maxZoom, bounds: [f.minLon, f.minLat, f.maxLon, f.maxLat] } };
879
+ }
880
+ let r = new RegExp(/pmtiles:\/\/(.+)\/(\d+)\/(\d+)\/(\d+)/), n = e2.url.match(r);
881
+ if (!n) throw new Error("Invalid PMTiles protocol URL");
882
+ let s = n[1], o = this.tiles.get(s);
883
+ o || (o = new x(s), this.tiles.set(s, o));
884
+ let a = n[2], u = n[3], c = n[4], d = yield o.getHeader(), h = yield o == null ? void 0 : o.getZxy(+a, +u, +c, t.signal);
885
+ if (h) return { data: new Uint8Array(h.data), cacheControl: h.cacheControl, expires: h.expires };
886
+ if (d.tileType === 1) {
887
+ if (this.errorOnMissingTile) throw new Error("Tile not found.");
888
+ return { data: new Uint8Array() };
889
+ }
890
+ return { data: null };
891
+ }), "tilev4");
892
+ this.tile = j(this.tilev4);
893
+ this.tiles = /* @__PURE__ */ new Map(), this.metadata = (e == null ? void 0 : e.metadata) || false, this.errorOnMissingTile = (e == null ? void 0 : e.errorOnMissingTile) || false;
894
+ }
895
+ add(e) {
896
+ this.tiles.set(e.source.getKey(), e);
897
+ }
898
+ get(e) {
899
+ return this.tiles.get(e);
900
+ }
901
+ };
902
+ l(T, "Protocol");
903
+ function w(i2, e) {
904
+ return (e >>> 0) * 4294967296 + (i2 >>> 0);
905
+ }
906
+ l(w, "toNum");
907
+ function F(i2, e) {
908
+ let t = e.buf, r = t[e.pos++], n = (r & 112) >> 4;
909
+ if (r < 128 || (r = t[e.pos++], n |= (r & 127) << 3, r < 128) || (r = t[e.pos++], n |= (r & 127) << 10, r < 128) || (r = t[e.pos++], n |= (r & 127) << 17, r < 128) || (r = t[e.pos++], n |= (r & 127) << 24, r < 128) || (r = t[e.pos++], n |= (r & 1) << 31, r < 128)) return w(i2, n);
910
+ throw new Error("Expected varint not more than 10 bytes");
911
+ }
912
+ l(F, "readVarintRemainder");
913
+ function v(i2) {
914
+ let e = i2.buf, t = e[i2.pos++], r = t & 127;
915
+ return t < 128 || (t = e[i2.pos++], r |= (t & 127) << 7, t < 128) || (t = e[i2.pos++], r |= (t & 127) << 14, t < 128) || (t = e[i2.pos++], r |= (t & 127) << 21, t < 128) ? r : (t = e[i2.pos], r |= (t & 15) << 28, F(r, i2));
916
+ }
917
+ l(v, "readVarint");
918
+ function k(i2, e, t, r) {
919
+ if (r === 0) {
920
+ t === 1 && (e[0] = i2 - 1 - e[0], e[1] = i2 - 1 - e[1]);
921
+ let n = e[0];
922
+ e[0] = e[1], e[1] = n;
923
+ }
924
+ }
925
+ l(k, "rotate");
926
+ function N(i2, e) {
927
+ let t = b(2, i2), r = e, n = e, s = e, o = [0, 0], a = 1;
928
+ for (; a < t; ) r = 1 & s / 2, n = 1 & (s ^ r), k(a, o, r, n), o[0] += a * r, o[1] += a * n, s = s / 4, a *= 2;
929
+ return [i2, o[0], o[1]];
930
+ }
931
+ l(N, "idOnLevel");
932
+ var q = [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];
933
+ function G(i2, e, t) {
934
+ if (i2 > 26) throw new Error("Tile zoom level exceeds max safe number limit (26)");
935
+ if (e > b(2, i2) - 1 || t > b(2, i2) - 1) throw new Error("tile x/y outside zoom level bounds");
936
+ let r = q[i2], n = b(2, i2), s = 0, o = 0, a = 0, u = [e, t], c = n / 2;
937
+ for (; c > 0; ) s = (u[0] & c) > 0 ? 1 : 0, o = (u[1] & c) > 0 ? 1 : 0, a += c * c * (3 * s ^ o), k(c, u, s, o), c = c / 2;
938
+ return r + a;
939
+ }
940
+ l(G, "zxyToTileId");
941
+ function ie(i2) {
942
+ let e = 0, t = 0;
943
+ for (let r = 0; r < 27; r++) {
944
+ let n = (1 << r) * (1 << r);
945
+ if (e + n > i2) return N(r, i2 - e);
946
+ e += n;
947
+ }
948
+ throw new Error("Tile zoom level exceeds max safe number limit (26)");
949
+ }
950
+ l(ie, "tileIdToZxy");
951
+ var J = ((s) => (s[s.Unknown = 0] = "Unknown", s[s.None = 1] = "None", s[s.Gzip = 2] = "Gzip", s[s.Brotli = 3] = "Brotli", s[s.Zstd = 4] = "Zstd", s))(J || {});
952
+ function D(i2, e) {
953
+ return m(this, null, function* () {
954
+ if (e === 1 || e === 0) return i2;
955
+ if (e === 2) {
956
+ if (typeof globalThis.DecompressionStream == "undefined") return decompressSync(new Uint8Array(i2));
957
+ let t = new Response(i2).body;
958
+ if (!t) throw new Error("Failed to read response stream");
959
+ let r = t.pipeThrough(new globalThis.DecompressionStream("gzip"));
960
+ return new Response(r).arrayBuffer();
961
+ }
962
+ throw new Error("Compression method not supported");
963
+ });
964
+ }
965
+ l(D, "defaultDecompress");
966
+ var O = ((o) => (o[o.Unknown = 0] = "Unknown", o[o.Mvt = 1] = "Mvt", o[o.Png = 2] = "Png", o[o.Jpeg = 3] = "Jpeg", o[o.Webp = 4] = "Webp", o[o.Avif = 5] = "Avif", o))(O || {});
967
+ function _(i2) {
968
+ return i2 === 1 ? ".mvt" : i2 === 2 ? ".png" : i2 === 3 ? ".jpg" : i2 === 4 ? ".webp" : i2 === 5 ? ".avif" : "";
969
+ }
970
+ l(_, "tileTypeExt");
971
+ var Y = 127;
972
+ function Q(i2, e) {
973
+ let t = 0, r = i2.length - 1;
974
+ for (; t <= r; ) {
975
+ let n = r + t >> 1, s = e - i2[n].tileId;
976
+ if (s > 0) t = n + 1;
977
+ else if (s < 0) r = n - 1;
978
+ else return i2[n];
979
+ }
980
+ return r >= 0 && (i2[r].runLength === 0 || e - i2[r].tileId < i2[r].runLength) ? i2[r] : null;
981
+ }
982
+ l(Q, "findTile");
983
+ var A = class A2 {
984
+ constructor(e) {
985
+ this.file = e;
986
+ }
987
+ getKey() {
988
+ return this.file.name;
989
+ }
990
+ getBytes(e, t) {
991
+ return m(this, null, function* () {
992
+ return { data: yield this.file.slice(e, e + t).arrayBuffer() };
993
+ });
994
+ }
995
+ };
996
+ l(A, "FileSource");
997
+ var U = class U2 {
998
+ constructor(e, t = new Headers()) {
999
+ this.url = e, this.customHeaders = t, this.mustReload = false;
1000
+ let r = "";
1001
+ "navigator" in globalThis && (r = globalThis.navigator.userAgent || "");
1002
+ let n = r.indexOf("Windows") > -1, s = /Chrome|Chromium|Edg|OPR|Brave/.test(r);
1003
+ this.chromeWindowsNoCache = false, n && s && (this.chromeWindowsNoCache = true);
1004
+ }
1005
+ getKey() {
1006
+ return this.url;
1007
+ }
1008
+ setHeaders(e) {
1009
+ this.customHeaders = e;
1010
+ }
1011
+ getBytes(e, t, r, n) {
1012
+ return m(this, null, function* () {
1013
+ let s, o;
1014
+ r ? o = r : (s = new AbortController(), o = s.signal);
1015
+ let a = new Headers(this.customHeaders);
1016
+ a.set("range", `bytes=${e}-${e + t - 1}`);
1017
+ let u;
1018
+ this.mustReload ? u = "reload" : this.chromeWindowsNoCache && (u = "no-store");
1019
+ let c = yield fetch(this.url, { signal: o, cache: u, headers: a });
1020
+ if (e === 0 && c.status === 416) {
1021
+ let y = c.headers.get("Content-Range");
1022
+ if (!y || !y.startsWith("bytes */")) throw new Error("Missing content-length on 416 response");
1023
+ let f = +y.substr(8);
1024
+ c = yield fetch(this.url, { signal: o, cache: "reload", headers: { range: `bytes=0-${f - 1}` } });
1025
+ }
1026
+ let d = c.headers.get("Etag");
1027
+ if (d != null && d.startsWith("W/") && (d = null), c.status === 416 || n && d && d !== n) throw this.mustReload = true, new E(`Server returned non-matching ETag ${n} after one retry. Check browser extensions and servers for issues that may affect correct ETag headers.`);
1028
+ if (c.status >= 300) throw new Error(`Bad response code: ${c.status}`);
1029
+ let h = c.headers.get("Content-Length");
1030
+ if (c.status === 200 && (!h || +h > t)) throw s && s.abort(), new Error("Server returned no content-length header or content-length exceeding request. Check that your storage backend supports HTTP Byte Serving.");
1031
+ return { data: yield c.arrayBuffer(), etag: d || void 0, cacheControl: c.headers.get("Cache-Control") || void 0, expires: c.headers.get("Expires") || void 0 };
1032
+ });
1033
+ }
1034
+ };
1035
+ l(U, "FetchSource");
1036
+ var C = U;
1037
+ function g(i2, e) {
1038
+ let t = i2.getUint32(e + 4, true), r = i2.getUint32(e + 0, true);
1039
+ return t * b(2, 32) + r;
1040
+ }
1041
+ l(g, "getUint64");
1042
+ function X(i2, e) {
1043
+ let t = new DataView(i2), r = t.getUint8(7);
1044
+ if (r > 3) throw new Error(`Archive is spec version ${r} but this library supports up to spec version 3`);
1045
+ return { specVersion: r, rootDirectoryOffset: g(t, 8), rootDirectoryLength: g(t, 16), jsonMetadataOffset: g(t, 24), jsonMetadataLength: g(t, 32), leafDirectoryOffset: g(t, 40), leafDirectoryLength: g(t, 48), tileDataOffset: g(t, 56), tileDataLength: g(t, 64), numAddressedTiles: g(t, 72), numTileEntries: g(t, 80), numTileContents: g(t, 88), clustered: t.getUint8(96) === 1, internalCompression: t.getUint8(97), tileCompression: t.getUint8(98), tileType: t.getUint8(99), minZoom: t.getUint8(100), maxZoom: t.getUint8(101), minLon: t.getInt32(102, true) / 1e7, minLat: t.getInt32(106, true) / 1e7, maxLon: t.getInt32(110, true) / 1e7, maxLat: t.getInt32(114, true) / 1e7, centerZoom: t.getUint8(118), centerLon: t.getInt32(119, true) / 1e7, centerLat: t.getInt32(123, true) / 1e7, etag: e };
1046
+ }
1047
+ l(X, "bytesToHeader");
1048
+ function Z(i2) {
1049
+ let e = { buf: new Uint8Array(i2), pos: 0 }, t = v(e), r = [], n = 0;
1050
+ for (let s = 0; s < t; s++) {
1051
+ let o = v(e);
1052
+ r.push({ tileId: n + o, offset: 0, length: 0, runLength: 1 }), n += o;
1053
+ }
1054
+ for (let s = 0; s < t; s++) r[s].runLength = v(e);
1055
+ for (let s = 0; s < t; s++) r[s].length = v(e);
1056
+ for (let s = 0; s < t; s++) {
1057
+ let o = v(e);
1058
+ o === 0 && s > 0 ? r[s].offset = r[s - 1].offset + r[s - 1].length : r[s].offset = o - 1;
1059
+ }
1060
+ return r;
1061
+ }
1062
+ l(Z, "deserializeIndex");
1063
+ var R = class R2 extends Error {
1064
+ };
1065
+ l(R, "EtagMismatch");
1066
+ var E = R;
1067
+ function K(i2, e) {
1068
+ return m(this, null, function* () {
1069
+ let t = yield i2.getBytes(0, 16384);
1070
+ if (new DataView(t.data).getUint16(0, true) !== 19792) throw new Error("Wrong magic number for PMTiles archive");
1071
+ let n = t.data.slice(0, Y), s = X(n, t.etag), o = t.data.slice(s.rootDirectoryOffset, s.rootDirectoryOffset + s.rootDirectoryLength), a = `${i2.getKey()}|${s.etag || ""}|${s.rootDirectoryOffset}|${s.rootDirectoryLength}`, u = Z(yield e(o, s.internalCompression));
1072
+ return [s, [a, u.length, u]];
1073
+ });
1074
+ }
1075
+ l(K, "getHeaderAndRoot");
1076
+ function I(i2, e, t, r, n) {
1077
+ return m(this, null, function* () {
1078
+ let s = yield i2.getBytes(t, r, void 0, n.etag), o = yield e(s.data, n.internalCompression), a = Z(o);
1079
+ if (a.length === 0) throw new Error("Empty directory is invalid");
1080
+ return a;
1081
+ });
1082
+ }
1083
+ l(I, "getDirectory");
1084
+ var H = class H2 {
1085
+ constructor(e = 100, t = true, r = D) {
1086
+ this.cache = /* @__PURE__ */ new Map(), this.maxCacheEntries = e, this.counter = 1, this.decompress = r;
1087
+ }
1088
+ getHeader(e) {
1089
+ return m(this, null, function* () {
1090
+ let t = e.getKey(), r = this.cache.get(t);
1091
+ if (r) return r.lastUsed = this.counter++, r.data;
1092
+ let n = yield K(e, this.decompress);
1093
+ 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];
1094
+ });
1095
+ }
1096
+ getDirectory(e, t, r, n) {
1097
+ return m(this, null, function* () {
1098
+ let s = `${e.getKey()}|${n.etag || ""}|${t}|${r}`, o = this.cache.get(s);
1099
+ if (o) return o.lastUsed = this.counter++, o.data;
1100
+ let a = yield I(e, this.decompress, t, r, n);
1101
+ return this.cache.set(s, { lastUsed: this.counter++, data: a }), this.prune(), a;
1102
+ });
1103
+ }
1104
+ prune() {
1105
+ if (this.cache.size > this.maxCacheEntries) {
1106
+ let e = 1 / 0, t;
1107
+ this.cache.forEach((r, n) => {
1108
+ r.lastUsed < e && (e = r.lastUsed, t = n);
1109
+ }), t && this.cache.delete(t);
1110
+ }
1111
+ }
1112
+ invalidate(e) {
1113
+ return m(this, null, function* () {
1114
+ this.cache.delete(e.getKey());
1115
+ });
1116
+ }
1117
+ };
1118
+ l(H, "ResolvedValueCache");
1119
+ var M = class M2 {
1120
+ constructor(e = 100, t = true, r = D) {
1121
+ this.cache = /* @__PURE__ */ new Map(), this.invalidations = /* @__PURE__ */ new Map(), this.maxCacheEntries = e, this.counter = 1, this.decompress = r;
1122
+ }
1123
+ getHeader(e) {
1124
+ return m(this, null, function* () {
1125
+ let t = e.getKey(), r = this.cache.get(t);
1126
+ if (r) return r.lastUsed = this.counter++, yield r.data;
1127
+ let n = new Promise((s, o) => {
1128
+ K(e, this.decompress).then((a) => {
1129
+ a[1] && this.cache.set(a[1][0], { lastUsed: this.counter++, data: Promise.resolve(a[1][2]) }), s(a[0]), this.prune();
1130
+ }).catch((a) => {
1131
+ o(a);
1132
+ });
1133
+ });
1134
+ return this.cache.set(t, { lastUsed: this.counter++, data: n }), n;
1135
+ });
1136
+ }
1137
+ getDirectory(e, t, r, n) {
1138
+ return m(this, null, function* () {
1139
+ let s = `${e.getKey()}|${n.etag || ""}|${t}|${r}`, o = this.cache.get(s);
1140
+ if (o) return o.lastUsed = this.counter++, yield o.data;
1141
+ let a = new Promise((u, c) => {
1142
+ I(e, this.decompress, t, r, n).then((d) => {
1143
+ u(d), this.prune();
1144
+ }).catch((d) => {
1145
+ c(d);
1146
+ });
1147
+ });
1148
+ return this.cache.set(s, { lastUsed: this.counter++, data: a }), a;
1149
+ });
1150
+ }
1151
+ prune() {
1152
+ if (this.cache.size >= this.maxCacheEntries) {
1153
+ let e = 1 / 0, t;
1154
+ this.cache.forEach((r, n) => {
1155
+ r.lastUsed < e && (e = r.lastUsed, t = n);
1156
+ }), t && this.cache.delete(t);
1157
+ }
1158
+ }
1159
+ invalidate(e) {
1160
+ return m(this, null, function* () {
1161
+ let t = e.getKey();
1162
+ if (this.invalidations.get(t)) return yield this.invalidations.get(t);
1163
+ this.cache.delete(e.getKey());
1164
+ let r = new Promise((n, s) => {
1165
+ this.getHeader(e).then((o) => {
1166
+ n(), this.invalidations.delete(t);
1167
+ }).catch((o) => {
1168
+ s(o);
1169
+ });
1170
+ });
1171
+ this.invalidations.set(t, r);
1172
+ });
1173
+ }
1174
+ };
1175
+ l(M, "SharedPromiseCache");
1176
+ var P = M;
1177
+ var B = class B2 {
1178
+ constructor(e, t, r) {
1179
+ typeof e == "string" ? this.source = new C(e) : this.source = e, r ? this.decompress = r : this.decompress = D, t ? this.cache = t : this.cache = new P();
1180
+ }
1181
+ getHeader() {
1182
+ return m(this, null, function* () {
1183
+ return yield this.cache.getHeader(this.source);
1184
+ });
1185
+ }
1186
+ getZxyAttempt(e, t, r, n) {
1187
+ return m(this, null, function* () {
1188
+ let s = G(e, t, r), o = yield this.cache.getHeader(this.source);
1189
+ if (e < o.minZoom || e > o.maxZoom) return;
1190
+ let a = o.rootDirectoryOffset, u = o.rootDirectoryLength;
1191
+ for (let c = 0; c <= 3; c++) {
1192
+ let d = yield this.cache.getDirectory(this.source, a, u, o), h = Q(d, s);
1193
+ if (h) {
1194
+ if (h.runLength > 0) {
1195
+ let p = yield this.source.getBytes(o.tileDataOffset + h.offset, h.length, n, o.etag);
1196
+ return { data: yield this.decompress(p.data, o.tileCompression), cacheControl: p.cacheControl, expires: p.expires };
1197
+ }
1198
+ a = o.leafDirectoryOffset + h.offset, u = h.length;
1199
+ } else return;
1200
+ }
1201
+ throw new Error("Maximum directory depth exceeded");
1202
+ });
1203
+ }
1204
+ getZxy(e, t, r, n) {
1205
+ return m(this, null, function* () {
1206
+ try {
1207
+ return yield this.getZxyAttempt(e, t, r, n);
1208
+ } catch (s) {
1209
+ if (s instanceof E) return this.cache.invalidate(this.source), yield this.getZxyAttempt(e, t, r, n);
1210
+ throw s;
1211
+ }
1212
+ });
1213
+ }
1214
+ getMetadataAttempt() {
1215
+ return m(this, null, function* () {
1216
+ let 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");
1217
+ return JSON.parse(n.decode(r));
1218
+ });
1219
+ }
1220
+ getMetadata() {
1221
+ return m(this, null, function* () {
1222
+ try {
1223
+ return yield this.getMetadataAttempt();
1224
+ } catch (e) {
1225
+ if (e instanceof E) return this.cache.invalidate(this.source), yield this.getMetadataAttempt();
1226
+ throw e;
1227
+ }
1228
+ });
1229
+ }
1230
+ getTileJson(e) {
1231
+ return m(this, null, function* () {
1232
+ let t = yield this.getHeader(), r = yield this.getMetadata(), n = _(t.tileType);
1233
+ return { tilejson: "3.0.0", scheme: "xyz", tiles: [`${e}/{z}/{x}/{y}${n}`], 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 };
1234
+ });
1235
+ }
1236
+ };
1237
+ l(B, "PMTiles");
1238
+ var x = B;
1239
+ function Point(x22, y) {
1240
+ this.x = x22;
1241
+ this.y = y;
1242
+ }
1243
+ Point.prototype = {
1244
+ /**
1245
+ * Clone this point, returning a new point that can be modified
1246
+ * without affecting the old one.
1247
+ * @return {Point} the clone
1248
+ */
1249
+ clone() {
1250
+ return new Point(this.x, this.y);
1251
+ },
1252
+ /**
1253
+ * Add this point's x & y coordinates to another point,
1254
+ * yielding a new point.
1255
+ * @param {Point} p the other point
1256
+ * @return {Point} output point
1257
+ */
1258
+ add(p) {
1259
+ return this.clone()._add(p);
1260
+ },
1261
+ /**
1262
+ * Subtract this point's x & y coordinates to from point,
1263
+ * yielding a new point.
1264
+ * @param {Point} p the other point
1265
+ * @return {Point} output point
1266
+ */
1267
+ sub(p) {
1268
+ return this.clone()._sub(p);
1269
+ },
1270
+ /**
1271
+ * Multiply this point's x & y coordinates by point,
1272
+ * yielding a new point.
1273
+ * @param {Point} p the other point
1274
+ * @return {Point} output point
1275
+ */
1276
+ multByPoint(p) {
1277
+ return this.clone()._multByPoint(p);
1278
+ },
1279
+ /**
1280
+ * Divide this point's x & y coordinates by point,
1281
+ * yielding a new point.
1282
+ * @param {Point} p the other point
1283
+ * @return {Point} output point
1284
+ */
1285
+ divByPoint(p) {
1286
+ return this.clone()._divByPoint(p);
1287
+ },
1288
+ /**
1289
+ * Multiply this point's x & y coordinates by a factor,
1290
+ * yielding a new point.
1291
+ * @param {number} k factor
1292
+ * @return {Point} output point
1293
+ */
1294
+ mult(k2) {
1295
+ return this.clone()._mult(k2);
1296
+ },
1297
+ /**
1298
+ * Divide this point's x & y coordinates by a factor,
1299
+ * yielding a new point.
1300
+ * @param {number} k factor
1301
+ * @return {Point} output point
1302
+ */
1303
+ div(k2) {
1304
+ return this.clone()._div(k2);
1305
+ },
1306
+ /**
1307
+ * Rotate this point around the 0, 0 origin by an angle a,
1308
+ * given in radians
1309
+ * @param {number} a angle to rotate around, in radians
1310
+ * @return {Point} output point
1311
+ */
1312
+ rotate(a) {
1313
+ return this.clone()._rotate(a);
1314
+ },
1315
+ /**
1316
+ * Rotate this point around p point by an angle a,
1317
+ * given in radians
1318
+ * @param {number} a angle to rotate around, in radians
1319
+ * @param {Point} p Point to rotate around
1320
+ * @return {Point} output point
1321
+ */
1322
+ rotateAround(a, p) {
1323
+ return this.clone()._rotateAround(a, p);
1324
+ },
1325
+ /**
1326
+ * Multiply this point by a 4x1 transformation matrix
1327
+ * @param {[number, number, number, number]} m transformation matrix
1328
+ * @return {Point} output point
1329
+ */
1330
+ matMult(m2) {
1331
+ return this.clone()._matMult(m2);
1332
+ },
1333
+ /**
1334
+ * Calculate this point but as a unit vector from 0, 0, meaning
1335
+ * that the distance from the resulting point to the 0, 0
1336
+ * coordinate will be equal to 1 and the angle from the resulting
1337
+ * point to the 0, 0 coordinate will be the same as before.
1338
+ * @return {Point} unit vector point
1339
+ */
1340
+ unit() {
1341
+ return this.clone()._unit();
1342
+ },
1343
+ /**
1344
+ * Compute a perpendicular point, where the new y coordinate
1345
+ * is the old x coordinate and the new x coordinate is the old y
1346
+ * coordinate multiplied by -1
1347
+ * @return {Point} perpendicular point
1348
+ */
1349
+ perp() {
1350
+ return this.clone()._perp();
1351
+ },
1352
+ /**
1353
+ * Return a version of this point with the x & y coordinates
1354
+ * rounded to integers.
1355
+ * @return {Point} rounded point
1356
+ */
1357
+ round() {
1358
+ return this.clone()._round();
1359
+ },
1360
+ /**
1361
+ * Return the magnitude of this point: this is the Euclidean
1362
+ * distance from the 0, 0 coordinate to this point's x and y
1363
+ * coordinates.
1364
+ * @return {number} magnitude
1365
+ */
1366
+ mag() {
1367
+ return Math.sqrt(this.x * this.x + this.y * this.y);
1368
+ },
1369
+ /**
1370
+ * Judge whether this point is equal to another point, returning
1371
+ * true or false.
1372
+ * @param {Point} other the other point
1373
+ * @return {boolean} whether the points are equal
1374
+ */
1375
+ equals(other) {
1376
+ return this.x === other.x && this.y === other.y;
1377
+ },
1378
+ /**
1379
+ * Calculate the distance from this point to another point
1380
+ * @param {Point} p the other point
1381
+ * @return {number} distance
1382
+ */
1383
+ dist(p) {
1384
+ return Math.sqrt(this.distSqr(p));
1385
+ },
1386
+ /**
1387
+ * Calculate the distance from this point to another point,
1388
+ * without the square root step. Useful if you're comparing
1389
+ * relative distances.
1390
+ * @param {Point} p the other point
1391
+ * @return {number} distance
1392
+ */
1393
+ distSqr(p) {
1394
+ const dx = p.x - this.x, dy = p.y - this.y;
1395
+ return dx * dx + dy * dy;
1396
+ },
1397
+ /**
1398
+ * Get the angle from the 0, 0 coordinate to this point, in radians
1399
+ * coordinates.
1400
+ * @return {number} angle
1401
+ */
1402
+ angle() {
1403
+ return Math.atan2(this.y, this.x);
1404
+ },
1405
+ /**
1406
+ * Get the angle from this point to another point, in radians
1407
+ * @param {Point} b the other point
1408
+ * @return {number} angle
1409
+ */
1410
+ angleTo(b2) {
1411
+ return Math.atan2(this.y - b2.y, this.x - b2.x);
1412
+ },
1413
+ /**
1414
+ * Get the angle between this point and another point, in radians
1415
+ * @param {Point} b the other point
1416
+ * @return {number} angle
1417
+ */
1418
+ angleWith(b2) {
1419
+ return this.angleWithSep(b2.x, b2.y);
1420
+ },
1421
+ /**
1422
+ * Find the angle of the two vectors, solving the formula for
1423
+ * the cross product a x b = |a||b|sin(θ) for θ.
1424
+ * @param {number} x the x-coordinate
1425
+ * @param {number} y the y-coordinate
1426
+ * @return {number} the angle in radians
1427
+ */
1428
+ angleWithSep(x22, y) {
1429
+ return Math.atan2(
1430
+ this.x * y - this.y * x22,
1431
+ this.x * x22 + this.y * y
1432
+ );
1433
+ },
1434
+ /** @param {[number, number, number, number]} m */
1435
+ _matMult(m2) {
1436
+ const x22 = m2[0] * this.x + m2[1] * this.y, y = m2[2] * this.x + m2[3] * this.y;
1437
+ this.x = x22;
1438
+ this.y = y;
1439
+ return this;
1440
+ },
1441
+ /** @param {Point} p */
1442
+ _add(p) {
1443
+ this.x += p.x;
1444
+ this.y += p.y;
1445
+ return this;
1446
+ },
1447
+ /** @param {Point} p */
1448
+ _sub(p) {
1449
+ this.x -= p.x;
1450
+ this.y -= p.y;
1451
+ return this;
1452
+ },
1453
+ /** @param {number} k */
1454
+ _mult(k2) {
1455
+ this.x *= k2;
1456
+ this.y *= k2;
1457
+ return this;
1458
+ },
1459
+ /** @param {number} k */
1460
+ _div(k2) {
1461
+ this.x /= k2;
1462
+ this.y /= k2;
1463
+ return this;
1464
+ },
1465
+ /** @param {Point} p */
1466
+ _multByPoint(p) {
1467
+ this.x *= p.x;
1468
+ this.y *= p.y;
1469
+ return this;
1470
+ },
1471
+ /** @param {Point} p */
1472
+ _divByPoint(p) {
1473
+ this.x /= p.x;
1474
+ this.y /= p.y;
1475
+ return this;
1476
+ },
1477
+ _unit() {
1478
+ this._div(this.mag());
1479
+ return this;
1480
+ },
1481
+ _perp() {
1482
+ const y = this.y;
1483
+ this.y = this.x;
1484
+ this.x = -y;
1485
+ return this;
1486
+ },
1487
+ /** @param {number} angle */
1488
+ _rotate(angle) {
1489
+ const cos = Math.cos(angle), sin = Math.sin(angle), x22 = cos * this.x - sin * this.y, y = sin * this.x + cos * this.y;
1490
+ this.x = x22;
1491
+ this.y = y;
1492
+ return this;
1493
+ },
1494
+ /**
1495
+ * @param {number} angle
1496
+ * @param {Point} p
1497
+ */
1498
+ _rotateAround(angle, p) {
1499
+ const cos = Math.cos(angle), sin = Math.sin(angle), x22 = p.x + cos * (this.x - p.x) - sin * (this.y - p.y), y = p.y + sin * (this.x - p.x) + cos * (this.y - p.y);
1500
+ this.x = x22;
1501
+ this.y = y;
1502
+ return this;
1503
+ },
1504
+ _round() {
1505
+ this.x = Math.round(this.x);
1506
+ this.y = Math.round(this.y);
1507
+ return this;
1508
+ },
1509
+ constructor: Point
1510
+ };
1511
+ Point.convert = function(p) {
1512
+ if (p instanceof Point) {
1513
+ return (
1514
+ /** @type {Point} */
1515
+ p
1516
+ );
1517
+ }
1518
+ if (Array.isArray(p)) {
1519
+ return new Point(+p[0], +p[1]);
1520
+ }
1521
+ if (p.x !== void 0 && p.y !== void 0) {
1522
+ return new Point(+p.x, +p.y);
1523
+ }
1524
+ throw new Error("Expected [x, y] or {x, y} point format");
1525
+ };
1526
+ var VectorTileFeature = class {
1527
+ /**
1528
+ * @param {Pbf} pbf
1529
+ * @param {number} end
1530
+ * @param {number} extent
1531
+ * @param {string[]} keys
1532
+ * @param {(number | string | boolean)[]} values
1533
+ */
1534
+ constructor(pbf, end, extent, keys, values) {
1535
+ this.properties = {};
1536
+ this.extent = extent;
1537
+ this.type = 0;
1538
+ this.id = void 0;
1539
+ this._pbf = pbf;
1540
+ this._geometry = -1;
1541
+ this._keys = keys;
1542
+ this._values = values;
1543
+ pbf.readFields(readFeature, this, end);
1544
+ }
1545
+ loadGeometry() {
1546
+ const pbf = this._pbf;
1547
+ pbf.pos = this._geometry;
1548
+ const end = pbf.readVarint() + pbf.pos;
1549
+ const lines = [];
1550
+ let line;
1551
+ let cmd = 1;
1552
+ let length = 0;
1553
+ let x22 = 0;
1554
+ let y = 0;
1555
+ while (pbf.pos < end) {
1556
+ if (length <= 0) {
1557
+ const cmdLen = pbf.readVarint();
1558
+ cmd = cmdLen & 7;
1559
+ length = cmdLen >> 3;
1560
+ }
1561
+ length--;
1562
+ if (cmd === 1 || cmd === 2) {
1563
+ x22 += pbf.readSVarint();
1564
+ y += pbf.readSVarint();
1565
+ if (cmd === 1) {
1566
+ if (line) lines.push(line);
1567
+ line = [];
1568
+ }
1569
+ if (line) line.push(new Point(x22, y));
1570
+ } else if (cmd === 7) {
1571
+ if (line) {
1572
+ line.push(line[0].clone());
1573
+ }
1574
+ } else {
1575
+ throw new Error(`unknown command ${cmd}`);
1576
+ }
1577
+ }
1578
+ if (line) lines.push(line);
1579
+ return lines;
1580
+ }
1581
+ bbox() {
1582
+ const pbf = this._pbf;
1583
+ pbf.pos = this._geometry;
1584
+ const end = pbf.readVarint() + pbf.pos;
1585
+ let cmd = 1, length = 0, x22 = 0, y = 0, x1 = Infinity, x222 = -Infinity, y1 = Infinity, y2 = -Infinity;
1586
+ while (pbf.pos < end) {
1587
+ if (length <= 0) {
1588
+ const cmdLen = pbf.readVarint();
1589
+ cmd = cmdLen & 7;
1590
+ length = cmdLen >> 3;
1591
+ }
1592
+ length--;
1593
+ if (cmd === 1 || cmd === 2) {
1594
+ x22 += pbf.readSVarint();
1595
+ y += pbf.readSVarint();
1596
+ if (x22 < x1) x1 = x22;
1597
+ if (x22 > x222) x222 = x22;
1598
+ if (y < y1) y1 = y;
1599
+ if (y > y2) y2 = y;
1600
+ } else if (cmd !== 7) {
1601
+ throw new Error(`unknown command ${cmd}`);
1602
+ }
1603
+ }
1604
+ return [x1, y1, x222, y2];
1605
+ }
1606
+ /**
1607
+ * @param {number} x
1608
+ * @param {number} y
1609
+ * @param {number} z
1610
+ * @return {Feature}
1611
+ */
1612
+ toGeoJSON(x22, y, z2) {
1613
+ const size = this.extent * Math.pow(2, z2), x0 = this.extent * x22, y0 = this.extent * y, vtCoords = this.loadGeometry();
1614
+ function projectPoint(p) {
1615
+ return [
1616
+ (p.x + x0) * 360 / size - 180,
1617
+ 360 / Math.PI * Math.atan(Math.exp((1 - (p.y + y0) * 2 / size) * Math.PI)) - 90
1618
+ ];
1619
+ }
1620
+ function projectLine(line) {
1621
+ return line.map(projectPoint);
1622
+ }
1623
+ let geometry;
1624
+ if (this.type === 1) {
1625
+ const points = [];
1626
+ for (const line of vtCoords) {
1627
+ points.push(line[0]);
1628
+ }
1629
+ const coordinates = projectLine(points);
1630
+ geometry = points.length === 1 ? { type: "Point", coordinates: coordinates[0] } : { type: "MultiPoint", coordinates };
1631
+ } else if (this.type === 2) {
1632
+ const coordinates = vtCoords.map(projectLine);
1633
+ geometry = coordinates.length === 1 ? { type: "LineString", coordinates: coordinates[0] } : { type: "MultiLineString", coordinates };
1634
+ } else if (this.type === 3) {
1635
+ const polygons = classifyRings(vtCoords);
1636
+ const coordinates = [];
1637
+ for (const polygon of polygons) {
1638
+ coordinates.push(polygon.map(projectLine));
1639
+ }
1640
+ geometry = coordinates.length === 1 ? { type: "Polygon", coordinates: coordinates[0] } : { type: "MultiPolygon", coordinates };
1641
+ } else {
1642
+ throw new Error("unknown feature type");
1643
+ }
1644
+ const result = {
1645
+ type: "Feature",
1646
+ geometry,
1647
+ properties: this.properties
1648
+ };
1649
+ if (this.id != null) {
1650
+ result.id = this.id;
1651
+ }
1652
+ return result;
1653
+ }
1654
+ };
1655
+ VectorTileFeature.types = ["Unknown", "Point", "LineString", "Polygon"];
1656
+ function readFeature(tag, feature, pbf) {
1657
+ if (tag === 1) feature.id = pbf.readVarint();
1658
+ else if (tag === 2) readTag(pbf, feature);
1659
+ else if (tag === 3) feature.type = /** @type {0 | 1 | 2 | 3} */
1660
+ pbf.readVarint();
1661
+ else if (tag === 4) feature._geometry = pbf.pos;
1662
+ }
1663
+ function readTag(pbf, feature) {
1664
+ const end = pbf.readVarint() + pbf.pos;
1665
+ while (pbf.pos < end) {
1666
+ const key = feature._keys[pbf.readVarint()];
1667
+ const value = feature._values[pbf.readVarint()];
1668
+ feature.properties[key] = value;
1669
+ }
1670
+ }
1671
+ function classifyRings(rings) {
1672
+ const len = rings.length;
1673
+ if (len <= 1) return [rings];
1674
+ const polygons = [];
1675
+ let polygon, ccw;
1676
+ for (let i2 = 0; i2 < len; i2++) {
1677
+ const area = signedArea(rings[i2]);
1678
+ if (area === 0) continue;
1679
+ if (ccw === void 0) ccw = area < 0;
1680
+ if (ccw === area < 0) {
1681
+ if (polygon) polygons.push(polygon);
1682
+ polygon = [rings[i2]];
1683
+ } else if (polygon) {
1684
+ polygon.push(rings[i2]);
1685
+ }
1686
+ }
1687
+ if (polygon) polygons.push(polygon);
1688
+ return polygons;
1689
+ }
1690
+ function signedArea(ring) {
1691
+ let sum = 0;
1692
+ for (let i2 = 0, len = ring.length, j2 = len - 1, p1, p2; i2 < len; j2 = i2++) {
1693
+ p1 = ring[i2];
1694
+ p2 = ring[j2];
1695
+ sum += (p2.x - p1.x) * (p1.y + p2.y);
1696
+ }
1697
+ return sum;
1698
+ }
1699
+ var VectorTileLayer = class {
1700
+ /**
1701
+ * @param {Pbf} pbf
1702
+ * @param {number} [end]
1703
+ */
1704
+ constructor(pbf, end) {
1705
+ this.version = 1;
1706
+ this.name = "";
1707
+ this.extent = 4096;
1708
+ this.length = 0;
1709
+ this._pbf = pbf;
1710
+ this._keys = [];
1711
+ this._values = [];
1712
+ this._features = [];
1713
+ pbf.readFields(readLayer, this, end);
1714
+ this.length = this._features.length;
1715
+ }
1716
+ /** return feature `i` from this layer as a `VectorTileFeature`
1717
+ * @param {number} i
1718
+ */
1719
+ feature(i2) {
1720
+ if (i2 < 0 || i2 >= this._features.length) throw new Error("feature index out of bounds");
1721
+ this._pbf.pos = this._features[i2];
1722
+ const end = this._pbf.readVarint() + this._pbf.pos;
1723
+ return new VectorTileFeature(this._pbf, end, this.extent, this._keys, this._values);
1724
+ }
1725
+ };
1726
+ function readLayer(tag, layer, pbf) {
1727
+ if (tag === 15) layer.version = pbf.readVarint();
1728
+ else if (tag === 1) layer.name = pbf.readString();
1729
+ else if (tag === 5) layer.extent = pbf.readVarint();
1730
+ else if (tag === 2) layer._features.push(pbf.pos);
1731
+ else if (tag === 3) layer._keys.push(pbf.readString());
1732
+ else if (tag === 4) layer._values.push(readValueMessage(pbf));
1733
+ }
1734
+ function readValueMessage(pbf) {
1735
+ let value = null;
1736
+ const end = pbf.readVarint() + pbf.pos;
1737
+ while (pbf.pos < end) {
1738
+ const tag = pbf.readVarint() >> 3;
1739
+ value = tag === 1 ? pbf.readString() : tag === 2 ? pbf.readFloat() : tag === 3 ? pbf.readDouble() : tag === 4 ? pbf.readVarint64() : tag === 5 ? pbf.readVarint() : tag === 6 ? pbf.readSVarint() : tag === 7 ? pbf.readBoolean() : null;
1740
+ }
1741
+ if (value == null) {
1742
+ throw new Error("unknown feature value");
1743
+ }
1744
+ return value;
1745
+ }
1746
+ var VectorTile = class {
1747
+ /**
1748
+ * @param {Pbf} pbf
1749
+ * @param {number} [end]
1750
+ */
1751
+ constructor(pbf, end) {
1752
+ this.layers = pbf.readFields(readTile, {}, end);
1753
+ }
1754
+ };
1755
+ function readTile(tag, layers, pbf) {
1756
+ if (tag === 3) {
1757
+ const layer = new VectorTileLayer(pbf, pbf.readVarint() + pbf.pos);
1758
+ if (layer.length) layers[layer.name] = layer;
1759
+ }
1760
+ }
1761
+ var SHIFT_LEFT_32 = (1 << 16) * (1 << 16);
1762
+ var SHIFT_RIGHT_32 = 1 / SHIFT_LEFT_32;
1763
+ var TEXT_DECODER_MIN_LENGTH = 12;
1764
+ var utf8TextDecoder = typeof TextDecoder === "undefined" ? null : new TextDecoder("utf-8");
1765
+ var PBF_VARINT = 0;
1766
+ var PBF_FIXED64 = 1;
1767
+ var PBF_BYTES = 2;
1768
+ var PBF_FIXED32 = 5;
1769
+ var Pbf = class {
1770
+ /**
1771
+ * @param {Uint8Array | ArrayBuffer} [buf]
1772
+ */
1773
+ constructor(buf = new Uint8Array(16)) {
1774
+ this.buf = ArrayBuffer.isView(buf) ? buf : new Uint8Array(buf);
1775
+ this.dataView = new DataView(this.buf.buffer);
1776
+ this.pos = 0;
1777
+ this.type = 0;
1778
+ this.length = this.buf.length;
1779
+ }
1780
+ // === READING =================================================================
1781
+ /**
1782
+ * @template T
1783
+ * @param {(tag: number, result: T, pbf: Pbf) => void} readField
1784
+ * @param {T} result
1785
+ * @param {number} [end]
1786
+ */
1787
+ readFields(readField, result, end = this.length) {
1788
+ while (this.pos < end) {
1789
+ const val = this.readVarint(), tag = val >> 3, startPos = this.pos;
1790
+ this.type = val & 7;
1791
+ readField(tag, result, this);
1792
+ if (this.pos === startPos) this.skip(val);
1793
+ }
1794
+ return result;
1795
+ }
1796
+ /**
1797
+ * @template T
1798
+ * @param {(tag: number, result: T, pbf: Pbf) => void} readField
1799
+ * @param {T} result
1800
+ */
1801
+ readMessage(readField, result) {
1802
+ return this.readFields(readField, result, this.readVarint() + this.pos);
1803
+ }
1804
+ readFixed32() {
1805
+ const val = this.dataView.getUint32(this.pos, true);
1806
+ this.pos += 4;
1807
+ return val;
1808
+ }
1809
+ readSFixed32() {
1810
+ const val = this.dataView.getInt32(this.pos, true);
1811
+ this.pos += 4;
1812
+ return val;
1813
+ }
1814
+ // 64-bit int handling is based on github.com/dpw/node-buffer-more-ints (MIT-licensed)
1815
+ readFixed64() {
1816
+ const val = this.dataView.getUint32(this.pos, true) + this.dataView.getUint32(this.pos + 4, true) * SHIFT_LEFT_32;
1817
+ this.pos += 8;
1818
+ return val;
1819
+ }
1820
+ readSFixed64() {
1821
+ const val = this.dataView.getUint32(this.pos, true) + this.dataView.getInt32(this.pos + 4, true) * SHIFT_LEFT_32;
1822
+ this.pos += 8;
1823
+ return val;
1824
+ }
1825
+ readFloat() {
1826
+ const val = this.dataView.getFloat32(this.pos, true);
1827
+ this.pos += 4;
1828
+ return val;
1829
+ }
1830
+ readDouble() {
1831
+ const val = this.dataView.getFloat64(this.pos, true);
1832
+ this.pos += 8;
1833
+ return val;
1834
+ }
1835
+ /**
1836
+ * @param {boolean} [isSigned]
1837
+ */
1838
+ readVarint(isSigned) {
1839
+ const buf = this.buf;
1840
+ let val, b2;
1841
+ b2 = buf[this.pos++];
1842
+ val = b2 & 127;
1843
+ if (b2 < 128) return val;
1844
+ b2 = buf[this.pos++];
1845
+ val |= (b2 & 127) << 7;
1846
+ if (b2 < 128) return val;
1847
+ b2 = buf[this.pos++];
1848
+ val |= (b2 & 127) << 14;
1849
+ if (b2 < 128) return val;
1850
+ b2 = buf[this.pos++];
1851
+ val |= (b2 & 127) << 21;
1852
+ if (b2 < 128) return val;
1853
+ b2 = buf[this.pos];
1854
+ val |= (b2 & 15) << 28;
1855
+ return readVarintRemainder(val, isSigned, this);
1856
+ }
1857
+ readVarint64() {
1858
+ return this.readVarint(true);
1859
+ }
1860
+ readSVarint() {
1861
+ const num = this.readVarint();
1862
+ return num % 2 === 1 ? (num + 1) / -2 : num / 2;
1863
+ }
1864
+ readBoolean() {
1865
+ return Boolean(this.readVarint());
1866
+ }
1867
+ readString() {
1868
+ const end = this.readVarint() + this.pos;
1869
+ const pos = this.pos;
1870
+ this.pos = end;
1871
+ if (end - pos >= TEXT_DECODER_MIN_LENGTH && utf8TextDecoder) {
1872
+ return utf8TextDecoder.decode(this.buf.subarray(pos, end));
1873
+ }
1874
+ return readUtf8(this.buf, pos, end);
1875
+ }
1876
+ readBytes() {
1877
+ const end = this.readVarint() + this.pos, buffer = this.buf.subarray(this.pos, end);
1878
+ this.pos = end;
1879
+ return buffer;
1880
+ }
1881
+ // verbose for performance reasons; doesn't affect gzipped size
1882
+ /**
1883
+ * @param {number[]} [arr]
1884
+ * @param {boolean} [isSigned]
1885
+ */
1886
+ readPackedVarint(arr = [], isSigned) {
1887
+ const end = this.readPackedEnd();
1888
+ while (this.pos < end) arr.push(this.readVarint(isSigned));
1889
+ return arr;
1890
+ }
1891
+ /** @param {number[]} [arr] */
1892
+ readPackedSVarint(arr = []) {
1893
+ const end = this.readPackedEnd();
1894
+ while (this.pos < end) arr.push(this.readSVarint());
1895
+ return arr;
1896
+ }
1897
+ /** @param {boolean[]} [arr] */
1898
+ readPackedBoolean(arr = []) {
1899
+ const end = this.readPackedEnd();
1900
+ while (this.pos < end) arr.push(this.readBoolean());
1901
+ return arr;
1902
+ }
1903
+ /** @param {number[]} [arr] */
1904
+ readPackedFloat(arr = []) {
1905
+ const end = this.readPackedEnd();
1906
+ while (this.pos < end) arr.push(this.readFloat());
1907
+ return arr;
1908
+ }
1909
+ /** @param {number[]} [arr] */
1910
+ readPackedDouble(arr = []) {
1911
+ const end = this.readPackedEnd();
1912
+ while (this.pos < end) arr.push(this.readDouble());
1913
+ return arr;
1914
+ }
1915
+ /** @param {number[]} [arr] */
1916
+ readPackedFixed32(arr = []) {
1917
+ const end = this.readPackedEnd();
1918
+ while (this.pos < end) arr.push(this.readFixed32());
1919
+ return arr;
1920
+ }
1921
+ /** @param {number[]} [arr] */
1922
+ readPackedSFixed32(arr = []) {
1923
+ const end = this.readPackedEnd();
1924
+ while (this.pos < end) arr.push(this.readSFixed32());
1925
+ return arr;
1926
+ }
1927
+ /** @param {number[]} [arr] */
1928
+ readPackedFixed64(arr = []) {
1929
+ const end = this.readPackedEnd();
1930
+ while (this.pos < end) arr.push(this.readFixed64());
1931
+ return arr;
1932
+ }
1933
+ /** @param {number[]} [arr] */
1934
+ readPackedSFixed64(arr = []) {
1935
+ const end = this.readPackedEnd();
1936
+ while (this.pos < end) arr.push(this.readSFixed64());
1937
+ return arr;
1938
+ }
1939
+ readPackedEnd() {
1940
+ return this.type === PBF_BYTES ? this.readVarint() + this.pos : this.pos + 1;
1941
+ }
1942
+ /** @param {number} val */
1943
+ skip(val) {
1944
+ const type = val & 7;
1945
+ if (type === PBF_VARINT) while (this.buf[this.pos++] > 127) {
1946
+ }
1947
+ else if (type === PBF_BYTES) this.pos = this.readVarint() + this.pos;
1948
+ else if (type === PBF_FIXED32) this.pos += 4;
1949
+ else if (type === PBF_FIXED64) this.pos += 8;
1950
+ else throw new Error(`Unimplemented type: ${type}`);
1951
+ }
1952
+ // === WRITING =================================================================
1953
+ /**
1954
+ * @param {number} tag
1955
+ * @param {number} type
1956
+ */
1957
+ writeTag(tag, type) {
1958
+ this.writeVarint(tag << 3 | type);
1959
+ }
1960
+ /** @param {number} min */
1961
+ realloc(min) {
1962
+ let length = this.length || 16;
1963
+ while (length < this.pos + min) length *= 2;
1964
+ if (length !== this.length) {
1965
+ const buf = new Uint8Array(length);
1966
+ buf.set(this.buf);
1967
+ this.buf = buf;
1968
+ this.dataView = new DataView(buf.buffer);
1969
+ this.length = length;
1970
+ }
1971
+ }
1972
+ finish() {
1973
+ this.length = this.pos;
1974
+ this.pos = 0;
1975
+ return this.buf.subarray(0, this.length);
1976
+ }
1977
+ /** @param {number} val */
1978
+ writeFixed32(val) {
1979
+ this.realloc(4);
1980
+ this.dataView.setInt32(this.pos, val, true);
1981
+ this.pos += 4;
1982
+ }
1983
+ /** @param {number} val */
1984
+ writeSFixed32(val) {
1985
+ this.realloc(4);
1986
+ this.dataView.setInt32(this.pos, val, true);
1987
+ this.pos += 4;
1988
+ }
1989
+ /** @param {number} val */
1990
+ writeFixed64(val) {
1991
+ this.realloc(8);
1992
+ this.dataView.setInt32(this.pos, val & -1, true);
1993
+ this.dataView.setInt32(this.pos + 4, Math.floor(val * SHIFT_RIGHT_32), true);
1994
+ this.pos += 8;
1995
+ }
1996
+ /** @param {number} val */
1997
+ writeSFixed64(val) {
1998
+ this.realloc(8);
1999
+ this.dataView.setInt32(this.pos, val & -1, true);
2000
+ this.dataView.setInt32(this.pos + 4, Math.floor(val * SHIFT_RIGHT_32), true);
2001
+ this.pos += 8;
2002
+ }
2003
+ /** @param {number} val */
2004
+ writeVarint(val) {
2005
+ val = +val || 0;
2006
+ if (val > 268435455 || val < 0) {
2007
+ writeBigVarint(val, this);
2008
+ return;
2009
+ }
2010
+ this.realloc(4);
2011
+ this.buf[this.pos++] = val & 127 | (val > 127 ? 128 : 0);
2012
+ if (val <= 127) return;
2013
+ this.buf[this.pos++] = (val >>>= 7) & 127 | (val > 127 ? 128 : 0);
2014
+ if (val <= 127) return;
2015
+ this.buf[this.pos++] = (val >>>= 7) & 127 | (val > 127 ? 128 : 0);
2016
+ if (val <= 127) return;
2017
+ this.buf[this.pos++] = val >>> 7 & 127;
2018
+ }
2019
+ /** @param {number} val */
2020
+ writeSVarint(val) {
2021
+ this.writeVarint(val < 0 ? -val * 2 - 1 : val * 2);
2022
+ }
2023
+ /** @param {boolean} val */
2024
+ writeBoolean(val) {
2025
+ this.writeVarint(+val);
2026
+ }
2027
+ /** @param {string} str */
2028
+ writeString(str) {
2029
+ str = String(str);
2030
+ this.realloc(str.length * 4);
2031
+ this.pos++;
2032
+ const startPos = this.pos;
2033
+ this.pos = writeUtf8(this.buf, str, this.pos);
2034
+ const len = this.pos - startPos;
2035
+ if (len >= 128) makeRoomForExtraLength(startPos, len, this);
2036
+ this.pos = startPos - 1;
2037
+ this.writeVarint(len);
2038
+ this.pos += len;
2039
+ }
2040
+ /** @param {number} val */
2041
+ writeFloat(val) {
2042
+ this.realloc(4);
2043
+ this.dataView.setFloat32(this.pos, val, true);
2044
+ this.pos += 4;
2045
+ }
2046
+ /** @param {number} val */
2047
+ writeDouble(val) {
2048
+ this.realloc(8);
2049
+ this.dataView.setFloat64(this.pos, val, true);
2050
+ this.pos += 8;
2051
+ }
2052
+ /** @param {Uint8Array} buffer */
2053
+ writeBytes(buffer) {
2054
+ const len = buffer.length;
2055
+ this.writeVarint(len);
2056
+ this.realloc(len);
2057
+ for (let i2 = 0; i2 < len; i2++) this.buf[this.pos++] = buffer[i2];
2058
+ }
2059
+ /**
2060
+ * @template T
2061
+ * @param {(obj: T, pbf: Pbf) => void} fn
2062
+ * @param {T} obj
2063
+ */
2064
+ writeRawMessage(fn, obj) {
2065
+ this.pos++;
2066
+ const startPos = this.pos;
2067
+ fn(obj, this);
2068
+ const len = this.pos - startPos;
2069
+ if (len >= 128) makeRoomForExtraLength(startPos, len, this);
2070
+ this.pos = startPos - 1;
2071
+ this.writeVarint(len);
2072
+ this.pos += len;
2073
+ }
2074
+ /**
2075
+ * @template T
2076
+ * @param {number} tag
2077
+ * @param {(obj: T, pbf: Pbf) => void} fn
2078
+ * @param {T} obj
2079
+ */
2080
+ writeMessage(tag, fn, obj) {
2081
+ this.writeTag(tag, PBF_BYTES);
2082
+ this.writeRawMessage(fn, obj);
2083
+ }
2084
+ /**
2085
+ * @param {number} tag
2086
+ * @param {number[]} arr
2087
+ */
2088
+ writePackedVarint(tag, arr) {
2089
+ if (arr.length) this.writeMessage(tag, writePackedVarint, arr);
2090
+ }
2091
+ /**
2092
+ * @param {number} tag
2093
+ * @param {number[]} arr
2094
+ */
2095
+ writePackedSVarint(tag, arr) {
2096
+ if (arr.length) this.writeMessage(tag, writePackedSVarint, arr);
2097
+ }
2098
+ /**
2099
+ * @param {number} tag
2100
+ * @param {boolean[]} arr
2101
+ */
2102
+ writePackedBoolean(tag, arr) {
2103
+ if (arr.length) this.writeMessage(tag, writePackedBoolean, arr);
2104
+ }
2105
+ /**
2106
+ * @param {number} tag
2107
+ * @param {number[]} arr
2108
+ */
2109
+ writePackedFloat(tag, arr) {
2110
+ if (arr.length) this.writeMessage(tag, writePackedFloat, arr);
2111
+ }
2112
+ /**
2113
+ * @param {number} tag
2114
+ * @param {number[]} arr
2115
+ */
2116
+ writePackedDouble(tag, arr) {
2117
+ if (arr.length) this.writeMessage(tag, writePackedDouble, arr);
2118
+ }
2119
+ /**
2120
+ * @param {number} tag
2121
+ * @param {number[]} arr
2122
+ */
2123
+ writePackedFixed32(tag, arr) {
2124
+ if (arr.length) this.writeMessage(tag, writePackedFixed32, arr);
2125
+ }
2126
+ /**
2127
+ * @param {number} tag
2128
+ * @param {number[]} arr
2129
+ */
2130
+ writePackedSFixed32(tag, arr) {
2131
+ if (arr.length) this.writeMessage(tag, writePackedSFixed32, arr);
2132
+ }
2133
+ /**
2134
+ * @param {number} tag
2135
+ * @param {number[]} arr
2136
+ */
2137
+ writePackedFixed64(tag, arr) {
2138
+ if (arr.length) this.writeMessage(tag, writePackedFixed64, arr);
2139
+ }
2140
+ /**
2141
+ * @param {number} tag
2142
+ * @param {number[]} arr
2143
+ */
2144
+ writePackedSFixed64(tag, arr) {
2145
+ if (arr.length) this.writeMessage(tag, writePackedSFixed64, arr);
2146
+ }
2147
+ /**
2148
+ * @param {number} tag
2149
+ * @param {Uint8Array} buffer
2150
+ */
2151
+ writeBytesField(tag, buffer) {
2152
+ this.writeTag(tag, PBF_BYTES);
2153
+ this.writeBytes(buffer);
2154
+ }
2155
+ /**
2156
+ * @param {number} tag
2157
+ * @param {number} val
2158
+ */
2159
+ writeFixed32Field(tag, val) {
2160
+ this.writeTag(tag, PBF_FIXED32);
2161
+ this.writeFixed32(val);
2162
+ }
2163
+ /**
2164
+ * @param {number} tag
2165
+ * @param {number} val
2166
+ */
2167
+ writeSFixed32Field(tag, val) {
2168
+ this.writeTag(tag, PBF_FIXED32);
2169
+ this.writeSFixed32(val);
2170
+ }
2171
+ /**
2172
+ * @param {number} tag
2173
+ * @param {number} val
2174
+ */
2175
+ writeFixed64Field(tag, val) {
2176
+ this.writeTag(tag, PBF_FIXED64);
2177
+ this.writeFixed64(val);
2178
+ }
2179
+ /**
2180
+ * @param {number} tag
2181
+ * @param {number} val
2182
+ */
2183
+ writeSFixed64Field(tag, val) {
2184
+ this.writeTag(tag, PBF_FIXED64);
2185
+ this.writeSFixed64(val);
2186
+ }
2187
+ /**
2188
+ * @param {number} tag
2189
+ * @param {number} val
2190
+ */
2191
+ writeVarintField(tag, val) {
2192
+ this.writeTag(tag, PBF_VARINT);
2193
+ this.writeVarint(val);
2194
+ }
2195
+ /**
2196
+ * @param {number} tag
2197
+ * @param {number} val
2198
+ */
2199
+ writeSVarintField(tag, val) {
2200
+ this.writeTag(tag, PBF_VARINT);
2201
+ this.writeSVarint(val);
2202
+ }
2203
+ /**
2204
+ * @param {number} tag
2205
+ * @param {string} str
2206
+ */
2207
+ writeStringField(tag, str) {
2208
+ this.writeTag(tag, PBF_BYTES);
2209
+ this.writeString(str);
2210
+ }
2211
+ /**
2212
+ * @param {number} tag
2213
+ * @param {number} val
2214
+ */
2215
+ writeFloatField(tag, val) {
2216
+ this.writeTag(tag, PBF_FIXED32);
2217
+ this.writeFloat(val);
2218
+ }
2219
+ /**
2220
+ * @param {number} tag
2221
+ * @param {number} val
2222
+ */
2223
+ writeDoubleField(tag, val) {
2224
+ this.writeTag(tag, PBF_FIXED64);
2225
+ this.writeDouble(val);
2226
+ }
2227
+ /**
2228
+ * @param {number} tag
2229
+ * @param {boolean} val
2230
+ */
2231
+ writeBooleanField(tag, val) {
2232
+ this.writeVarintField(tag, +val);
2233
+ }
2234
+ };
2235
+ function readVarintRemainder(l2, s, p) {
2236
+ const buf = p.buf;
2237
+ let h, b2;
2238
+ b2 = buf[p.pos++];
2239
+ h = (b2 & 112) >> 4;
2240
+ if (b2 < 128) return toNum(l2, h, s);
2241
+ b2 = buf[p.pos++];
2242
+ h |= (b2 & 127) << 3;
2243
+ if (b2 < 128) return toNum(l2, h, s);
2244
+ b2 = buf[p.pos++];
2245
+ h |= (b2 & 127) << 10;
2246
+ if (b2 < 128) return toNum(l2, h, s);
2247
+ b2 = buf[p.pos++];
2248
+ h |= (b2 & 127) << 17;
2249
+ if (b2 < 128) return toNum(l2, h, s);
2250
+ b2 = buf[p.pos++];
2251
+ h |= (b2 & 127) << 24;
2252
+ if (b2 < 128) return toNum(l2, h, s);
2253
+ b2 = buf[p.pos++];
2254
+ h |= (b2 & 1) << 31;
2255
+ if (b2 < 128) return toNum(l2, h, s);
2256
+ throw new Error("Expected varint not more than 10 bytes");
2257
+ }
2258
+ function toNum(low, high, isSigned) {
2259
+ return isSigned ? high * 4294967296 + (low >>> 0) : (high >>> 0) * 4294967296 + (low >>> 0);
2260
+ }
2261
+ function writeBigVarint(val, pbf) {
2262
+ let low, high;
2263
+ if (val >= 0) {
2264
+ low = val % 4294967296 | 0;
2265
+ high = val / 4294967296 | 0;
2266
+ } else {
2267
+ low = ~(-val % 4294967296);
2268
+ high = ~(-val / 4294967296);
2269
+ if (low ^ 4294967295) {
2270
+ low = low + 1 | 0;
2271
+ } else {
2272
+ low = 0;
2273
+ high = high + 1 | 0;
2274
+ }
2275
+ }
2276
+ if (val >= 18446744073709552e3 || val < -18446744073709552e3) {
2277
+ throw new Error("Given varint doesn't fit into 10 bytes");
2278
+ }
2279
+ pbf.realloc(10);
2280
+ writeBigVarintLow(low, high, pbf);
2281
+ writeBigVarintHigh(high, pbf);
2282
+ }
2283
+ function writeBigVarintLow(low, high, pbf) {
2284
+ pbf.buf[pbf.pos++] = low & 127 | 128;
2285
+ low >>>= 7;
2286
+ pbf.buf[pbf.pos++] = low & 127 | 128;
2287
+ low >>>= 7;
2288
+ pbf.buf[pbf.pos++] = low & 127 | 128;
2289
+ low >>>= 7;
2290
+ pbf.buf[pbf.pos++] = low & 127 | 128;
2291
+ low >>>= 7;
2292
+ pbf.buf[pbf.pos] = low & 127;
2293
+ }
2294
+ function writeBigVarintHigh(high, pbf) {
2295
+ const lsb = (high & 7) << 4;
2296
+ pbf.buf[pbf.pos++] |= lsb | ((high >>>= 3) ? 128 : 0);
2297
+ if (!high) return;
2298
+ pbf.buf[pbf.pos++] = high & 127 | ((high >>>= 7) ? 128 : 0);
2299
+ if (!high) return;
2300
+ pbf.buf[pbf.pos++] = high & 127 | ((high >>>= 7) ? 128 : 0);
2301
+ if (!high) return;
2302
+ pbf.buf[pbf.pos++] = high & 127 | ((high >>>= 7) ? 128 : 0);
2303
+ if (!high) return;
2304
+ pbf.buf[pbf.pos++] = high & 127 | ((high >>>= 7) ? 128 : 0);
2305
+ if (!high) return;
2306
+ pbf.buf[pbf.pos++] = high & 127;
2307
+ }
2308
+ function makeRoomForExtraLength(startPos, len, pbf) {
2309
+ const extraLen = len <= 16383 ? 1 : len <= 2097151 ? 2 : len <= 268435455 ? 3 : Math.floor(Math.log(len) / (Math.LN2 * 7));
2310
+ pbf.realloc(extraLen);
2311
+ for (let i2 = pbf.pos - 1; i2 >= startPos; i2--) pbf.buf[i2 + extraLen] = pbf.buf[i2];
2312
+ }
2313
+ function writePackedVarint(arr, pbf) {
2314
+ for (let i2 = 0; i2 < arr.length; i2++) pbf.writeVarint(arr[i2]);
2315
+ }
2316
+ function writePackedSVarint(arr, pbf) {
2317
+ for (let i2 = 0; i2 < arr.length; i2++) pbf.writeSVarint(arr[i2]);
2318
+ }
2319
+ function writePackedFloat(arr, pbf) {
2320
+ for (let i2 = 0; i2 < arr.length; i2++) pbf.writeFloat(arr[i2]);
2321
+ }
2322
+ function writePackedDouble(arr, pbf) {
2323
+ for (let i2 = 0; i2 < arr.length; i2++) pbf.writeDouble(arr[i2]);
2324
+ }
2325
+ function writePackedBoolean(arr, pbf) {
2326
+ for (let i2 = 0; i2 < arr.length; i2++) pbf.writeBoolean(arr[i2]);
2327
+ }
2328
+ function writePackedFixed32(arr, pbf) {
2329
+ for (let i2 = 0; i2 < arr.length; i2++) pbf.writeFixed32(arr[i2]);
2330
+ }
2331
+ function writePackedSFixed32(arr, pbf) {
2332
+ for (let i2 = 0; i2 < arr.length; i2++) pbf.writeSFixed32(arr[i2]);
2333
+ }
2334
+ function writePackedFixed64(arr, pbf) {
2335
+ for (let i2 = 0; i2 < arr.length; i2++) pbf.writeFixed64(arr[i2]);
2336
+ }
2337
+ function writePackedSFixed64(arr, pbf) {
2338
+ for (let i2 = 0; i2 < arr.length; i2++) pbf.writeSFixed64(arr[i2]);
2339
+ }
2340
+ function readUtf8(buf, pos, end) {
2341
+ let str = "";
2342
+ let i2 = pos;
2343
+ while (i2 < end) {
2344
+ const b0 = buf[i2];
2345
+ let c = null;
2346
+ let bytesPerSequence = b0 > 239 ? 4 : b0 > 223 ? 3 : b0 > 191 ? 2 : 1;
2347
+ if (i2 + bytesPerSequence > end) break;
2348
+ let b1, b2, b3;
2349
+ if (bytesPerSequence === 1) {
2350
+ if (b0 < 128) {
2351
+ c = b0;
2352
+ }
2353
+ } else if (bytesPerSequence === 2) {
2354
+ b1 = buf[i2 + 1];
2355
+ if ((b1 & 192) === 128) {
2356
+ c = (b0 & 31) << 6 | b1 & 63;
2357
+ if (c <= 127) {
2358
+ c = null;
2359
+ }
2360
+ }
2361
+ } else if (bytesPerSequence === 3) {
2362
+ b1 = buf[i2 + 1];
2363
+ b2 = buf[i2 + 2];
2364
+ if ((b1 & 192) === 128 && (b2 & 192) === 128) {
2365
+ c = (b0 & 15) << 12 | (b1 & 63) << 6 | b2 & 63;
2366
+ if (c <= 2047 || c >= 55296 && c <= 57343) {
2367
+ c = null;
2368
+ }
2369
+ }
2370
+ } else if (bytesPerSequence === 4) {
2371
+ b1 = buf[i2 + 1];
2372
+ b2 = buf[i2 + 2];
2373
+ b3 = buf[i2 + 3];
2374
+ if ((b1 & 192) === 128 && (b2 & 192) === 128 && (b3 & 192) === 128) {
2375
+ c = (b0 & 15) << 18 | (b1 & 63) << 12 | (b2 & 63) << 6 | b3 & 63;
2376
+ if (c <= 65535 || c >= 1114112) {
2377
+ c = null;
2378
+ }
2379
+ }
2380
+ }
2381
+ if (c === null) {
2382
+ c = 65533;
2383
+ bytesPerSequence = 1;
2384
+ } else if (c > 65535) {
2385
+ c -= 65536;
2386
+ str += String.fromCharCode(c >>> 10 & 1023 | 55296);
2387
+ c = 56320 | c & 1023;
2388
+ }
2389
+ str += String.fromCharCode(c);
2390
+ i2 += bytesPerSequence;
2391
+ }
2392
+ return str;
2393
+ }
2394
+ function writeUtf8(buf, str, pos) {
2395
+ for (let i2 = 0, c, lead; i2 < str.length; i2++) {
2396
+ c = str.charCodeAt(i2);
2397
+ if (c > 55295 && c < 57344) {
2398
+ if (lead) {
2399
+ if (c < 56320) {
2400
+ buf[pos++] = 239;
2401
+ buf[pos++] = 191;
2402
+ buf[pos++] = 189;
2403
+ lead = c;
2404
+ continue;
2405
+ } else {
2406
+ c = lead - 55296 << 10 | c - 56320 | 65536;
2407
+ lead = null;
2408
+ }
2409
+ } else {
2410
+ if (c > 56319 || i2 + 1 === str.length) {
2411
+ buf[pos++] = 239;
2412
+ buf[pos++] = 191;
2413
+ buf[pos++] = 189;
2414
+ } else {
2415
+ lead = c;
2416
+ }
2417
+ continue;
2418
+ }
2419
+ } else if (lead) {
2420
+ buf[pos++] = 239;
2421
+ buf[pos++] = 191;
2422
+ buf[pos++] = 189;
2423
+ lead = null;
2424
+ }
2425
+ if (c < 128) {
2426
+ buf[pos++] = c;
2427
+ } else {
2428
+ if (c < 2048) {
2429
+ buf[pos++] = c >> 6 | 192;
2430
+ } else {
2431
+ if (c < 65536) {
2432
+ buf[pos++] = c >> 12 | 224;
2433
+ } else {
2434
+ buf[pos++] = c >> 18 | 240;
2435
+ buf[pos++] = c >> 12 & 63 | 128;
2436
+ }
2437
+ buf[pos++] = c >> 6 & 63 | 128;
2438
+ }
2439
+ buf[pos++] = c & 63 | 128;
2440
+ }
2441
+ }
2442
+ return pos;
2443
+ }
2444
+ var DEFAULT_CACHE_SIZE = 64;
2445
+ function toIndex(z2, x22, y) {
2446
+ return `${x22}:${y}:${z2}`;
2447
+ }
2448
+ function parseTile(buffer) {
2449
+ const tile = new VectorTile(new Pbf(buffer));
2450
+ const result = {};
2451
+ for (const [layerName, layer] of Object.entries(tile.layers)) {
2452
+ const features = [];
2453
+ for (let i2 = 0; i2 < layer.length; i2++) {
2454
+ const feature = layer.feature(i2);
2455
+ features.push({
2456
+ id: feature.id,
2457
+ type: feature.type,
2458
+ properties: feature.properties,
2459
+ geometry: feature.loadGeometry(),
2460
+ extent: layer.extent
2461
+ });
2462
+ }
2463
+ result[layerName] = features;
2464
+ }
2465
+ return result;
2466
+ }
2467
+ function transformForOverzoom(corrections, scale, offsetX, offsetY) {
2468
+ const result = {};
2469
+ for (const [layerName, features] of Object.entries(corrections)) {
2470
+ result[layerName] = features.map((feature) => {
2471
+ const extent = feature.extent;
2472
+ const childExtent = extent / scale;
2473
+ const startX = offsetX * childExtent;
2474
+ const startY = offsetY * childExtent;
2475
+ const newGeometry = feature.geometry.map((ring) => {
2476
+ return ring.map((point) => {
2477
+ const x22 = (point.x - startX) * scale;
2478
+ const y = (point.y - startY) * scale;
2479
+ return { x: x22, y };
2480
+ });
2481
+ });
2482
+ return {
2483
+ ...feature,
2484
+ geometry: newGeometry,
2485
+ // Keep original extent since we scaled coordinates to match
2486
+ extent
2487
+ };
2488
+ });
2489
+ }
2490
+ return result;
2491
+ }
2492
+ var CorrectionsSource = class {
2493
+ /**
2494
+ * @param {string} pmtilesUrl - URL to the PMTiles file
2495
+ * @param {Object} [options] - Options
2496
+ * @param {number} [options.cacheSize=64] - Maximum number of tiles to cache
2497
+ * @param {number} [options.maxDataZoom] - Maximum zoom level in PMTiles (auto-detected if not provided)
2498
+ */
2499
+ constructor(pmtilesUrl, options = {}) {
2500
+ this.pmtilesUrl = pmtilesUrl;
2501
+ this.pmtiles = new x(pmtilesUrl);
2502
+ this.cacheSize = options.cacheSize ?? DEFAULT_CACHE_SIZE;
2503
+ this.maxDataZoom = options.maxDataZoom;
2504
+ this.cache = /* @__PURE__ */ new Map();
2505
+ this.inflight = /* @__PURE__ */ new Map();
2506
+ }
2507
+ /**
2508
+ * Get the PMTiles source object.
2509
+ * @returns {PMTiles}
2510
+ */
2511
+ getSource() {
2512
+ return this.pmtiles;
2513
+ }
2514
+ /**
2515
+ * Clear the tile cache.
2516
+ */
2517
+ clearCache() {
2518
+ this.cache.clear();
2519
+ this.inflight.clear();
2520
+ }
2521
+ /**
2522
+ * Auto-detect max zoom from PMTiles metadata.
2523
+ * @returns {Promise<number>}
2524
+ * @private
2525
+ */
2526
+ async _getMaxDataZoom() {
2527
+ if (this.maxDataZoom !== void 0) {
2528
+ return this.maxDataZoom;
2529
+ }
2530
+ const header = await this.pmtiles.getHeader();
2531
+ this.maxDataZoom = header.maxZoom;
2532
+ return this.maxDataZoom;
2533
+ }
2534
+ /**
2535
+ * Fetch and parse a tile from PMTiles.
2536
+ * Implements in-flight request deduplication from protomaps-leaflet.
2537
+ * @param {number} z
2538
+ * @param {number} x
2539
+ * @param {number} y
2540
+ * @returns {Promise<Object<string, Array>>}
2541
+ * @private
2542
+ */
2543
+ async _fetchTile(z2, x22, y) {
2544
+ const idx = toIndex(z2, x22, y);
2545
+ return new Promise((resolve, reject) => {
2546
+ const entry = this.cache.get(idx);
2547
+ if (entry) {
2548
+ entry.used = performance.now();
2549
+ resolve(entry.data);
2550
+ return;
2551
+ }
2552
+ const ifentry = this.inflight.get(idx);
2553
+ if (ifentry) {
2554
+ ifentry.push({ resolve, reject });
2555
+ return;
2556
+ }
2557
+ this.inflight.set(idx, []);
2558
+ this.pmtiles.getZxy(z2, x22, y).then((result) => {
2559
+ let data;
2560
+ if (result) {
2561
+ data = parseTile(result.data);
2562
+ } else {
2563
+ data = {};
2564
+ }
2565
+ this.cache.set(idx, { used: performance.now(), data });
2566
+ const ifentry2 = this.inflight.get(idx);
2567
+ if (ifentry2) {
2568
+ for (const waiter of ifentry2) {
2569
+ waiter.resolve(data);
2570
+ }
2571
+ }
2572
+ this.inflight.delete(idx);
2573
+ resolve(data);
2574
+ if (this.cache.size > this.cacheSize) {
2575
+ let minUsed = Infinity;
2576
+ let minKey = void 0;
2577
+ this.cache.forEach((value, key) => {
2578
+ if (value.used < minUsed) {
2579
+ minUsed = value.used;
2580
+ minKey = key;
2581
+ }
2582
+ });
2583
+ if (minKey) {
2584
+ this.cache.delete(minKey);
2585
+ }
2586
+ }
2587
+ }).catch((e) => {
2588
+ const ifentry2 = this.inflight.get(idx);
2589
+ if (ifentry2) {
2590
+ for (const waiter of ifentry2) {
2591
+ waiter.reject(e);
2592
+ }
2593
+ }
2594
+ this.inflight.delete(idx);
2595
+ reject(e);
2596
+ });
2597
+ });
2598
+ }
2599
+ /**
2600
+ * Get corrections for a tile as a dict of layer name to features.
2601
+ * Supports overzoom beyond maxDataZoom by scaling parent tile data.
2602
+ * @param {number} z - Zoom level
2603
+ * @param {number} x - Tile X coordinate
2604
+ * @param {number} y - Tile Y coordinate
2605
+ * @returns {Promise<Object<string, Array>>} Map of layer name to array of features
2606
+ */
2607
+ async get(z2, x22, y) {
2608
+ const maxDataZoom = await this._getMaxDataZoom();
2609
+ if (z2 > maxDataZoom) {
2610
+ const zoomDiff = z2 - maxDataZoom;
2611
+ const scale = 1 << zoomDiff;
2612
+ const parentX = Math.floor(x22 / scale);
2613
+ const parentY = Math.floor(y / scale);
2614
+ const offsetX = x22 % scale;
2615
+ const offsetY = y % scale;
2616
+ const corrections = await this._fetchTile(maxDataZoom, parentX, parentY);
2617
+ if (Object.keys(corrections).length > 0) {
2618
+ return transformForOverzoom(corrections, scale, offsetX, offsetY);
2619
+ }
2620
+ return {};
2621
+ }
2622
+ return await this._fetchTile(z2, x22, y);
2623
+ }
2624
+ };
2625
+ var MIN_LINE_WIDTH = 0.5;
2626
+ function getLineWidth(zoom, lineWidthStops) {
2627
+ const zooms = Object.keys(lineWidthStops).map(Number).sort((a, b2) => a - b2);
2628
+ if (lineWidthStops[zoom] !== void 0) {
2629
+ return lineWidthStops[zoom];
2630
+ }
2631
+ if (zoom < zooms[0]) {
2632
+ const z1 = zooms[0];
2633
+ const z2 = zooms[1];
2634
+ const w1 = lineWidthStops[z1];
2635
+ const w2 = lineWidthStops[z2];
2636
+ const slope = (w2 - w1) / (z2 - z1);
2637
+ return Math.max(MIN_LINE_WIDTH, w1 + slope * (zoom - z1));
2638
+ }
2639
+ if (zoom > zooms[zooms.length - 1]) {
2640
+ const z1 = zooms[zooms.length - 2];
2641
+ const z2 = zooms[zooms.length - 1];
2642
+ const w1 = lineWidthStops[z1];
2643
+ const w2 = lineWidthStops[z2];
2644
+ const slope = (w2 - w1) / (z2 - z1);
2645
+ return Math.max(MIN_LINE_WIDTH, w2 + slope * (zoom - z2));
2646
+ }
2647
+ for (let i2 = 0; i2 < zooms.length - 1; i2++) {
2648
+ if (zoom > zooms[i2] && zoom < zooms[i2 + 1]) {
2649
+ const z1 = zooms[i2];
2650
+ const z2 = zooms[i2 + 1];
2651
+ const w1 = lineWidthStops[z1];
2652
+ const w2 = lineWidthStops[z2];
2653
+ const t = (zoom - z1) / (z2 - z1);
2654
+ return w1 + t * (w2 - w1);
2655
+ }
2656
+ }
2657
+ return 1;
2658
+ }
2659
+ function getFeaturesBoundingBox(features, tileSize, padding = 0) {
2660
+ let minX = Infinity, minY = Infinity;
2661
+ let maxX = -Infinity, maxY = -Infinity;
2662
+ for (const feature of features) {
2663
+ const scale = tileSize / feature.extent;
2664
+ for (const ring of feature.geometry) {
2665
+ for (const point of ring) {
2666
+ const px = point.x * scale;
2667
+ const py = point.y * scale;
2668
+ if (px < minX) minX = px;
2669
+ if (py < minY) minY = py;
2670
+ if (px > maxX) maxX = px;
2671
+ if (py > maxY) maxY = py;
2672
+ }
2673
+ }
2674
+ }
2675
+ return {
2676
+ minX: Math.max(0, Math.floor(minX - padding)),
2677
+ minY: Math.max(0, Math.floor(minY - padding)),
2678
+ maxX: Math.min(tileSize, Math.ceil(maxX + padding)),
2679
+ maxY: Math.min(tileSize, Math.ceil(maxY + padding))
2680
+ };
2681
+ }
2682
+ function medianFromHistogram(histogram, values) {
2683
+ const count = values.length;
2684
+ if (count === 0) return 0;
2685
+ histogram.fill(0);
2686
+ for (let i2 = 0; i2 < count; i2++) {
2687
+ histogram[values[i2]]++;
2688
+ }
2689
+ const medianPos = count >> 1;
2690
+ let cumulative = 0;
2691
+ for (let v2 = 0; v2 < 256; v2++) {
2692
+ cumulative += histogram[v2];
2693
+ if (cumulative > medianPos) {
2694
+ return v2;
2695
+ }
2696
+ }
2697
+ return 0;
2698
+ }
2699
+ function applyMedianBlurAlongPath(ctx, features, lineWidth, tileSize, maskCanvas) {
2700
+ if (features.length === 0) return;
2701
+ const imageData = ctx.getImageData(0, 0, tileSize, tileSize);
2702
+ const data = imageData.data;
2703
+ const width = tileSize;
2704
+ const height = tileSize;
2705
+ if (!maskCanvas || maskCanvas.width !== tileSize || maskCanvas.height !== tileSize) {
2706
+ maskCanvas = new OffscreenCanvas(tileSize, tileSize);
2707
+ }
2708
+ const maskCtx = maskCanvas.getContext("2d");
2709
+ maskCtx.fillStyle = "black";
2710
+ maskCtx.fillRect(0, 0, tileSize, tileSize);
2711
+ maskCtx.strokeStyle = "white";
2712
+ maskCtx.lineWidth = lineWidth;
2713
+ maskCtx.lineCap = "round";
2714
+ maskCtx.lineJoin = "round";
2715
+ for (const feature of features) {
2716
+ const scale = tileSize / feature.extent;
2717
+ for (const ring of feature.geometry) {
2718
+ if (ring.length === 0) continue;
2719
+ maskCtx.beginPath();
2720
+ maskCtx.moveTo(ring[0].x * scale, ring[0].y * scale);
2721
+ for (let i2 = 1; i2 < ring.length; i2++) {
2722
+ maskCtx.lineTo(ring[i2].x * scale, ring[i2].y * scale);
2723
+ }
2724
+ maskCtx.stroke();
2725
+ }
2726
+ }
2727
+ const maskData = maskCtx.getImageData(0, 0, tileSize, tileSize).data;
2728
+ const radius = Math.max(2, Math.ceil(lineWidth / 2) + 1);
2729
+ const output = new Uint8ClampedArray(data);
2730
+ const bbox = getFeaturesBoundingBox(features, tileSize, radius);
2731
+ const histogram = new Uint16Array(256);
2732
+ const rValues = [];
2733
+ const gValues = [];
2734
+ const bValues = [];
2735
+ for (let y = bbox.minY; y < bbox.maxY; y++) {
2736
+ for (let x22 = bbox.minX; x22 < bbox.maxX; x22++) {
2737
+ const maskIdx = (y * width + x22) * 4;
2738
+ if (maskData[maskIdx] < 128) continue;
2739
+ rValues.length = 0;
2740
+ gValues.length = 0;
2741
+ bValues.length = 0;
2742
+ for (let dy = -radius; dy <= radius; dy++) {
2743
+ for (let dx = -radius; dx <= radius; dx++) {
2744
+ const nx = x22 + dx;
2745
+ const ny = y + dy;
2746
+ if (nx < 0 || nx >= width || ny < 0 || ny >= height) continue;
2747
+ const nMaskIdx = (ny * width + nx) * 4;
2748
+ if (maskData[nMaskIdx] >= 128) continue;
2749
+ const nIdx = nMaskIdx;
2750
+ rValues.push(data[nIdx]);
2751
+ gValues.push(data[nIdx + 1]);
2752
+ bValues.push(data[nIdx + 2]);
2753
+ }
2754
+ }
2755
+ if (rValues.length >= 3) {
2756
+ const idx = maskIdx;
2757
+ output[idx] = medianFromHistogram(histogram, rValues);
2758
+ output[idx + 1] = medianFromHistogram(histogram, gValues);
2759
+ output[idx + 2] = medianFromHistogram(histogram, bValues);
2760
+ }
2761
+ }
2762
+ }
2763
+ ctx.putImageData(new ImageData(output, width, height), 0, 0);
2764
+ }
2765
+ function isAtExtentEdge(coord, extent, tolerance = 0.01) {
2766
+ const tol = extent * tolerance;
2767
+ return coord <= tol || coord >= extent - tol;
2768
+ }
2769
+ function extendFeaturesEnds(features, extensionLength) {
2770
+ return features.map((feature) => {
2771
+ const extent = feature.extent;
2772
+ const newGeometry = feature.geometry.map((ring) => {
2773
+ if (ring.length < 2) return ring;
2774
+ const newRing = [...ring];
2775
+ const start = ring[0];
2776
+ const second = ring[1];
2777
+ if (!isAtExtentEdge(start.x, extent) && !isAtExtentEdge(start.y, extent)) {
2778
+ const dx = start.x - second.x;
2779
+ const dy = start.y - second.y;
2780
+ const len = Math.sqrt(dx * dx + dy * dy);
2781
+ if (len > 0) {
2782
+ const ux = dx / len;
2783
+ const uy = dy / len;
2784
+ newRing[0] = {
2785
+ x: start.x + ux * extensionLength,
2786
+ y: start.y + uy * extensionLength
2787
+ };
2788
+ }
2789
+ }
2790
+ const lastIdx = ring.length - 1;
2791
+ const end = ring[lastIdx];
2792
+ const prev = ring[lastIdx - 1];
2793
+ if (!isAtExtentEdge(end.x, extent) && !isAtExtentEdge(end.y, extent)) {
2794
+ const dx = end.x - prev.x;
2795
+ const dy = end.y - prev.y;
2796
+ const len = Math.sqrt(dx * dx + dy * dy);
2797
+ if (len > 0) {
2798
+ const ux = dx / len;
2799
+ const uy = dy / len;
2800
+ newRing[lastIdx] = {
2801
+ x: end.x + ux * extensionLength,
2802
+ y: end.y + uy * extensionLength
2803
+ };
2804
+ }
2805
+ }
2806
+ return newRing;
2807
+ });
2808
+ return { ...feature, geometry: newGeometry };
2809
+ });
2810
+ }
2811
+ function drawFeatures(ctx, features, color, lineWidth, tileSize, dashArray, alpha) {
2812
+ const prevAlpha = ctx.globalAlpha;
2813
+ if (alpha !== void 0) {
2814
+ ctx.globalAlpha = alpha;
2815
+ }
2816
+ ctx.strokeStyle = color;
2817
+ ctx.lineWidth = lineWidth;
2818
+ ctx.lineJoin = "round";
2819
+ if (dashArray && dashArray.length > 0) {
2820
+ ctx.setLineDash(dashArray);
2821
+ ctx.lineCap = "butt";
2822
+ } else {
2823
+ ctx.setLineDash([]);
2824
+ ctx.lineCap = "round";
2825
+ }
2826
+ for (const feature of features) {
2827
+ const scale = tileSize / feature.extent;
2828
+ for (const ring of feature.geometry) {
2829
+ if (ring.length === 0) continue;
2830
+ ctx.beginPath();
2831
+ ctx.moveTo(ring[0].x * scale, ring[0].y * scale);
2832
+ for (let i2 = 1; i2 < ring.length; i2++) {
2833
+ ctx.lineTo(ring[i2].x * scale, ring[i2].y * scale);
2834
+ }
2835
+ ctx.stroke();
2836
+ }
2837
+ }
2838
+ if (alpha !== void 0) {
2839
+ ctx.globalAlpha = prevAlpha;
2840
+ }
2841
+ }
2842
+ var BoundaryCorrector = class {
2843
+ /**
2844
+ * @param {string} pmtilesUrl - URL to the PMTiles file
2845
+ * @param {Object} [options] - Options
2846
+ * @param {number} [options.cacheSize=64] - Maximum number of tiles to cache
2847
+ * @param {number} [options.maxDataZoom] - Maximum zoom level in PMTiles (auto-detected if not provided)
2848
+ */
2849
+ constructor(pmtilesUrl, options = {}) {
2850
+ this.correctionsSource = new CorrectionsSource(pmtilesUrl, options);
2851
+ this._maskCanvas = null;
2852
+ }
2853
+ /**
2854
+ * Get the PMTiles source object.
2855
+ * @returns {PMTiles}
2856
+ */
2857
+ getSource() {
2858
+ return this.correctionsSource.getSource();
2859
+ }
2860
+ /**
2861
+ * Clear the tile cache.
2862
+ */
2863
+ clearCache() {
2864
+ this.correctionsSource.clearCache();
2865
+ }
2866
+ /**
2867
+ * Get corrections for a tile as a dict of layer name to features.
2868
+ * Supports overzoom beyond maxDataZoom by scaling parent tile data.
2869
+ * @param {number} z - Zoom level
2870
+ * @param {number} x - Tile X coordinate
2871
+ * @param {number} y - Tile Y coordinate
2872
+ * @returns {Promise<Object<string, Array>>} Map of layer name to array of features
2873
+ */
2874
+ async getCorrections(z2, x22, y) {
2875
+ return await this.correctionsSource.get(z2, x22, y);
2876
+ }
2877
+ /**
2878
+ * Apply corrections to a raster tile.
2879
+ * @param {Object<string, Array>} corrections - Feature map from getCorrections
2880
+ * @param {ArrayBuffer} rasterTile - The original raster tile as ArrayBuffer
2881
+ * @param {Object} layerConfig - Layer configuration with colors and styles
2882
+ * @param {number} zoom - Current zoom level
2883
+ * @param {number} [tileSize=256] - Size of the tile in pixels
2884
+ * @returns {Promise<ArrayBuffer>} The corrected tile as ArrayBuffer (PNG)
2885
+ */
2886
+ async fixTile(corrections, rasterTile, layerConfig, zoom, tileSize = 256) {
2887
+ const {
2888
+ startZoom = 0,
2889
+ zoomThreshold,
2890
+ lineWidthStops,
2891
+ delWidthFactor
2892
+ } = layerConfig;
2893
+ if (zoom < startZoom) {
2894
+ return rasterTile;
2895
+ }
2896
+ let activeLineStyles;
2897
+ if (layerConfig.getLineStylesForZoom) {
2898
+ activeLineStyles = layerConfig.getLineStylesForZoom(zoom);
2899
+ } else {
2900
+ const allStyles = layerConfig.lineStyles || [];
2901
+ activeLineStyles = allStyles.filter((style) => {
2902
+ const styleStart = style.startZoom ?? startZoom;
2903
+ const styleEnd = style.endZoom ?? Infinity;
2904
+ return zoom >= styleStart && zoom <= styleEnd;
2905
+ });
2906
+ }
2907
+ const useOsm = zoom >= zoomThreshold;
2908
+ const addLayerName = useOsm ? "to-add-osm" : "to-add-ne";
2909
+ const delLayerName = useOsm ? "to-del-osm" : "to-del-ne";
2910
+ const canvas = new OffscreenCanvas(tileSize, tileSize);
2911
+ const ctx = canvas.getContext("2d");
2912
+ const blob = new Blob([rasterTile]);
2913
+ const imageBitmap = await createImageBitmap(blob);
2914
+ ctx.drawImage(imageBitmap, 0, 0, tileSize, tileSize);
2915
+ const baseLineWidth = getLineWidth(zoom, lineWidthStops);
2916
+ const maxWidthFraction = activeLineStyles.length > 0 ? Math.max(...activeLineStyles.map((s) => s.widthFraction ?? 1)) : 1;
2917
+ const delLineWidth = baseLineWidth * maxWidthFraction * delWidthFactor;
2918
+ const delFeatures = corrections[delLayerName] || [];
2919
+ if (delFeatures.length > 0) {
2920
+ if (!this._maskCanvas || this._maskCanvas.width !== tileSize) {
2921
+ this._maskCanvas = new OffscreenCanvas(tileSize, tileSize);
2922
+ }
2923
+ applyMedianBlurAlongPath(ctx, delFeatures, delLineWidth, tileSize, this._maskCanvas);
2924
+ }
2925
+ let addFeatures = corrections[addLayerName] || [];
2926
+ if (addFeatures.length > 0 && activeLineStyles.length > 0) {
2927
+ const extensionFactor = layerConfig.lineExtensionFactor ?? 0.5;
2928
+ if (extensionFactor > 0 && delFeatures.length > 0) {
2929
+ const extent = addFeatures[0]?.extent || 4096;
2930
+ const extensionLength = delLineWidth * extensionFactor / tileSize * extent;
2931
+ addFeatures = extendFeaturesEnds(addFeatures, extensionLength);
2932
+ }
2933
+ for (const style of activeLineStyles) {
2934
+ const { color, widthFraction = 1, dashArray, alpha = 1 } = style;
2935
+ const lineWidth = baseLineWidth * widthFraction;
2936
+ drawFeatures(ctx, addFeatures, color, lineWidth, tileSize, dashArray, alpha);
2937
+ }
2938
+ }
2939
+ const outputBlob = await canvas.convertToBlob({ type: "image/png" });
2940
+ return outputBlob.arrayBuffer();
2941
+ }
2942
+ /**
2943
+ * Fetch a tile, apply corrections, and return the result.
2944
+ * @param {string} tileUrl - URL of the raster tile
2945
+ * @param {number} z - Zoom level
2946
+ * @param {number} x - Tile X coordinate
2947
+ * @param {number} y - Tile Y coordinate
2948
+ * @param {Object} layerConfig - Layer configuration with colors and styles
2949
+ * @param {Object} [options] - Fetch options
2950
+ * @param {number} [options.tileSize=256] - Tile size in pixels
2951
+ * @param {AbortSignal} [options.signal] - Abort signal for fetch
2952
+ * @param {RequestMode} [options.mode] - Fetch mode (e.g., 'cors')
2953
+ * @returns {Promise<{data: ArrayBuffer, wasFixed: boolean}>}
2954
+ */
2955
+ async fetchAndFixTile(tileUrl, z2, x22, y, layerConfig, options = {}) {
2956
+ const { tileSize = 256, signal, mode } = options;
2957
+ const fetchOptions = {};
2958
+ if (signal) fetchOptions.signal = signal;
2959
+ if (mode) fetchOptions.mode = mode;
2960
+ if (!layerConfig) {
2961
+ const response = await fetch(tileUrl, fetchOptions);
2962
+ if (!response.ok) throw new Error(`Tile fetch failed: ${response.status}`);
2963
+ return { data: await response.arrayBuffer(), wasFixed: false };
2964
+ }
2965
+ const [tileResult, correctionsResult] = await Promise.allSettled([
2966
+ fetch(tileUrl, fetchOptions).then((r) => {
2967
+ if (!r.ok) throw new Error(`Tile fetch failed: ${r.status}`);
2968
+ return r.arrayBuffer();
2969
+ }),
2970
+ this.getCorrections(z2, x22, y)
2971
+ ]);
2972
+ if (signal?.aborted) {
2973
+ throw new DOMException("Aborted", "AbortError");
2974
+ }
2975
+ if (tileResult.status === "rejected") {
2976
+ throw tileResult.reason;
2977
+ }
2978
+ const tileData = tileResult.value;
2979
+ const correctionsFailed = correctionsResult.status === "rejected";
2980
+ const correctionsError = correctionsFailed ? correctionsResult.reason : null;
2981
+ const corrections = correctionsResult.status === "fulfilled" ? correctionsResult.value : {};
2982
+ const hasCorrections = Object.values(corrections).some((arr) => arr && arr.length > 0);
2983
+ if (!hasCorrections) {
2984
+ return { data: tileData, wasFixed: false, correctionsFailed, correctionsError };
2985
+ }
2986
+ const fixedData = await this.fixTile(corrections, tileData, layerConfig, z2, tileSize);
2987
+ return { data: fixedData, wasFixed: true, correctionsFailed: false, correctionsError: null };
2988
+ }
2989
+ };
2990
+
2991
+ // src/index.js
2992
+ var PROTOCOL_PREFIX = "ibc";
2993
+ function parseCorrectionsUrl(url) {
2994
+ const withoutProtocol = url.replace(`${PROTOCOL_PREFIX}://`, "");
2995
+ let configId = null;
2996
+ let tileUrl = withoutProtocol;
2997
+ const atIndex = withoutProtocol.indexOf("@");
2998
+ if (atIndex > 0 && atIndex < withoutProtocol.indexOf("/")) {
2999
+ configId = withoutProtocol.substring(0, atIndex);
3000
+ tileUrl = withoutProtocol.substring(atIndex + 1);
3001
+ }
3002
+ const urlObj = new URL(tileUrl);
3003
+ const pathParts = urlObj.pathname.split("/").filter((p) => p.length > 0);
3004
+ let z2, x3, y;
3005
+ for (let i2 = pathParts.length - 1; i2 >= 2; i2--) {
3006
+ const yPart = pathParts[i2].replace(/\.[^.]+$/, "");
3007
+ const xPart = pathParts[i2 - 1];
3008
+ const zPart = pathParts[i2 - 2];
3009
+ if (/^\d+$/.test(zPart) && /^\d+$/.test(xPart) && /^\d+$/.test(yPart)) {
3010
+ z2 = parseInt(zPart, 10);
3011
+ x3 = parseInt(xPart, 10);
3012
+ y = parseInt(yPart, 10);
3013
+ break;
3014
+ }
3015
+ }
3016
+ return { configId, tileUrl, z: z2, x: x3, y };
3017
+ }
3018
+ async function fetchAndFixTile(tileUrl, z2, x3, y, tileFixer, layerConfig, tileSize, options = {}) {
3019
+ const { data, correctionsFailed, correctionsError } = await tileFixer.fetchAndFixTile(
3020
+ tileUrl,
3021
+ z2,
3022
+ x3,
3023
+ y,
3024
+ layerConfig,
3025
+ { tileSize, signal: options.signal }
3026
+ );
3027
+ return { data, correctionsFailed, correctionsError };
3028
+ }
3029
+ var CorrectionProtocol = class {
3030
+ /**
3031
+ * @param {Object} [options]
3032
+ * @param {string} [options.pmtilesUrl] - URL to PMTiles file (defaults to CDN)
3033
+ * @param {number} [options.tileSize=256] - Tile size in pixels
3034
+ */
3035
+ constructor(options = {}) {
3036
+ this._pmtilesUrl = options.pmtilesUrl ?? getPmtilesUrl();
3037
+ this._tileSize = options.tileSize ?? 256;
3038
+ this._tileFixer = new BoundaryCorrector(this._pmtilesUrl);
3039
+ this._registry = layerConfigs.createMergedRegistry();
3040
+ this._listeners = /* @__PURE__ */ new Map();
3041
+ this._loadFn = this._createLoadFunction();
3042
+ }
3043
+ /**
3044
+ * Add a listener for an event.
3045
+ * @param {'correctionerror'} event - Event name
3046
+ * @param {Function} listener - Callback function receiving event data
3047
+ * @returns {this}
3048
+ */
3049
+ on(event, listener) {
3050
+ if (!this._listeners.has(event)) {
3051
+ this._listeners.set(event, /* @__PURE__ */ new Set());
3052
+ }
3053
+ this._listeners.get(event).add(listener);
3054
+ return this;
3055
+ }
3056
+ /**
3057
+ * Remove an event listener.
3058
+ * @param {'correctionerror'} event - Event name
3059
+ * @param {Function} listener - Callback to remove
3060
+ * @returns {this}
3061
+ */
3062
+ off(event, listener) {
3063
+ this._listeners.get(event)?.delete(listener);
3064
+ return this;
3065
+ }
3066
+ /**
3067
+ * Emit an event to all listeners.
3068
+ * @param {string} event - Event name
3069
+ * @param {Object} data - Event data
3070
+ * @private
3071
+ */
3072
+ _emit(event, data) {
3073
+ this._listeners.get(event)?.forEach((fn) => fn(data));
3074
+ }
3075
+ /**
3076
+ * Add a custom layer config to the registry.
3077
+ * @param {Object} layerConfig - LayerConfig to add
3078
+ * @returns {this}
3079
+ */
3080
+ addLayerConfig(layerConfig) {
3081
+ this._registry.register(layerConfig);
3082
+ return this;
3083
+ }
3084
+ /**
3085
+ * Get the registry.
3086
+ * @returns {LayerConfigRegistry}
3087
+ */
3088
+ getRegistry() {
3089
+ return this._registry;
3090
+ }
3091
+ /**
3092
+ * Get the TileFixer instance.
3093
+ * @returns {TileFixer}
3094
+ */
3095
+ getTileFixer() {
3096
+ return this._tileFixer;
3097
+ }
3098
+ /**
3099
+ * Register the protocol with MapLibre GL.
3100
+ * @param {typeof import('maplibre-gl')} maplibregl - MapLibre GL namespace
3101
+ * @returns {this}
3102
+ */
3103
+ register(maplibregl) {
3104
+ maplibregl.addProtocol(PROTOCOL_PREFIX, this._loadFn);
3105
+ return this;
3106
+ }
3107
+ /**
3108
+ * Unregister the protocol from MapLibre GL.
3109
+ * @param {typeof import('maplibre-gl')} maplibregl - MapLibre GL namespace
3110
+ * @returns {this}
3111
+ */
3112
+ unregister(maplibregl) {
3113
+ maplibregl.removeProtocol(PROTOCOL_PREFIX);
3114
+ return this;
3115
+ }
3116
+ /**
3117
+ * Create the protocol load function.
3118
+ * @returns {Function}
3119
+ * @private
3120
+ */
3121
+ _createLoadFunction() {
3122
+ const self = this;
3123
+ return async (params, abortController) => {
3124
+ const { configId, tileUrl, z: z2, x: x3, y } = parseCorrectionsUrl(params.url);
3125
+ if (z2 === void 0 || x3 === void 0 || y === void 0) {
3126
+ console.warn(`[CorrectionProtocol] Could not parse tile coordinates from URL: ${params.url}, falling back to original`);
3127
+ const response = await fetch(tileUrl, { signal: abortController?.signal });
3128
+ return { data: await response.arrayBuffer() };
3129
+ }
3130
+ let layerConfig;
3131
+ if (configId) {
3132
+ layerConfig = self._registry.get(configId);
3133
+ } else {
3134
+ layerConfig = self._registry.detectFromTileUrls([tileUrl]);
3135
+ }
3136
+ try {
3137
+ const result = await fetchAndFixTile(
3138
+ tileUrl,
3139
+ z2,
3140
+ x3,
3141
+ y,
3142
+ self._tileFixer,
3143
+ layerConfig,
3144
+ self._tileSize,
3145
+ { signal: abortController?.signal }
3146
+ );
3147
+ if (result.correctionsFailed) {
3148
+ console.warn("[CorrectionProtocol] Corrections fetch failed:", result.correctionsError);
3149
+ self._emit("correctionerror", { error: result.correctionsError, coords: { z: z2, x: x3, y }, tileUrl });
3150
+ }
3151
+ return { data: result.data };
3152
+ } catch (err2) {
3153
+ console.warn("[CorrectionProtocol] Error applying corrections, falling back to original:", err2);
3154
+ self._emit("correctionerror", { error: err2, coords: { z: z2, x: x3, y }, tileUrl });
3155
+ const response = await fetch(tileUrl, { signal: abortController?.signal });
3156
+ return { data: await response.arrayBuffer() };
3157
+ }
3158
+ };
3159
+ }
3160
+ };
3161
+ function registerCorrectionProtocol(maplibregl, options = {}) {
3162
+ const protocol = new CorrectionProtocol(options);
3163
+ return protocol.register(maplibregl);
3164
+ }
3165
+ return __toCommonJS(index_exports);
3166
+ })();
3167
+ //# sourceMappingURL=index.global.js.map