PageSourceSearch

https://traveltime.com/_next/static/media/maplibre-gl-worker-dev.0xw2gz_pbvrte.mjs

js traveltime.com collected 2026-10-02 16:59:12 UTC 38,038 bytes, 1,027 lines download raw bytes

vendor: 4,933 bytes, lines 1-119
1/**
2* MapLibre GL JS
3* @license 3-Clause BSD. Full text of license: https://github.com/maplibre/maplibre-gl-js/blob/v6.4.1/LICENSE.txt
4*/
5import { B as PbfReader, Bn as JSON_PREFIX, D as SymbolBucket, Dn as getArrayBuffer, Dt as RGBAImage, Et as AlphaImage, Fn as removeProtocol, I as potpack, K as FillExtrusionBucket, Nn as addProtocol, On as getJSON, P as ImageAtlas, Rn as isAbortError, S as createStyleLayer, U as LineBucket, Ur as EXTENT, Vt as CollisionBoxArray, W as GeoJSONVT, Wi as Point, an as register, bt as DEMData, c as FeatureIndex, d as DictionaryCoder, fr as getImageData, g as OverscaledTileID, i as clipGeometry, ir as ensureError, jn as makeRequest, l as MLTVectorTile, m as fromVectorTileJs, mn as createExpression, mr as isImageBitmap, mt as FillBucket, n as performSymbolLayout, nn as rtlWorkerPlugin, o as BoundedLRUCache, or as extend, p as GeoJSONWrapper, tn as EvaluationParameters, ut as VectorTile, vn as featureFilter, x as Actor, xr as mapObject, yn as groupByLayout, yr as isWorker, zr as warnOnce } from "./maplibre-gl-shared-dev.mjs";
6//#region src/style/style_layer_index.ts
7var StyleLayerIndex = class {
8	constructor(layerConfigs, globalState) {
9		this.keyCache = {};
10		if (layerConfigs) this.replace(layerConfigs, globalState);
11	}
12	replace(layerConfigs, globalState) {
13		this._layerConfigs = {};
14		this._layers = {};
15		this.update(layerConfigs, [], globalState);
16	}
17	update(layerConfigs, removedIds, globalState) {
18		for (const layerConfig of layerConfigs) {
19			this._layerConfigs[layerConfig.id] = layerConfig;
20			const layer = this._layers[layerConfig.id] = createStyleLayer(layerConfig, globalState);
21			layer._featureFilter = featureFilter(layer.filter, `layers[${layerConfig.id}].filter`, globalState);
22			if (this.keyCache[layerConfig.id]) delete this.keyCache[layerConfig.id];
23		}
24		for (const id of removedIds) {
25			delete this.keyCache[id];
26			delete this._layerConfigs[id];
27			delete this._layers[id];
28		}
29		this.familiesBySource = {};
30		const groups = groupByLayout(Object.values(this._layerConfigs), this.keyCache);
31		for (const layerConfigs of groups) {
32			const layers = layerConfigs.map((layerConfig) => this._layers[layerConfig.id]);
33			const layer = layers[0];
34			if (layer.isHidden()) continue;
35			const sourceId = layer.source || "";
36			let sourceGroup = this.familiesBySource[sourceId];
37			sourceGroup ||= this.familiesBySource[sourceId] = {};
38			const sourceLayerId = layer.sourceLayer || "_geojsonTileLayer";
39			let sourceLayerFamilies = sourceGroup[sourceLayerId];
40			sourceLayerFamilies ||= sourceGroup[sourceLayerId] = [];
41			sourceLayerFamilies.push(layers);
42		}
43	}
44};
45//#endregion
46//#region src/render/glyph_atlas.ts
47const padding = 1;
48var GlyphAtlas = class {
49	constructor(stacks) {
50		const positions = {};
51		const bins = [];
52		for (const stack in stacks) {
53			const glyphs = stacks[stack];
54			const stackPositions = positions[stack] = {};
55			for (const id in glyphs) {
56				const src = glyphs[+id];
57				if (!src || src.bitmap.width === 0 || src.bitmap.height === 0) continue;
58				const bin = {
59					x: 0,
60					y: 0,
61					w: src.bitmap.width + 2,
62					h: src.bitmap.height + 2
63				};
64				bins.push(bin);
65				stackPositions[id] = {
66					rect: bin,
67					metrics: src.metrics
68				};
69			}
70		}
71		const { w, h } = potpack(bins);
72		const image = new AlphaImage({
73			width: w || 1,
74			height: h || 1
75		});
76		for (const stack in stacks) {
77			const glyphs = stacks[stack];
78			for (const id in glyphs) {
79				const src = glyphs[+id];
80				if (!src || src.bitmap.width === 0 || src.bitmap.height === 0) continue;
81				const bin = positions[stack][id].rect;
82				AlphaImage.copy(src.bitmap, image, {
83					x: 0,
84					y: 0
85				}, {
86					x: bin.x + padding,
87					y: bin.y + padding
88				}, src.bitmap);
89			}
90		}
91		this.image = image;
92		this.positions = positions;
93	}
94};
95register("GlyphAtlas", GlyphAtlas);
96//#endregion
97//#region src/source/worker_tile.ts
98var WorkerTile = class {
99	constructor(params) {
100		this.tileID = new OverscaledTileID(params.tileID.overscaledZ, params.tileID.wrap, params.tileID.canonical.z, params.tileID.canonical.x, params.tileID.canonical.y);
101		this.uid = params.uid;
102		this.zoom = params.zoom;
103		this.pixelRatio = params.pixelRatio;
104		this.tileSize = params.tileSize;
105		this.source = params.source;
106		this.overscaling = this.tileID.overscaleFactor();
107		this.showCollisionBoxes = params.showCollisionBoxes;
108		this.collectResourceTiming = !!params.collectResourceTiming;
109		this.returnDependencies = !!params.returnDependencies;
110		this.promoteId = params.promoteId;
111		this.inFlightDependencies = [];
112	}
113	async parse(data, layerIndex, availableImages, actor, subdivisionGranularity) {
114		this.data = data;
115		this.collisionBoxArray = new CollisionBoxArray();
116		const sourceLayerCoder = new DictionaryCoder(Object.keys(data.layers).sort());
117		const featureIndex = new FeatureIndex(this.tileID, this.promoteId);
118		featureIndex.bucketLayerIDs = [];
119		const buckets = {};
120		const options = {
121			featureIndex,
122			iconDependencies: {},
123			patternDependencies: {},
124			glyphDependencies: {},
125			dashDependencies: {},
126			availableImages,
127			subdivisionGranularity
128		};
129		const layerFamilies = layerIndex.familiesBySource[this.source];
130		for (const sourceLayerId in layerFamilies) {
131			const sourceLayer = data.layers[sourceLayerId];
132			if (!sourceLayer) continue;
133			if (sourceLayer.version === 1) warnOnce(`Vector tile source "${this.source}" layer "${sourceLayerId}" does not use vector tile spec v2 and therefore may have some rendering errors.`);
134			const sourceLayerIndex = sourceLayerCoder.encode(sourceLayerId);
135			const features = [];
136			for (let index = 0; index < sourceLayer.length; index++) {
137				const feature = sourceLayer.feature(index);
138				const id = featureIndex.getId(feature, sourceLayerId);
139				features.push({
140					feature,
141					id,
142					index,
143					sourceLayerIndex
144				});
145			}
146			for (const family of layerFamilies[sourceLayerId]) {
147				const layer = family[0];
148				if (layer.source !== this.source) warnOnce(`layer.source = ${layer.source} does not equal this.source = ${this.source}`);
149				if (layer.isHidden(this.zoom, true)) continue;
150				recalculateLayers(family, this.zoom, availableImages);
151				(buckets[layer.id] = layer.createBucket({
152					index: featureIndex.bucketLayerIDs.length,
153					layers: family,
154					zoom: this.zoom,
155					pixelRatio: this.pixelRatio,
156					overscaling: this.overscaling,
157					collisionBoxArray: this.collisionBoxArray,
158					sourceLayerIndex,
159					sourceID: this.source
160				})).populate(features, options, this.tileID.canonical);
161				featureIndex.bucketLayerIDs.push(family.map((l) => l.id));
162			}
163		}
164		const stacks = mapObject(options.glyphDependencies, (glyphs) => Object.keys(glyphs).map(Number));
165		for (const request of this.inFlightDependencies) request?.abort();
166		this.inFlightDependencies = [];
167		let getGlyphsPromise = Promise.resolve({});
168		if (Object.keys(stacks).length) {
169			const abortController = new AbortController();
170			this.inFlightDependencies.push(abortController);
171			getGlyphsPromise = actor.sendAsync({
172				type: "GG",
173				data: {
174					stacks,
175					source: this.source,
176					tileID: this.tileID,
177					type: "glyphs"
178				}
179			}, abortController);
180		}
181		const icons = Object.keys(options.iconDependencies);
182		let getIconsPromise = Promise.resolve({});
183		if (icons.length) {
184			const abortController = new AbortController();
185			this.inFlightDependencies.push(abortController);
186			getIconsPromise = actor.sendAsync({
187				type: "GI",
188				data: {
189					icons,
190					source: this.source,
191					tileID: this.tileID,
192					type: "icons"
193				}
194			}, abortController);
195		}
196		const patterns = Object.keys(options.patternDependencies);
197		let getPatternsPromise = Promise.resolve({});
198		if (patterns.length) {
199			const abortController = new AbortController();
200			this.inFlightDependencies.push(abortController);
201			getPatternsPromise = actor.sendAsync({
202				type: "GI",
203				data: {
204					icons: patterns,
205					source: this.source,
206					tileID: this.tileID,
207					type: "patterns"
208				}
209			}, abortController);
210		}
211		const dashes = options.dashDependencies;
212		let getDashesPromise = Promise.resolve({});
213		if (Object.keys(dashes).length) {
214			const abortController = new AbortController();
215			this.inFlightDependencies.push(abortController);
216			getDashesPromise = actor.sendAsync({
217				type: "GDA",
218				data: { dashes }
219			}, abortController);
220		}
221		const [glyphMap, iconMap, patternMap, dashPositions] = await Promise.all([
222			getGlyphsPromise,
223			getIconsPromise,
224			getPatternsPromise,
225			getDashesPromise
226		]);
227		const glyphAtlas = new GlyphAtlas(glyphMap);
228		const imageAtlas = new ImageAtlas(iconMap, patternMap);
229		for (const key in buckets) {
230			const bucket = buckets[key];
231			if (bucket instanceof SymbolBucket) {
232				recalculateLayers(bucket.layers, this.zoom, availableImages);
233				performSymbolLayout({
234					bucket,
235					glyphMap,
236					glyphPositions: glyphAtlas.positions,
237					imageMap: iconMap,
238					imagePositions: imageAtlas.iconPositions,
239					showCollisionBoxes: this.showCollisionBoxes,
240					canonical: this.tileID.canonical,
241					subdivisionGranularity: options.subdivisionGranularity
242				});
243			} else if (bucket.hasDependencies && (bucket instanceof FillBucket || bucket instanceof FillExtrusionBucket || bucket instanceof LineBucket)) {
244				recalculateLayers(bucket.layers, this.zoom, availableImages);
245				bucket.addFeatures(options, this.tileID.canonical, imageAtlas.patternPositions, dashPositions);
246			}
vendor: 6,657 bytes, lines 246-454
246
247		}
248		return {
249			buckets: Object.values(buckets).filter((b) => !b.isEmpty()),
250			featureIndex,
251			collisionBoxArray: this.collisionBoxArray,
252			glyphAtlasImage: glyphAtlas.image,
253			imageAtlas,
254			dashPositions,
255			glyphMap: this.returnDependencies ? glyphMap : null,
256			iconMap: this.returnDependencies ? iconMap : null,
257			glyphPositions: this.returnDependencies ? glyphAtlas.positions : null
258		};
259	}
260};
261function recalculateLayers(layers, zoom, availableImages) {
262	const parameters = new EvaluationParameters(zoom);
263	for (const layer of layers) layer.recalculate(parameters, availableImages);
264}
265//#endregion
266//#region src/source/worker_tile_state.ts
267var WorkerTileState = class {
268	constructor() {
269		this.loading = {};
270		this.loaded = {};
271		this.parsing = {};
272	}
273	startLoading(uid, tile) {
274		this.loading[uid] = tile;
275	}
276	finishLoading(uid) {
277		delete this.loading[uid];
278	}
279	abort(uid) {
280		const tile = this.loading[uid];
281		if (!tile?.abort) return;
282		tile.abort.abort();
283		delete this.loading[uid];
284	}
285	getParsing(uid) {
286		return this.parsing[uid];
287	}
288	setParsing(uid, state) {
289		this.parsing[uid] = state;
290	}
291	removeParsing(uid) {
292		delete this.parsing[uid];
293	}
294	markLoaded(uid, tile) {
295		this.loaded[uid] = tile;
296	}
297	getLoaded(uid) {
298		const tile = this.loaded[uid];
299		if (!tile) return void 0;
300		return tile;
301	}
302	removeLoaded(uid) {
303		delete this.loaded[uid];
304	}
305	clearLoaded() {
306		this.loaded = {};
307	}
308};
309//#endregion
310//#region src/util/request_performance.ts
311/**
312* @internal
313* Safe wrapper for the performance resource timing API in web workers with graceful degradation
314*/
315var RequestPerformance = class {
316	constructor(url) {
317		this.start = `${url}#start`;
318		this.end = `${url}#end`;
319		this.measure = url;
320		performance.mark(this.start);
321	}
322	finish() {
323		performance.mark(this.end);
324		let resourceTimingData = performance.getEntriesByName(this.measure);
325		if (resourceTimingData.length === 0) {
326			performance.measure(this.measure, this.start, this.end);
327			resourceTimingData = performance.getEntriesByName(this.measure);
328			performance.clearMarks(this.start);
329			performance.clearMarks(this.end);
330			performance.clearMeasures(this.measure);
331		}
332		return resourceTimingData;
333	}
334};
335//#endregion
336//#region src/source/vector_tile_overzoomed.ts
337var VectorTileFeatureOverzoomed = class {
338	constructor(type, geometry, properties, id, extent) {
339		this.type = type;
340		this.properties = properties ? properties : {};
341		this.extent = extent;
342		this.pointsArray = geometry;
343		this.id = id;
344	}
345	loadGeometry() {
346		return this.pointsArray.map((ring) => ring.map((point) => new Point(point.x, point.y)));
347	}
348};
349var VectorTileLayerOverzoomed = class {
350	constructor(features, layerName, extent) {
351		this.version = 2;
352		this._myFeatures = features;
353		this.name = layerName;
354		this.length = features.length;
355		this.extent = extent;
356	}
357	feature(i) {
358		return this._myFeatures[i];
359	}
360};
361var VectorTileOverzoomed = class {
362	constructor() {
363		this.layers = {};
364	}
365	addLayer(layer) {
366		this.layers[layer.name] = layer;
367	}
368};
369/**
370* This function slices a source tile layer into an overzoomed tile layer for a target tile ID.
371* @param sourceLayer - the source tile layer to slice
372* @param maxZoomTileID - the maximum zoom tile ID
373* @param targetTileID - the target tile ID
374* @returns - the overzoomed tile layer
375*/
376function sliceVectorTileLayer(sourceLayer, maxZoomTileID, targetTileID) {
377	const { extent } = sourceLayer;
378	const dz = targetTileID.z - maxZoomTileID.z;
379	const scale = Math.pow(2, dz);
380	const offsetX = (targetTileID.x - maxZoomTileID.x * scale) * extent;
381	const offsetY = (targetTileID.y - maxZoomTileID.y * scale) * extent;
382	const featureWrappers = [];
383	for (let index = 0; index < sourceLayer.length; index++) {
384		const feature = sourceLayer.feature(index);
385		let geometry = feature.loadGeometry();
386		for (const ring of geometry) for (const point of ring) {
387			point.x = point.x * scale - offsetX;
388			point.y = point.y * scale - offsetY;
389		}
390		const buffer = 128;
391		geometry = clipGeometry(geometry, feature.type, -128, -128, extent + buffer, extent + buffer);
392		if (geometry.length === 0) continue;
393		featureWrappers.push(new VectorTileFeatureOverzoomed(feature.type, geometry, feature.properties, feature.id, extent));
394	}
395	return new VectorTileLayerOverzoomed(featureWrappers, sourceLayer.name, extent);
396}
397//#endregion
398//#region src/source/vector_tile_worker_source.ts
399/**
400* The {@link WorkerSource} implementation that supports {@link VectorTileSource}. This class is
401* used by vector tile sources to perform tile processing operations in a separate worker thread.
402*/
403var VectorTileWorkerSource = class {
404	constructor(actor, layerIndex, availableImages) {
405		this.actor = actor;
406		this.layerIndex = layerIndex;
407		this.availableImages = availableImages;
408		this.tileState = new WorkerTileState();
409		this.overzoomedTileResultCache = new BoundedLRUCache(1e3);
410	}
411	/**
412	* Loads a vector tile
413	*/
414	loadVectorTile(params, rawData) {
415		try {
416			return {
417				vectorTile: params.encoding !== "mlt" ? new VectorTile(new PbfReader(rawData)) : new MLTVectorTile(rawData),
418				rawData
419			};
420		} catch (ex) {
421			const bytes = new Uint8Array(rawData);
422			const isGzipped = bytes[0] === 31 && bytes[1] === 139;
423			let errorMessage = `Unable to parse the tile at ${params.request.url}, `;
424			if (isGzipped) errorMessage += "please make sure the data is not gzipped and that you have configured the relevant header in the server";
425			else errorMessage += `got error: ${ensureError(ex).message}`;
426			throw new Error(errorMessage);
427		}
428	}
429	/**
430	* Implements {@link WorkerSource.loadTile}.
431	*/
432	async loadTile(params) {
433		const { uid, overzoomParameters } = params;
434		if (overzoomParameters) params.request = overzoomParameters.overzoomRequest;
435		const timing = this._startRequestTiming(params);
436		const workerTile = new WorkerTile(params);
437		this.tileState.startLoading(uid, workerTile);
438		const abortController = new AbortController();
439		workerTile.abort = abortController;
440		try {
441			const tileResponse = await getArrayBuffer(params.request, abortController);
442			if (params.etag && params.etag === tileResponse.etag) {
443				this.tileState.finishLoading(uid);
444				return this._getEtagUnmodifiedResult(tileResponse, timing);
445			}
446			const tileResult = this.loadVectorTile(params, tileResponse.data);
447			this.tileState.finishLoading(uid);
448			if (!tileResult) return null;
449			let { vectorTile, rawData } = tileResult;
450			if (overzoomParameters) ({vectorTile, rawData} = this._getOverzoomTile(params, vectorTile));
451			const cacheControl = this._getExpiryData(tileResponse);
452			const resourceTiming = this._finishRequestTiming(timing);
453			workerTile.vectorTile = vectorTile;
454			
vendor: 4,272 bytes, lines 454-567
454this.tileState.markLoaded(uid, workerTile);
455			const parsingState = {
456				rawData,
457				cacheControl,
458				resourceTiming
459			};
460			this.tileState.setParsing(uid, parsingState);
461			return await this._parseWorkerTile(workerTile, params);
462		} catch (err) {
463			this.tileState.finishLoading(uid);
464			this.tileState.markLoaded(uid, workerTile);
465			throw err;
466		}
467	}
468	_getEtagUnmodifiedResult(response, timing) {
469		const cacheControl = this._getExpiryData(response);
470		const resourceTiming = this._finishRequestTiming(timing);
471		return extend({ etagUnmodified: true }, cacheControl, resourceTiming);
472	}
473	async _parseWorkerTile(workerTile, params) {
474		const parseState = this.tileState.getParsing(workerTile.uid);
475		let result = await workerTile.parse(workerTile.vectorTile, this.layerIndex, this.availableImages, this.actor, params.subdivisionGranularity);
476		if (parseState) {
477			const { rawData, cacheControl, resourceTiming } = parseState;
478			const encoding = params.overzoomParameters ? "mvt" : params.encoding;
479			result = extend({
480				rawTileData: rawData.slice(0),
481				encoding
482			}, result, cacheControl, resourceTiming);
483			this.tileState.removeParsing(workerTile.uid);
484		}
485		return result;
486	}
487	_getExpiryData({ expires, cacheControl, etag }) {
488		const data = {};
489		if (expires) data.expires = expires;
490		if (cacheControl) data.cacheControl = cacheControl;
491		if (etag) data.etag = etag;
492		return data;
493	}
494	_startRequestTiming(params) {
495		if (!params.request?.collectResourceTiming) return;
496		return new RequestPerformance(params.request.url);
497	}
498	_finishRequestTiming(timing) {
499		const timingData = timing?.finish();
500		if (!timingData) return {};
501		return { resourceTiming: JSON.parse(JSON.stringify(timingData)) };
502	}
503	/**
504	* If we are seeking a tile deeper than the source's max available canonical tile, get the overzoomed tile
505	* @param params - the worker tile parameters
506	* @param maxZoomVectorTile - the original vector tile at the source's max available canonical zoom
507	* @returns the overzoomed tile and its raw data
508	*/
509	_getOverzoomTile(params, maxZoomVectorTile) {
510		const { tileID, source, overzoomParameters } = params;
511		const { maxZoomTileID } = overzoomParameters;
512		const cacheKey = `${maxZoomTileID.key}_${tileID.key}_${params.request?.url}`;
513		const cachedOverzoomTile = this.overzoomedTileResultCache.get(cacheKey);
514		if (cachedOverzoomTile) return cachedOverzoomTile;
515		const overzoomedVectorTile = new VectorTileOverzoomed();
516		const layerFamilies = this.layerIndex.familiesBySource[source];
517		for (const sourceLayerId in layerFamilies) {
518			const sourceLayer = maxZoomVectorTile.layers[sourceLayerId];
519			if (!sourceLayer) continue;
520			const slicedTileLayer = sliceVectorTileLayer(sourceLayer, maxZoomTileID, tileID.canonical);
521			if (slicedTileLayer.length > 0) overzoomedVectorTile.addLayer(slicedTileLayer);
522		}
523		const overzoomedVectorTileResult = {
524			vectorTile: overzoomedVectorTile,
525			rawData: fromVectorTileJs(overzoomedVectorTile).buffer
526		};
527		this.overzoomedTileResultCache.set(cacheKey, overzoomedVectorTileResult);
528		return overzoomedVectorTileResult;
529	}
530	/**
531	* Implements {@link WorkerSource.reloadTile}.
532	*/
533	async reloadTile(params) {
534		const uid = params.uid;
535		const workerTile = this.tileState.getLoaded(uid);
536		if (!workerTile) throw new Error("Should not be trying to reload a tile that was never loaded or has been removed");
537		if (!workerTile.vectorTile) return;
538		workerTile.showCollisionBoxes = params.showCollisionBoxes;
539		return await this._parseWorkerTile(workerTile, params);
540	}
541	/**
542	* Implements {@link WorkerSource.abortTile}.
543	*/
544	async abortTile(params) {
545		this.tileState.abort(params.uid);
546	}
547	/**
548	* Implements {@link WorkerSource.removeTile}.
549	*/
550	async removeTile(params) {
551		this.tileState.removeLoaded(params.uid);
552	}
553};
554//#endregion
555//#region src/source/raster_dem_tile_worker_source.ts
556var RasterDEMTileWorkerSource = class {
557	constructor() {
558		this.loaded = {};
559	}
560	async loadTile(params) {
561		const { uid, encoding, rawImageData, redFactor, greenFactor, blueFactor, baseShift } = params;
562		const width = rawImageData.width + 2;
563		const height = rawImageData.height + 2;
564		const imagePixels = isImageBitmap(rawImageData) ? new RGBAImage({
565			width,
566			height
567		}, await getImageData(rawImageData, -1, -1
vendor: 17,658 bytes, lines 567-1027
567, width, height)) : rawImageData;
568		const dem = new DEMData(uid, imagePixels, encoding, redFactor, greenFactor, blueFactor, baseShift);
569		this.loaded ||= {};
570		this.loaded[uid] = dem;
571		return dem;
572	}
573	removeTile(params) {
574		const loaded = this.loaded, uid = params.uid;
575		if (loaded?.[uid]) delete loaded[uid];
576	}
577};
578//#endregion
579//#region src/source/geojson_worker_source.ts
580/**
581* The {@link WorkerSource} implementation that supports {@link GeoJSONSource}.
582* This class is designed to be easily reused to support custom source types
583* for data formats that can be parsed/converted into an in-memory GeoJSON
584* representation. To do so, create it with
585* `new GeoJSONWorkerSource(actor, layerIndex, customLoadGeoJSONFunction)`.
586* For a full example, see [mapbox-gl-topojson](https://github.com/developmentseed/mapbox-gl-topojson).
587*/
588var GeoJSONWorkerSource = class {
589	constructor(actor, layerIndex, availableImages, createGeoJSONIndexFunc = createGeoJSONIndex) {
590		this.actor = actor;
591		this.layerIndex = layerIndex;
592		this.availableImages = availableImages;
593		this.tileState = new WorkerTileState();
594		this._createGeoJSONIndex = createGeoJSONIndexFunc;
595	}
596	/**
597	* Retrieves and sends loaded vector tiles to the main thread.
598	*/
599	loadVectorTile(params) {
600		if (!this._geoJSONIndex) throw new Error("Unable to parse the data into a cluster or geojson");
601		const { z, x, y } = params.tileID.canonical;
602		const geoJSONTile = this._geoJSONIndex.getTile(z, x, y);
603		if (!geoJSONTile) return null;
604		const geojsonWrapper = new GeoJSONWrapper(geoJSONTile.features, {
605			version: 2,
606			extent: EXTENT
607		});
608		return {
609			vectorTile: geojsonWrapper,
610			rawData: fromVectorTileJs(geojsonWrapper, JSON_PREFIX).buffer
611		};
612	}
613	/**
614	* Implements {@link WorkerSource.loadTile}.
615	*/
616	async loadTile(params) {
617		const { uid } = params;
618		const workerTile = new WorkerTile(params);
619		workerTile.abort = new AbortController();
620		try {
621			const loadResult = this.loadVectorTile(params);
622			if (!loadResult) return null;
623			const { vectorTile, rawData } = loadResult;
624			workerTile.vectorTile = vectorTile;
625			this.tileState.markLoaded(uid, workerTile);
626			const parsingState = { rawData };
627			this.tileState.setParsing(uid, parsingState);
628			return await this._parseWorkerTile(workerTile, params);
629		} catch (err) {
630			this.tileState.markLoaded(uid, workerTile);
631			throw err;
632		}
633	}
634	async _parseWorkerTile(workerTile, params) {
635		const parseState = this.tileState.getParsing(workerTile.uid);
636		let result = await workerTile.parse(workerTile.vectorTile, this.layerIndex, this.availableImages, this.actor, params.subdivisionGranularity);
637		if (parseState) {
638			const { rawData } = parseState;
639			result = extend({
640				rawTileData: rawData.slice(0),
641				encoding: "mvt"
642			}, result);
643			this.tileState.removeParsing(workerTile.uid);
644		}
645		return result;
646	}
647	/**
648	* Implements {@link WorkerSource.abortTile}.
649	*/
650	async abortTile(params) {
651		this.tileState.abort(params.uid);
652	}
653	/**
654	* Implements {@link WorkerSource.removeTile}.
655	*/
656	async removeTile(params) {
657		this.tileState.removeLoaded(params.uid);
658	}
659	/**
660	* Fetches (if appropriate), parses and indexes geojson data into tiles. This
661	* preparatory method must be called before {@link GeoJSONWorkerSource.loadTile}
662	* can correctly serve up tiles. The first call to this method must contain a valid
663	* {@link params.data}, {@link params.request} or {@link params.dataDiff}. Subsequent
664	* calls may omit these parameters to reprocess the existing data (such as to update
665	* clustering options).
666	*
667	* Defers to {@link GeoJSONWorkerSource.loadAndProcessGeoJSON} for the pre-processing.
668	*
669	* When a `loadData` request comes in while a previous one is being processed,
670	* the previous one is aborted.
671	*
672	* @param params - the parameters
673	* @returns a promise that resolves when the data is loaded and parsed into a GeoJSON object
674	*/
675	async loadData(params) {
676		this._pendingRequest?.abort();
677		const timing = this._startRequestTiming(params);
678		this._pendingRequest = new AbortController();
679		try {
680			await this.loadAndProcessGeoJSON(params, this._pendingRequest);
681			delete this._pendingRequest;
682			this.tileState.clearLoaded();
683			const result = {};
684			if (params.request) result.data = params.data;
685			this._finishRequestTiming(timing, params, result);
686			return result;
687		} catch (err) {
688			delete this._pendingRequest;
689			if (!isAbortError(err)) throw err;
690			return { abandoned: true };
691		}
692	}
693	_startRequestTiming(params) {
694		if (!params.request?.collectResourceTiming) return;
695		return new RequestPerformance(params.request.url);
696	}
697	_finishRequestTiming(timing, params, result) {
698		const timingData = timing?.finish();
699		if (!timingData) return;
700		result.resourceTiming = { [params.source]: JSON.parse(JSON.stringify(timingData)) };
701	}
702	/**
703	* Implements {@link WorkerSource.reloadTile}.
704	*
705	* If the tile is loaded, reload by re-parsing the already available tile data.
706	* Otherwise, such as after a setData() call, we load the tile fresh.
707	*
708	* @param params - the parameters
709	* @returns A promise that resolves when the tile is reloaded
710	*/
711	async reloadTile(params) {
712		const uid = params.uid;
713		const workerTile = this.tileState.getLoaded(uid);
714		if (!workerTile) return await this.loadTile(params);
715		if (!workerTile.vectorTile) return;
716		workerTile.showCollisionBoxes = params.showCollisionBoxes;
717		return await this._parseWorkerTile(workerTile, params);
718	}
719	/**
720	* Fetch, parse and process GeoJSON according to the given parameters.
721	* Defers to {@link GeoJSONWorkerSource._loadGeoJSONFromString} for the fetching and parsing.
722	*
723	* @param params - the parameters
724	* @param abortController - the abort controller that allows aborting this operation
725	* @returns a promise that is resolved with the processes GeoJSON
726	*/
727	async loadAndProcessGeoJSON(params, abortController) {
728		if (params.request) params.data = (await getJSON(params.request, abortController)).data;
729		if (params.data) {
730			params.data = this._filterGeoJSON(params.data, params.filter, params.source);
731			this._geoJSONIndex = this._createGeoJSONIndex(params.data, params);
732			return;
733		}
734		if (params.dataDiff) {
735			this._geoJSONIndex ??= this._createGeoJSONIndex({
736				type: "FeatureCollection",
737				features: []
738			}, params);
739			this._geoJSONIndex.updateData(params.dataDiff, this._getFilterPredicate(params.filter, params.source));
740			return;
741		}
742		if (params.updateCluster) this._geoJSONIndex.updateClusterOptions(params.geojsonVtOptions.cluster, getSuperclusterOptions(params));
743		if (this._geoJSONIndex == null) throw new Error(`Input data given to '${params.source}' is not a valid GeoJSON object.`);
744	}
745	/**
746	* Applies a filter to a GeoJSON object.
747	*/
748	_filterGeoJSON(data, filter, source) {
749		if (data.type !== "FeatureCollection") return data;
750		const predicate = this._getFilterPredicate(filter, source);
751		if (!predicate) return data;
752		return {
753			type: "FeatureCollection",
754			features: data.features.filter((feature) => predicate(feature))
755		};
756	}
757	/**
758	* Gets a predicate function that can be used to filter GeoJSON features.
759	*/
760	_getFilterPredicate(filter, source) {
761		if (typeof filter !== "boolean" && !filter?.length) return void 0;
762		const compiled = createExpression(filter, `sources.${source}.filter`, {
763			type: "boolean",
764			"property-type": "data-driven",
765			overridable: false,
766			transition: false
767		});
768		if (compiled.result === "error") throw new Error(compiled.value.map((err) => `${err.key}: ${err.message}`).join(", "));
769		return (feature) => compiled.value.evaluate({ zoom: 0 }, feature);
770	}
771	async removeSource(_params) {
772		this._pendingRequest?.abort();
773	}
774	getClusterExpansionZoom(params) {
775		return this._geoJSONIndex.getClusterExpansionZoom(params.clusterId);
776	}
777	getClusterChildren(params) {
778		return this._geoJSONIndex.getClusterChildren(params.clusterId);
779	}
780	getClusterLeaves(params) {
781		return this._geoJSONIndex.getClusterLeaves(params.clusterId, params.limit, params.offset);
782	}
783};
784function createGeoJSONIndex(data, params) {
785	const options = extend(params.geojsonVtOptions || {}, {
786		updateable: true,
787		clusterOptions: getSuperclusterOptions(params)
788	});
789	return new GeoJSONVT(data, options);
790}
791function getSuperclusterOptions({ geojsonVtOptions, clusterProperties, source }) {
792	if (!clusterProperties || !geojsonVtOptions.clusterOptions) return geojsonVtOptions.clusterOptions;
793	const mapExpressions = {};
794	const reduceExpressions = {};
795	const globals = {
796		accumulated: null,
797		zoom: 0
798	};
799	const feature = { properties: null };
800	const propertyNames = Object.keys(clusterProperties);
801	for (const key of propertyNames) {
802		const [operator, mapExpression] = clusterProperties[key];
803		const mapExpressionParsed = createExpression(mapExpression, `sources.${source}.clusterProperties.${key}[1]`);
804		const reduceExpressionParsed = createExpression(typeof operator === "string" ? [
805			operator,
806			["accumulated"],
807			["get", key]
808		] : operator, `sources.${source}.clusterProperties.${key}[0]`);
809		mapExpressions[key] = mapExpressionParsed.value;
810		reduceExpressions[key] = reduceExpressionParsed.value;
811	}
812	geojsonVtOptions.clusterOptions.map = (pointProperties) => {
813		feature.properties = pointProperties;
814		const properties = {};
815		for (const key of propertyNames) properties[key] = mapExpressions[key].evaluate(globals, feature);
816		return properties;
817	};
818	geojsonVtOptions.clusterOptions.reduce = (accumulated, clusterProperties) => {
819		feature.properties = clusterProperties;
820		for (const key of propertyNames) {
821			globals.accumulated = accumulated[key];
822			accumulated[key] = reduceExpressions[key].evaluate(globals, feature);
823		}
824	};
825	return geojsonVtOptions.clusterOptions;
826}
827//#endregion
828//#region src/source/worker.ts
829/**
830* Loads an external script into worker (global) scope. The loader picks a
831* strategy based on what the script actually is:
832*
833* - `.mjs` URLs: dynamic `import()` directly, no fetch/sniff overhead. Worker
834*   CSP needs `script-src` to permit the URL.
835*
836* - Other URLs: fetch the source and sniff for ESM syntax (top-level `import`
837*   or `export`). If ESM is detected, run it through a blob-URL dynamic
838*   `import()` so the browser parses it as a module; this requires
839*   `script-src blob:` in the worker CSP. Otherwise treat it as UMD/IIFE and
840*   run it via `globalThis.eval`, which requires `script-src 'unsafe-eval'`.
841*/
842async function loadScript(url) {
843	if (url.endsWith(".mjs")) {
844		await import(
845			/* @vite-ignore */
846			url
847);
848		return;
849	}
850	const response = await fetch(url, { credentials: "same-origin" });
851	if (!response.ok) throw new Error(`Failed to load ${url}: ${response.status}`);
852	const code = await response.text();
853	if (/^[ \t]*(import|export)\s/m.test(code)) {
854		const blobUrl = URL.createObjectURL(new Blob([code], { type: "text/javascript" }));
855		try {
856			await import(
857				/* @vite-ignore */
858				blobUrl
859);
860		} finally {
861			URL.revokeObjectURL(blobUrl);
862		}
863		return;
864	}
865	globalThis.eval(code);
866}
867/**
868* The Worker class responsible for background thread related execution
869*/
870var Worker = class {
871	constructor(self) {
872		this.self = self;
873		this.actor = new Actor(self);
874		this.layerIndexes = {};
875		this.availableImages = {};
876		this.workerSources = {};
877		this.demWorkerSources = {};
878		this.externalWorkerSourceTypes = {};
879		this.globalStates = /* @__PURE__ */ new Map();
880		this.self.registerWorkerSource = (name, WorkerSource) => {
881			if (this.externalWorkerSourceTypes[name]) throw new Error(`Worker source with name "${name}" already registered.`);
882			this.externalWorkerSourceTypes[name] = WorkerSource;
883		};
884		this.self.addProtocol = addProtocol;
885		this.self.removeProtocol = removeProtocol;
886		this.self.registerRTLTextPlugin = (rtlTextPlugin) => {
887			rtlWorkerPlugin.setMethods(rtlTextPlugin);
888		};
889		this.self.makeRequest = makeRequest;
890		this.actor.registerMessageHandler("LDT", (mapId, params) => {
891			return this._getDEMWorkerSource(mapId, params.source).loadTile(params);
892		});
893		this.actor.registerMessageHandler("RDT", async (mapId, params) => {
894			this._getDEMWorkerSource(mapId, params.source).removeTile(params);
895		});
896		this.actor.registerMessageHandler("GCEZ", async (mapId, params) => {
897			return this._getWorkerSource(mapId, params.type, params.source).getClusterExpansionZoom(params);
898		});
899		this.actor.registerMessageHandler("GCC", async (mapId, params) => {
900			return this._getWorkerSource(mapId, params.type, params.source).getClusterChildren(params);
901		});
902		this.actor.registerMessageHandler("GCL", async (mapId, params) => {
903			return this._getWorkerSource(mapId, params.type, params.source).getClusterLeaves(params);
904		});
905		this.actor.registerMessageHandler("LD", (mapId, params) => {
906			return this._getWorkerSource(mapId, params.type, params.source).loadData(params);
907		});
908		this.actor.registerMessageHandler("LT", (mapId, params) => {
909			return this._getWorkerSource(mapId, params.type, params.source).loadTile(params);
910		});
911		this.actor.registerMessageHandler("RT", (mapId, params) => {
912			return this._getWorkerSource(mapId, params.type, params.source).reloadTile(params);
913		});
914		this.actor.registerMessageHandler("AT", (mapId, params) => {
915			return this._getWorkerSource(mapId, params.type, params.source).abortTile(params);
916		});
917		this.actor.registerMessageHandler("RMT", (mapId, params) => {
918			return this._getWorkerSource(mapId, params.type, params.source).removeTile(params);
919		});
920		this.actor.registerMessageHandler("RS", async (mapId, params) => {
921			if (!this.workerSources[mapId]?.[params.type]?.[params.source]) return;
922			const worker = this.workerSources[mapId][params.type][params.source];
923			delete this.workerSources[mapId][params.type][params.source];
924			if (worker.removeSource !== void 0) worker.removeSource(params);
925		});
926		this.actor.registerMessageHandler("RM", async (mapId) => {
927			delete this.layerIndexes[mapId];
928			delete this.availableImages[mapId];
929			delete this.workerSources[mapId];
930			delete this.demWorkerSources[mapId];
931			this.globalStates.delete(mapId);
932		});
933		this.actor.registerMessageHandler("SR", async (_mapId, params) => {
934			this.referrer = params;
935		});
936		this.actor.registerMessageHandler("SRPS", (mapId, params) => {
937			return this._syncRTLPluginState(mapId, params);
938		});
939		this.actor.registerMessageHandler("IS", async (_mapId, params) => {
940			await loadScript(params);
941		});
942		this.actor.registerMessageHandler("SI", (mapId, params) => {
943			return this._setImages(mapId, params);
944		});
945		this.actor.registerMessageHandler("UL", async (mapId, params) => {
946			this._getLayerIndex(mapId).update(params.layers, params.removedIds, this._getGlobalState(mapId));
947		});
948		this.actor.registerMessageHandler("UGS", async (mapId, params) => {
949			const globalState = this._getGlobalState(mapId);
950			for (const key in params) globalState[key] = params[key];
951		});
952		this.actor.registerMessageHandler("SL", async (mapId, params) => {
953			this._getLayerIndex(mapId).replace(params, this._getGlobalState(mapId));
954		});
955	}
956	_getGlobalState(mapId) {
957		let state = this.globalStates.get(mapId);
958		if (!state) {
959			state = {};
960			this.globalStates.set(mapId, state);
961		}
962		return state;
963	}
964	async _setImages(mapId, images) {
965		this.availableImages[mapId] = images;
966		for (const workerSource in this.workerSources[mapId]) {
967			const ws = this.workerSources[mapId][workerSource];
968			for (const source in ws) ws[source].availableImages = images;
969		}
970	}
971	async _syncRTLPluginState(mapId, incomingState) {
972		return await rtlWorkerPlugin.syncState(incomingState, loadScript);
973	}
974	_getAvailableImages(mapId) {
975		let availableImages = this.availableImages[mapId];
976		availableImages ||= [];
977		return availableImages;
978	}
979	_getLayerIndex(mapId) {
980		let layerIndexes = this.layerIndexes[mapId];
981		layerIndexes ||= this.layerIndexes[mapId] = new StyleLayerIndex();
982		return layerIndexes;
983	}
984	/**
985	* This is basically a lazy initialization of a worker per mapId and sourceType and sourceName
986	* @param mapId - the mapId
987	* @param sourceType - the source type - 'vector' for example
988	* @param sourceName - the source name - 'osm' for example
989	* @returns a new instance or a cached one
990	*/
991	_getWorkerSource(mapId, sourceType, sourceName) {
992		this.workerSources[mapId] ||= {};
993		this.workerSources[mapId][sourceType] ||= {};
994		if (!this.workerSources[mapId][sourceType][sourceName]) {
995			const actor = { sendAsync: (message, abortController) => {
996				message.targetMapId = mapId;
997				return this.actor.sendAsync(message, abortController);
998			} };
999			switch (sourceType) {
1000				case "vector":
1001					this.workerSources[mapId][sourceType][sourceName] = new VectorTileWorkerSource(actor, this._getLayerIndex(mapId), this._getAvailableImages(mapId));
1002					break;
1003				case "geojson":
1004					this.workerSources[mapId][sourceType][sourceName] = new GeoJSONWorkerSource(actor, this._getLayerIndex(mapId), this._getAvailableImages(mapId));
1005					break;
1006				default: this.workerSources[mapId][sourceType][sourceName] = new this.externalWorkerSourceTypes[sourceType](actor, this._getLayerIndex(mapId), this._getAvailableImages(mapId));
1007			}
1008		}
1009		return this.workerSources[mapId][sourceType][sourceName];
1010	}
1011	/**
1012	* This is basically a lazy initialization of a worker per mapId and source
1013	* @param mapId - the mapId
1014	* @param sourceType - the source type - 'raster-dem' for example
1015	* @returns a new instance or a cached one
1016	*/
1017	_getDEMWorkerSource(mapId, sourceType) {
1018		this.demWorkerSources[mapId] ||= {};
1019		this.demWorkerSources[mapId][sourceType] ||= new RasterDEMTileWorkerSource();
1020		return this.demWorkerSources[mapId][sourceType];
1021	}
1022};
1023if (isWorker(self)) self.worker = new Worker(self);
1024//#endregion
1025export { Worker as default };
1026
1027//# sourceMappingURL=maplibre-gl-worker-dev.mjs.map

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.