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