.zip` with the
+ GeoPackage inside. The largest `.gpkg` member wins if there are several;
+ anything else in the archive (metadata PDFs, licence texts) is ignored.
+ """
+ import io
+ import zipfile
+
+ try:
+ with zipfile.ZipFile(io.BytesIO(payload)) as zf:
+ members = [i for i in zf.infolist() if i.filename.lower().endswith(".gpkg")]
+ if not members:
+ raise BuildingLookupError(
+ "the building tile ZIP holds no GeoPackage"
+ )
+ member = max(members, key=lambda i: i.file_size)
+ return zf.read(member)
+ except zipfile.BadZipFile as exc:
+ raise BuildingLookupError(
+ f"the building tile was announced as ZIP but did not open: {exc}"
+ ) from exc
+
+
+def _features_from_item(
+ item: StacItem,
+ client: GeotorgetClient | None = None,
+ window_boxes: list[tuple[float, float, float, float]] | None = None,
+) -> list[dict[str, Any]]:
+ """Every building-like feature an item carries.
+
+ A STAC item may *be* the building -- geometry inline, no download -- or it
+ may be a tile whose asset holds thousands of them. Lantmaeteriet's live
+ catalogue publishes `byggnader` as one zipped **GeoPackage** per
+ municipality, so the asset path is the normal one and the inline path the
+ exception — and `window_boxes` (the search window, in each frame the file
+ could be in) keeps a whole city from being decoded for a 150 m search.
+ """
+ # A usable data asset wins over the item's own geometry: a tile item's
+ # geometry is the TILE's outline — for Lantmaeteriet, the whole
+ # municipality — and reading it as a building both invents a footprint
+ # nobody has and skips the real ones in the asset. Inline geometry is the
+ # fallback for catalogues whose items *are* the buildings.
+ asset = item.pick(MEDIA_GEOPACKAGE, MEDIA_ZIP, MEDIA_GEOJSON)
+ if asset is None or not asset.href or client is None:
+ geom = (item.raw or {}).get("geometry")
+ if geom:
+ return [{"geometry": geom, "properties": (item.raw or {}).get("properties") or {},
+ "id": item.item_id}]
+ return []
+ media = asset.effective_media_type
+ payload = client.download(asset.href)
+ if media == MEDIA_GEOJSON:
+ return _features_from_geojson(payload)
+ if payload[:4] == b"PK\x03\x04":
+ payload = _gpkg_from_zip(payload)
+ try:
+ return read_features(payload, bboxes=window_boxes)
+ except GeoPackageError as exc:
+ raise BuildingLookupError(
+ f"the building tile for this site could not be read: {exc}"
+ ) from exc
+
+
+def _features_from_geojson(payload: bytes) -> list[dict[str, Any]]:
+ """A GeoJSON FeatureCollection asset, for catalogues that publish one."""
+ import json
+
+ try:
+ doc = json.loads(payload.decode("utf-8"))
+ except (UnicodeDecodeError, ValueError) as exc:
+ raise BuildingLookupError(
+ f"the building tile was announced as GeoJSON but did not parse: {exc}"
+ ) from exc
+ if isinstance(doc, dict) and doc.get("type") == "FeatureCollection":
+ return list(doc.get("features") or [])
+ if isinstance(doc, dict) and doc.get("type") == "Feature":
+ return [doc]
+ return []
+
+
+def buildings_from_features(
+ features: Iterable[dict[str, Any]],
+ *,
+ latitude: float,
+ longitude: float,
+ fallback_id: str = "building",
+) -> list[Building]:
+ """Turn GeoJSON-ish features into ranked Building candidates."""
+ site_n, site_e = sweref.wgs84_to_sweref99tm(latitude, longitude)
+ out: list[Building] = []
+ for i, feat in enumerate(features):
+ for j, ring in enumerate(_rings_from_geometry(feat.get("geometry") or {})):
+ ring_sweref = _to_sweref(ring)
+ area = _shoelace_area(ring_sweref)
+ if area < MIN_FOOTPRINT_AREA_M2 or area > MAX_FOOTPRINT_AREA_M2:
+ continue
+ cx, cy = _centroid(ring_sweref)
+ props = dict(feat.get("properties") or {})
+ bid = str(feat.get("id") or props.get("objektidentitet") or f"{fallback_id}-{i}")
+ if j:
+ bid = f"{bid}-{j}"
+ out.append(Building(
+ building_id=bid,
+ ring_sweref=ring_sweref,
+ area_m2=area,
+ distance_m=math.hypot(cx - site_e, cy - site_n),
+ properties={k: v for k, v in props.items() if isinstance(v, (str, int, float))},
+ ))
+ out.sort(key=lambda b: b.distance_m)
+ return out
+
+
+def search_buildings(
+ client: GeotorgetClient,
+ *,
+ latitude: float,
+ longitude: float,
+ radius_m: float = DEFAULT_SEARCH_RADIUS_M,
+ limit: int = 50,
+ collection: str = COLLECTION_BUILDINGS,
+ bbox_epsg: int = 4326,
+) -> list[Building]:
+ """Building footprints near a site, nearest first."""
+ bbox = sweref.stac_search_bbox(latitude, longitude, radius_m, bbox_epsg)
+ # The same window in every frame and axis order a tile could be stored
+ # in. Coordinate magnitude keeps the frames apart (degrees never look
+ # like metres), and carrying both axis orders costs nothing but a few
+ # extra decoded rows — a box only ever widens what is kept.
+ def swapped(b):
+ return (b[1], b[0], b[3], b[2])
+
+ wgs = sweref.stac_search_bbox(latitude, longitude, radius_m, 4326)
+ swe = sweref.stac_search_bbox(latitude, longitude, radius_m, 3006)
+ window_boxes = [wgs, swapped(wgs), swe, swapped(swe)]
+ items = client.search(collection, bbox, limit=limit)
+ features: list[dict[str, Any]] = []
+ for item in items:
+ features.extend(_features_from_item(item, client, window_boxes))
+ if not features:
+ raise BuildingLookupError(
+ "no building footprints were returned for this site. The Geotorget "
+ "account needs access to 'Byggnad Nedladdning, vektor', and the data "
+ "covers Sweden only."
+ )
+ return buildings_from_features(
+ features, latitude=latitude, longitude=longitude
+ )
+
+
+def point_in_ring(x: float, y: float, ring: list[tuple[float, float]]) -> bool:
+ """Ray-casting point-in-polygon, in the ring's own projected frame."""
+ inside = False
+ n = len(ring)
+ for i in range(n):
+ x1, y1 = ring[i]
+ x2, y2 = ring[(i + 1) % n]
+ if (y1 > y) != (y2 > y):
+ if y2 != y1 and x < x1 + (y - y1) * (x2 - x1) / (y2 - y1):
+ inside = not inside
+ return inside
+
+
+def inflate_ring(ring: list[tuple[float, float]], metres: float) -> list[tuple[float, float]]:
+ """Push a ring outward from its centroid by roughly `metres`.
+
+ Approximate on purpose: a true polygon offset needs a geometry library, and
+ this only has to catch the eaves. For the compact, roughly convex outlines
+ houses actually have, scaling about the centroid is within a few centimetres
+ of a proper offset; for a long thin wing it over-buffers the short sides,
+ which costs a little neighbouring ground rather than losing roof.
+ """
+ if metres <= 0 or len(ring) < 3:
+ return ring
+ cx, cy = _centroid(ring)
+ out = []
+ for x, y in ring:
+ dx, dy = x - cx, y - cy
+ d = math.hypot(dx, dy)
+ if d < 1e-9:
+ out.append((x, y))
+ continue
+ scale = (d + metres) / d
+ out.append((cx + dx * scale, cy + dy * scale))
+ return out
+
+
+def clip_to_footprint(points, ring: list[tuple[float, float]],
+ *, buffer_m: float = DEFAULT_EAVES_BUFFER_M):
+ """Keep only the returns standing on one building.
+
+ `points` is (N, 3) in SWEREF 99 TM metres, the frame the LiDAR arrives in.
+ """
+ import numpy as np
+
+ pts = np.asarray(points, dtype=float)
+ if len(pts) == 0 or len(ring) < 3:
+ return pts
+ outline = inflate_ring(ring, buffer_m)
+
+ # Cheap rejection first: most of a tile is nowhere near the building.
+ xs = [p[0] for p in outline]
+ ys = [p[1] for p in outline]
+ box = (
+ (pts[:, 0] >= min(xs)) & (pts[:, 0] <= max(xs))
+ & (pts[:, 1] >= min(ys)) & (pts[:, 1] <= max(ys))
+ )
+ candidates = np.nonzero(box)[0]
+ keep = [i for i in candidates if point_in_ring(pts[i, 0], pts[i, 1], outline)]
+ return pts[keep]
diff --git a/roofmodel/ftw_roofmodel/geopackage.py b/roofmodel/ftw_roofmodel/geopackage.py
new file mode 100644
index 000000000..76e3c757c
--- /dev/null
+++ b/roofmodel/ftw_roofmodel/geopackage.py
@@ -0,0 +1,303 @@
+"""Read polygon features out of a GeoPackage, using only the standard library.
+
+Lantmaeteriet publishes *Byggnad Nedladdning, vektor* as GeoPackage, so a STAC
+item for a building tile carries a `.gpkg` asset rather than inline GeoJSON.
+
+A GeoPackage is a SQLite database with an agreed set of metadata tables, and
+geometry stored as a small binary header followed by standard WKB. Both are
+published specifications with fixed layouts, so decoding them here costs about
+a hundred lines of `sqlite3` and `struct` -- against a GDAL/fiona/geopandas
+dependency that would not install on a Pi without a compiler and pulls in a
+second projection stack we already decided not to carry (see sweref.py, which
+implements SWEREF 99 TM directly for the same reason).
+
+Only what a roof model needs is read: polygon and multipolygon rings, in the
+file's own coordinate reference system. Curves, triangulated surfaces and the
+extended (`GPB` "extended geometry") binary types are rejected explicitly rather
+than mis-parsed, because a wrong ring silently clips the wrong LiDAR.
+
+References
+----------
+GeoPackage Encoding Standard (OGC 12-128r19), clause 2.1.3 "BLOB Format".
+OpenGIS Simple Features (OGC 06-103r4), clause 8.2 "Well-known Binary".
+"""
+
+from __future__ import annotations
+
+import os
+import sqlite3
+import struct
+import tempfile
+from typing import Any, Iterator
+
+# "GP" -- the two magic bytes every GeoPackage geometry blob starts with.
+GPKG_MAGIC = b"GP"
+
+# Envelope sizes in doubles, indexed by the header's envelope indicator.
+# 0 = absent, 1 = xy, 2 = xyz, 3 = xym, 4 = xyzm. 5-7 are reserved.
+_ENVELOPE_DOUBLES = {0: 0, 1: 4, 2: 6, 3: 6, 4: 8}
+
+# WKB geometry type codes we can use. The ISO variants add 1000 for Z, 2000 for
+# M and 3000 for ZM, so the base code is recovered with % 1000.
+_WKB_POLYGON = 3
+_WKB_MULTIPOLYGON = 6
+
+# The EWKB flag bits PostGIS adds to the type word. GeoPackage forbids them, but
+# files written by other tools do turn up, and reading a flagged type as a
+# geometry code would silently produce nonsense.
+_EWKB_Z = 0x80000000
+_EWKB_M = 0x40000000
+_EWKB_SRID = 0x20000000
+
+
+class GeoPackageError(ValueError):
+ """The file is not a GeoPackage, or holds geometry we will not guess at."""
+
+
+def _unpack(fmt: str, data: bytes, offset: int) -> tuple[Any, ...]:
+ size = struct.calcsize(fmt)
+ if offset + size > len(data):
+ raise GeoPackageError("geometry blob ended mid-value")
+ return struct.unpack_from(fmt, data, offset)
+
+
+def _dimensions(type_word: int) -> tuple[int, int]:
+ """(base geometry code, coordinates per point) for a WKB type word."""
+ has_z = bool(type_word & _EWKB_Z)
+ has_m = bool(type_word & _EWKB_M)
+ code = type_word & ~(_EWKB_Z | _EWKB_M | _EWKB_SRID)
+ # ISO style: 1000/2000/3000 offsets carry the same information.
+ if code >= 3000:
+ code, has_z, has_m = code - 3000, True, True
+ elif code >= 2000:
+ code, has_m = code - 2000, True
+ elif code >= 1000:
+ code, has_z = code - 1000, True
+ return code, 2 + int(has_z) + int(has_m)
+
+
+def _read_ring(data: bytes, offset: int, endian: str, coords: int) -> tuple[list[tuple[float, float]], int]:
+ (count,) = _unpack(endian + "I", data, offset)
+ offset += 4
+ stride = 8 * coords
+ ring: list[tuple[float, float]] = []
+ for _ in range(count):
+ x, y = _unpack(endian + "dd", data, offset)
+ ring.append((x, y))
+ offset += stride
+ return ring, offset
+
+
+def _read_polygon(data: bytes, offset: int, endian: str, coords: int) -> tuple[list[list[tuple[float, float]]], int]:
+ (n_rings,) = _unpack(endian + "I", data, offset)
+ offset += 4
+ rings = []
+ for _ in range(n_rings):
+ ring, offset = _read_ring(data, offset, endian, coords)
+ rings.append(ring)
+ return rings, offset
+
+
+def _read_geometry(data: bytes, offset: int) -> tuple[list[list[list[tuple[float, float]]]], int]:
+ """Read one WKB geometry, returning it as a list of polygons."""
+ (byte_order,) = _unpack("B", data, offset)
+ endian = "<" if byte_order == 1 else ">"
+ (type_word,) = _unpack(endian + "I", data, offset + 1)
+ offset += 5
+ if type_word & _EWKB_SRID:
+ offset += 4 # embedded SRID, which we take from the header instead
+ code, coords = _dimensions(type_word)
+ if code == _WKB_POLYGON:
+ rings, offset = _read_polygon(data, offset, endian, coords)
+ return [rings], offset
+ if code == _WKB_MULTIPOLYGON:
+ (n,) = _unpack(endian + "I", data, offset)
+ offset += 4
+ polys = []
+ for _ in range(n):
+ # Each part carries its own byte order and type word.
+ part, offset = _read_geometry(data, offset)
+ polys.extend(part)
+ return polys, offset
+ raise GeoPackageError(
+ f"WKB geometry type {code} is not a polygon; a building footprint must be "
+ "a Polygon or MultiPolygon"
+ )
+
+
+def parse_geometry_blob(blob: bytes) -> dict[str, Any] | None:
+ """Decode a GeoPackage geometry BLOB into a GeoJSON-shaped geometry.
+
+ Returns None for the empty geometry, which GeoPackage represents with a flag
+ rather than an absent row.
+ """
+ if len(blob) < 8 or blob[:2] != GPKG_MAGIC:
+ raise GeoPackageError("not a GeoPackage geometry blob (bad magic)")
+ flags = blob[3]
+ if flags & 0x20:
+ raise GeoPackageError(
+ "extended (ExtendedGeoPackageBinary) geometry is not supported"
+ )
+ envelope_indicator = (flags >> 1) & 0x07
+ if envelope_indicator not in _ENVELOPE_DOUBLES:
+ raise GeoPackageError(f"reserved envelope indicator {envelope_indicator}")
+ if flags & 0x10: # empty geometry
+ return None
+ offset = 8 + 8 * _ENVELOPE_DOUBLES[envelope_indicator]
+ polygons, _ = _read_geometry(blob, offset)
+ if not polygons:
+ return None
+ if len(polygons) == 1:
+ return {"type": "Polygon", "coordinates": [[list(p) for p in r] for r in polygons[0]]}
+ return {
+ "type": "MultiPolygon",
+ "coordinates": [[[list(p) for p in r] for r in poly] for poly in polygons],
+ }
+
+
+def _feature_tables(conn: sqlite3.Connection) -> list[tuple[str, str]]:
+ """(table, geometry column) for every feature table in the file."""
+ try:
+ rows = conn.execute(
+ "SELECT c.table_name, g.column_name FROM gpkg_contents c "
+ "JOIN gpkg_geometry_columns g ON g.table_name = c.table_name "
+ "WHERE c.data_type = 'features'"
+ ).fetchall()
+ except sqlite3.DatabaseError as exc:
+ raise GeoPackageError(f"not a readable GeoPackage: {exc}") from exc
+ return [(str(t), str(c)) for t, c in rows]
+
+
+def _blob_envelope(blob: bytes) -> tuple[float, float, float, float] | None:
+ """The header envelope of a geometry blob as (minx, miny, maxx, maxy).
+
+ GeoPackage stores it as [minx, maxx, miny, maxy] doubles right after the
+ 8-byte header (OGC 12-128r19, clause 2.1.3), in the header's own byte
+ order. None when the writer chose not to include one.
+ """
+ if len(blob) < 8 or blob[:2] != GPKG_MAGIC:
+ return None
+ flags = blob[3]
+ if ((flags >> 1) & 0x07) == 0 or flags & 0x10:
+ return None
+ endian = "<" if flags & 0x01 else ">"
+ try:
+ minx, maxx, miny, maxy = _unpack(endian + "dddd", blob, 8)
+ except GeoPackageError:
+ return None
+ return (minx, miny, maxx, maxy)
+
+
+def _intersects(a: tuple[float, float, float, float], b: tuple[float, float, float, float]) -> bool:
+ return a[0] <= b[2] and a[2] >= b[0] and a[1] <= b[3] and a[3] >= b[1]
+
+
+def _geometry_bounds(geometry: dict[str, Any]) -> tuple[float, float, float, float] | None:
+ """(minx, miny, maxx, maxy) over every ring of a parsed geometry.
+
+ The fallback when a writer omitted the header envelope — Lantmaeteriet's
+ municipality files do (flags 0x00 on every blob), so without this the
+ bbox filter would keep all 90k+ rows and the row limit would truncate the
+ table before it ever reached the site.
+ """
+ polys = geometry.get("coordinates") or []
+ if geometry.get("type") == "Polygon":
+ polys = [polys]
+ xs: list[float] = []
+ ys: list[float] = []
+ for poly in polys:
+ for ring in poly:
+ for point in ring:
+ xs.append(point[0])
+ ys.append(point[1])
+ if not xs:
+ return None
+ return (min(xs), min(ys), max(xs), max(ys))
+
+
+def read_features(
+ data: bytes,
+ *,
+ limit: int = 5000,
+ bboxes: list[tuple[float, float, float, float]] | None = None,
+) -> list[dict[str, Any]]:
+ """Every polygon feature in a GeoPackage, as GeoJSON-shaped dicts.
+
+ Attributes travel alongside the geometry so the picker can label a building
+ with whatever the source calls it.
+
+ `bboxes` filters by the geometry blobs' header envelopes: a row is kept
+ when its envelope intersects ANY of the boxes (each (minx, miny, maxx,
+ maxy)). More than one box exists because the file's CRS isn't declared to
+ this reader — the caller passes the same window in every frame the file
+ could be in, and the frames' coordinate magnitudes are so far apart
+ (degrees vs. six-figure metres) that only the matching one can intersect.
+ Lantmaeteriet ships one GeoPackage per *municipality*, so without a filter
+ a 150 m search would decode a whole city.
+ """
+ return list(iter_features(data, limit=limit, bboxes=bboxes))
+
+
+def iter_features(
+ data: bytes,
+ *,
+ limit: int = 5000,
+ bboxes: list[tuple[float, float, float, float]] | None = None,
+) -> Iterator[dict[str, Any]]:
+ if not data.startswith(b"SQLite format 3\x00"):
+ raise GeoPackageError(
+ "asset is not a GeoPackage (missing the SQLite file header)"
+ )
+ # sqlite3 opens paths, not buffers, and a GeoPackage is random-access by
+ # design, so the bytes land in a temp file for the life of the read.
+ fd, path = tempfile.mkstemp(suffix=".gpkg")
+ try:
+ with os.fdopen(fd, "wb") as fh:
+ fh.write(data)
+ conn = sqlite3.connect(path)
+ try:
+ conn.row_factory = sqlite3.Row
+ yielded = 0
+ for table, geom_col in _feature_tables(conn):
+ cursor = conn.execute(f'SELECT * FROM "{table}"')
+ for row in cursor:
+ if yielded >= limit:
+ return
+ blob = row[geom_col]
+ if not isinstance(blob, (bytes, bytearray)):
+ continue
+ env = None
+ if bboxes:
+ env = _blob_envelope(bytes(blob))
+ if env is not None and not any(_intersects(env, b) for b in bboxes):
+ continue
+ try:
+ geometry = parse_geometry_blob(bytes(blob))
+ except GeoPackageError:
+ # One unreadable row must not lose the other buildings
+ # in the tile.
+ continue
+ if geometry is None:
+ continue
+ if bboxes and env is None:
+ bounds = _geometry_bounds(geometry)
+ if bounds is not None and not any(_intersects(bounds, b) for b in bboxes):
+ continue
+ props = {
+ k: row[k]
+ for k in row.keys()
+ if k != geom_col and isinstance(row[k], (str, int, float))
+ }
+ yield {
+ "id": str(props.get("objektidentitet") or f"{table}-{yielded}"),
+ "geometry": geometry,
+ "properties": props,
+ }
+ yielded += 1
+ finally:
+ conn.close()
+ finally:
+ try:
+ os.unlink(path)
+ except OSError: # pragma: no cover - Windows may hold the handle briefly
+ pass
diff --git a/roofmodel/ftw_roofmodel/geotorget.py b/roofmodel/ftw_roofmodel/geotorget.py
new file mode 100644
index 000000000..bbe4a13e6
--- /dev/null
+++ b/roofmodel/ftw_roofmodel/geotorget.py
@@ -0,0 +1,326 @@
+"""STAC catalog access: authentication, search, and asset download.
+
+The default catalog is Lantmaeteriet's Geotorget, where two products are used,
+both free open data (CC BY 4.0) but both gated behind a Geotorget account the
+operator orders themselves:
+
+ * *Byggnad Nedladdning, vektor* -- building footprint polygons.
+ * *Laserdata Nedladdning, Skog* -- airborne LiDAR, 1-2 points/m2, from 2018.
+
+Authentication is HTTP Basic with the operator's own Geotorget account
+username and password: Lantmaeteriet provides no OAuth for its STAC download
+APIs, so the account credential is the only door. Credentials are the
+operator's own and are never shipped, logged or echoed back through the API.
+FTW stores them the same way it stores `weather.api_key`, and redacts them in
+config responses.
+
+Nothing below is Lantmaeteriet-specific beyond the defaults: search is the
+standard `POST {base}/search` of the STAC API spec and downloads follow asset
+hrefs, so any STAC-conformant catalog behind Basic auth (or none) works by
+pointing `base_url` and the collection ids elsewhere. The one non-standard
+wrinkle is the search bbox CRS -- the spec mandates WGS84, Lantmaeteriet
+expects SWEREF 99 TM -- which is why callers choose the bbox they send (see
+`--bbox-epsg` in __main__).
+
+Only `requests` is used. The STAC API is plain JSON over HTTP, so pulling in
+pystac-client would add a dependency for a search body we can write in six
+lines -- and a thinner surface is easier to keep working when Lantmaeteriet
+moves an endpoint.
+"""
+
+from __future__ import annotations
+
+import dataclasses
+import datetime as dt
+from typing import Any, Iterable
+
+# Roots of the STAC APIs, as verified against the live service (2026-09-02):
+# Lantmaeteriet does not serve one catalogue — vector products and elevation
+# products have separate STAC roots. The standard search endpoint is
+# POST {base}/search on each, it takes a WGS84 (lon/lat) bbox per the STAC
+# spec, and the catalogue metadata is anonymously readable; the Geotorget
+# credentials are enforced on the asset downloads (dl1.lantmateriet.se
+# answers 401 without them).
+DEFAULT_BASE_URL = "https://api.lantmateriet.se/stac-vektor/v1"
+DEFAULT_LIDAR_BASE_URL = "https://api.lantmateriet.se/stac-hojd/v1"
+
+# Collection ids as published in the live catalogues. Buildings are one item
+# per municipality whose asset is a ZIP holding a GeoPackage; "Laserdata Skog"
+# is published as `dsm-skoglig-copc` — a surface-model point cloud in
+# LAZ/COPC — on the elevation root.
+COLLECTION_BUILDINGS = "byggnader"
+COLLECTION_LIDAR = "dsm-skoglig-copc"
+
+# Media types, so an asset is chosen by *what it is* rather than by hoping the
+# publisher named the key "data". Byggnader delivers a zipped GeoPackage;
+# Laserdata Skog delivers LAZ organised as COPC (Cloud Optimized Point Cloud).
+MEDIA_GEOPACKAGE = "application/geopackage+sqlite3"
+MEDIA_COPC = "application/vnd.laszip+copc"
+MEDIA_LAZ = "application/vnd.laszip"
+MEDIA_LAS = "application/vnd.las"
+MEDIA_GEOJSON = "application/geo+json"
+MEDIA_ZIP = "application/zip"
+
+# Longest suffix first: a COPC file is also a .laz, and reading it as a plain
+# one would download the whole tile instead of the part we asked for.
+_EXTENSION_MEDIA: tuple[tuple[str, str], ...] = (
+ (".copc.laz", MEDIA_COPC),
+ (".gpkg", MEDIA_GEOPACKAGE),
+ (".geojson", MEDIA_GEOJSON),
+ (".laz", MEDIA_LAZ),
+ (".las", MEDIA_LAS),
+ (".zip", MEDIA_ZIP),
+)
+
+
+class GeotorgetError(RuntimeError):
+ """Any failure talking to Geotorget."""
+
+
+class MissingCredentials(GeotorgetError):
+ """No usable credentials were supplied."""
+
+
+@dataclasses.dataclass(frozen=True)
+class Credentials:
+ username: str
+ password: str
+
+ def validate(self) -> None:
+ if not self.username or not self.password:
+ raise MissingCredentials(
+ "a STAC username and password are both required; for Lantmäteriet, "
+ "order access at https://geotorget.lantmateriet.se and set "
+ "roofmodel.stac_username and roofmodel.stac_password to your "
+ "Geotorget account credentials"
+ )
+
+
+def media_type_for(href: str) -> str | None:
+ """Media type implied by a URL's extension, or None if it says nothing."""
+ path = href.split("?", 1)[0].split("#", 1)[0].lower()
+ for suffix, media in _EXTENSION_MEDIA:
+ if path.endswith(suffix):
+ return media
+ return None
+
+
+@dataclasses.dataclass(frozen=True)
+class Asset:
+ """One STAC asset: where it is, and what it is."""
+
+ href: str
+ media_type: str | None = None
+ roles: tuple[str, ...] = ()
+ title: str = ""
+
+ @property
+ def effective_media_type(self) -> str | None:
+ """Declared media type, or the one the extension implies.
+
+ Catalogues are inconsistent about `type`, and an asset with no declared
+ type is common enough that refusing to guess would mean refusing most
+ real items. The extension is only consulted when nothing was declared.
+ """
+ return self.media_type or media_type_for(self.href)
+
+
+@dataclasses.dataclass
+class StacItem:
+ """One STAC item, reduced to what the pipeline needs."""
+
+ item_id: str
+ collection: str
+ assets: dict[str, Asset]
+ captured_at: dt.datetime | None
+ raw: dict[str, Any] = dataclasses.field(default_factory=dict, repr=False)
+
+ def __post_init__(self) -> None:
+ # A bare href is accepted wherever an Asset is, so callers and tests can
+ # write {"data": "http://.../tile.copc.laz"} without losing the typing
+ # that selection depends on -- the extension supplies it.
+ self.assets = {
+ name: value if isinstance(value, Asset) else Asset(href=str(value))
+ for name, value in (self.assets or {}).items()
+ }
+
+ def pick(self, *media_types: str) -> Asset | None:
+ """Best asset for a wanted media type, most preferred type first.
+
+ Where nothing declares a usable type the search widens: an asset with
+ the `data` role, then a lone asset, since an item carrying exactly one
+ asset is unambiguous however it is labelled.
+
+ Both fallbacks consider only assets of *unknown* type. Guessing in the
+ absence of information is reasonable; guessing against it is not, and an
+ item whose single asset is a thumbnail must not be handed back as a
+ point cloud.
+ """
+ for wanted in media_types:
+ for asset in self.assets.values():
+ if asset.effective_media_type == wanted:
+ return asset
+ untyped = [a for a in self.assets.values() if a.effective_media_type is None]
+ for asset in untyped:
+ if "data" in asset.roles:
+ return asset
+ if len(untyped) == 1:
+ return untyped[0]
+ return None
+
+ def asset_url(self, *preferred: str) -> str | None:
+ """First matching asset href, trying each preferred key in order."""
+ for key in preferred:
+ if key in self.assets:
+ return self.assets[key].href
+ first = next(iter(self.assets.values()), None)
+ return first.href if first else None
+
+
+def _parse_datetime(value: str | None) -> dt.datetime | None:
+ """Parse a STAC RFC 3339 timestamp.
+
+ Lantmaeteriet is backfilling `properties.datetime` across 2026, so it is
+ routinely absent. That is a missing provenance date, not an error -- the UI
+ degrades to "capture date unknown" rather than refusing the model.
+ """
+ if not value:
+ return None
+ try:
+ return dt.datetime.fromisoformat(value.replace("Z", "+00:00"))
+ except ValueError:
+ return None
+
+
+def _item_from_feature(feature: dict[str, Any]) -> StacItem:
+ props = feature.get("properties") or {}
+ assets = {
+ name: Asset(
+ href=asset.get("href", ""),
+ media_type=asset.get("type") or None,
+ roles=tuple(asset.get("roles") or ()),
+ title=str(asset.get("title") or ""),
+ )
+ for name, asset in (feature.get("assets") or {}).items()
+ if asset.get("href")
+ }
+ captured = _parse_datetime(props.get("datetime")) or _parse_datetime(
+ props.get("start_datetime")
+ )
+ if captured is None:
+ # Laser strips carry an acquisition date as `datum` (e.g. "20180301")
+ # even where the STAC datetime has not been backfilled yet.
+ datum = props.get("datum")
+ if datum:
+ try:
+ captured = dt.datetime.strptime(str(datum), "%Y%m%d").replace(
+ tzinfo=dt.timezone.utc
+ )
+ except ValueError:
+ captured = None
+ return StacItem(
+ item_id=feature.get("id", ""),
+ collection=feature.get("collection", ""),
+ assets=assets,
+ captured_at=captured,
+ raw=feature,
+ )
+
+
+class StacClient:
+ """Thin client for a STAC search-and-download API over HTTP Basic auth.
+
+ Defaults target Lantmaeteriet's Geotorget catalog, but nothing here
+ depends on it: base_url and the collection ids passed to `search` are the
+ whole coupling.
+ """
+
+ def __init__(
+ self,
+ credentials: Credentials,
+ session: Any = None,
+ base_url: str = DEFAULT_BASE_URL,
+ timeout: float = 60.0,
+ ) -> None:
+ self._base_url = base_url.rstrip("/")
+ # Lantmäteriet always demands the operator's Geotorget account, so
+ # missing credentials there deserve the ordering instructions early.
+ # A custom catalog may be open: no credentials means anonymous access,
+ # while half a credential is still an error either way.
+ self._anonymous = not (credentials.username or credentials.password)
+ if not self._anonymous or self._base_url in (DEFAULT_BASE_URL, DEFAULT_LIDAR_BASE_URL):
+ credentials.validate()
+ self._credentials = credentials
+ self._timeout = timeout
+ if session is None:
+ import requests # imported lazily so tests can inject a fake session
+
+ session = requests.Session()
+ if not self._anonymous:
+ session.auth = (credentials.username, credentials.password)
+ self._session = session
+
+ @property
+ def session(self) -> Any:
+ """The authenticated session, for readers that stream their own ranges."""
+ return self._session
+
+ def search(
+ self,
+ collection: str,
+ bbox: tuple[float, float, float, float],
+ limit: int = 20,
+ ) -> list[StacItem]:
+ """POST {base}/search for one collection over a bbox.
+
+ The bbox is (min_x, min_y, max_x, max_y) in whatever CRS the catalog
+ expects -- the STAC spec says WGS84 lon/lat, and the live Lantmaeteriet
+ service follows it -- so the caller chooses what to send and no
+ reprojection happens here.
+ """
+ body = {
+ "collections": [collection],
+ "bbox": list(bbox),
+ "limit": limit,
+ }
+ url = f"{self._base_url}/search"
+ try:
+ resp = self._session.post(url, json=body, timeout=self._timeout)
+ except Exception as exc: # network, DNS, TLS
+ raise GeotorgetError(f"STAC search failed: {exc}") from exc
+ if resp.status_code in (401, 403):
+ if self._anonymous:
+ raise MissingCredentials(
+ f"the STAC catalog requires credentials for {collection} "
+ f"(HTTP {resp.status_code}). Set roofmodel.stac_username "
+ "and roofmodel.stac_password for this catalog."
+ )
+ raise MissingCredentials(
+ f"the STAC catalog rejected the credentials for {collection} "
+ f"(HTTP {resp.status_code}). Check the username and password, and "
+ "that the account has ordered access to this product."
+ )
+ if resp.status_code != 200:
+ raise GeotorgetError(f"STAC search returned HTTP {resp.status_code}")
+ payload = resp.json()
+ return [_item_from_feature(f) for f in payload.get("features", [])]
+
+ def download(self, url: str) -> bytes:
+ """Fetch one asset."""
+ try:
+ resp = self._session.get(url, timeout=self._timeout)
+ except Exception as exc:
+ raise GeotorgetError(f"asset download failed: {exc}") from exc
+ if resp.status_code != 200:
+ raise GeotorgetError(f"asset download returned HTTP {resp.status_code}")
+ return resp.content
+
+
+def newest_capture(items: Iterable[StacItem]) -> dt.datetime | None:
+ """Most recent known capture date across items, or None if none carry one."""
+ dates = [i.captured_at for i in items if i.captured_at is not None]
+ return max(dates) if dates else None
+
+
+# The client predates its generalization; the old name stays importable.
+GeotorgetClient = StacClient
diff --git a/roofmodel/ftw_roofmodel/pipeline.py b/roofmodel/ftw_roofmodel/pipeline.py
new file mode 100644
index 000000000..f8f764e3c
--- /dev/null
+++ b/roofmodel/ftw_roofmodel/pipeline.py
@@ -0,0 +1,310 @@
+"""Derive roof geometry for a site: STAC search -> LiDAR -> planes -> arrays.
+
+The output contract is a versioned `roof_model.json`, which is the whole reason
+this lives in a separate module rather than inside core: core only ever reads
+that document, so the heavy geospatial dependencies, their failure modes and
+their update cadence stay on this side of the boundary.
+
+Nothing here is authoritative. The derived arrays *pre-fill* the operator's
+editable `weather.pv_arrays`; they are hints, and the numeric editor stays the
+final word. A failure produces a clean error and leaves the existing config
+untouched.
+"""
+
+from __future__ import annotations
+
+import dataclasses
+import datetime as dt
+from typing import Any
+
+from . import geotorget, pointcloud, sweref
+from .buildings import (
+ DEFAULT_EAVES_BUFFER_M,
+ DEFAULT_SEARCH_RADIUS_M,
+ Building,
+ building_from_drawn_footprint,
+ clip_to_footprint,
+ search_buildings,
+)
+from .geotorget import (
+ COLLECTION_BUILDINGS,
+ COLLECTION_LIDAR,
+ Credentials,
+ GeotorgetClient,
+ GeotorgetError,
+ StacItem,
+ newest_capture,
+)
+from .segment import (
+ DEFAULT_MODULE_W_PER_M2,
+ DEFAULT_PACKING_FACTOR,
+ RoofPlane,
+ segment_roof,
+)
+
+SCHEMA_VERSION = 1
+
+# How far around the site to pull LiDAR. 40 m comfortably contains a detached
+# house and its outbuildings without dragging in the neighbours' roofs.
+DEFAULT_RADIUS_M = 40.0
+
+# Roof faces smaller than this are dormers, porches and sheds: real surfaces,
+# but not worth proposing as a PV array.
+MIN_ARRAY_AREA_M2 = 8.0
+
+# Lantmaeteriet's Laserdata Skog is specified at 1-2 points/m2.
+NOMINAL_POINT_DENSITY = 1.5
+
+# Below this, a clipped footprint cannot support a plane fit -- segment_roof
+# needs 40 points for a single face, and a roof has at least two.
+MIN_POINTS_AFTER_CLIP = 80
+
+
+class RoofModelError(RuntimeError):
+ """Derivation failed."""
+
+
+@dataclasses.dataclass
+class DerivedArray:
+ name: str
+ rated_w: float
+ tilt_deg: float
+ azimuth_deg: float
+ area_m2: float
+ segment_id: str
+
+ def to_json(self) -> dict[str, Any]:
+ return {
+ "name": self.name,
+ "rated_w": round(self.rated_w),
+ "tilt_deg": round(self.tilt_deg, 1),
+ "azimuth_deg": round(self.azimuth_deg, 1),
+ "area_m2": round(self.area_m2, 1),
+ "segment_id": self.segment_id,
+ }
+
+
+def _compass_name(azimuth_deg: float, tilt_deg: float) -> str:
+ """Human-readable face name, e.g. "Roof south"."""
+ if tilt_deg < 5.0:
+ return "Roof flat"
+ points = [
+ (0, "north"), (45, "north-east"), (90, "east"), (135, "south-east"),
+ (180, "south"), (225, "south-west"), (270, "west"), (315, "north-west"),
+ (360, "north"),
+ ]
+ best = min(points, key=lambda p: abs(p[0] - azimuth_deg))
+ return f"Roof {best[1]}"
+
+
+def planes_to_arrays(
+ planes: list[RoofPlane],
+ *,
+ packing_factor: float = DEFAULT_PACKING_FACTOR,
+ module_w_per_m2: float = DEFAULT_MODULE_W_PER_M2,
+ min_area_m2: float = MIN_ARRAY_AREA_M2,
+) -> list[DerivedArray]:
+ """Convert roof planes into candidate PV arrays.
+
+ North-facing pitched roofs are dropped: at Swedish latitudes a north face
+ at any real pitch yields so little that proposing it as an array would be
+ noise in the operator's config. Flat roofs are kept -- they are mounted to
+ face south regardless of which way the building points.
+ """
+ arrays: list[DerivedArray] = []
+ used: dict[str, int] = {}
+ for idx, plane in enumerate(planes):
+ if plane.area_m2 < min_area_m2:
+ continue
+ if plane.tilt_deg >= 5.0 and (plane.azimuth_deg <= 45.0 or plane.azimuth_deg >= 315.0):
+ continue
+ name = _compass_name(plane.azimuth_deg, plane.tilt_deg)
+ used[name] = used.get(name, 0) + 1
+ if used[name] > 1:
+ name = f"{name} {used[name]}"
+ arrays.append(
+ DerivedArray(
+ name=name,
+ rated_w=plane.rated_w(packing_factor, module_w_per_m2),
+ tilt_deg=plane.tilt_deg,
+ azimuth_deg=plane.azimuth_deg,
+ area_m2=plane.area_m2,
+ segment_id=f"seg-{idx}",
+ )
+ )
+ return arrays
+
+
+def load_points(data: bytes) -> Any:
+ """Decode a whole LAZ/LAS payload into (N, 3) SWEREF 99 TM metres.
+
+ Re-exported from pointcloud so that laspy stays lazily imported: everything
+ above -- projection, segmentation, array derivation -- is importable and
+ testable without the geospatial stack installed.
+ """
+ return pointcloud.load_points(data)
+
+
+def _read_lidar(
+ client: GeotorgetClient,
+ items: list[StacItem],
+ chosen: Building | None,
+) -> tuple[Any, str]:
+ """Points for the first readable LiDAR asset, and how they were fetched.
+
+ Laserdata Skog is LAZ organised as COPC, so when the operator has already
+ picked a building there is no reason to move the rest of a 2.5 km tile
+ across the network: the footprint's bounding box is exactly the query COPC
+ is built to answer. Everything about that is best-effort -- a plain LAZ
+ asset, a host that ignores `Range`, or a laspy without COPC support all
+ fall back to reading the tile whole.
+ """
+ for item in items:
+ asset = item.pick(
+ geotorget.MEDIA_COPC, geotorget.MEDIA_LAZ, geotorget.MEDIA_LAS
+ )
+ if asset is None or not asset.href:
+ continue
+ if chosen is not None and asset.effective_media_type == geotorget.MEDIA_COPC:
+ session = getattr(client, "session", None)
+ if session is not None:
+ bounds = pointcloud.bounds_of(chosen.ring_sweref, DEFAULT_EAVES_BUFFER_M)
+ try:
+ return pointcloud.read_copc_window(session, asset.href, bounds), "copc-window"
+ except pointcloud.PointCloudError:
+ # A slow success beats a failure; the operator gets their
+ # roof either way, and `fetch` records which path ran.
+ pass
+ return load_points(client.download(asset.href)), "whole-tile"
+ raise RoofModelError("LiDAR tiles carried no readable point data")
+
+
+def derive(
+ *,
+ latitude: float,
+ longitude: float,
+ credentials: Credentials,
+ client: GeotorgetClient | None = None,
+ radius_m: float = DEFAULT_RADIUS_M,
+ packing_factor: float = DEFAULT_PACKING_FACTOR,
+ module_w_per_m2: float = DEFAULT_MODULE_W_PER_M2,
+ building_id: str | None = None,
+ footprint: list[Any] | None = None,
+ now: dt.datetime | None = None,
+ base_url: str = geotorget.DEFAULT_BASE_URL,
+ buildings_collection: str = COLLECTION_BUILDINGS,
+ lidar_collection: str = COLLECTION_LIDAR,
+ bbox_epsg: int = 4326,
+) -> dict[str, Any]:
+ """Derive a roof model for one site and return it as a JSON-ready dict.
+
+ Pass `building_id` -- one the operator picked from `search_buildings` -- to
+ clip the LiDAR to that footprint before segmenting, or `footprint` -- a
+ hand-drawn [lon, lat] ring -- where the catalog publishes no building
+ dataset to pick from. A drawn footprint wins over a building id. Without
+ either the whole radius is segmented, which will happily return the
+ neighbour's roof and lets coplanar buildings steal each other's points;
+ see buildings.py.
+
+ The catalog parameters default to Lantmaeteriet; any STAC-conformant
+ catalog can stand in (see geotorget.py), as long as its data arrives in
+ SWEREF 99 TM -- the segmentation works in that frame.
+ """
+ # Lantmaeteriet splits its STAC service per product family: buildings live
+ # on the vector root, the point clouds on the elevation root. An injected
+ # client (tests, the demo) serves both; so does a custom single-root
+ # catalog. Only the Lantmaeteriet default needs the second client.
+ lidar_client = client
+ if client is None:
+ client = GeotorgetClient(credentials, base_url=base_url)
+ lidar_client = client
+ if base_url == geotorget.DEFAULT_BASE_URL:
+ lidar_client = GeotorgetClient(
+ credentials, base_url=geotorget.DEFAULT_LIDAR_BASE_URL
+ )
+
+ chosen: Building | None = None
+ if footprint:
+ chosen = building_from_drawn_footprint(footprint)
+ elif building_id:
+ # Re-find the picked footprint with the same reach the picker's own
+ # search had. `radius_m` is the LiDAR/segmentation radius (tens of
+ # metres); a building the operator picked from the 150 m search would
+ # vanish here if it alone bounded the re-search.
+ candidates = search_buildings(
+ client, latitude=latitude, longitude=longitude,
+ radius_m=max(radius_m, DEFAULT_SEARCH_RADIUS_M),
+ collection=buildings_collection, bbox_epsg=bbox_epsg,
+ )
+ chosen = next((b for b in candidates if b.building_id == building_id), None)
+ if chosen is None:
+ raise RoofModelError(
+ f"building {building_id!r} was not found near this site; it may "
+ "have been picked against a different coordinate"
+ )
+
+ # The LiDAR lookup centres on the roof being derived: for a picked
+ # building that is its centroid, not the site pin — a barn at the edge of
+ # the search radius must find *its* tile, not the pin's.
+ lidar_lat, lidar_lon = latitude, longitude
+ if chosen is not None:
+ lidar_lat, lidar_lon = chosen.centroid_wgs84()
+ bbox = sweref.stac_search_bbox(lidar_lat, lidar_lon, radius_m, bbox_epsg)
+
+ try:
+ lidar_items: list[StacItem] = lidar_client.search(lidar_collection, bbox)
+ except GeotorgetError:
+ raise
+ if not lidar_items:
+ hint = "; Lantmaeteriet data is Sweden only" if lidar_collection == COLLECTION_LIDAR else ""
+ raise RoofModelError(
+ f"no LiDAR tiles cover ({lidar_lat:.5f}, {lidar_lon:.5f}) in "
+ f"collection {lidar_collection!r}{hint}"
+ )
+
+ points, fetch = _read_lidar(lidar_client, lidar_items, chosen)
+ if points is None or len(points) == 0:
+ raise RoofModelError("LiDAR tiles carried no readable point data")
+
+ total_returns = len(points)
+ if chosen is not None:
+ points = clip_to_footprint(points, chosen.ring_sweref)
+ if len(points) < MIN_POINTS_AFTER_CLIP:
+ raise RoofModelError(
+ f"only {len(points)} LiDAR returns fall on building "
+ f"{chosen.building_id!r}. The footprint and the point cloud may "
+ "be from different years, or the building is newer than the scan."
+ )
+
+ planes = segment_roof(points, point_density=NOMINAL_POINT_DENSITY)
+ arrays = planes_to_arrays(
+ planes, packing_factor=packing_factor, module_w_per_m2=module_w_per_m2
+ )
+
+ captured = newest_capture(lidar_items)
+ stamp = now or dt.datetime.now(dt.timezone.utc)
+ return {
+ "schema_version": SCHEMA_VERSION,
+ "site": {"latitude": latitude, "longitude": longitude, "radius_m": radius_m},
+ "source": {
+ "provider": "lantmateriet" if base_url == geotorget.DEFAULT_BASE_URL else base_url,
+ "collection": lidar_collection,
+ "item_count": len(lidar_items),
+ "dataset_datetime": captured.isoformat() if captured else None,
+ # "copc-window" means only the footprint's neighbourhood was moved
+ # across the network, which also makes returns_in_radius below a
+ # count over that window rather than over the whole search radius.
+ "fetch": fetch,
+ },
+ "building": {
+ "building_id": chosen.building_id,
+ "area_m2": round(chosen.area_m2, 1),
+ "footprint": chosen.to_geojson()["geometry"],
+ "returns_used": len(points),
+ "returns_in_radius": total_returns,
+ } if chosen is not None else None,
+ "arrays": [a.to_json() for a in arrays],
+ "planes_found": len(planes),
+ "captured_at_ms": int(captured.timestamp() * 1000) if captured else None,
+ "derived_at_ms": int(stamp.timestamp() * 1000),
+ }
diff --git a/roofmodel/ftw_roofmodel/pointcloud.py b/roofmodel/ftw_roofmodel/pointcloud.py
new file mode 100644
index 000000000..c49927dea
--- /dev/null
+++ b/roofmodel/ftw_roofmodel/pointcloud.py
@@ -0,0 +1,245 @@
+"""Read Lantmaeteriet LiDAR, fetching only the part of the tile we need.
+
+*Laserdata Nedladdning, Skog* is delivered as LAZ organised as **COPC** (Cloud
+Optimized Point Cloud): the points are ordered into an octree and the node index
+lives in a VLR at a known offset, so a reader that can issue HTTP range requests
+can pull the handful of octree nodes covering one building instead of the whole
+2.5 km tile.
+
+That is worth real money on a Pi. A Laserdata Skog tile is hundreds of megabytes;
+a detached house is a few tens of metres across. Since the operator has already
+told us *which building* they mean, the bounding box of that footprint is exactly
+the query COPC exists to answer.
+
+The fallbacks are deliberate and ordered, because none of the preconditions are
+guaranteed:
+
+ 1. COPC asset + a bounding box + a server that honours `Range` -> spatial query.
+ 2. Anything else -> download the asset and read it whole.
+
+A server that ignores `Range` returns 200 with the entire body, which would
+otherwise be mistaken for a successful partial read, so that case is detected on
+the status code rather than assumed away.
+"""
+
+from __future__ import annotations
+
+import io
+from typing import Any
+
+__all__ = [
+ "PointCloudError",
+ "HttpRangeFile",
+ "bounds_of",
+ "copc_query_z_range",
+ "load_points",
+ "read_copc_window",
+]
+
+# Read this much per range request. COPC chunks are small, and a request per
+# chunk would spend more time in round trips than in transfer.
+DEFAULT_CHUNK_BYTES = 1 << 20
+
+
+class PointCloudError(RuntimeError):
+ """The LiDAR asset could not be read."""
+
+
+class HttpRangeFile(io.RawIOBase):
+ """A seekable read-only file over HTTP `Range` requests.
+
+ laspy's COPC reader needs `seek`/`read` and nothing else, so this is the
+ whole adapter: it turns an HTTP URL into something that behaves like an open
+ file without ever holding the tile in memory.
+ """
+
+ def __init__(self, session: Any, url: str, *, timeout: float = 60.0,
+ chunk_bytes: int = DEFAULT_CHUNK_BYTES) -> None:
+ self._session = session
+ self._url = url
+ self._timeout = timeout
+ self._chunk = max(1, chunk_bytes)
+ self._pos = 0
+ self._size: int | None = None
+ # One cached chunk. COPC reads are clustered -- header, then index, then
+ # the nodes -- so a single block absorbs most of the repeat traffic.
+ self._cache: tuple[int, bytes] | None = None
+ self.requests = 0
+ self.bytes_fetched = 0
+
+ # -- io.RawIOBase ----------------------------------------------------
+ def readable(self) -> bool:
+ return True
+
+ def seekable(self) -> bool:
+ return True
+
+ def tell(self) -> int:
+ return self._pos
+
+ def seek(self, offset: int, whence: int = io.SEEK_SET) -> int:
+ if whence == io.SEEK_SET:
+ self._pos = offset
+ elif whence == io.SEEK_CUR:
+ self._pos += offset
+ elif whence == io.SEEK_END:
+ self._pos = self.size + offset
+ else: # pragma: no cover - io module only defines the three
+ raise ValueError(f"invalid whence {whence}")
+ self._pos = max(0, self._pos)
+ return self._pos
+
+ def read(self, size: int = -1) -> bytes:
+ if size is None or size < 0:
+ size = max(0, self.size - self._pos)
+ if size == 0:
+ return b""
+ data = self._read_at(self._pos, size)
+ self._pos += len(data)
+ return data
+
+ def readall(self) -> bytes:
+ return self.read(-1)
+
+ def readinto(self, buffer) -> int: # type: ignore[override]
+ data = self.read(len(buffer))
+ buffer[: len(data)] = data
+ return len(data)
+
+ # -- range plumbing --------------------------------------------------
+ @property
+ def size(self) -> int:
+ if self._size is None:
+ self._size = self._head_size()
+ return self._size
+
+ def _head_size(self) -> int:
+ try:
+ resp = self._session.head(self._url, timeout=self._timeout)
+ except Exception as exc:
+ raise PointCloudError(f"could not stat {self._url}: {exc}") from exc
+ length = (getattr(resp, "headers", None) or {}).get("Content-Length")
+ if getattr(resp, "status_code", 0) != 200 or not length:
+ raise PointCloudError(
+ "the LiDAR host did not report a size, so it cannot be read in ranges"
+ )
+ return int(length)
+
+ def _read_at(self, offset: int, size: int) -> bytes:
+ cached = self._from_cache(offset, size)
+ if cached is not None:
+ return cached
+ want = max(size, self._chunk)
+ end = offset + want - 1
+ try:
+ resp = self._session.get(
+ self._url,
+ headers={"Range": f"bytes={offset}-{end}"},
+ timeout=self._timeout,
+ )
+ except Exception as exc:
+ raise PointCloudError(f"range request failed: {exc}") from exc
+ status = getattr(resp, "status_code", 0)
+ if status == 200:
+ # The server ignored Range and sent everything. Honest failure: the
+ # caller falls back to a whole-tile read rather than silently
+ # paying for the full download on every seek.
+ raise PointCloudError("the LiDAR host does not support range requests")
+ if status != 206:
+ raise PointCloudError(f"range request returned HTTP {status}")
+ body = resp.content
+ self.requests += 1
+ self.bytes_fetched += len(body)
+ self._cache = (offset, body)
+ return body[:size]
+
+ def _from_cache(self, offset: int, size: int) -> bytes | None:
+ if self._cache is None:
+ return None
+ start, body = self._cache
+ if offset < start or offset + size > start + len(body):
+ return None
+ rel = offset - start
+ return body[rel : rel + size]
+
+
+def bounds_of(ring: list[tuple[float, float]], pad_m: float = 2.0) -> tuple[float, float, float, float]:
+ xs = [p[0] for p in ring]
+ ys = [p[1] for p in ring]
+ return (min(xs) - pad_m, min(ys) - pad_m, max(xs) + pad_m, max(ys) + pad_m)
+
+
+def _points_from_las(las: Any) -> Any:
+ import numpy as np
+
+ return np.column_stack([np.asarray(las.x), np.asarray(las.y), np.asarray(las.z)])
+
+
+def load_points(data: bytes) -> Any:
+ """Decode a whole LAZ/LAS payload into (N, 3) SWEREF 99 TM metres."""
+ laspy = _import_laspy()
+ with laspy.open(io.BytesIO(data)) as reader:
+ las = reader.read()
+ return _points_from_las(las)
+
+
+def _import_laspy():
+ try:
+ import laspy
+ except ImportError as exc: # pragma: no cover - depends on the install
+ raise PointCloudError(
+ "laspy is required to read Lantmaeteriet LiDAR. Install the module's "
+ "extras: pip install -e roofmodel[geo]"
+ ) from exc
+ return laspy
+
+
+def copc_query_z_range(center_z: float, halfsize: float) -> tuple[float, float]:
+ """The vertical range a windowed COPC query must span: the whole cube.
+
+ Lantmäteriet's COPC writer emits octree z-keys measured from some other
+ origin than the file's own cube (observed live on Laserdata Skog: a level-6
+ node keyed z=19, implying a -1698..-1542 m slab, holds points at +18..+42 m
+ while its x/y keys are exact). A 2D query lets laspy fill z from the header
+ and prune nodes by those broken slabs, which silently discards every dense
+ deep level and leaves only the sparse preview points. Spanning the full
+ cube keeps z from ever pruning; x/y pruning and the exact post-filter still
+ bound the read.
+ """
+ pad = abs(halfsize) + 1.0
+ return (center_z - 2.0 * pad, center_z + 2.0 * pad)
+
+
+def read_copc_window(
+ session: Any,
+ url: str,
+ bounds: tuple[float, float, float, float],
+ *,
+ timeout: float = 60.0,
+) -> Any:
+ """Points inside `bounds` from a COPC file, over HTTP range requests.
+
+ Raises PointCloudError if the file or the host cannot support it, so the
+ caller can fall back to a whole-tile read.
+ """
+ laspy = _import_laspy()
+ try:
+ from laspy.copc import Bounds, CopcReader
+ except ImportError as exc:
+ raise PointCloudError(
+ "this laspy build has no COPC support; install laspy[lazrs] 2.5 or newer"
+ ) from exc
+
+ min_x, min_y, max_x, max_y = bounds
+ handle = HttpRangeFile(session, url, timeout=timeout)
+ try:
+ with CopcReader.open(handle) as reader:
+ info = reader.copc_info
+ z_lo, z_hi = copc_query_z_range(float(info.center[2]), float(info.halfsize))
+ query = Bounds(mins=[min_x, min_y, z_lo], maxs=[max_x, max_y, z_hi])
+ points = reader.query(query)
+ except PointCloudError:
+ raise
+ except Exception as exc:
+ raise PointCloudError(f"COPC read failed: {exc}") from exc
+ return _points_from_las(points)
diff --git a/roofmodel/ftw_roofmodel/segment.py b/roofmodel/ftw_roofmodel/segment.py
new file mode 100644
index 000000000..5a2bc0a11
--- /dev/null
+++ b/roofmodel/ftw_roofmodel/segment.py
@@ -0,0 +1,251 @@
+"""Roof-plane segmentation from a LiDAR point cloud.
+
+Implements the method described in the SPAN paper (Yavuzdogan, *Renewable
+Energy* 2023, doi:10.1016/j.renene.2023.119022): iterative RANSAC plane fitting
+to pull one roof surface at a time out of the cloud, then DBSCAN over each
+plane's inliers to split faces that share a plane but not a location -- the two
+halves of a gable on opposite wings of a building fit the same equation and are
+not the same roof face.
+
+The method is reimplemented from its description. No code is taken from SPAN's
+QGIS plugin, which is GPL; everything here uses numpy and scikit-learn, both
+BSD, so this module carries no copyleft obligation.
+
+Coordinates are SWEREF 99 TM metres as (easting, northing, height). Azimuth
+follows FTW's convention: 0 = north, 90 = east, 180 = south, 270 = west.
+"""
+
+from __future__ import annotations
+
+import dataclasses
+import math
+
+import numpy as np
+
+# A roof plane must hold at least this many returns to be believed. Below this
+# a "plane" is usually a chimney, an aerial, or three points of noise that
+# happen to be collinear.
+MIN_PLANE_POINTS = 40
+
+# Surfaces flatter than this are treated as flat roofs: their azimuth is
+# meaningless (the normal is essentially vertical, so its horizontal component
+# is numerical noise that can point anywhere).
+FLAT_TILT_DEG = 5.0
+
+# Roofs steeper than this are walls, dormer cheeks or mis-fits.
+MAX_TILT_DEG = 80.0
+
+# Fraction of a roof plane's area that can carry modules once you subtract
+# ridges, eaves, chimneys, vents and walkways.
+DEFAULT_PACKING_FACTOR = 0.70
+
+# Module DC rating per square metre of module. ~20% efficiency at 1000 W/m2.
+DEFAULT_MODULE_W_PER_M2 = 200.0
+
+
+@dataclasses.dataclass
+class RoofPlane:
+ """One contiguous roof surface."""
+
+ tilt_deg: float
+ azimuth_deg: float
+ area_m2: float
+ point_count: int
+ mean_height_m: float
+
+ def rated_w(
+ self,
+ packing_factor: float = DEFAULT_PACKING_FACTOR,
+ module_w_per_m2: float = DEFAULT_MODULE_W_PER_M2,
+ ) -> float:
+ """Installable DC capacity for this surface, in watts."""
+ return self.area_m2 * packing_factor * module_w_per_m2
+
+ def kwp(
+ self,
+ packing_factor: float = DEFAULT_PACKING_FACTOR,
+ module_w_per_m2: float = DEFAULT_MODULE_W_PER_M2,
+ ) -> float:
+ """Installable DC capacity for this surface, in kWp (test helper)."""
+ return self.rated_w(packing_factor, module_w_per_m2) / 1000.0
+
+
+def _fit_plane(points: np.ndarray) -> np.ndarray:
+ """Least-squares plane through points; returns a unit normal pointing up.
+
+ Uses the smallest singular vector of the mean-centred points, which is the
+ total-least-squares fit -- it minimises perpendicular distance rather than
+ vertical distance, so a steep roof is not biased the way an ordinary
+ z = ax + by + c regression would bias it.
+ """
+ centred = points - points.mean(axis=0)
+ _, _, vh = np.linalg.svd(centred, full_matrices=False)
+ normal = vh[-1]
+ if normal[2] < 0:
+ normal = -normal
+ return normal / np.linalg.norm(normal)
+
+
+def _tilt_azimuth(normal: np.ndarray) -> tuple[float, float]:
+ """Convert an upward unit normal to (tilt_deg, azimuth_deg)."""
+ tilt = math.degrees(math.acos(max(-1.0, min(1.0, float(normal[2])))))
+ if tilt < FLAT_TILT_DEG:
+ # Horizontal component is noise at this point; report due south, which
+ # is what a flat-roof array is normally mounted to face anyway.
+ return tilt, 180.0
+ east, north = float(normal[0]), float(normal[1])
+ azimuth = math.degrees(math.atan2(east, north)) % 360.0
+ return tilt, azimuth
+
+
+def _convex_hull_area(xy: np.ndarray) -> float:
+ """Area of the convex hull of 2D points (monotone chain, shoelace).
+
+ Hand-rolled to avoid a scipy dependency for one small routine. The hull
+ overestimates a concave roof outline, so it is only used as a fallback
+ when the point count is too low for the density estimate to be stable.
+ """
+ pts = np.unique(xy, axis=0)
+ if len(pts) < 3:
+ return 0.0
+ order = np.lexsort((pts[:, 1], pts[:, 0]))
+ pts = pts[order]
+
+ def cross(o, a, b):
+ return (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0])
+
+ lower: list = []
+ for p in pts:
+ while len(lower) >= 2 and cross(lower[-2], lower[-1], p) <= 0:
+ lower.pop()
+ lower.append(p)
+ upper: list = []
+ for p in pts[::-1]:
+ while len(upper) >= 2 and cross(upper[-2], upper[-1], p) <= 0:
+ upper.pop()
+ upper.append(p)
+ hull = np.array(lower[:-1] + upper[:-1])
+ if len(hull) < 3:
+ return 0.0
+ x, y = hull[:, 0], hull[:, 1]
+ return 0.5 * abs(float(np.dot(x, np.roll(y, 1)) - np.dot(y, np.roll(x, 1))))
+
+
+def _surface_area(points: np.ndarray, tilt_deg: float, point_density: float | None) -> float:
+ """Sloped surface area of a roof face, in m2.
+
+ LiDAR density is quoted per square metre of *ground*, so a known density
+ gives the horizontal footprint directly from the point count; dividing by
+ cos(tilt) lifts that onto the slope. Without a density we fall back to the
+ convex hull of the horizontal projection, which is looser -- it fills in
+ L-shapes and courtyards.
+ """
+ if point_density and point_density > 0:
+ horizontal = len(points) / point_density
+ else:
+ horizontal = _convex_hull_area(points[:, :2])
+ cos_t = math.cos(math.radians(min(tilt_deg, MAX_TILT_DEG)))
+ if cos_t <= 1e-6:
+ return horizontal
+ return horizontal / cos_t
+
+
+def _ransac_plane(
+ points: np.ndarray,
+ threshold_m: float,
+ iterations: int,
+ rng: np.random.Generator,
+) -> np.ndarray | None:
+ """Return a boolean inlier mask for the best plane found, or None.
+
+ Plain RANSAC over point triples. scikit-learn's RANSACRegressor is not used
+ because it regresses z on (x, y) and so cannot represent a vertical or
+ near-vertical surface, and weights errors vertically rather than
+ perpendicular to the plane.
+ """
+ n = len(points)
+ if n < 3:
+ return None
+ best_mask = None
+ best_count = 0
+ for _ in range(iterations):
+ idx = rng.choice(n, size=3, replace=False)
+ a, b, c = points[idx]
+ normal = np.cross(b - a, c - a)
+ norm = np.linalg.norm(normal)
+ if norm < 1e-9:
+ continue # degenerate (collinear) sample
+ normal = normal / norm
+ distances = np.abs((points - a) @ normal)
+ mask = distances < threshold_m
+ count = int(mask.sum())
+ if count > best_count:
+ best_count, best_mask = count, mask
+ if best_mask is None or best_count < 3:
+ return None
+ return best_mask
+
+
+def segment_roof(
+ points: np.ndarray,
+ *,
+ threshold_m: float = 0.25,
+ max_planes: int = 8,
+ min_plane_points: int = MIN_PLANE_POINTS,
+ cluster_eps_m: float = 1.5,
+ point_density: float | None = None,
+ ransac_iterations: int = 200,
+ seed: int = 0,
+) -> list[RoofPlane]:
+ """Segment a roof point cloud into planes.
+
+ `points` is an (N, 3) array of SWEREF 99 TM (easting, northing, height).
+ Returns planes ordered by descending area. Determinism is deliberate: the
+ same cloud must always yield the same arrays, or an operator re-running a
+ derive would see the geometry shuffle for no reason.
+ """
+ from sklearn.cluster import DBSCAN # imported here to keep import cost off the CLI path
+
+ pts = np.asarray(points, dtype=float)
+ if pts.ndim != 2 or pts.shape[1] != 3:
+ raise ValueError(f"points must be (N, 3), got {pts.shape}")
+
+ rng = np.random.default_rng(seed)
+ remaining = pts
+ planes: list[RoofPlane] = []
+
+ for _ in range(max_planes):
+ if len(remaining) < min_plane_points:
+ break
+ mask = _ransac_plane(remaining, threshold_m, ransac_iterations, rng)
+ if mask is None or int(mask.sum()) < min_plane_points:
+ break
+ inliers = remaining[mask]
+ remaining = remaining[~mask]
+
+ # One plane equation can describe several disjoint faces. Split them.
+ labels = DBSCAN(eps=cluster_eps_m, min_samples=10).fit(inliers[:, :2]).labels_
+ for label in sorted(set(labels)):
+ if label == -1:
+ continue # DBSCAN noise
+ cluster = inliers[labels == label]
+ if len(cluster) < min_plane_points:
+ continue
+ normal = _fit_plane(cluster)
+ tilt, azimuth = _tilt_azimuth(normal)
+ if tilt > MAX_TILT_DEG:
+ continue # a wall, not a roof
+ planes.append(
+ RoofPlane(
+ tilt_deg=round(tilt, 1),
+ # Round before normalising: 359.97 rounds to 360.0, which is
+ # the same direction as 0 but reads as an out-of-range value.
+ azimuth_deg=round(azimuth, 1) % 360.0,
+ area_m2=round(_surface_area(cluster, tilt, point_density), 1),
+ point_count=len(cluster),
+ mean_height_m=round(float(cluster[:, 2].mean()), 2),
+ )
+ )
+
+ planes.sort(key=lambda p: p.area_m2, reverse=True)
+ return planes
diff --git a/roofmodel/ftw_roofmodel/sweref.py b/roofmodel/ftw_roofmodel/sweref.py
new file mode 100644
index 000000000..2d5e8f296
--- /dev/null
+++ b/roofmodel/ftw_roofmodel/sweref.py
@@ -0,0 +1,191 @@
+"""SWEREF 99 TM <-> WGS84 conversion.
+
+Lantmaeteriet publishes everything in SWEREF 99 TM (EPSG:3006) while FTW stores
+site location as WGS84 latitude/longitude, so every bounding box we send and
+every point cloud we read has to cross this boundary.
+
+This is Lantmaeteriet's own published Gauss conformal projection algorithm
+(Krueger series), implemented directly rather than pulled in via pyproj. The
+reason is proportion: pyproj ships a full PROJ build for what is, here, exactly
+one projection with fixed parameters. The series below is accurate to well under
+a millimetre across Sweden, which is several orders of magnitude finer than the
+1-2 points/m2 LiDAR it is used to place.
+
+SWEREF 99 TM is a transverse Mercator on GRS 80 with central meridian 15 deg E,
+scale factor 0.9996, false easting 500 000 m and false northing 0.
+"""
+
+from __future__ import annotations
+
+import math
+
+# GRS 80 ellipsoid.
+_A = 6378137.0
+_F = 1.0 / 298.257222101
+
+# SWEREF 99 TM projection parameters.
+_CENTRAL_MERIDIAN = 15.0
+_SCALE = 0.9996
+_FALSE_EASTING = 500000.0
+_FALSE_NORTHING = 0.0
+
+# Derived constants, computed once.
+_E2 = _F * (2.0 - _F)
+_N = _F / (2.0 - _F)
+_A_HAT = _A / (1.0 + _N) * (1.0 + _N**2 / 4.0 + _N**4 / 64.0)
+
+
+def _forward_coefficients() -> tuple[float, float, float, float]:
+ n = _N
+ return (
+ n / 2.0 - 2.0 * n**2 / 3.0 + 5.0 * n**3 / 16.0 + 41.0 * n**4 / 180.0,
+ 13.0 * n**2 / 48.0 - 3.0 * n**3 / 5.0 + 557.0 * n**4 / 1440.0,
+ 61.0 * n**3 / 240.0 - 103.0 * n**4 / 140.0,
+ 49561.0 * n**4 / 161280.0,
+ )
+
+
+def _inverse_coefficients() -> tuple[float, float, float, float]:
+ n = _N
+ return (
+ n / 2.0 - 2.0 * n**2 / 3.0 + 37.0 * n**3 / 96.0 - n**4 / 360.0,
+ n**2 / 48.0 + n**3 / 15.0 - 437.0 * n**4 / 1440.0,
+ 17.0 * n**3 / 480.0 - 37.0 * n**4 / 840.0,
+ 4397.0 * n**4 / 161280.0,
+ )
+
+
+def wgs84_to_sweref99tm(lat: float, lon: float) -> tuple[float, float]:
+ """Convert WGS84 degrees to SWEREF 99 TM (northing, easting) in metres."""
+ phi = math.radians(lat)
+ lam = math.radians(lon)
+ lam0 = math.radians(_CENTRAL_MERIDIAN)
+
+ e2 = _E2
+ a_coef = e2
+ b_coef = (5.0 * e2**2 - e2**3) / 6.0
+ c_coef = (104.0 * e2**3 - 45.0 * e2**4) / 120.0
+ d_coef = 1237.0 * e2**4 / 1260.0
+
+ sin_phi = math.sin(phi)
+ phi_star = phi - sin_phi * math.cos(phi) * (
+ a_coef
+ + b_coef * sin_phi**2
+ + c_coef * sin_phi**4
+ + d_coef * sin_phi**6
+ )
+
+ dlam = lam - lam0
+ xi_p = math.atan2(math.tan(phi_star), math.cos(dlam))
+ eta_p = math.atanh(math.cos(phi_star) * math.sin(dlam))
+
+ b1, b2, b3, b4 = _forward_coefficients()
+ scaled = _SCALE * _A_HAT
+ northing = _FALSE_NORTHING + scaled * (
+ xi_p
+ + b1 * math.sin(2 * xi_p) * math.cosh(2 * eta_p)
+ + b2 * math.sin(4 * xi_p) * math.cosh(4 * eta_p)
+ + b3 * math.sin(6 * xi_p) * math.cosh(6 * eta_p)
+ + b4 * math.sin(8 * xi_p) * math.cosh(8 * eta_p)
+ )
+ easting = _FALSE_EASTING + scaled * (
+ eta_p
+ + b1 * math.cos(2 * xi_p) * math.sinh(2 * eta_p)
+ + b2 * math.cos(4 * xi_p) * math.sinh(4 * eta_p)
+ + b3 * math.cos(6 * xi_p) * math.sinh(6 * eta_p)
+ + b4 * math.cos(8 * xi_p) * math.sinh(8 * eta_p)
+ )
+ return northing, easting
+
+
+def sweref99tm_to_wgs84(northing: float, easting: float) -> tuple[float, float]:
+ """Convert SWEREF 99 TM (northing, easting) in metres to WGS84 degrees."""
+ scaled = _SCALE * _A_HAT
+ xi = (northing - _FALSE_NORTHING) / scaled
+ eta = (easting - _FALSE_EASTING) / scaled
+
+ d1, d2, d3, d4 = _inverse_coefficients()
+ xi_p = (
+ xi
+ - d1 * math.sin(2 * xi) * math.cosh(2 * eta)
+ - d2 * math.sin(4 * xi) * math.cosh(4 * eta)
+ - d3 * math.sin(6 * xi) * math.cosh(6 * eta)
+ - d4 * math.sin(8 * xi) * math.cosh(8 * eta)
+ )
+ eta_p = (
+ eta
+ - d1 * math.cos(2 * xi) * math.sinh(2 * eta)
+ - d2 * math.cos(4 * xi) * math.sinh(4 * eta)
+ - d3 * math.cos(6 * xi) * math.sinh(6 * eta)
+ - d4 * math.cos(8 * xi) * math.sinh(8 * eta)
+ )
+
+ phi_star = math.asin(math.sin(xi_p) / math.cosh(eta_p))
+ dlam = math.atan2(math.sinh(eta_p), math.cos(xi_p))
+
+ e2 = _E2
+ a_star = e2 + e2**2 + e2**3 + e2**4
+ b_star = -(7.0 * e2**2 + 17.0 * e2**3 + 30.0 * e2**4) / 6.0
+ c_star = (224.0 * e2**3 + 889.0 * e2**4) / 120.0
+ d_star = -(4279.0 * e2**4) / 1260.0
+
+ sin_ps = math.sin(phi_star)
+ phi = phi_star + sin_ps * math.cos(phi_star) * (
+ a_star
+ + b_star * sin_ps**2
+ + c_star * sin_ps**4
+ + d_star * sin_ps**6
+ )
+ lam = math.radians(_CENTRAL_MERIDIAN) + dlam
+ return math.degrees(phi), math.degrees(lam)
+
+
+def bbox_wgs84_to_sweref99tm(
+ min_lat: float, min_lon: float, max_lat: float, max_lon: float
+) -> tuple[float, float, float, float]:
+ """Project a WGS84 bounding box to a SWEREF 99 TM (minE, minN, maxE, maxN).
+
+ All four corners are projected and the extremes taken, rather than just the
+ two diagonal corners: the projection is not axis-aligned, so a box's
+ projected edges bow outward and the diagonal-only result would clip.
+ """
+ corners = [
+ wgs84_to_sweref99tm(min_lat, min_lon),
+ wgs84_to_sweref99tm(min_lat, max_lon),
+ wgs84_to_sweref99tm(max_lat, min_lon),
+ wgs84_to_sweref99tm(max_lat, max_lon),
+ ]
+ northings = [c[0] for c in corners]
+ eastings = [c[1] for c in corners]
+ return min(eastings), min(northings), max(eastings), max(northings)
+
+
+def stac_search_bbox(
+ lat: float, lon: float, radius_m: float, bbox_epsg: int = 3006
+) -> tuple[float, float, float, float]:
+ """Bounding box around a site, in the CRS a STAC catalog expects.
+
+ EPSG:3006 (the default) is what Lantmaeteriet's catalog takes; EPSG:4326
+ in lon/lat order is what the STAC spec itself mandates, for catalogs that
+ follow it. Anything else would need a projection stack this module
+ deliberately does not carry.
+ """
+ south, west, north, east = metre_box_around(lat, lon, radius_m)
+ if bbox_epsg == 4326:
+ return (west, south, east, north)
+ if bbox_epsg == 3006:
+ return bbox_wgs84_to_sweref99tm(south, west, north, east)
+ raise ValueError(f"unsupported bbox EPSG {bbox_epsg}; use 3006 or 4326")
+
+
+def metre_box_around(lat: float, lon: float, radius_m: float) -> tuple[float, float, float, float]:
+ """Return a WGS84 (min_lat, min_lon, max_lat, max_lon) box of +/- radius_m.
+
+ Built by projecting the centre, stepping in metres in SWEREF 99 TM, and
+ unprojecting: doing it that way keeps the box square on the ground instead
+ of stretching with latitude the way a naive degree offset would.
+ """
+ n, e = wgs84_to_sweref99tm(lat, lon)
+ south, west = sweref99tm_to_wgs84(n - radius_m, e - radius_m)
+ north, east = sweref99tm_to_wgs84(n + radius_m, e + radius_m)
+ return south, west, north, east
diff --git a/roofmodel/pyproject.toml b/roofmodel/pyproject.toml
new file mode 100644
index 000000000..4e138a246
--- /dev/null
+++ b/roofmodel/pyproject.toml
@@ -0,0 +1,27 @@
+[build-system]
+requires = ["setuptools>=68"]
+build-backend = "setuptools.build_meta"
+
+[project]
+name = "ftw-roofmodel"
+version = "0.1.0"
+description = "Derive PV array geometry from Lantmateriet building and LiDAR open data"
+requires-python = ">=3.10"
+# Core dependencies are permissive-licensed and light enough to install on a Pi.
+dependencies = [
+ "numpy>=1.24",
+ "scikit-learn>=1.3",
+ "requests>=2.31",
+]
+
+[project.optional-dependencies]
+# LAZ decoding pulls a compiled backend, so it is opt-in. Everything except the
+# point-cloud read works without it, which keeps the module testable in CI.
+geo = ["laspy[lazrs]>=2.5"]
+test = ["pytest==8.4.2"]
+
+[tool.setuptools.packages.find]
+include = ["ftw_roofmodel*"]
+
+[tool.pytest.ini_options]
+testpaths = ["tests"]
diff --git a/roofmodel/tests/__init__.py b/roofmodel/tests/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/roofmodel/tests/test_assets.py b/roofmodel/tests/test_assets.py
new file mode 100644
index 000000000..107a5baef
--- /dev/null
+++ b/roofmodel/tests/test_assets.py
@@ -0,0 +1,212 @@
+"""Choosing STAC assets by what they are, and reading them in ranges.
+
+Both Lantmaeteriet products are STAC APIs; they differ in what their items point
+at. Byggnad-vektor delivers GeoPackage, Laserdata Skog delivers LAZ organised as
+COPC. Selecting on media type rather than on an asset key is what keeps that
+difference from becoming a pile of special cases.
+"""
+
+from __future__ import annotations
+
+import io
+
+import pytest
+
+from ftw_roofmodel.geotorget import (
+ MEDIA_COPC,
+ MEDIA_GEOJSON,
+ MEDIA_GEOPACKAGE,
+ MEDIA_LAZ,
+ Asset,
+ StacItem,
+ _item_from_feature,
+ media_type_for,
+)
+from ftw_roofmodel.pointcloud import HttpRangeFile, PointCloudError, bounds_of
+
+
+def item(assets):
+ return StacItem("i", "c", assets, None, raw={})
+
+
+def test_a_bare_href_still_gets_a_type_from_its_extension():
+ """Tests and simple catalogues pass strings; selection must still work."""
+ it = item({"data": "https://x/tile.copc.laz"})
+ assert isinstance(it.assets["data"], Asset)
+ assert it.pick(MEDIA_COPC).href == "https://x/tile.copc.laz"
+
+
+def test_copc_is_recognised_before_plain_laz():
+ """A COPC file is also a .laz; reading it as one costs the whole tile."""
+ assert media_type_for("https://x/y/tile.copc.laz") == MEDIA_COPC
+ assert media_type_for("https://x/y/tile.laz") == MEDIA_LAZ
+
+
+def test_query_strings_do_not_hide_the_extension():
+ """Signed download URLs carry tokens after a '?'."""
+ assert media_type_for("https://x/tile.gpkg?token=abc&x=1") == MEDIA_GEOPACKAGE
+
+
+def test_a_declared_type_beats_the_extension():
+ """The catalogue knows better than the filename."""
+ a = Asset(href="https://x/download", media_type=MEDIA_GEOPACKAGE)
+ assert a.effective_media_type == MEDIA_GEOPACKAGE
+
+
+def test_preference_order_is_honoured():
+ it = item({
+ "laz": Asset("https://x/t.laz", MEDIA_LAZ),
+ "copc": Asset("https://x/t.copc.laz", MEDIA_COPC),
+ })
+ assert it.pick(MEDIA_COPC, MEDIA_LAZ).effective_media_type == MEDIA_COPC
+ assert it.pick(MEDIA_LAZ, MEDIA_COPC).effective_media_type == MEDIA_LAZ
+
+
+def test_falls_back_to_the_data_role_when_the_type_is_unknown():
+ it = item({
+ "thumbnail": Asset("https://x/preview.png", "image/png", roles=("thumbnail",)),
+ "mystery": Asset("https://x/blob", None, roles=("data",)),
+ })
+ assert it.pick(MEDIA_COPC).href == "https://x/blob"
+
+
+def test_a_lone_asset_is_unambiguous_whatever_it_is_called():
+ assert item({"whatever": Asset("https://x/blob")}).pick(MEDIA_COPC).href == "https://x/blob"
+
+
+def test_several_unlabelled_assets_are_refused_rather_than_guessed():
+ it = item({"a": Asset("https://x/a"), "b": Asset("https://x/b")})
+ assert it.pick(MEDIA_COPC) is None
+
+
+def test_stac_assets_keep_their_type_and_roles():
+ feature = {
+ "id": "tile-1",
+ "collection": "laserdata-nedladdning-skog",
+ "assets": {
+ "data": {
+ "href": "https://x/t.copc.laz",
+ "type": MEDIA_COPC,
+ "roles": ["data"],
+ "title": "Punktmoln",
+ }
+ },
+ "properties": {},
+ }
+ parsed = _item_from_feature(feature)
+ asset = parsed.pick(MEDIA_COPC)
+ assert asset.media_type == MEDIA_COPC
+ assert asset.roles == ("data",)
+ assert asset.title == "Punktmoln"
+
+
+def test_geojson_and_geopackage_are_both_selectable():
+ it = item({"gj": Asset("https://x/b.geojson"), "gp": Asset("https://x/b.gpkg")})
+ assert it.pick(MEDIA_GEOPACKAGE, MEDIA_GEOJSON).href == "https://x/b.gpkg"
+ assert it.pick(MEDIA_GEOJSON, MEDIA_GEOPACKAGE).href == "https://x/b.geojson"
+
+
+# --- range reads ------------------------------------------------------------
+
+
+class FakeResponse:
+ def __init__(self, status, content=b"", headers=None):
+ self.status_code = status
+ self.content = content
+ self.headers = headers or {}
+
+
+class RangeServer:
+ """Serves a byte string over Range, and counts what was actually moved."""
+
+ def __init__(self, body: bytes, *, supports_range: bool = True):
+ self.body = body
+ self.supports_range = supports_range
+ self.requests: list[str] = []
+
+ def head(self, url, timeout=None):
+ return FakeResponse(200, headers={"Content-Length": str(len(self.body))})
+
+ def get(self, url, headers=None, timeout=None):
+ rng = (headers or {}).get("Range")
+ if not self.supports_range or not rng:
+ self.requests.append("full")
+ return FakeResponse(200, self.body)
+ self.requests.append(rng)
+ spec = rng.split("=", 1)[1]
+ start, end = spec.split("-")
+ lo = int(start)
+ hi = min(int(end), len(self.body) - 1)
+ return FakeResponse(206, self.body[lo : hi + 1])
+
+
+BODY = bytes(range(256)) * 40 # 10 240 bytes, every offset distinguishable
+
+
+def test_reads_a_window_without_moving_the_whole_file():
+ server = RangeServer(BODY)
+ fh = HttpRangeFile(server, "https://x/t.copc.laz", chunk_bytes=512)
+ fh.seek(1000)
+ assert fh.read(16) == BODY[1000:1016]
+ assert fh.bytes_fetched == 512, "one chunk, not the whole file"
+ assert len(server.requests) == 1
+
+
+def test_seek_and_tell_track_the_position():
+ fh = HttpRangeFile(RangeServer(BODY), "https://x/t", chunk_bytes=64)
+ assert fh.seek(100) == 100 and fh.tell() == 100
+ fh.read(10)
+ assert fh.tell() == 110
+ assert fh.seek(-10, io.SEEK_END) == len(BODY) - 10
+ assert fh.seek(5, io.SEEK_CUR) == len(BODY) - 5
+
+
+def test_a_second_read_inside_the_chunk_costs_no_request():
+ server = RangeServer(BODY)
+ fh = HttpRangeFile(server, "https://x/t", chunk_bytes=1024)
+ fh.seek(0)
+ fh.read(8)
+ before = len(server.requests)
+ fh.seek(64)
+ assert fh.read(8) == BODY[64:72]
+ assert len(server.requests) == before, "the chunk was already held"
+
+
+def test_reading_across_the_chunk_boundary_fetches_again():
+ server = RangeServer(BODY)
+ fh = HttpRangeFile(server, "https://x/t", chunk_bytes=128)
+ fh.seek(0)
+ assert fh.read(8) == BODY[0:8]
+ fh.seek(4096)
+ assert fh.read(8) == BODY[4096:4104]
+ assert len(server.requests) == 2
+
+
+def test_a_host_that_ignores_range_is_detected_not_trusted():
+ """A 200 means the whole body arrived; treating it as partial corrupts."""
+ fh = HttpRangeFile(RangeServer(BODY, supports_range=False), "https://x/t")
+ fh.seek(10)
+ with pytest.raises(PointCloudError, match="range requests"):
+ fh.read(4)
+
+
+def test_a_host_that_will_not_report_a_size_is_refused():
+ class NoLength:
+ def head(self, url, timeout=None):
+ return FakeResponse(200, headers={})
+
+ with pytest.raises(PointCloudError, match="size"):
+ HttpRangeFile(NoLength(), "https://x/t").size
+
+
+def test_readinto_fills_the_buffer():
+ fh = HttpRangeFile(RangeServer(BODY), "https://x/t", chunk_bytes=256)
+ fh.seek(32)
+ buf = bytearray(16)
+ assert fh.readinto(buf) == 16
+ assert bytes(buf) == BODY[32:48]
+
+
+def test_bounds_pad_the_footprint_so_the_eaves_survive():
+ ring = [(100.0, 200.0), (110.0, 200.0), (110.0, 220.0), (100.0, 220.0)]
+ assert bounds_of(ring, 1.0) == (99.0, 199.0, 111.0, 221.0)
diff --git a/roofmodel/tests/test_buildings.py b/roofmodel/tests/test_buildings.py
new file mode 100644
index 000000000..90805abc7
--- /dev/null
+++ b/roofmodel/tests/test_buildings.py
@@ -0,0 +1,236 @@
+"""Building lookup, frame detection and footprint clipping."""
+
+from __future__ import annotations
+
+import math
+
+import numpy as np
+import pytest
+
+from ftw_roofmodel import sweref
+from ftw_roofmodel.buildings import (
+ Building,
+ BuildingLookupError,
+ buildings_from_features,
+ clip_to_footprint,
+ inflate_ring,
+ point_in_ring,
+ search_buildings,
+)
+from ftw_roofmodel.geotorget import COLLECTION_BUILDINGS, Credentials, GeotorgetClient
+
+STOCKHOLM = (59.33, 18.07)
+
+
+def square_ring(cx, cy, side):
+ h = side / 2.0
+ return [(cx - h, cy - h), (cx + h, cy - h), (cx + h, cy + h), (cx - h, cy + h)]
+
+
+class FakeResponse:
+ def __init__(self, payload, status_code=200):
+ self._payload = payload
+ self.status_code = status_code
+
+ def json(self):
+ return self._payload
+
+
+class FakeSession:
+ """Records what was asked for and replays a canned STAC response."""
+
+ def __init__(self, payload):
+ self.payload = payload
+ self.posts = []
+
+ def post(self, url, json=None, timeout=None):
+ self.posts.append((url, json))
+ return FakeResponse(self.payload)
+
+
+def stac_feature(ring, feature_id="bldg-1", **props):
+ return {
+ "id": feature_id,
+ "collection": COLLECTION_BUILDINGS,
+ "geometry": {"type": "Polygon", "coordinates": [[list(p) for p in ring] + [list(ring[0])]]},
+ "properties": props,
+ "assets": {},
+ }
+
+
+def test_area_and_centroid_of_a_known_square():
+ ring = square_ring(674000.0, 6580000.0, 10.0)
+ [b] = buildings_from_features(
+ [{"geometry": {"type": "Polygon", "coordinates": [ring]}, "id": "sq"}],
+ latitude=STOCKHOLM[0], longitude=STOCKHOLM[1],
+ )
+ assert b.area_m2 == pytest.approx(100.0)
+ cx, cy = b.centroid_sweref()
+ assert (cx, cy) == pytest.approx((674000.0, 6580000.0))
+
+
+def test_wgs84_rings_are_projected_before_measuring():
+ """A ring in degrees must be recognised and converted, not measured raw."""
+ lat, lon = STOCKHOLM
+ n, e = sweref.wgs84_to_sweref99tm(lat, lon)
+ ring_sweref = square_ring(e, n, 12.0)
+ ring_wgs84 = []
+ for x, y in ring_sweref:
+ blat, blon = sweref.sweref99tm_to_wgs84(y, x) # ring is (E, N)
+ ring_wgs84.append([blon, blat]) # GeoJSON is [lon, lat]
+
+ [b] = buildings_from_features(
+ [{"geometry": {"type": "Polygon", "coordinates": [ring_wgs84]}, "id": "deg"}],
+ latitude=lat, longitude=lon,
+ )
+ # 12 m square, recovered through a full round trip through degrees.
+ assert b.area_m2 == pytest.approx(144.0, abs=0.5)
+
+
+def test_tiles_and_slivers_are_not_offered_as_buildings():
+ lat, lon = STOCKHOLM
+ n, e = sweref.wgs84_to_sweref99tm(lat, lon)
+ feats = [
+ {"geometry": {"type": "Polygon", "coordinates": [square_ring(e, n, 2500.0)]}, "id": "tile"},
+ {"geometry": {"type": "Polygon", "coordinates": [square_ring(e, n, 1.0)]}, "id": "sliver"},
+ {"geometry": {"type": "Polygon", "coordinates": [square_ring(e, n, 11.0)]}, "id": "house"},
+ ]
+ got = buildings_from_features(feats, latitude=lat, longitude=lon)
+ assert [b.building_id for b in got] == ["house"]
+
+
+def test_candidates_come_back_nearest_first():
+ lat, lon = STOCKHOLM
+ n, e = sweref.wgs84_to_sweref99tm(lat, lon)
+ feats = [
+ {"geometry": {"type": "Polygon", "coordinates": [square_ring(e + 60, n, 10.0)]}, "id": "far"},
+ {"geometry": {"type": "Polygon", "coordinates": [square_ring(e + 5, n, 10.0)]}, "id": "near"},
+ {"geometry": {"type": "Polygon", "coordinates": [square_ring(e + 25, n, 10.0)]}, "id": "mid"},
+ ]
+ got = buildings_from_features(feats, latitude=lat, longitude=lon)
+ assert [b.building_id for b in got] == ["near", "mid", "far"]
+ assert got[0].distance_m < got[1].distance_m < got[2].distance_m
+
+
+def test_multipolygon_yields_one_candidate_per_part():
+ lat, lon = STOCKHOLM
+ n, e = sweref.wgs84_to_sweref99tm(lat, lon)
+ feat = {
+ "id": "pair",
+ "geometry": {
+ "type": "MultiPolygon",
+ "coordinates": [[square_ring(e, n, 10.0)], [square_ring(e + 30, n, 12.0)]],
+ },
+ }
+ got = buildings_from_features([feat], latitude=lat, longitude=lon)
+ assert len(got) == 2
+ assert len({b.building_id for b in got}) == 2, "parts must not share an id"
+
+
+def test_search_queries_the_building_collection_and_maps_results():
+ lat, lon = STOCKHOLM
+ n, e = sweref.wgs84_to_sweref99tm(lat, lon)
+ session = FakeSession({"features": [stac_feature(square_ring(e, n, 10.0), "b1")]})
+ client = GeotorgetClient(Credentials("u", "t"), session=session)
+
+ got = search_buildings(client, latitude=lat, longitude=lon)
+
+ assert [b.building_id for b in got] == ["b1"]
+ (_, body), = session.posts
+ assert body["collections"] == [COLLECTION_BUILDINGS]
+ # The bbox is WGS84 lon/lat per the STAC spec — verified against the live
+ # Lantmaeteriet service, which follows it.
+ assert 17.9 < body["bbox"][0] < 18.2, body["bbox"]
+ assert 59.2 < body["bbox"][1] < 59.5, body["bbox"]
+
+
+def test_search_says_what_to_do_when_nothing_comes_back():
+ client = GeotorgetClient(Credentials("u", "t"), session=FakeSession({"features": []}))
+ with pytest.raises(BuildingLookupError) as exc:
+ search_buildings(client, latitude=STOCKHOLM[0], longitude=STOCKHOLM[1])
+ assert "Byggnad" in str(exc.value)
+
+
+def test_point_in_ring_handles_edges_and_outside():
+ ring = square_ring(0.0, 0.0, 10.0)
+ assert point_in_ring(0.0, 0.0, ring)
+ assert point_in_ring(4.9, 4.9, ring)
+ assert not point_in_ring(5.1, 0.0, ring)
+ assert not point_in_ring(0.0, 99.0, ring)
+
+
+def test_inflate_ring_grows_the_outline():
+ ring = square_ring(0.0, 0.0, 10.0)
+ bigger = inflate_ring(ring, 1.0)
+ # Corners sit at radius 7.07; pushing 1 m out puts them at 8.07.
+ assert math.hypot(*bigger[0]) == pytest.approx(math.hypot(*ring[0]) + 1.0)
+ assert all(point_in_ring(x, y, bigger) for x, y in ring)
+
+
+def test_clip_keeps_the_building_and_drops_the_neighbours():
+ rng = np.random.default_rng(3)
+ mine = np.column_stack([
+ rng.uniform(-4, 4, 400), rng.uniform(-4, 4, 400), rng.uniform(0, 4, 400)])
+ theirs = np.column_stack([
+ rng.uniform(46, 54, 400), rng.uniform(-4, 4, 400), rng.uniform(0, 4, 400)])
+ cloud = np.vstack([mine, theirs])
+
+ kept = clip_to_footprint(cloud, square_ring(0.0, 0.0, 10.0), buffer_m=0.0)
+
+ assert len(kept) == len(mine)
+ assert kept[:, 0].max() < 10.0
+
+
+def test_clip_keeps_the_eaves():
+ """Roof returns overhang the wall line; clipping exactly would shave them."""
+ ring = square_ring(0.0, 0.0, 10.0)
+ eaves = np.array([[5.4, 0.0, 3.0], [-5.4, 0.0, 3.0], [0.0, 5.4, 3.0]])
+
+ assert len(clip_to_footprint(eaves, ring, buffer_m=0.0)) == 0
+ assert len(clip_to_footprint(eaves, ring, buffer_m=1.0)) == 3
+
+
+def test_clip_of_an_empty_cloud_is_empty_not_an_error():
+ assert len(clip_to_footprint(np.empty((0, 3)), square_ring(0, 0, 10))) == 0
+
+
+def test_geojson_feature_is_wgs84_and_closed():
+ lat, lon = STOCKHOLM
+ n, e = sweref.wgs84_to_sweref99tm(lat, lon)
+ b = Building("b1", square_ring(e, n, 10.0), 100.0, 0.0)
+ feat = b.to_geojson()
+
+ ring = feat["geometry"]["coordinates"][0]
+ assert ring[0] == ring[-1], "GeoJSON rings must close"
+ for x, y in ring:
+ assert -180 <= x <= 180 and -90 <= y <= 90
+ assert feat["properties"]["latitude"] == pytest.approx(lat, abs=1e-3)
+ assert feat["properties"]["longitude"] == pytest.approx(lon, abs=1e-3)
+
+
+def test_both_ring_orders_come_back_at_the_real_site():
+ """Axis order must not depend on where the ring came from.
+
+ A GeoPackage stores x=easting first; wgs84_to_sweref99tm returns northing
+ first; EPSG's registry declares EPSG:3006 north-first and some exports
+ follow it. The first mismatch shipped: GeoPackage-sourced buildings — the
+ normal Lantmäteriet case — reported their centroids in the Indian Ocean
+ (lat ≈ 4°) with 8 000 km distances, while every test asserted only areas
+ and SWEREF centroids, both of which are blind to a consistent swap.
+ """
+ lat, lon = STOCKHOLM
+ n, e = sweref.wgs84_to_sweref99tm(lat, lon)
+ ring_en = square_ring(e, n, 10.0) # as a GeoPackage stores it
+ ring_ne = [(y, x) for x, y in ring_en] # as the EPSG registry says
+
+ for ring in (ring_en, ring_ne):
+ [b] = buildings_from_features(
+ [{"geometry": {"type": "Polygon", "coordinates": [ring]}, "id": "b"}],
+ latitude=lat, longitude=lon,
+ )
+ feat = b.to_geojson()
+ assert feat["properties"]["latitude"] == pytest.approx(lat, abs=1e-3)
+ assert feat["properties"]["longitude"] == pytest.approx(lon, abs=1e-3)
+ assert b.distance_m < 50.0, (
+ f"a building drawn around the site is {b.distance_m:.0f} m away"
+ )
diff --git a/roofmodel/tests/test_derive_footprint.py b/roofmodel/tests/test_derive_footprint.py
new file mode 100644
index 000000000..466b8fae5
--- /dev/null
+++ b/roofmodel/tests/test_derive_footprint.py
@@ -0,0 +1,232 @@
+"""Deriving against a picked building footprint."""
+
+from __future__ import annotations
+
+import math
+
+import numpy as np
+import pytest
+
+from ftw_roofmodel import pipeline, sweref
+from ftw_roofmodel.buildings import BuildingLookupError, clip_to_footprint
+from ftw_roofmodel.geotorget import COLLECTION_BUILDINGS, Credentials, StacItem
+from ftw_roofmodel.pipeline import RoofModelError, derive
+from ftw_roofmodel.segment import segment_roof
+
+STOCKHOLM = (59.33, 18.07)
+
+
+def roof_face(tilt, azimuth, w, d, origin, density=8, noise=0.04, seed=1):
+ """Sample a tilted rectangle. Written as the inverse of what segment.py
+ computes, so recovering the tilt is a real test rather than a tautology."""
+ rng = np.random.default_rng(seed)
+ n = int(w * d * density)
+ x = rng.uniform(0, w, n)
+ y = rng.uniform(0, d, n)
+ az = math.radians(azimuth)
+ s = math.tan(math.radians(tilt))
+ z = -(x * math.sin(az) + y * math.cos(az)) * s + rng.normal(0, noise, n)
+ return np.column_stack([x + origin[0], y + origin[1], z + origin[2]])
+
+
+def ring(cx, cy, w, d):
+ return [(cx, cy), (cx + w, cy), (cx + w, cy + d), (cx, cy + d)]
+
+
+class FakeClient:
+ """Stands in for Geotorget: canned buildings, canned LiDAR."""
+
+ def __init__(self, buildings_payload, points):
+ self._buildings = buildings_payload
+ self._points = points
+ self.searched = []
+ self.searched_boxes = []
+
+ def search(self, collection, bbox, limit=20):
+ self.searched.append(collection)
+ self.searched_boxes.append((collection, bbox))
+ if collection == COLLECTION_BUILDINGS:
+ return [StacItem(f["id"], collection, {}, None, raw=f) for f in self._buildings]
+ return [StacItem("lidar-1", collection, {"data": "http://x/tile.laz"}, None, raw={})]
+
+ def download(self, url):
+ return b"laz-bytes"
+
+
+@pytest.fixture
+def scene(monkeypatch):
+ """A house and a neighbour that share a ridge orientation.
+
+ The neighbour is the point: an azimuth-180 plane is z = f(y) with no x term,
+ so it extends across the whole tile and the two buildings compete for each
+ other's returns unless the cloud is clipped first.
+ """
+ n, e = sweref.wgs84_to_sweref99tm(*STOCKHOLM)
+ mine = np.vstack([
+ roof_face(35, 180, 12, 6, (e, n, 0), seed=2),
+ roof_face(35, 0, 12, 6, (e, n + 6, 4.2), seed=3),
+ ])
+ neighbour = np.vstack([
+ roof_face(35, 180, 12, 6, (e + 40, n, 0), seed=4),
+ roof_face(35, 0, 12, 6, (e + 40, n + 6, 4.2), seed=5),
+ ])
+ cloud = np.vstack([mine, neighbour])
+
+ buildings = [
+ {"id": "mine", "geometry": {"type": "Polygon",
+ "coordinates": [[list(p) for p in ring(e, n, 12, 12)]]}, "properties": {}},
+ {"id": "neighbour", "geometry": {"type": "Polygon",
+ "coordinates": [[list(p) for p in ring(e + 40, n, 12, 12)]]}, "properties": {}},
+ ]
+ monkeypatch.setattr(pipeline, "load_points", lambda data: cloud)
+ return FakeClient(buildings, cloud), cloud, (e, n)
+
+
+def test_derive_clips_to_the_picked_building(scene):
+ client, cloud, _ = scene
+ model = derive(
+ latitude=STOCKHOLM[0], longitude=STOCKHOLM[1],
+ credentials=Credentials("u", "t"), client=client, building_id="mine",
+ )
+
+ b = model["building"]
+ assert b["building_id"] == "mine"
+ assert b["returns_in_radius"] == len(cloud)
+ # Roughly half the tile is the neighbour's, and it must be gone.
+ assert b["returns_used"] < b["returns_in_radius"] * 0.6
+ assert model["arrays"], "a clipped house still has a south roof"
+
+
+def test_clipping_recovers_the_true_area_the_neighbour_would_have_stolen(scene):
+ """The measurable payoff: coplanar buildings stop eating each other."""
+ _, cloud, (e, n) = scene
+ truth = 12 * 6 / math.cos(math.radians(35))
+
+ whole_tile = [p for p in segment_roof(cloud, point_density=8.0)
+ if abs(p.azimuth_deg - 180) < 5]
+ clipped = [p for p in segment_roof(clip_to_footprint(cloud, ring(e, n, 12, 12)),
+ point_density=8.0)
+ if abs(p.azimuth_deg - 180) < 5]
+
+ assert len(clipped) == 1, "one building has one south face"
+ assert clipped[0].area_m2 == pytest.approx(truth, rel=0.10)
+ # Unclipped, the two south faces are coplanar and merge into one oversized
+ # segment, so the site's own roof cannot be measured at all.
+ assert len(whole_tile) != 1 or whole_tile[0].area_m2 > truth * 1.5
+
+
+def test_derive_without_a_building_id_does_not_search_for_buildings(scene):
+ client, _, _ = scene
+ model = derive(
+ latitude=STOCKHOLM[0], longitude=STOCKHOLM[1],
+ credentials=Credentials("u", "t"), client=client,
+ )
+ assert COLLECTION_BUILDINGS not in client.searched
+ assert model["building"] is None
+
+
+def test_derive_rejects_a_building_id_that_is_not_there(scene):
+ client, _, _ = scene
+ with pytest.raises(RoofModelError) as exc:
+ derive(
+ latitude=STOCKHOLM[0], longitude=STOCKHOLM[1],
+ credentials=Credentials("u", "t"), client=client, building_id="not-a-building",
+ )
+ assert "not found" in str(exc.value)
+
+
+def test_derive_explains_a_footprint_with_no_returns_on_it(monkeypatch, scene):
+ """A building newer than the scan is a real case and needs a real message."""
+ client, _, (e, n) = scene
+ empty = np.empty((0, 3))
+ monkeypatch.setattr(pipeline, "load_points", lambda data: np.vstack([
+ roof_face(35, 180, 12, 6, (e + 400, n, 0), seed=9)]))
+
+ with pytest.raises(RoofModelError) as exc:
+ derive(
+ latitude=STOCKHOLM[0], longitude=STOCKHOLM[1],
+ credentials=Credentials("u", "t"), client=client, building_id="mine",
+ )
+ msg = str(exc.value)
+ assert "fall on building" in msg and "newer than the scan" in msg
+
+
+def test_derive_clips_to_a_drawn_footprint(scene):
+ """Where the catalog has no building dataset, the operator traces the
+ outline by hand — and that must clip exactly like a picked building,
+ without any building search happening at all."""
+ client, cloud, (e, n) = scene
+ corners = []
+ for ee, nn in ring(e, n, 12, 12):
+ lat, lon = sweref.sweref99tm_to_wgs84(nn, ee)
+ corners.append([lon, lat])
+ corners.append(list(corners[0])) # GeoJSON rings close themselves
+
+ model = derive(
+ latitude=STOCKHOLM[0], longitude=STOCKHOLM[1],
+ credentials=Credentials("u", "t"), client=client, footprint=corners,
+ )
+
+ assert COLLECTION_BUILDINGS not in client.searched
+ b = model["building"]
+ assert b["building_id"] == "drawn-footprint"
+ assert b["returns_used"] < b["returns_in_radius"] * 0.6
+ assert model["arrays"], "a traced house still has a south roof"
+
+
+def test_a_drawn_footprint_needs_three_corners(scene):
+ client, _, _ = scene
+ with pytest.raises(Exception) as exc:
+ derive(
+ latitude=STOCKHOLM[0], longitude=STOCKHOLM[1],
+ credentials=Credentials("u", "t"), client=client,
+ footprint=[[18.06, 59.33], [18.07, 59.33]],
+ )
+ assert "three corners" in str(exc.value)
+
+
+def test_the_re_search_reaches_as_far_as_the_picker_did(monkeypatch, scene):
+ """A barn 100 m out is inside the picker's 150 m search but outside the
+ 40 m LiDAR radius. The derive's re-find must use the picker's reach, or
+ every such pick dies with "not found near this site"."""
+ client, _, _ = scene
+ real_search = pipeline.search_buildings
+ radii = []
+
+ def windowed(client_, *, latitude, longitude, radius_m, **kw):
+ radii.append(radius_m)
+ # Model the real windowing: the barn only comes back when the search
+ # reaches at least as far as the picker's default.
+ if radius_m < 150.0:
+ raise BuildingLookupError("nothing inside this window")
+ return real_search(client_, latitude=latitude, longitude=longitude,
+ radius_m=radius_m, **kw)
+
+ monkeypatch.setattr(pipeline, "search_buildings", windowed)
+ model = derive(
+ latitude=STOCKHOLM[0], longitude=STOCKHOLM[1],
+ credentials=Credentials("u", "t"), client=client, building_id="mine",
+ )
+ assert model["building"]["building_id"] == "mine"
+ assert radii and min(radii) >= 150.0
+
+
+def test_the_lidar_lookup_centres_on_the_picked_building(scene):
+ """The tile search must cover the roof being derived, not the pin: a
+ building at the search edge can sit on a different tile."""
+ client, _, (e, n) = scene
+ derive(
+ latitude=STOCKHOLM[0], longitude=STOCKHOLM[1],
+ credentials=Credentials("u", "t"), client=client, building_id="neighbour",
+ )
+ lidar_bboxes = [b for c, b in getattr(client, "searched_boxes", [])
+ if c != COLLECTION_BUILDINGS]
+ assert lidar_bboxes, "the LiDAR collection was searched"
+ west, south, east, north = lidar_bboxes[-1]
+ centre_n, centre_e = sweref.wgs84_to_sweref99tm(
+ (south + north) / 2.0, (west + east) / 2.0
+ )
+ # The neighbour's centroid is 40 m east of the site; the bbox centre must
+ # follow it rather than stay on the pin.
+ assert centre_e == pytest.approx(e + 40 + 6, abs=15.0)
+ assert centre_n == pytest.approx(n + 6, abs=15.0)
diff --git a/roofmodel/tests/test_geopackage.py b/roofmodel/tests/test_geopackage.py
new file mode 100644
index 000000000..54c49e424
--- /dev/null
+++ b/roofmodel/tests/test_geopackage.py
@@ -0,0 +1,201 @@
+"""Decoding GeoPackage, the format Lantmaeteriet ships building vectors in.
+
+The fixtures are built byte by byte from the published layouts rather than by
+round-tripping the decoder, so a decoder that agrees with itself but not with
+the standard still fails here.
+"""
+
+from __future__ import annotations
+
+import os
+import sqlite3
+import struct
+import tempfile
+
+import pytest
+
+from ftw_roofmodel.geopackage import (
+ GeoPackageError,
+ parse_geometry_blob,
+ read_features,
+)
+
+SWEREF = 3006
+
+
+def wkb_polygon(rings, *, little=True, z=False):
+ """Standard WKB polygon, per OGC 06-103r4 clause 8.2."""
+ e = "<" if little else ">"
+ code = 1003 if z else 3
+ out = struct.pack("B", 1 if little else 0) + struct.pack(e + "I", code)
+ out += struct.pack(e + "I", len(rings))
+ for ring in rings:
+ out += struct.pack(e + "I", len(ring))
+ for point in ring:
+ out += struct.pack(e + "dd", point[0], point[1])
+ if z:
+ out += struct.pack(e + "d", point[2] if len(point) > 2 else 0.0)
+ return out
+
+
+def wkb_multipolygon(polygons, *, little=True):
+ e = "<" if little else ">"
+ out = struct.pack("B", 1 if little else 0) + struct.pack(e + "I", 6)
+ out += struct.pack(e + "I", len(polygons))
+ for rings in polygons:
+ out += wkb_polygon(rings, little=little)
+ return out
+
+
+def gpkg_blob(wkb, *, envelope=None, srs_id=SWEREF, little=True, empty=False):
+ """GeoPackage geometry BLOB, per OGC 12-128r19 clause 2.1.3.
+
+ Header is magic(2) + version(1) + flags(1) + srs_id(4), then the envelope,
+ then the WKB.
+ """
+ indicator = 0 if envelope is None else 1
+ flags = (1 if little else 0) | (indicator << 1) | (0x10 if empty else 0)
+ e = "<" if little else ">"
+ header = b"GP" + bytes([0, flags]) + struct.pack(e + "i", srs_id)
+ assert len(header) == 8, "the GeoPackage header is 8 bytes before the envelope"
+ body = b""
+ if envelope is not None:
+ body = struct.pack(e + "dddd", *envelope)
+ assert len(body) == 32, "an xy envelope is four doubles"
+ return header + body + wkb
+
+
+SQUARE = [[(0.0, 0.0), (10.0, 0.0), (10.0, 10.0), (0.0, 10.0), (0.0, 0.0)]]
+
+
+def test_reads_a_plain_polygon():
+ geom = parse_geometry_blob(gpkg_blob(wkb_polygon(SQUARE)))
+ assert geom["type"] == "Polygon"
+ assert geom["coordinates"][0][0] == [0.0, 0.0]
+ assert geom["coordinates"][0][2] == [10.0, 10.0]
+ assert len(geom["coordinates"][0]) == 5
+
+
+def test_skips_the_envelope_when_one_is_present():
+ """The envelope sits between the header and the WKB and must be stepped over."""
+ with_env = parse_geometry_blob(
+ gpkg_blob(wkb_polygon(SQUARE), envelope=(0.0, 10.0, 0.0, 10.0))
+ )
+ without = parse_geometry_blob(gpkg_blob(wkb_polygon(SQUARE)))
+ assert with_env == without
+
+
+def test_reads_big_endian_geometry():
+ assert parse_geometry_blob(
+ gpkg_blob(wkb_polygon(SQUARE, little=False), little=False)
+ ) == parse_geometry_blob(gpkg_blob(wkb_polygon(SQUARE)))
+
+
+def test_reads_3d_polygons_by_stepping_the_z():
+ """Building footprints carry heights; the z must not shift the ring."""
+ ring = [[(0.0, 0.0, 12.5), (10.0, 0.0, 12.5), (10.0, 10.0, 12.5), (0.0, 0.0, 12.5)]]
+ geom = parse_geometry_blob(gpkg_blob(wkb_polygon(ring, z=True)))
+ assert geom["coordinates"][0] == [[0.0, 0.0], [10.0, 0.0], [10.0, 10.0], [0.0, 0.0]]
+
+
+def test_reads_a_multipolygon_as_several_rings():
+ other = [[(20.0, 20.0), (30.0, 20.0), (30.0, 30.0), (20.0, 20.0)]]
+ geom = parse_geometry_blob(gpkg_blob(wkb_multipolygon([SQUARE, other])))
+ assert geom["type"] == "MultiPolygon"
+ assert len(geom["coordinates"]) == 2
+
+
+def test_an_interior_ring_survives():
+ """A courtyard is a second ring, and dropping it would inflate the roof."""
+ hole = [(2.0, 2.0), (4.0, 2.0), (4.0, 4.0), (2.0, 2.0)]
+ geom = parse_geometry_blob(gpkg_blob(wkb_polygon(SQUARE + [hole])))
+ assert len(geom["coordinates"]) == 2
+
+
+def test_empty_geometry_is_none_not_an_error():
+ assert parse_geometry_blob(gpkg_blob(b"", empty=True)) is None
+
+
+def test_rejects_a_blob_that_is_not_a_geopackage_geometry():
+ with pytest.raises(GeoPackageError, match="magic"):
+ parse_geometry_blob(b"XX" + bytes(20))
+
+
+def test_refuses_extended_geometry_rather_than_guessing():
+ blob = bytearray(gpkg_blob(wkb_polygon(SQUARE)))
+ blob[3] |= 0x20
+ with pytest.raises(GeoPackageError, match="extended"):
+ parse_geometry_blob(bytes(blob))
+
+
+def test_refuses_a_non_polygon_rather_than_mis_clipping():
+ point = struct.pack("B", 1) + struct.pack(" arrays ------------------------------------------------------
+
+def test_north_facing_pitched_roofs_are_not_proposed():
+ """At Swedish latitudes a north pitch yields too little to be worth adding
+ to an operator's config."""
+ planes = [
+ RoofPlane(tilt_deg=35, azimuth_deg=0, area_m2=60, point_count=200, mean_height_m=6),
+ RoofPlane(tilt_deg=35, azimuth_deg=180, area_m2=60, point_count=200, mean_height_m=6),
+ ]
+ arrays = planes_to_arrays(planes)
+ assert len(arrays) == 1
+ assert arrays[0].azimuth_deg == 180
+
+
+def test_flat_roofs_are_kept_regardless_of_building_orientation():
+ planes = [RoofPlane(tilt_deg=1.0, azimuth_deg=180, area_m2=90, point_count=300, mean_height_m=9)]
+ assert len(planes_to_arrays(planes)) == 1
+
+
+def test_tiny_faces_are_dropped():
+ """Dormers and porches are real surfaces but not candidate arrays."""
+ planes = [RoofPlane(tilt_deg=35, azimuth_deg=180, area_m2=3.0, point_count=50, mean_height_m=5)]
+ assert planes_to_arrays(planes) == []
+
+
+def test_arrays_get_readable_and_unique_names():
+ planes = [
+ RoofPlane(tilt_deg=35, azimuth_deg=180, area_m2=60, point_count=200, mean_height_m=6),
+ RoofPlane(tilt_deg=35, azimuth_deg=182, area_m2=40, point_count=150, mean_height_m=6),
+ RoofPlane(tilt_deg=35, azimuth_deg=270, area_m2=30, point_count=120, mean_height_m=6),
+ ]
+ arrays = planes_to_arrays(planes)
+ names = [a.name for a in arrays]
+ assert len(set(names)) == len(names), names
+ assert names[0] == "Roof south"
+ assert "Roof west" in names
+
+
+def test_array_json_matches_the_config_field_names():
+ """The document pre-fills weather.pv_arrays, so the keys must line up."""
+ planes = [RoofPlane(tilt_deg=35, azimuth_deg=180, area_m2=60, point_count=200, mean_height_m=6)]
+ payload = planes_to_arrays(planes)[0].to_json()
+ assert set(payload) >= {"name", "rated_w", "tilt_deg", "azimuth_deg"}
+ assert payload["rated_w"] > 0
+
+
+# --- end to end ------------------------------------------------------------
+
+def _patched_points(monkeypatch, cloud):
+ monkeypatch.setattr(pipeline, "load_points", lambda data: cloud)
+
+
+def test_derive_produces_a_versioned_document(monkeypatch):
+ gable = np.vstack([
+ make_plane(tilt_deg=35, azimuth_deg=180, width=12, depth=6, seed=11),
+ make_plane(tilt_deg=35, azimuth_deg=0, width=12, depth=6, origin=(0, 6, -4.2), seed=12),
+ ])
+ _patched_points(monkeypatch, gable)
+ session = FakeSession(search={"features": [feature()]}, asset=b"laz-bytes")
+ client = GeotorgetClient(CREDS, session=session)
+
+ model = pipeline.derive(
+ latitude=59.33, longitude=18.07, credentials=CREDS, client=client,
+ now=dt.datetime(2026, 7, 31, tzinfo=dt.timezone.utc),
+ )
+
+ assert model["schema_version"] == pipeline.SCHEMA_VERSION
+ assert model["source"]["provider"] == "lantmateriet"
+ assert model["captured_at_ms"] > 0
+ assert model["derived_at_ms"] == 1785456000000
+ # The gable's north face is dropped, so exactly the south face survives.
+ assert len(model["arrays"]) == 1
+ south = model["arrays"][0]
+ assert south["azimuth_deg"] == pytest.approx(180.0, abs=3.0)
+ assert south["tilt_deg"] == pytest.approx(35.0, abs=3.0)
+ assert south["rated_w"] > 0
+ # Must be JSON-serialisable for the subprocess contract.
+ json.dumps(model)
+
+
+def test_derive_searches_the_spec_bbox(monkeypatch):
+ _patched_points(monkeypatch, make_plane(tilt_deg=35, azimuth_deg=180))
+ session = FakeSession(search={"features": [feature()]}, asset=b"x")
+ pipeline.derive(
+ latitude=59.33, longitude=18.07, credentials=CREDS,
+ client=GeotorgetClient(CREDS, session=session), radius_m=40.0,
+ )
+ (_, body), = session.posts
+ # WGS84 lon/lat per the STAC spec, the live service's frame — and still
+ # square on the ground: built by stepping metres in SWEREF and
+ # unprojecting, which is what stac_search_bbox does.
+ expected = sweref.stac_search_bbox(59.33, 18.07, 40.0, 4326)
+ assert list(body["bbox"]) == pytest.approx(list(expected))
+
+
+def test_derive_uses_both_lantmateriet_roots_by_default(monkeypatch):
+ """The live service splits its STAC per product family: buildings on the
+ vector root, point clouds on the elevation root. The default derive must
+ build a client for each."""
+ made = []
+
+ class RecordingClient:
+ def __init__(self, credentials, base_url=None, **kw):
+ made.append(base_url)
+
+ def search(self, collection, bbox, limit=20):
+ return []
+
+ monkeypatch.setattr(pipeline, "GeotorgetClient", RecordingClient)
+ with pytest.raises(RoofModelError):
+ pipeline.derive(latitude=59.33, longitude=18.07, credentials=CREDS)
+ assert made == [
+ pipeline.geotorget.DEFAULT_BASE_URL,
+ pipeline.geotorget.DEFAULT_LIDAR_BASE_URL,
+ ]
+
+
+def test_derive_uses_one_client_for_a_custom_catalog(monkeypatch):
+ """A custom single-root catalog serves both collections itself."""
+ made = []
+
+ class RecordingClient:
+ def __init__(self, credentials, base_url=None, **kw):
+ made.append(base_url)
+
+ def search(self, collection, bbox, limit=20):
+ return []
+
+ monkeypatch.setattr(pipeline, "GeotorgetClient", RecordingClient)
+ with pytest.raises(RoofModelError):
+ pipeline.derive(
+ latitude=59.33, longitude=18.07, credentials=CREDS,
+ base_url="https://stac.example.org",
+ )
+ assert made == ["https://stac.example.org"]
+
+
+def test_derive_outside_sweden_says_so(monkeypatch):
+ """No tiles come back for a site Lantmaeteriet does not cover."""
+ session = FakeSession(search={"features": []})
+ with pytest.raises(RoofModelError) as exc:
+ pipeline.derive(
+ latitude=-33.87, longitude=151.21, credentials=CREDS,
+ client=GeotorgetClient(CREDS, session=session),
+ )
+ assert "Sweden only" in str(exc.value)
+
+
+def test_derive_reports_unknown_capture_date_without_failing(monkeypatch):
+ _patched_points(monkeypatch, make_plane(tilt_deg=35, azimuth_deg=180))
+ session = FakeSession(search={"features": [feature(datetime_value=None)]}, asset=b"x")
+ model = pipeline.derive(
+ latitude=59.33, longitude=18.07, credentials=CREDS,
+ client=GeotorgetClient(CREDS, session=session),
+ )
+ assert model["captured_at_ms"] is None
+ assert model["source"]["dataset_datetime"] is None
+ assert model["arrays"], "a missing provenance date must not block the model"
diff --git a/roofmodel/tests/test_pointcloud.py b/roofmodel/tests/test_pointcloud.py
new file mode 100644
index 000000000..ea3f6a101
--- /dev/null
+++ b/roofmodel/tests/test_pointcloud.py
@@ -0,0 +1,29 @@
+"""The COPC window query must never prune on z.
+
+Lantmäteriet's COPC writer keys octree nodes with a z origin that does not
+match the file's own cube (seen live: a node keyed to a slab 1.7 km underground
+holding points at +18..+42 m). Pruning by those keys silently drops the dense
+deep levels, so the query's vertical range has to cover every slab the cube
+could describe.
+"""
+
+from ftw_roofmodel.pointcloud import copc_query_z_range
+
+
+def test_the_query_covers_the_whole_octree_cube():
+ for center, half in [(332.51, 5000.005), (0.0, 128.0), (-250.0, 4096.0)]:
+ z_lo, z_hi = copc_query_z_range(center, half)
+ assert z_lo < center - half
+ assert z_hi > center + half
+
+
+def test_the_query_stays_bounded_for_scaled_int_filters():
+ # laspy's post-filter casts scaled bounds to int32; the range must stay
+ # proportional to the cube, never an arbitrary huge sentinel.
+ z_lo, z_hi = copc_query_z_range(332.51, 5000.005)
+ assert z_hi - z_lo < 10 * 5000.005
+
+
+def test_a_degenerate_cube_still_yields_a_range():
+ z_lo, z_hi = copc_query_z_range(100.0, 0.0)
+ assert z_lo < 100.0 < z_hi
diff --git a/roofmodel/tests/test_segment.py b/roofmodel/tests/test_segment.py
new file mode 100644
index 000000000..e8ec35451
--- /dev/null
+++ b/roofmodel/tests/test_segment.py
@@ -0,0 +1,188 @@
+"""Roof segmentation tests.
+
+Every case is a synthetic roof whose tilt, azimuth and area are known exactly by
+construction, so the assertions check recovered geometry against ground truth
+rather than against a previous run's output.
+"""
+
+import math
+
+import numpy as np
+import pytest
+
+from ftw_roofmodel.segment import RoofPlane, segment_roof
+
+
+def make_plane(
+ *,
+ tilt_deg: float,
+ azimuth_deg: float,
+ width: float = 10.0,
+ depth: float = 8.0,
+ origin=(0.0, 0.0, 0.0),
+ density: float = 8.0,
+ noise_m: float = 0.0,
+ seed: int = 1,
+) -> np.ndarray:
+ """Sample a rectangular sloped surface with a known tilt and azimuth.
+
+ The surface is generated by taking a horizontal grid and raising it along
+ the downslope direction, which is the inverse of what segment_roof does, so
+ the test never shares an implementation with the code under test.
+ """
+ rng = np.random.default_rng(seed)
+ n = max(int(width * depth * density), 60)
+ x = rng.uniform(0, width, n)
+ y = rng.uniform(0, depth, n)
+
+ # Aspect points the way the surface faces; height falls off along it.
+ az = math.radians(azimuth_deg)
+ east_dir, north_dir = math.sin(az), math.cos(az)
+ slope = math.tan(math.radians(tilt_deg))
+ z = -(x * east_dir + y * north_dir) * slope
+
+ if noise_m:
+ z = z + rng.normal(0.0, noise_m, n)
+
+ return np.column_stack([x + origin[0], y + origin[1], z + origin[2]])
+
+
+@pytest.mark.parametrize(
+ "tilt,azimuth",
+ [
+ (35.0, 180.0), # classic south-facing pitched roof
+ (30.0, 90.0), # east
+ (30.0, 270.0), # west
+ (45.0, 0.0), # north
+ (20.0, 225.0), # south-west
+ (60.0, 135.0), # steep south-east
+ ],
+)
+def test_recovers_known_tilt_and_azimuth(tilt, azimuth):
+ cloud = make_plane(tilt_deg=tilt, azimuth_deg=azimuth)
+ planes = segment_roof(cloud, point_density=8.0)
+ assert planes, "expected at least one plane"
+ got = planes[0]
+ assert got.tilt_deg == pytest.approx(tilt, abs=1.5)
+ # Compare on the circle so 359.5 vs 0.5 is a 1-degree error, not 359.
+ delta = abs((got.azimuth_deg - azimuth + 180.0) % 360.0 - 180.0)
+ assert delta < 2.0, f"azimuth {got.azimuth_deg} vs {azimuth}"
+
+
+def test_flat_roof_reports_flat_and_does_not_invent_an_azimuth():
+ """A horizontal surface has no meaningful aspect: its normal is vertical,
+ so the horizontal component is pure noise and could point anywhere."""
+ cloud = make_plane(tilt_deg=0.0, azimuth_deg=180.0, noise_m=0.02)
+ planes = segment_roof(cloud, point_density=8.0)
+ assert planes
+ assert planes[0].tilt_deg < 5.0
+ assert planes[0].azimuth_deg == 180.0
+
+
+def test_gable_roof_splits_into_two_opposing_faces():
+ """The canonical case: one ridge, two faces 180 degrees apart."""
+ south = make_plane(tilt_deg=35, azimuth_deg=180, depth=6, origin=(0, 0, 0), seed=2)
+ north = make_plane(tilt_deg=35, azimuth_deg=0, depth=6, origin=(0, 6, -4.2), seed=3)
+ planes = segment_roof(np.vstack([south, north]), point_density=8.0)
+
+ assert len(planes) >= 2, f"expected two faces, got {len(planes)}"
+ azimuths = sorted(p.azimuth_deg for p in planes[:2])
+ opposed = abs((azimuths[1] - azimuths[0]) - 180.0)
+ assert opposed < 5.0, f"faces should oppose, got {azimuths}"
+ for p in planes[:2]:
+ assert p.tilt_deg == pytest.approx(35.0, abs=2.0)
+
+
+def test_two_separate_buildings_on_the_same_plane_are_split():
+ """Two roofs with identical pitch and aspect satisfy one plane equation.
+ RANSAC alone would merge them; the DBSCAN pass is what separates them."""
+ a = make_plane(tilt_deg=30, azimuth_deg=180, origin=(0, 0, 0), seed=4)
+ b = make_plane(tilt_deg=30, azimuth_deg=180, origin=(60, 0, 0), seed=5)
+ planes = segment_roof(np.vstack([a, b]), point_density=8.0, cluster_eps_m=1.5)
+
+ assert len(planes) >= 2, "spatially disjoint faces must not be merged"
+ for p in planes[:2]:
+ assert p.tilt_deg == pytest.approx(30.0, abs=2.0)
+
+
+def test_area_is_the_sloped_area_not_the_footprint():
+ """A 10x8 footprint at 60 degrees covers 80 / cos(60) = 160 m2 of roof."""
+ cloud = make_plane(tilt_deg=60.0, azimuth_deg=180.0, width=10, depth=8, density=10)
+ planes = segment_roof(cloud, point_density=10.0)
+ assert planes
+ assert planes[0].area_m2 == pytest.approx(160.0, rel=0.15)
+
+
+def test_area_of_a_flat_roof_matches_its_footprint():
+ cloud = make_plane(tilt_deg=0.0, azimuth_deg=180.0, width=12, depth=10, density=10)
+ planes = segment_roof(cloud, point_density=10.0)
+ assert planes
+ assert planes[0].area_m2 == pytest.approx(120.0, rel=0.15)
+
+
+def test_survives_realistic_measurement_noise():
+ """1-2 pts/m2 airborne LiDAR carries several centimetres of range noise."""
+ cloud = make_plane(tilt_deg=35.0, azimuth_deg=180.0, noise_m=0.05, density=6)
+ planes = segment_roof(cloud, point_density=6.0, threshold_m=0.3)
+ assert planes
+ assert planes[0].tilt_deg == pytest.approx(35.0, abs=3.0)
+
+
+def test_walls_are_rejected():
+ """A near-vertical surface is a wall or a dormer cheek, not a roof."""
+ cloud = make_plane(tilt_deg=88.0, azimuth_deg=180.0)
+ planes = segment_roof(cloud, point_density=8.0)
+ assert all(p.tilt_deg <= 80.0 for p in planes)
+
+
+def test_noise_alone_yields_nothing_believable():
+ """A handful of scattered returns must not become a roof."""
+ rng = np.random.default_rng(7)
+ cloud = rng.uniform(0, 10, size=(25, 3))
+ assert segment_roof(cloud, point_density=8.0) == []
+
+
+def test_is_deterministic():
+ """Re-running a derive must not shuffle an operator's arrays."""
+ cloud = make_plane(tilt_deg=35, azimuth_deg=180)
+ a = segment_roof(cloud, point_density=8.0)
+ b = segment_roof(cloud, point_density=8.0)
+ assert a == b
+
+
+def test_planes_are_ordered_by_area():
+ big = make_plane(tilt_deg=30, azimuth_deg=180, width=14, depth=12, origin=(0, 0, 0), seed=8)
+ small = make_plane(tilt_deg=30, azimuth_deg=180, width=5, depth=4, origin=(70, 0, 0), seed=9)
+ planes = segment_roof(np.vstack([big, small]), point_density=8.0)
+ assert len(planes) >= 2
+ assert planes[0].area_m2 >= planes[1].area_m2
+
+
+def test_rejects_malformed_input():
+ with pytest.raises(ValueError):
+ segment_roof(np.zeros((10, 2)))
+
+
+def test_kwp_derives_from_area_with_packing_losses():
+ """A 100 m2 face cannot carry 100 m2 of modules."""
+ plane = RoofPlane(tilt_deg=35, azimuth_deg=180, area_m2=100.0, point_count=800, mean_height_m=6.0)
+ kwp = plane.kwp()
+ assert kwp == pytest.approx(100 * 0.70 * 200 / 1000.0)
+ assert kwp < 100 * 200 / 1000.0, "packing factor must reduce the raw area"
+
+
+def test_kwp_scales_with_area():
+ a = RoofPlane(tilt_deg=35, azimuth_deg=180, area_m2=50.0, point_count=1, mean_height_m=1.0)
+ b = RoofPlane(tilt_deg=35, azimuth_deg=180, area_m2=100.0, point_count=1, mean_height_m=1.0)
+ assert b.kwp() == pytest.approx(2 * a.kwp())
+
+
+def test_azimuth_never_reports_360():
+ """A north face fits at ~359.97 deg, which rounds to 360.0 -- the same
+ direction as 0 but an out-of-range-looking value for anything consuming it.
+ Caught by the demo, so pinned here."""
+ cloud = make_plane(tilt_deg=35, azimuth_deg=0, seed=21)
+ planes = segment_roof(cloud, point_density=8.0)
+ assert planes
+ for p in planes:
+ assert 0.0 <= p.azimuth_deg < 360.0, p.azimuth_deg
diff --git a/roofmodel/tests/test_source_formats.py b/roofmodel/tests/test_source_formats.py
new file mode 100644
index 000000000..db41dff69
--- /dev/null
+++ b/roofmodel/tests/test_source_formats.py
@@ -0,0 +1,314 @@
+"""The two Lantmaeteriet products end to end, in the formats they ship in.
+
+Both are STAC APIs over one client and one credential. What differs is the
+payload: *Byggnad Nedladdning, vektor* is GeoPackage, *Laserdata Nedladdning,
+Skog* is LAZ organised as COPC.
+"""
+
+from __future__ import annotations
+
+import json
+import math
+
+import numpy as np
+import pytest
+
+from ftw_roofmodel import pipeline, sweref
+from ftw_roofmodel.buildings import BuildingLookupError, search_buildings
+from ftw_roofmodel.geotorget import (
+ COLLECTION_BUILDINGS,
+ MEDIA_COPC,
+ MEDIA_GEOJSON,
+ MEDIA_GEOPACKAGE,
+ MEDIA_LAZ,
+ Asset,
+ Credentials,
+ StacItem,
+)
+from ftw_roofmodel.pipeline import derive
+from ftw_roofmodel.pointcloud import PointCloudError
+
+from .test_geopackage import build_gpkg, gpkg_blob, wkb_polygon
+
+STOCKHOLM = (59.33, 18.07)
+N, E = sweref.wgs84_to_sweref99tm(*STOCKHOLM)
+
+
+def square(cx, cy, w, d):
+ return [[(cx, cy), (cx + w, cy), (cx + w, cy + d), (cx, cy + d), (cx, cy)]]
+
+
+def roof_face(tilt, azimuth, w, d, origin, density=8, noise=0.04, seed=1):
+ rng = np.random.default_rng(seed)
+ n = int(w * d * density)
+ x = rng.uniform(0, w, n)
+ y = rng.uniform(0, d, n)
+ az = math.radians(azimuth)
+ s = math.tan(math.radians(tilt))
+ z = -(x * math.sin(az) + y * math.cos(az)) * s + rng.normal(0, noise, n)
+ return np.column_stack([x + origin[0], y + origin[1], z + origin[2]])
+
+
+HOUSE = np.vstack([
+ roof_face(35, 180, 12, 6, (E, N, 0), seed=2),
+ roof_face(35, 0, 12, 6, (E, N + 6, 4.2), seed=3),
+])
+
+
+class FakeClient:
+ """A Geotorget stand-in that serves typed assets."""
+
+ def __init__(self, building_asset=None, lidar_asset=None, payloads=None,
+ session=None):
+ self._building_asset = building_asset
+ self._lidar_asset = lidar_asset
+ self._payloads = payloads or {}
+ self.session = session
+ self.downloaded: list[str] = []
+
+ def search(self, collection, bbox, limit=20):
+ if collection == COLLECTION_BUILDINGS:
+ if self._building_asset is None:
+ return []
+ return [StacItem("tile-b", collection, {"data": self._building_asset}, None,
+ raw={"id": "tile-b"})]
+ if self._lidar_asset is None:
+ return []
+ return [StacItem("tile-l", collection, {"data": self._lidar_asset}, None,
+ raw={"id": "tile-l"})]
+
+ def download(self, url):
+ self.downloaded.append(url)
+ return self._payloads[url]
+
+
+def a_geopackage_of_two_buildings():
+ return build_gpkg([
+ ("house-1", "Bostad", gpkg_blob(wkb_polygon(square(E - 6, N - 3, 12, 12)))),
+ ("shed-1", "Komplementbyggnad",
+ gpkg_blob(wkb_polygon(square(E + 40, N + 40, 8, 8)))),
+ ])
+
+
+def test_buildings_come_out_of_a_geopackage_asset():
+ """The normal Byggnad-vektor path: the item points at a .gpkg tile."""
+ url = "https://api.lantmateriet.se/x/byggnad.gpkg"
+ client = FakeClient(
+ building_asset=Asset(url, MEDIA_GEOPACKAGE),
+ payloads={url: a_geopackage_of_two_buildings()},
+ )
+ found = search_buildings(client, latitude=STOCKHOLM[0], longitude=STOCKHOLM[1])
+
+ assert [b.building_id for b in found] == ["house-1", "shed-1"], "nearest first"
+ assert found[0].area_m2 == pytest.approx(144.0, rel=0.01)
+ assert found[0].properties["andamal"] == "Bostad"
+ assert client.downloaded == [url]
+
+
+def test_buildings_come_out_of_a_zipped_geopackage_asset():
+ """The live Lantmaeteriet shape: one item per municipality whose only
+ asset is byggnad_kn.zip with the GeoPackage inside."""
+ import io
+ import zipfile
+
+ buf = io.BytesIO()
+ with zipfile.ZipFile(buf, "w") as zf:
+ zf.writestr("byggnad_kn0180.gpkg", a_geopackage_of_two_buildings())
+ zf.writestr("licens.txt", "CC BY 4.0")
+ url = "https://dl1.lantmateriet.se/byggnadsverk/byggnad_kn0180.zip"
+ client = FakeClient(
+ building_asset=Asset(url, "application/zip"),
+ payloads={url: buf.getvalue()},
+ )
+ found = search_buildings(client, latitude=STOCKHOLM[0], longitude=STOCKHOLM[1])
+
+ assert [b.building_id for b in found] == ["house-1", "shed-1"]
+ assert client.downloaded == [url]
+
+
+def test_a_tile_asset_wins_over_the_tile_outline():
+ """The live municipality items carry their own geometry — the TILE's
+ outline, not a building. With a data asset present, the asset must be
+ read and the outline ignored; treating the outline as a building both
+ invented a giant footprint and skipped the 90k real ones (found live:
+ 'found=0' with no error, because the outline failed the area filter)."""
+ url = "https://dl1.lantmateriet.se/byggnadsverk/byggnad_kn0180.zip"
+ import io
+ import zipfile
+
+ buf = io.BytesIO()
+ with zipfile.ZipFile(buf, "w") as zf:
+ zf.writestr("byggnad_kn0180.gpkg", a_geopackage_of_two_buildings())
+ kommun_outline = {
+ "type": "Polygon",
+ "coordinates": [[[E - 20000, N - 20000], [E + 20000, N - 20000],
+ [E + 20000, N + 20000], [E - 20000, N + 20000],
+ [E - 20000, N - 20000]]],
+ }
+
+ class TileClient(FakeClient):
+ def search(self, collection, bbox, limit=20):
+ return [StacItem("0180", collection, {"data": Asset(url, "application/zip")},
+ None, raw={"id": "0180", "geometry": kommun_outline})]
+
+ client = TileClient(payloads={url: buf.getvalue()})
+ found = search_buildings(client, latitude=STOCKHOLM[0], longitude=STOCKHOLM[1])
+
+ assert [b.building_id for b in found] == ["house-1", "shed-1"]
+ assert client.downloaded == [url]
+
+
+def test_a_municipality_tile_is_filtered_to_the_search_window():
+ """One GeoPackage covers a whole municipality — Stockholm's has 90k+
+ buildings — so rows outside the search window must be dropped, or the
+ reader's row limit truncates the table before it reaches the site.
+
+ Both drop paths matter: a stored header envelope skips the row before
+ its WKB is decoded, and the live Lantmaeteriet files write NO envelopes
+ (flags 0x00), where the parsed geometry's own bounds must do it."""
+ far_e, far_n = E + 5000, N + 5000
+ gpkg = build_gpkg([
+ # Near the site, no envelope: kept via its parsed bounds.
+ ("near-1", "Bostad", gpkg_blob(wkb_polygon(square(E - 6, N - 3, 12, 12)))),
+ # Far away with an envelope: dropped before the WKB is decoded.
+ ("far-1", "Bostad", gpkg_blob(wkb_polygon(square(far_e, far_n, 12, 12)),
+ envelope=(far_e, far_e + 12, far_n, far_n + 12))),
+ # Far away without an envelope: dropped via its parsed bounds.
+ ("far-2", "Bostad", gpkg_blob(wkb_polygon(square(far_e, far_n - 60, 12, 12)))),
+ ])
+ url = "https://api.lantmateriet.se/x/byggnad_kn0180.gpkg"
+ client = FakeClient(building_asset=Asset(url, MEDIA_GEOPACKAGE), payloads={url: gpkg})
+ found = search_buildings(client, latitude=STOCKHOLM[0], longitude=STOCKHOLM[1])
+
+ assert [b.building_id for b in found] == ["near-1"]
+
+
+def test_buildings_come_out_of_a_geojson_asset_too():
+ """Some catalogues publish GeoJSON; both are handled by media type."""
+ url = "https://api.lantmateriet.se/x/byggnad.geojson"
+ doc = {
+ "type": "FeatureCollection",
+ "features": [{
+ "type": "Feature",
+ "id": "gj-1",
+ "geometry": {"type": "Polygon",
+ "coordinates": [[list(p) for p in square(E - 6, N - 3, 12, 12)[0]]]},
+ "properties": {"andamal": "Bostad"},
+ }],
+ }
+ client = FakeClient(
+ building_asset=Asset(url, MEDIA_GEOJSON),
+ payloads={url: json.dumps(doc).encode()},
+ )
+ found = search_buildings(client, latitude=STOCKHOLM[0], longitude=STOCKHOLM[1])
+ assert [b.building_id for b in found] == ["gj-1"]
+
+
+def test_an_unreadable_building_tile_says_what_is_wrong():
+ url = "https://api.lantmateriet.se/x/byggnad.gpkg"
+ client = FakeClient(
+ building_asset=Asset(url, MEDIA_GEOPACKAGE),
+ payloads={url: b"this is not a database"},
+ )
+ with pytest.raises(BuildingLookupError, match="could not be read"):
+ search_buildings(client, latitude=STOCKHOLM[0], longitude=STOCKHOLM[1])
+
+
+def test_an_item_with_no_usable_asset_is_skipped_not_fatal():
+ client = FakeClient(building_asset=Asset("https://x/preview.png", "image/png"))
+ with pytest.raises(BuildingLookupError, match="no building footprints"):
+ search_buildings(client, latitude=STOCKHOLM[0], longitude=STOCKHOLM[1])
+
+
+# --- LiDAR: COPC windowing -------------------------------------------------
+
+
+@pytest.fixture
+def lidar_scene(monkeypatch):
+ """A client whose LiDAR asset is COPC, with both read paths instrumented."""
+ gpkg_url = "https://api.lantmateriet.se/x/byggnad.gpkg"
+ copc_url = "https://api.lantmateriet.se/x/tile.copc.laz"
+ client = FakeClient(
+ building_asset=Asset(gpkg_url, MEDIA_GEOPACKAGE),
+ lidar_asset=Asset(copc_url, MEDIA_COPC),
+ payloads={gpkg_url: a_geopackage_of_two_buildings(), copc_url: b"laz-bytes"},
+ session=object(),
+ )
+ calls: dict[str, object] = {}
+
+ def fake_window(session, url, bounds, timeout=60.0):
+ calls["window"] = {"url": url, "bounds": bounds}
+ return HOUSE
+
+ monkeypatch.setattr(pipeline.pointcloud, "read_copc_window", fake_window)
+ monkeypatch.setattr(pipeline, "load_points", lambda data: HOUSE)
+ return client, calls, copc_url
+
+
+def test_a_picked_building_is_read_as_a_copc_window(lidar_scene):
+ """The payoff: a footprint costs a window, not a 2.5 km tile."""
+ client, calls, copc_url = lidar_scene
+ model = derive(
+ latitude=STOCKHOLM[0], longitude=STOCKHOLM[1],
+ credentials=Credentials("u", "t"), client=client, building_id="house-1",
+ )
+
+ assert model["source"]["fetch"] == "copc-window"
+ assert calls["window"]["url"] == copc_url
+ min_x, min_y, max_x, max_y = calls["window"]["bounds"]
+ # The footprint is 12 m square around the site, plus the eaves buffer.
+ assert min_x == pytest.approx(E - 7, abs=0.5)
+ assert max_x == pytest.approx(E + 7, abs=0.5)
+ assert copc_url not in client.downloaded, "the tile was never downloaded whole"
+
+
+def test_without_a_picked_building_the_tile_is_read_whole(lidar_scene):
+ """No footprint means no window to ask for."""
+ client, calls, copc_url = lidar_scene
+ model = derive(
+ latitude=STOCKHOLM[0], longitude=STOCKHOLM[1],
+ credentials=Credentials("u", "t"), client=client,
+ )
+ assert model["source"]["fetch"] == "whole-tile"
+ assert "window" not in calls
+ assert copc_url in client.downloaded
+
+
+def test_a_host_without_range_support_falls_back_to_the_whole_tile(monkeypatch, lidar_scene):
+ """Best-effort: the operator still gets their roof, just slower."""
+ client, _, copc_url = lidar_scene
+
+ def refuses(session, url, bounds, timeout=60.0):
+ raise PointCloudError("the LiDAR host does not support range requests")
+
+ monkeypatch.setattr(pipeline.pointcloud, "read_copc_window", refuses)
+ model = derive(
+ latitude=STOCKHOLM[0], longitude=STOCKHOLM[1],
+ credentials=Credentials("u", "t"), client=client, building_id="house-1",
+ )
+ assert model["source"]["fetch"] == "whole-tile"
+ assert copc_url in client.downloaded
+ assert model["arrays"], "and the roof still comes out"
+
+
+def test_a_plain_laz_asset_is_read_whole_even_with_a_building(monkeypatch):
+ """Only COPC can be windowed; plain LAZ has no index to seek with."""
+ gpkg_url = "https://api.lantmateriet.se/x/byggnad.gpkg"
+ laz_url = "https://api.lantmateriet.se/x/tile.laz"
+ client = FakeClient(
+ building_asset=Asset(gpkg_url, MEDIA_GEOPACKAGE),
+ lidar_asset=Asset(laz_url, MEDIA_LAZ),
+ payloads={gpkg_url: a_geopackage_of_two_buildings(), laz_url: b"laz-bytes"},
+ session=object(),
+ )
+ monkeypatch.setattr(pipeline, "load_points", lambda data: HOUSE)
+ called = []
+ monkeypatch.setattr(pipeline.pointcloud, "read_copc_window",
+ lambda *a, **k: called.append(1))
+
+ model = derive(
+ latitude=STOCKHOLM[0], longitude=STOCKHOLM[1],
+ credentials=Credentials("u", "t"), client=client, building_id="house-1",
+ )
+ assert model["source"]["fetch"] == "whole-tile"
+ assert not called
diff --git a/roofmodel/tests/test_sweref.py b/roofmodel/tests/test_sweref.py
new file mode 100644
index 000000000..1cd6dfa35
--- /dev/null
+++ b/roofmodel/tests/test_sweref.py
@@ -0,0 +1,148 @@
+"""SWEREF 99 TM projection tests.
+
+The projection has exact analytic properties at the central meridian and the
+equator, which pin the parameters without needing a published coordinate table.
+Round-trip accuracy then pins the series expansion itself.
+"""
+
+import math
+
+import pytest
+
+from ftw_roofmodel.sweref import (
+ bbox_wgs84_to_sweref99tm,
+ metre_box_around,
+ sweref99tm_to_wgs84,
+ wgs84_to_sweref99tm,
+)
+
+
+@pytest.mark.parametrize("lat", [0.0, 55.0, 59.33, 63.0, 69.0])
+def test_central_meridian_maps_to_false_easting(lat):
+ """On the central meridian easting is exactly the false easting, by
+ definition. Any error in scale, ellipsoid or meridian shows up here."""
+ _, easting = wgs84_to_sweref99tm(lat, 15.0)
+ assert easting == pytest.approx(500000.0, abs=1e-6)
+
+
+def test_equator_on_central_meridian_is_the_projection_origin():
+ northing, easting = wgs84_to_sweref99tm(0.0, 15.0)
+ assert northing == pytest.approx(0.0, abs=1e-6)
+ assert easting == pytest.approx(500000.0, abs=1e-6)
+
+
+@pytest.mark.parametrize(
+ "lat,lon",
+ [
+ (55.34, 13.15), # Smygehuk, southernmost Sweden
+ (59.33, 18.07), # Stockholm
+ (57.71, 11.97), # Gothenburg
+ (63.83, 20.26), # Umea
+ (67.86, 20.23), # Kiruna
+ (69.06, 20.55), # Treriksroeset, northernmost
+ ],
+)
+def test_round_trip_is_sub_millimetre(lat, lon):
+ """Project and unproject across the full extent of Sweden."""
+ n, e = wgs84_to_sweref99tm(lat, lon)
+ back_lat, back_lon = sweref99tm_to_wgs84(n, e)
+ # 1e-8 degrees is about 1 mm of latitude.
+ assert back_lat == pytest.approx(lat, abs=1e-8)
+ assert back_lon == pytest.approx(lon, abs=1e-8)
+
+
+def test_coordinates_land_in_the_expected_range_for_sweden():
+ """Sanity-check magnitudes: Swedish SWEREF 99 TM eastings sit inside
+ 260-920 km and northings inside 6100-7700 km. A transposed or
+ wrongly-scaled result would fall far outside."""
+ n, e = wgs84_to_sweref99tm(59.33, 18.07)
+ assert 260_000 < e < 920_000, e
+ assert 6_100_000 < n < 7_700_000, n
+
+
+def test_east_of_the_meridian_increases_easting():
+ _, west = wgs84_to_sweref99tm(59.33, 14.0)
+ _, east = wgs84_to_sweref99tm(59.33, 16.0)
+ assert west < 500000.0 < east
+
+
+def test_north_increases_northing():
+ south, _ = wgs84_to_sweref99tm(55.0, 15.0)
+ north, _ = wgs84_to_sweref99tm(65.0, 15.0)
+ assert north > south
+
+
+def test_one_degree_of_latitude_is_about_111_km():
+ a, _ = wgs84_to_sweref99tm(59.0, 15.0)
+ b, _ = wgs84_to_sweref99tm(60.0, 15.0)
+ # Scaled by k0 = 0.9996 on the central meridian.
+ assert 110_000 < (b - a) < 112_000
+
+
+def test_bbox_uses_all_four_corners():
+ """The projection is not axis-aligned, so the projected box must be at
+ least as large as the one implied by the two diagonal corners."""
+ min_lat, min_lon, max_lat, max_lon = 59.0, 17.0, 60.0, 19.0
+ min_e, min_n, max_e, max_n = bbox_wgs84_to_sweref99tm(
+ min_lat, min_lon, max_lat, max_lon
+ )
+ sw_n, sw_e = wgs84_to_sweref99tm(min_lat, min_lon)
+ ne_n, ne_e = wgs84_to_sweref99tm(max_lat, max_lon)
+ assert min_e <= sw_e and min_n <= sw_n
+ assert max_e >= ne_e and max_n >= ne_n
+ assert min_e < max_e and min_n < max_n
+
+
+def test_metre_box_is_square_on_the_ground():
+ """A 100 m box must measure 200 m on both axes regardless of latitude --
+ the whole reason it is built in projected metres rather than in degrees."""
+ for lat in (55.5, 59.33, 68.0):
+ south, west, north, east = metre_box_around(lat, 15.0, 100.0)
+ sn, se = wgs84_to_sweref99tm(south, west)
+ nn, ne = wgs84_to_sweref99tm(north, east)
+ assert (ne - se) == pytest.approx(200.0, abs=0.5)
+ assert (nn - sn) == pytest.approx(200.0, abs=0.5)
+
+
+def test_metre_box_brackets_its_centre():
+ south, west, north, east = metre_box_around(59.33, 18.07, 50.0)
+ assert south < 59.33 < north
+ assert west < 18.07 < east
+
+
+def test_stac_search_bbox_sweref_matches_the_long_form():
+ from ftw_roofmodel.sweref import bbox_wgs84_to_sweref99tm, stac_search_bbox
+
+ south, west, north, east = metre_box_around(59.33, 18.07, 40.0)
+ assert stac_search_bbox(59.33, 18.07, 40.0) == bbox_wgs84_to_sweref99tm(
+ south, west, north, east
+ )
+
+
+def test_stac_search_bbox_wgs84_is_lon_lat_ordered():
+ """The STAC spec's bbox is [west, south, east, north] in degrees."""
+ from ftw_roofmodel.sweref import stac_search_bbox
+
+ west, south, east, north = stac_search_bbox(59.33, 18.07, 40.0, bbox_epsg=4326)
+ assert west < 18.07 < east
+ assert south < 59.33 < north
+
+
+def test_stac_search_bbox_refuses_a_crs_it_cannot_produce():
+ from ftw_roofmodel.sweref import stac_search_bbox
+
+ with pytest.raises(ValueError):
+ stac_search_bbox(59.33, 18.07, 40.0, bbox_epsg=3857)
+
+
+def test_degree_box_would_have_been_wrong_at_high_latitude():
+ """Guards the reason metre_box_around exists: a fixed degree offset gives
+ wildly different ground distances at Malmoe and Kiruna, so anyone tempted to
+ simplify it back to degrees has to defeat this test first."""
+ span = []
+ for lat in (55.5, 68.0):
+ # What a naive 0.001-degree longitude offset would span, in metres.
+ _, e0 = wgs84_to_sweref99tm(lat, 15.0)
+ _, e1 = wgs84_to_sweref99tm(lat, 15.001)
+ span.append(e1 - e0)
+ assert span[0] / span[1] > 1.5, span
diff --git a/web/components/ftw-bar-chart.js b/web/components/ftw-bar-chart.js
index d7465a6ba..6f0144d8e 100644
--- a/web/components/ftw-bar-chart.js
+++ b/web/components/ftw-bar-chart.js
@@ -188,6 +188,26 @@ class FtwBarChart extends FtwElement {
opacity: 0.85;
pointer-events: none;
}
+ /* Optional dashed overlay line (e.g. STRÅNG-expected PV vs the
+ produced bars). An SVG stretched to fill .bar-area, plotted in a
+ 0..100 viewBox so it needs no pixel math against the CSS grid;
+ non-scaling-stroke keeps the dash crisp despite the stretch. */
+ .overlay-line {
+ position: absolute;
+ inset: 0;
+ width: 100%;
+ height: 100%;
+ pointer-events: none;
+ overflow: visible;
+ }
+ .overlay-line polyline {
+ fill: none;
+ stroke: var(--ftw-overlay-color, var(--amber, #f59e0b));
+ stroke-width: 1.5;
+ stroke-dasharray: 4 3;
+ vector-effect: non-scaling-stroke;
+ opacity: 0.9;
+ }
`;
static get observedAttributes() {
@@ -197,6 +217,7 @@ class FtwBarChart extends FtwElement {
constructor() {
super();
this._data = [];
+ this._overlay = null;
}
attributeChangedCallback() { this.update(); }
@@ -209,6 +230,16 @@ class FtwBarChart extends FtwElement {
}
get data() { return this._data; }
+ // Optional dashed overlay line, index-aligned with .data. Shape:
+ // { values: (number|null)[], color?: string }
+ // values[i] is plotted above column i on the SAME axis as the bars
+ // (nulls / non-finite entries break the line). Set null to remove.
+ set overlay(o) {
+ this._overlay = o && Array.isArray(o.values) ? o : null;
+ this.update();
+ }
+ get overlay() { return this._overlay; }
+
render() {
const accent = this.getAttribute("accent");
const height = this.getAttribute("chart-height");
@@ -262,6 +293,17 @@ class FtwBarChart extends FtwElement {
}
const avg = count > 0 ? sum / count : 0;
+ // Fold overlay values into the axis max so the expected line and the
+ // produced bars share one scale (an expected level above the tallest
+ // bar must still fit in-frame).
+ const overlayVals = this._overlay ? this._overlay.values : null;
+ if (overlayVals) {
+ for (const ov of overlayVals) {
+ const n = Number(ov);
+ if (isFinite(n) && n > max) max = n;
+ }
+ }
+
const colsSvg = this._data.map((d) => {
const v = Number(d.value) || 0;
// 2% floor keeps tiny-but-nonzero values visible; gate on v>0 so
@@ -300,10 +342,34 @@ class FtwBarChart extends FtwElement {
`title="average ${display}">`;
}
+ // Dashed overlay line (expected series). Plotted in a 0..100 viewBox
+ // stretched to fill .bar-area: x centers each column, y is the value
+ // as a percentage of the shared max (inverted — SVG y grows downward).
+ let overlayLine = "";
+ if (overlayVals && max > 0) {
+ const n = this._data.length;
+ const pts = [];
+ for (let i = 0; i < n; i++) {
+ const val = Number(overlayVals[i]);
+ if (!isFinite(val)) continue;
+ const x = n > 1 ? (i + 0.5) / n * 100 : 50;
+ const y = Math.max(0, Math.min(100, 100 - (val / max) * 100));
+ pts.push(`${x.toFixed(2)},${y.toFixed(2)}`);
+ }
+ if (pts.length >= 2) {
+ const color = this._overlay.color;
+ if (color) this.style.setProperty("--ftw-overlay-color", color);
+ overlayLine =
+ ``;
+ }
+ }
+
return `
${lblsSvg}
diff --git a/web/components/ftw-history-card.js b/web/components/ftw-history-card.js
index ed659092e..1e1393c0c 100644
--- a/web/components/ftw-history-card.js
+++ b/web/components/ftw-history-card.js
@@ -28,7 +28,7 @@
import { FtwElement, ftwDebugDelay } from "./ftw-element.js";
import { apiFetch } from "./api-fetch.js";
-import "./ftw-bar-chart.js";
+import "./ftw-bar-chart.js?v=strang1";
const FIELD_BY_METRIC = {
import: "import_wh",
@@ -82,6 +82,36 @@ function fetchDailyEnergy(days) {
return promise;
}
+// STRÅNG-based PV performance (expected-vs-actual). Only the "Produced"
+// (metric="pv") tile fetches this, to overlay the weather-expected line.
+// Tolerant: a disabled/absent service or any error resolves to
+// { enabled:false } so the bars still render without an overlay.
+const pvPerfFetchCache = new Map(); // days -> { at, data?, promise? }
+
+function fetchPVPerformance(days) {
+ const now = Date.now();
+ const cached = pvPerfFetchCache.get(days);
+ if (cached && cached.data && now - cached.at < DAILY_CACHE_TTL_MS) {
+ return Promise.resolve(cached.data);
+ }
+ if (cached && cached.promise && now - cached.at < DAILY_CACHE_TTL_MS) {
+ return cached.promise;
+ }
+ const promise = apiFetch("/api/pv/performance?days=" + days)
+ .then((r) => (r.ok ? r.json() : { enabled: false }))
+ .then((resp) => {
+ const data = resp || { enabled: false };
+ pvPerfFetchCache.set(days, { at: Date.now(), data });
+ return data;
+ })
+ .catch(() => {
+ pvPerfFetchCache.delete(days);
+ return { enabled: false };
+ });
+ pvPerfFetchCache.set(days, { at: now, promise });
+ return promise;
+}
+
class FtwHistoryCard extends FtwElement {
static styles = `
:host { display: block; }
@@ -205,6 +235,27 @@ class FtwHistoryCard extends FtwElement {
margin-left: 6px;
letter-spacing: 0;
}
+ /* STRÅNG expected-vs-actual caption under the Produced chart. Hidden
+ until the pv tile has a performance overlay to describe. The dashed
+ swatch mirrors the overlay line so the legend reads at a glance. */
+ .strang-note {
+ margin-top: 6px;
+ font-size: 0.72rem;
+ color: var(--fg-muted);
+ font-family: var(--mono);
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ }
+ .strang-note[hidden] { display: none; }
+ .strang-note .swatch {
+ display: inline-block;
+ width: 16px;
+ height: 0;
+ border-top: 2px dashed #fcd34d;
+ flex: 0 0 auto;
+ }
+ .strang-note .pr { color: var(--fg-label); font-weight: 600; }
@media (max-width: 900px) {
.card-inner { padding: var(--card-pad-tight, 12px 14px); }
}
@@ -302,6 +353,7 @@ class FtwHistoryCard extends FtwElement {
— kWh
+
`;
}
@@ -309,6 +361,7 @@ class FtwHistoryCard extends FtwElement {
afterRender() {
this._chart = this.shadowRoot.querySelector('[data-role="chart"]');
this._totalEl = this.shadowRoot.querySelector('[data-role="total"]');
+ this._strangEl = this.shadowRoot.querySelector('[data-role="strang"]');
this._toggleEl = this.shadowRoot.querySelector('.toggle');
if (this._chart) this._chart.setAttribute("accent", this._accent());
if (this._toggleEl) {
@@ -387,6 +440,12 @@ class FtwHistoryCard extends FtwElement {
this._totalEl.textContent = "— kWh";
}
this._chart.data = data;
+ // Produced tile: overlay the STRÅNG expected line. Fetched
+ // separately so a disabled/slow scoring service never holds up
+ // the bars. Aligned to the same day buckets by ISO date.
+ if (metric === "pv") {
+ this._loadOverlay(days, buckets.map((b) => b.day), seq);
+ }
};
// `?delay=N` — hold in the skeleton state for N ms after the
// fetch resolves, for inspecting the loading→loaded transition.
@@ -402,6 +461,58 @@ class FtwHistoryCard extends FtwElement {
this._totalEl.textContent = "failed to load";
});
}
+
+ // Fetch STRÅNG performance scores and overlay the expected-production
+ // line onto the Produced bars, aligned to `dayKeys` (ISO dates, same
+ // order as the bars). Hides the overlay + caption when scoring is
+ // unavailable. Guarded by `seq` so a stale response can't paint over a
+ // newer Week/Month selection.
+ _loadOverlay(days, dayKeys, seq) {
+ fetchPVPerformance(days)
+ .then((perf) => {
+ if (seq !== this._reqSeq || !this._chart) return;
+ if (!perf || perf.enabled === false || !Array.isArray(perf.items) || !perf.items.length) {
+ this._chart.overlay = null;
+ if (this._strangEl) this._strangEl.setAttribute("hidden", "");
+ return;
+ }
+ const expByDay = new Map();
+ for (const it of perf.items) {
+ if (it && it.day != null) expByDay.set(it.day, Number(it.expected_wh) || 0);
+ }
+ // kWh, index-aligned to the bars; null where no score exists so
+ // the dashed line breaks rather than dropping to zero.
+ const values = dayKeys.map((d) => {
+ const wh = expByDay.get(d);
+ return wh == null ? null : wh / 1000;
+ });
+ const hasAny = values.some((v) => v != null);
+ this._chart.overlay = hasAny ? { values, color: "#fcd34d" } : null;
+
+ if (this._strangEl) {
+ const pr = typeof perf.performance_ratio === "number" ? perf.performance_ratio : null;
+ const prTxt = pr != null ? `${Math.round(pr * 100)}% of expected` : "";
+ // Only announce the calibration once it is actually being applied to
+ // the forward forecast — reporting a factor we ignore would mislead.
+ const cal = perf.calibration;
+ const calTxt =
+ cal && cal.applied && typeof cal.factor === "number"
+ ? `calibrating forecast ×${cal.factor.toFixed(2)}`
+ : "";
+ this._strangEl.innerHTML =
+ ` expected (STRÅNG)` +
+ (prTxt ? " · " + prTxt : "") +
+ (calTxt ? " · " + calTxt : "");
+ if (hasAny) this._strangEl.removeAttribute("hidden");
+ else this._strangEl.setAttribute("hidden", "");
+ }
+ })
+ .catch(() => {
+ if (seq !== this._reqSeq || !this._chart) return;
+ this._chart.overlay = null;
+ if (this._strangEl) this._strangEl.setAttribute("hidden", "");
+ });
+ }
}
function fmtKwh(wh) {
diff --git a/web/components/index.js b/web/components/index.js
index 38c87bd81..b104323e4 100644
--- a/web/components/index.js
+++ b/web/components/index.js
@@ -23,8 +23,8 @@ import "./ftw-battery-control.js?v=apifetch1";
import "./ftw-pv-control.js?v=apifetch1";
import "./ftw-price-chart.js?v=zones1";
import "./ftw-energy-cake.js";
-import "./ftw-bar-chart.js";
-import "./ftw-history-card.js?v=apiread2";
+import "./ftw-bar-chart.js?v=strang1";
+import "./ftw-history-card.js?v=strang2";
import "./ftw-savings-card.js?v=zones1";
import "./ftw-update-check.js?v=apifetch1";
import "./ftw-notif-status.js?v=apifetch1";
diff --git a/web/components/pv-array-geometry.js b/web/components/pv-array-geometry.js
new file mode 100644
index 000000000..110f903e6
--- /dev/null
+++ b/web/components/pv-array-geometry.js
@@ -0,0 +1,208 @@
+// Turning a rectangle drawn on the map into a PV array.
+//
+// Drawing supplies two of the three numbers an array needs. Area comes from
+// the shape; azimuth from how the shape is turned. Tilt cannot be seen from
+// directly above at all, so it stays typed — and it is also what converts the
+// drawn outline into real panel area, because what you trace on a map is the
+// *horizontal projection* of a sloped rectangle, not the rectangle itself.
+//
+// Everything here is pure so it can be tested without a browser or a map.
+
+export const DEFAULT_PACKING_FACTOR = 0.7;
+export const DEFAULT_MODULE_W_PER_M2 = 200;
+export const DEFAULT_TILT_DEG = 35;
+
+// IUGG mean Earth radius. At the scale of one roof the radius matters far
+// less than the flat-Earth approximation below, which is exact enough for a
+// 20 m rectangle and meaningless across a county.
+const EARTH_RADIUS_M = 6371008.8;
+const DEG = Math.PI / 180;
+
+// Beyond this a roof is a wall: cos(tilt) approaches zero and the plan-area
+// division runs away. A wall has no horizontal projection to trace anyway, so
+// clamping here bounds the arithmetic instead of returning Infinity.
+const MAX_TILT_FOR_PROJECTION_DEG = 89;
+
+function stripClosingVertex(ring) {
+ if (ring.length > 1) {
+ const first = ring[0];
+ const last = ring[ring.length - 1];
+ if (first[0] === last[0] && first[1] === last[1]) return ring.slice(0, -1);
+ }
+ return ring.slice();
+}
+
+/**
+ * Project a WGS84 ring ([[lon, lat], …]) to metres about its own centroid.
+ *
+ * A local tangent plane, not a real projection: over one building the error
+ * is well under the precision anyone draws with, and it avoids carrying a
+ * projection library into the settings page.
+ */
+export function toLocalMetres(ring) {
+ const pts = stripClosingVertex(ring || []);
+ if (pts.length === 0) return [];
+ let lon0 = 0;
+ let lat0 = 0;
+ for (const [lon, lat] of pts) {
+ lon0 += lon;
+ lat0 += lat;
+ }
+ lon0 /= pts.length;
+ lat0 /= pts.length;
+ const mPerDegLat = EARTH_RADIUS_M * DEG;
+ const mPerDegLon = mPerDegLat * Math.cos(lat0 * DEG);
+ return pts.map(([lon, lat]) => [(lon - lon0) * mPerDegLon, (lat - lat0) * mPerDegLat]);
+}
+
+/** Area of the drawn outline in m², as seen from above. */
+export function planAreaM2(ring) {
+ const p = toLocalMetres(ring);
+ if (p.length < 3) return 0;
+ let twiceArea = 0;
+ for (let i = 0; i < p.length; i++) {
+ const [x1, y1] = p[i];
+ const [x2, y2] = p[(i + 1) % p.length];
+ twiceArea += x1 * y2 - x2 * y1;
+ }
+ return Math.abs(twiceArea) / 2;
+}
+
+/** Compass bearing of a local vector, 0 = north, 90 = east. */
+function bearingDeg(dx, dy) {
+ return (((Math.atan2(dx, dy) / DEG) % 360) + 360) % 360;
+}
+
+/**
+ * Direction of the ring's longest edge, as a line in [0, 180).
+ *
+ * For a panel rectangle that edge runs along the ridge, which is a line and
+ * not an arrow — calling it "north" rather than "south" would be a
+ * distinction the drawing does not contain.
+ */
+export function ridgeAzimuthDeg(ring) {
+ const p = toLocalMetres(ring);
+ if (p.length < 2) return null;
+ let longest = 0;
+ let bx = 0;
+ let by = 0;
+ for (let i = 0; i < p.length; i++) {
+ const [x1, y1] = p[i];
+ const [x2, y2] = p[(i + 1) % p.length];
+ const dx = x2 - x1;
+ const dy = y2 - y1;
+ const len = Math.hypot(dx, dy);
+ if (len > longest) {
+ longest = len;
+ bx = dx;
+ by = dy;
+ }
+ }
+ if (longest <= 0) return null;
+ return bearingDeg(bx, by) % 180;
+}
+
+/** Shortest angle between two compass bearings, in degrees. */
+export function angularDistanceDeg(a, b) {
+ const d = Math.abs((((a - b) % 360) + 360) % 360);
+ return d > 180 ? 360 - d : d;
+}
+
+/** Turn an azimuth to face the opposite way. */
+export function flipAzimuthDeg(azimuthDeg) {
+ return ((((azimuthDeg + 180) % 360) + 360) % 360);
+}
+
+/**
+ * The two directions the face could point: perpendicular to the ridge, either
+ * side of it. A flat outline genuinely does not say which.
+ */
+export function faceAzimuthCandidates(ring) {
+ const ridge = ridgeAzimuthDeg(ring);
+ if (ridge === null) return [];
+ return [(ridge + 90) % 360, (ridge + 270) % 360];
+}
+
+/**
+ * The candidate a panel is more likely to use: the equatorward one.
+ *
+ * This is a default, not a measurement. Both perpendiculars fit the drawing
+ * equally well, so the UI offers a flip rather than pretending to know.
+ */
+export function preferredAzimuthDeg(ring, latitudeDeg) {
+ const candidates = faceAzimuthCandidates(ring);
+ if (candidates.length === 0) return null;
+ const target = (latitudeDeg || 0) >= 0 ? 180 : 0;
+ const [a, b] = candidates;
+ return angularDistanceDeg(a, target) <= angularDistanceDeg(b, target) ? a : b;
+}
+
+/**
+ * Real panel area from the traced outline.
+ *
+ * A sloped rectangle of area A casts a shadow of A·cos(tilt) on the map, so
+ * recovering it divides that back out. A 35° roof carries about 22 % more
+ * panel than its outline suggests, which is the difference between a
+ * believable rating and a quietly low one.
+ */
+export function slopeAreaM2(planArea, tiltDeg) {
+ const tilt = Math.min(Math.max(tiltDeg || 0, 0), MAX_TILT_FOR_PROJECTION_DEG);
+ return planArea / Math.cos(tilt * DEG);
+}
+
+/** Installable DC capacity in watts for a roof area, matching the roof model's basis. */
+export function ratedWFromSlopeArea(areaM2, packingFactor, moduleWPerM2) {
+ const packing = packingFactor == null ? DEFAULT_PACKING_FACTOR : packingFactor;
+ const wPerM2 = moduleWPerM2 == null ? DEFAULT_MODULE_W_PER_M2 : moduleWPerM2;
+ return areaM2 * packing * wPerM2;
+}
+
+/** Human-readable face name, mirroring the roof model's naming. */
+export function compassName(azimuthDeg, tiltDeg) {
+ if (tiltDeg < 5) return "Roof flat";
+ const points = [
+ [0, "north"], [45, "north-east"], [90, "east"], [135, "south-east"],
+ [180, "south"], [225, "south-west"], [270, "west"], [315, "north-west"],
+ [360, "north"],
+ ];
+ let best = points[0];
+ for (const p of points) {
+ if (Math.abs(p[0] - azimuthDeg) < Math.abs(best[0] - azimuthDeg)) best = p;
+ }
+ return `Roof ${best[1]}`;
+}
+
+function round(value, places) {
+ const factor = 10 ** places;
+ return Math.round(value * factor) / factor;
+}
+
+/**
+ * Everything a drawn rectangle says about one array.
+ *
+ * Returns the config-shaped entry separately from the measurements, so only
+ * the four fields weather.pv_arrays actually defines are ever written back.
+ */
+export function arrayFromRing(ring, options) {
+ const opts = options || {};
+ const plan = planAreaM2(ring);
+ if (!(plan > 0)) return null;
+ const tiltDeg = opts.tiltDeg == null ? DEFAULT_TILT_DEG : opts.tiltDeg;
+ const candidates = faceAzimuthCandidates(ring);
+ const azimuth = opts.azimuthDeg == null
+ ? preferredAzimuthDeg(ring, opts.latitude)
+ : opts.azimuthDeg;
+ const azimuthDeg = azimuth == null ? 180 : Math.round(azimuth);
+ const slope = slopeAreaM2(plan, tiltDeg);
+ return {
+ array: {
+ name: opts.name || compassName(azimuthDeg, tiltDeg),
+ rated_w: Math.round(ratedWFromSlopeArea(slope, opts.packingFactor, opts.moduleWPerM2)),
+ tilt_deg: tiltDeg,
+ azimuth_deg: azimuthDeg,
+ },
+ planAreaM2: round(plan, 1),
+ slopeAreaM2: round(slope, 1),
+ azimuthCandidates: candidates.map((c) => Math.round(c)),
+ };
+}
diff --git a/web/components/pv-array-geometry.test.mjs b/web/components/pv-array-geometry.test.mjs
new file mode 100644
index 000000000..56b112cfb
--- /dev/null
+++ b/web/components/pv-array-geometry.test.mjs
@@ -0,0 +1,203 @@
+// node --test web/components/pv-array-geometry.test.mjs
+
+import assert from "node:assert/strict";
+import { describe, it } from "node:test";
+
+import {
+ DEFAULT_MODULE_W_PER_M2,
+ DEFAULT_PACKING_FACTOR,
+ angularDistanceDeg,
+ arrayFromRing,
+ compassName,
+ faceAzimuthCandidates,
+ flipAzimuthDeg,
+ ratedWFromSlopeArea,
+ planAreaM2,
+ preferredAzimuthDeg,
+ ridgeAzimuthDeg,
+ slopeAreaM2,
+} from "./pv-array-geometry.js";
+
+// Fixtures are built with the standard ellipsoidal metres-per-degree series,
+// deliberately *not* with the module's own spherical projection — a shape
+// round-tripped through the code under test would agree with itself and prove
+// nothing. The two disagree by roughly half a percent in area at this
+// latitude, which is the known bias of a spherical Earth against WGS84 and is
+// far below the precision anyone draws a roof with.
+const STOCKHOLM = { lat: 59.3293, lon: 18.0686 };
+
+function metresPerDegree(latDeg) {
+ const p = (latDeg * Math.PI) / 180;
+ return {
+ lat: 111132.92 - 559.82 * Math.cos(2 * p) + 1.175 * Math.cos(4 * p)
+ - 0.0023 * Math.cos(6 * p),
+ lon: 111412.84 * Math.cos(p) - 93.5 * Math.cos(3 * p) + 0.118 * Math.cos(5 * p),
+ };
+}
+
+/** Build a WGS84 ring from local east/north offsets in metres. */
+function ringFromMetres(offsets, origin) {
+ const m = metresPerDegree(origin.lat);
+ return offsets.map(([x, y]) => [origin.lon + x / m.lon, origin.lat + y / m.lat]);
+}
+
+/** Rotate local offsets counter-clockwise in the east/north plane. */
+function rotate(offsets, degrees) {
+ const r = (degrees * Math.PI) / 180;
+ const c = Math.cos(r);
+ const s = Math.sin(r);
+ return offsets.map(([x, y]) => [x * c - y * s, x * s + y * c]);
+}
+
+// 10 m along the ridge (east-west) by 6 m down the slope.
+const RECT_10x6 = [[-5, -3], [5, -3], [5, 3], [-5, 3]];
+
+describe("plan area", () => {
+ it("recovers the drawn size in square metres", () => {
+ const ring = ringFromMetres(RECT_10x6, STOCKHOLM);
+ const area = planAreaM2(ring);
+ assert.ok(Math.abs(area - 60) < 0.6, `area ${area} should be ~60 m²`);
+ });
+
+ it("does not care whether the ring repeats its first point", () => {
+ const ring = ringFromMetres(RECT_10x6, STOCKHOLM);
+ const closed = [...ring, ring[0]];
+ assert.ok(Math.abs(planAreaM2(ring) - planAreaM2(closed)) < 1e-9);
+ });
+
+ it("is unsigned, so winding order cannot produce a negative roof", () => {
+ const ring = ringFromMetres(RECT_10x6, STOCKHOLM);
+ assert.ok(Math.abs(planAreaM2(ring) - planAreaM2([...ring].reverse())) < 1e-9);
+ });
+
+ it("treats a shape with no area as no array", () => {
+ assert.equal(planAreaM2([]), 0);
+ assert.equal(planAreaM2([[18, 59], [18.001, 59]]), 0);
+ assert.equal(arrayFromRing([[18, 59], [18.001, 59]], {}), null);
+ });
+});
+
+describe("orientation", () => {
+ it("reads the ridge from the longest edge", () => {
+ const ring = ringFromMetres(RECT_10x6, STOCKHOLM);
+ // The 10 m edges run east-west: a ridge bearing of 90°.
+ assert.ok(Math.abs(ridgeAzimuthDeg(ring) - 90) < 0.5);
+ });
+
+ it("offers both faces the outline permits, and no others", () => {
+ const ring = ringFromMetres(RECT_10x6, STOCKHOLM);
+ const [a, b] = faceAzimuthCandidates(ring).map(Math.round);
+ assert.deepEqual([a, b].sort((x, y) => x - y), [0, 180]);
+ });
+
+ it("defaults to the equatorward face, per hemisphere", () => {
+ const north = ringFromMetres(RECT_10x6, STOCKHOLM);
+ assert.ok(Math.abs(preferredAzimuthDeg(north, STOCKHOLM.lat) - 180) < 0.5);
+
+ const south = ringFromMetres(RECT_10x6, { lat: -33.87, lon: 151.21 });
+ const picked = preferredAzimuthDeg(south, -33.87);
+ assert.ok(angularDistanceDeg(picked, 0) < 0.5, `expected ~0°, got ${picked}`);
+ });
+
+ it("follows the rectangle round as it turns", () => {
+ // Turning the shape 30° counter-clockwise swings the ridge from 90° to
+ // 60°, so the faces move with it: 150° and 330°, and south-ish wins.
+ const ring = ringFromMetres(rotate(RECT_10x6, 30), STOCKHOLM);
+ assert.ok(Math.abs(ridgeAzimuthDeg(ring) - 60) < 0.5);
+ assert.ok(Math.abs(preferredAzimuthDeg(ring, STOCKHOLM.lat) - 150) < 0.5);
+ });
+
+ it("keeps the ridge a line rather than an arrow", () => {
+ // Drawing the same rectangle the other way round is the same roof.
+ const ring = ringFromMetres(RECT_10x6, STOCKHOLM);
+ const reversed = ringFromMetres([...RECT_10x6].reverse(), STOCKHOLM);
+ assert.ok(Math.abs(ridgeAzimuthDeg(ring) - ridgeAzimuthDeg(reversed)) < 0.5);
+ });
+
+ it("flips to the opposite face", () => {
+ assert.equal(flipAzimuthDeg(180), 0);
+ assert.equal(flipAzimuthDeg(0), 180);
+ assert.equal(flipAzimuthDeg(270), 90);
+ assert.equal(flipAzimuthDeg(350), 170);
+ });
+
+ it("measures the shorter way round the compass", () => {
+ assert.equal(angularDistanceDeg(350, 10), 20);
+ assert.equal(angularDistanceDeg(10, 350), 20);
+ assert.equal(angularDistanceDeg(0, 180), 180);
+ });
+});
+
+describe("tilt turns an outline into panel area", () => {
+ it("leaves a flat roof alone", () => {
+ assert.ok(Math.abs(slopeAreaM2(60, 0) - 60) < 1e-9);
+ });
+
+ it("recovers the area hidden by the slope", () => {
+ // cos 60° = 0.5, so a 60 m² shadow is cast by 120 m² of roof.
+ assert.ok(Math.abs(slopeAreaM2(60, 60) - 120) < 1e-9);
+ // A 35° roof carries ~22 % more panel than its outline suggests.
+ assert.ok(Math.abs(slopeAreaM2(60, 35) - 73.24) < 0.05);
+ });
+
+ it("stays finite at a wall, where there is no outline to trace", () => {
+ assert.ok(Number.isFinite(slopeAreaM2(60, 90)));
+ });
+
+ it("means a steeper roof is a bigger array for the same drawing", () => {
+ const ring = ringFromMetres(RECT_10x6, STOCKHOLM);
+ const flat = arrayFromRing(ring, { latitude: STOCKHOLM.lat, tiltDeg: 0 });
+ const steep = arrayFromRing(ring, { latitude: STOCKHOLM.lat, tiltDeg: 45 });
+ assert.ok(steep.array.rated_w > flat.array.rated_w,
+ `${steep.array.rated_w} should exceed ${flat.array.rated_w}`);
+ });
+});
+
+describe("capacity", () => {
+ it("uses the same basis as the roof model", () => {
+ // 60 m² × 0.70 packing × 200 W/m² = 8400 W.
+ assert.ok(Math.abs(ratedWFromSlopeArea(60) - 8400) < 1e-9);
+ assert.equal(DEFAULT_PACKING_FACTOR, 0.7);
+ assert.equal(DEFAULT_MODULE_W_PER_M2, 200);
+ });
+
+ it("honours an overridden packing factor", () => {
+ assert.ok(Math.abs(ratedWFromSlopeArea(60, 0.5, 200) - 6000) < 1e-9);
+ });
+});
+
+describe("the entry written back to config", () => {
+ it("carries only the four fields weather.pv_arrays defines", () => {
+ const ring = ringFromMetres(RECT_10x6, STOCKHOLM);
+ const out = arrayFromRing(ring, { latitude: STOCKHOLM.lat });
+ assert.deepEqual(
+ Object.keys(out.array).sort(),
+ ["azimuth_deg", "name", "rated_w", "tilt_deg"],
+ );
+ });
+
+ it("describes a south-facing 35° roof from the drawing alone", () => {
+ const ring = ringFromMetres(RECT_10x6, STOCKHOLM);
+ const out = arrayFromRing(ring, { latitude: STOCKHOLM.lat });
+ assert.equal(out.array.azimuth_deg, 180);
+ assert.equal(out.array.tilt_deg, 35);
+ assert.equal(out.array.name, "Roof south");
+ assert.ok(Math.abs(out.planAreaM2 - 60) < 0.6);
+ assert.ok(Math.abs(out.slopeAreaM2 - 73.2) < 0.6);
+ assert.ok(Math.abs(out.array.rated_w - 10250) < 100);
+ assert.deepEqual(out.azimuthCandidates.slice().sort((a, b) => a - b), [0, 180]);
+ });
+
+ it("lets an explicit azimuth override the guess", () => {
+ const ring = ringFromMetres(RECT_10x6, STOCKHOLM);
+ const out = arrayFromRing(ring, { latitude: STOCKHOLM.lat, azimuthDeg: 0 });
+ assert.equal(out.array.azimuth_deg, 0);
+ assert.equal(out.array.name, "Roof north");
+ });
+
+ it("names a flat roof for what it is", () => {
+ assert.equal(compassName(180, 0), "Roof flat");
+ assert.equal(compassName(90, 35), "Roof east");
+ assert.equal(compassName(225, 35), "Roof south-west");
+ });
+});
diff --git a/web/index.html b/web/index.html
index 1e46ac6d0..fc50c95ad 100644
--- a/web/index.html
+++ b/web/index.html
@@ -5,10 +5,10 @@
FTW
-
+
0;)i[a++]=e[o++]}}return i}var HS=class extends LS{constructor(e,t,n,r,i,a,o,s){super(e,n,r,o??t.length),this.indexBuffer=t,this.symbolOffsetBuffer=i,this.symbolTableBuffer=a,this.sharedDictionaryCache=s}getValueFromBuffer(e){this.decodedDictionary??(this.decodedDictionary=this.sharedDictionaryCache?.decodedDictionary,this.decodedDictionary??(this.decodedDictionary=this.decodeDictionary(),this.sharedDictionaryCache&&(this.sharedDictionaryCache.decodedDictionary=this.decodedDictionary)));let t=this.indexBuffer[e],n=this.offsetBuffer[t],r=this.offsetBuffer[t+1];return Nx(this.decodedDictionary,n,r)}decodeDictionary(){return this.symbolLengthBuffer??=this.offsetToLengthBuffer(this.symbolOffsetBuffer),VS(this.symbolTableBuffer,this.symbolLengthBuffer,this.dataBuffer)}offsetToLengthBuffer(e){let t=new Uint32Array(e.length-1),n=e[0];for(let r=1;r1&&!c.nullable||l===1&&c.nullable)throw Error(`The number of streams for the child field ${c.name} does not match its nullability. nullibilty: ${c.nullable}, numStreams: ${l}`);let m;if(c.nullable){let n=Q(e,t);m=new Sx(Ex(e,n.numValues,n.byteLength,t),n.numValues)}let h=Ix(e,t,Q(e,t),void 0,m);if(s){if(!o)throw Error(`Incomplete shared FSST dictionary for column "${p}"`);u[f++]=new HS(p,h,i,a,o,s,m,d)}else u[f++]=new zS(p,h,i,a,m)}return u}var JS=class extends hy{constructor(e,t,n){super(e,new Uint8Array,n??t.length),this.values=t}getValueFromBuffer(e){return this.values[e]}},YS;(function(e){e[e.STRING=1]=`STRING`,e[e.INT32=2]=`INT32`,e[e.UINT32=4]=`UINT32`,e[e.INT64=8]=`INT64`,e[e.UINT64=16]=`UINT64`,e[e.FLOAT=32]=`FLOAT`,e[e.DOUBLE=64]=`DOUBLE`,e[e.PRESENCE=128]=`PRESENCE`})(YS||={});var XS;(function(e){e[e.FALSE=0]=`FALSE`,e[e.TRUE=1]=`TRUE`,e[e.START_MAP=2]=`START_MAP`,e[e.START_LIST=3]=`START_LIST`,e[e.COUNT=4]=`COUNT`})(XS||={});function ZS(e,t,n,r){let i=QS(n);if(r===0)return i.map(e=>new JS(e,[]));let a=$S(e,t,r),o=(a.presentStream?a.presentCount:a.lengthStream.length)/i.length,s=[],c=0,l=0;for(let e=0;ee.name+(t.name??``))}function $S(e,t,n){let r=e[t.get()];t.add(1);let i=Ix(e,t,Q(e,t)),a=n-1,o=[];r&YS.STRING&&(a-=eC(e,t,o)),a-=tC(e,t,r,o),a-=nC(e,t,r,o);let s,c=0;if(r&YS.PRESENCE){let n=rC(e,t);s=n.value,c=n.count,a--}let l=new Uint32Array;if(a>0&&(l=Ix(e,t,Q(e,t)),a--),a!==0)throw Error(`Unexpected number of remaining streams while decoding map column: ${a}`);return{lengthStream:i,dictionary:o,presentStream:s,presentCount:c,flattenedValues:l}}function eC(e,t,n){let r=e[t.get()];t.add(1);let i=US(``,e,t,r);if(i)for(let e=0;ea.length)throw Error(`Merged map counts underflow while decoding child streams`);let p=Array(n),m=r,h=i;for(let e=0;eo.length)throw Error(`Map value stream underflow while decoding feature payload`);let n=aC(o,h,t,c);p[e]=n.value,h=n.nextIndex}let g=0;for(let e=r;e=n)throw Error(`Unexpected end of map value stream`);let i=e[t];if(i===XS.FALSE)return{value:!1,nextIndex:t+1};if(i===XS.TRUE)return{value:!0,nextIndex:t+1};if(i===XS.START_MAP){let i=cC(e,t,n);return{value:oC(e,t+2,i,r).value,nextIndex:i}}if(i===XS.START_LIST){let i=cC(e,t,n),a=[],o=t+2;for(;o=n)throw Error(`Missing length for nested map/list payload`);let r=e[t+1];if(r<2)throw Error(`Invalid nested payload length: ${r}`);let i=t+r;if(i>n)throw Error(`Nested payload exceeds containing payload bounds`);return i}function lC(e,t){let n=e-XS.COUNT;if(n<0||n>=t.length)throw Error(`Scalar dictionary index out of range: ${e}`);return t[n]}function uC(e,t){for(let n of t)e.push(n)}function dC(e,t,n,r,i,a){return n.type===`scalarType`?a&&!a.has(n.name)?(Tx(r,e,t),null):fC(r,e,t,i,n.scalarType,n):n.complexType?.physicalType===wy.MAP?ZS(e,t,n,r):r===0?null:qS(e,t,n,a)}function fC(e,t,n,r,i,a){let o;if(e===0)return null;if(a.nullable){let e=Q(t,n),r=e.numValues,i=n.get(),a=Ex(t,r,e.byteLength,n);n.set(i+e.byteLength),o=new Sx(a,e.numValues)}let s=o??r;switch(i.physicalType){case Y.UINT_32:case Y.INT_32:return _C(t,n,a,i,s);case Y.STRING:{let r=a.nullable?e-1:e;return US(a.name,t,n,r,o)??null}case Y.BOOLEAN:return pC(t,n,a,r,s);case Y.UINT_64:case Y.INT_64:return gC(t,n,a,s,i);case Y.FLOAT:return mC(t,n,a,s);case Y.DOUBLE:return hC(t,n,a,s);default:throw Error(`The specified data type for the field is currently not supported: ${i}`)}}function pC(e,t,n,r,i){let a=Q(e,t),o=a.numValues,s=t.get(),c=vC(i)?i:void 0,l=Ex(e,o,a.byteLength,t,c);t.set(s+a.byteLength);let u=new Sx(l,o);return new PS(n.name,u,i)}function mC(e,t,n,r){let i=Q(e,t),a=vC(r)?r:void 0,o=Ox(e,t,i.numValues,a);return new FS(n.name,o,r)}function hC(e,t,n,r){let i=Q(e,t),a=vC(r)?r:void 0,o=kx(e,t,i.numValues,a);return new vy(n.name,o,r)}function gC(e,t,n,r,i){let a=Q(e,t),o=nS(a,r,e,t,`int64`),s=i.physicalType===Y.INT_64;if(o===$.FLAT){let i=vC(r)?r:void 0,o=s?Wx(e,t,a,i):Gx(e,t,a,i);return new aS(n.name,o,r)}if(o===$.SEQUENCE){let r=Ux(e,t,a);return new oS(n.name,r[0],r[1],a.numRleValues,s)}let c=s?Jx(e,t,a):Yx(e,t,a);return new IS(n.name,c,r,s)}function _C(e,t,n,r,i){let a=Q(e,t),o=nS(a,i,e,t),s=r.physicalType===Y.INT_32;if(o===$.FLAT){let r=vC(i)?i:void 0,o=s?Fx(e,t,a,void 0,r):Ix(e,t,a,void 0,r);return new _y(n.name,o,i)}if(o===$.SEQUENCE){let r=Hx(e,t,a);return new by(n.name,r[0],r[1],a.numRleValues,s)}let c=s?Bx(e,t,a):Vx(e,t,a);return new xy(n.name,c,i,s)}function vC(e){return e instanceof Sx}const yC={ID:0,ID_NULLABLE:1,ID_LONG:2,GEOMETRY:4,SCALAR_BASE:10,STRUCT:30,MAP:31};function bC(e){switch(e){case yC.ID:case yC.ID|yC.ID_NULLABLE:case yC.ID|yC.ID_LONG:case yC.ID|yC.ID_LONG|yC.ID_NULLABLE:return{nullable:(e&yC.ID_NULLABLE)!==0,columnScope:Cy.FEATURE,type:`scalarType`,scalarType:{longID:(e&yC.ID_LONG)!==0,type:`logicalType`,logicalType:Ty.ID}};case yC.GEOMETRY:return{nullable:!1,columnScope:Cy.FEATURE,type:`complexType`,complexType:{type:`physicalType`,physicalType:wy.GEOMETRY,children:[]}};case yC.STRUCT:return{nullable:!1,columnScope:Cy.FEATURE,type:`complexType`,complexType:{type:`physicalType`,physicalType:wy.STRUCT,children:[]}};case yC.MAP:return{nullable:!0,columnScope:Cy.FEATURE,type:`complexType`,complexType:{type:`physicalType`,physicalType:wy.MAP,children:[]}};default:return EC(e)}}function xC(e){return e>=yC.SCALAR_BASE}function SC(e){return e===yC.STRUCT||e===yC.MAP}function CC(e){if(e.type===`scalarType`){let t=e.scalarType;if(t.type===`physicalType`)switch(t.physicalType){case Y.BOOLEAN:case Y.INT_8:case Y.UINT_8:case Y.INT_32:case Y.UINT_32:case Y.INT_64:case Y.UINT_64:case Y.FLOAT:case Y.DOUBLE:return!1;case Y.STRING:return!0;default:return!1}if(t.type===`logicalType`)return!1}else if(e.type===`complexType`){let t=e.complexType;if(t.type===`physicalType`)switch(t.physicalType){case wy.GEOMETRY:case wy.STRUCT:case wy.MAP:return!0;default:return!1}}return console.warn(`Unexpected column type in hasStreamCount`,e),!1}function wC(e){return e.type===`scalarType`&&e.scalarType?.type===`logicalType`&&e.scalarType.logicalType===Ty.ID}function TC(e){return e.type===`complexType`&&e.complexType?.type===`physicalType`&&e.complexType.physicalType===wy.GEOMETRY}function EC(e){let t;switch(e){case 10:case 11:t=Y.BOOLEAN;break;case 12:case 13:t=Y.INT_8;break;case 14:case 15:t=Y.UINT_8;break;case 16:case 17:t=Y.INT_32;break;case 18:case 19:t=Y.UINT_32;break;case 20:case 21:t=Y.INT_64;break;case 22:case 23:t=Y.UINT_64;break;case 24:case 25:t=Y.FLOAT;break;case 26:case 27:t=Y.DOUBLE;break;case 28:case 29:t=Y.STRING;break;default:return null}return{nullable:!!(e&1),columnScope:Cy.FEATURE,type:`scalarType`,scalarType:{longID:!1,type:`physicalType`,physicalType:t}}}const DC=new TextDecoder,OC=`0-3(ID), 4(GEOMETRY), 10-29(scalars), 30(STRUCT), 31(MAP)`;function kC(e,t){let n=xb(e,t,1)[0];if(n===0)return``;let r=t.get(),i=r+n,a=e.subarray(r,i);return t.add(n),DC.decode(a)}function AC(e){let t=e.name,n=e.nullable;return e.type===`scalarType`?{type:`scalarField`,scalarField:e.scalarType,name:t,nullable:n}:{type:`complexField`,complexField:e.complexType,name:t,nullable:n}}function jC(e,t){let n=xb(e,t,1)[0]>>>0,r=n>=yC.SCALAR_BASE?bC(n):null;if(!r)throw Error(`Unsupported field type code ${n}. Supported: 10-29(scalars), 30(STRUCT), 31(MAP)`);let i={...r,name:kC(e,t)};if(i.type===`complexType`&&SC(n)){let n=i.complexType,r=xb(e,t,1)[0]>>>0;n.children=Array(r);for(let i=0;i>>0,r=bC(n);if(!r)throw Error(`Unsupported column type code ${n}. Supported: ${OC}`);let i;if(xC(n))i=kC(e,t);else if(n>>0,r=a.complexType;r.children=Array(n);for(let i=0;i>>0,a=xb(e,t,1)[0]>>>0;r.columns=Array(a);for(let n=0;n>>0,o=r.get()+a;if(o>e.length)throw Error(`Block overruns tile: ${o} > ${e.length}`);let s=xb(e,r,1)[0]>>>0;if(s!==1&&s!==2){r.set(o);continue}let[c,l]=NC(e,r),u=c.featureTables[0],d=null,f=null,p=[],m=0;for(let i of u.columns){let a=i.name;if(wC(i)){let t=null;if(i.nullable){let n=Q(e,r),i=r.get(),a=Ex(e,n.numValues,n.byteLength,r);r.set(i+n.byteLength),t=new Sx(a,n.numValues)}let o=Q(e,r);m=t?t.size():o.decompressedCount,d=FC(e,i,r,a,o,t??m,n)}else if(TC(i)){let n=xb(e,r,1)[0];if(m===0){let t=r.get();m=Q(e,r).decompressedCount,r.set(t)}t&&(t.scale=t.extent/l),f=kS(e,n,r,m,t)}else{let t=CC(i)?xb(e,r,1)[0]:1;if(t===0)continue;let n=dC(e,r,i,t,m,void 0);if(n){if(Array.isArray(n))for(let e of n)p.push(e);else p.push(n)}}}let h=new Sy(u.name,f,d,p,l);i.push(h),r.set(o)}return i}function FC(e,t,n,r,i,a,o=!1){let s=t.scalarType?.longID?Y.UINT_64:Y.UINT_32,c=typeof a==`number`?void 0:a,l=nS(i,a,e,n,s===Y.UINT_64?`int64`:`int32`);if(s===Y.UINT_32)switch(l){case $.FLAT:return new _y(r,Ix(e,n,i,void 0,c),a);case $.SEQUENCE:{let t=Hx(e,n,i);return new by(r,t[0],t[1],i.numRleValues,!1)}case $.CONST:return new xy(r,Vx(e,n,i),a,!1)}switch(l){case $.FLAT:return o?new vy(r,Kx(e,n,i,c),a):new aS(r,Gx(e,n,i,c),a);case $.SEQUENCE:{let t=Ux(e,n,i);return new oS(r,t[0],t[1],i.numRleValues,!1)}case $.CONST:return new IS(r,Yx(e,n,i),a,!1)}throw Error(`Vector type not supported for id column.`)}var IC=class{constructor(e,t){switch(this._featureData=e,this.properties=this._featureData.properties||{},this._featureData.geometry?.type){case lS.POINT:case lS.MULTIPOINT:this.type=1;break;case lS.LINESTRING:case lS.MULTILINESTRING:this.type=2;break;case lS.POLYGON:case lS.MULTIPOLYGON:this.type=3;break;default:this.type=0}this.extent=t,this.id=Number(this._featureData.id)}loadGeometry(){let e=[];for(let t of this._featureData.geometry.coordinates){let n=[];for(let e of t)n.push(new l(e.x,e.y));e.push(n)}return e}},LC=class{constructor(e){this.features=[],this.featureTable=e,this.name=e.name,this.extent=e.extent,this.version=2,this.features=e.getFeatures(),this.length=this.features.length}feature(e){return new IC(this.features[e],this.extent)}},RC=class{constructor(e){this.layers={};let t=PC(new Uint8Array(e));this.layers=t.reduce((e,t)=>({...e,[t.name]:new LC(t)}),{})}},zC=class{constructor(e,t){this.tileID=e,this.x=e.canonical.x,this.y=e.canonical.y,this.z=e.canonical.z,this.grid=new gc(j,16,0),this.grid3D=new gc(j,16,0),this.featureIndexArray=new nu,this.promoteId=t}insert(e,t,n,r,i,a){let o=this.featureIndexArray.length;this.featureIndexArray.emplaceBack(n,r,i);let s=a?this.grid3D:this.grid;for(let e of t){let t=[1/0,1/0,-1/0,-1/0];for(let n of e)t[0]=Math.min(t[0],n.x),t[1]=Math.min(t[1],n.y),t[2]=Math.max(t[2],n.x),t[3]=Math.max(t[3],n.y);t[0]<8192&&t[1]<8192&&t[2]>=0&&t[3]>=0&&s.insert(o,t[0],t[1],t[2],t[3])}}loadVTLayers(){if(!this.vtLayers){switch(this.encoding){case`mlt`:this.vtLayers=new RC(this.rawTileData).layers;break;default:this.vtLayers=new $p(new i_(this.rawTileData)).layers}this.sourceLayerCoder=new py(this.vtLayers?Object.keys(this.vtLayers).sort():[ny])}return this.vtLayers}query(e,t,n,r){this.loadVTLayers();let i=e.params,a=j/e.tileSize/e.scale,o=ts(i.filter,`queryRenderedFeatures filter`,i.globalState),s=e.queryGeometry,c=e.queryPadding*a,l=Wp.fromPoints(s),u=this.grid.query(l.minX-c,l.minY-c,l.maxX+c,l.maxY+c),d=Wp.fromPoints(e.cameraQueryGeometry).expandBy(c),f=this.grid3D.query(d.minX,d.minY,d.maxX,d.maxY,(t,n,r,i)=>wd(e.cameraQueryGeometry,t-c,n-c,r+c,i+c));for(let e of f)u.push(e);u.sort(HC);let p={},m;for(let c of u){if(c===m)continue;m=c;let l=this.featureIndexArray.get(c),u=null;this.loadMatchingFeature(p,l.bucketIndex,l.sourceLayerIndex,l.featureIndex,o,i.layers,i.availableImages,t,n,r,(t,n,r)=>(u||=cd(t),n.queryIntersectsFeature({queryGeometry:s,feature:t,featureState:r,geometry:u,zoom:this.z,transform:e.transform,pixelsToTileUnits:a,pixelPosMatrix:e.pixelPosMatrix,unwrappedTileID:this.tileID.toUnwrapped(),getElevation:e.getElevation})))}return p}loadMatchingFeature(e,t,n,r,i,a,o,s,c,l,u){let d=this.bucketLayerIDs[t];if(a&&!d.some(e=>a.has(e)))return;let f=this.sourceLayerCoder.decode(n),p=this.vtLayers[f].feature(r);if(i.needGeometry){let e=ld(p,!0);if(!i.filter(new U(this.tileID.overscaledZ),e,this.tileID.canonical))return}else if(!i.filter(new U(this.tileID.overscaledZ),p))return;let m=this.getId(p,f);for(let t of d){if(a&&!a.has(t))continue;let n=s[t];if(!n)continue;let i={};m&&l&&(i=l.getState(n.sourceLayer||`_geojsonTileLayer`,m));let d=St({},c[t]);d.paint=VC(d.paint,n.paint,p,i,o),d.layout=VC(d.layout,n.layout,p,i,o);let f=!u||u(p,n,i);if(!f)continue;let h=new my(p,this.z,this.x,this.y,m);h.layer=d;let g=e[t];g===void 0&&(g=e[t]=[]),g.push({featureIndex:r,feature:h,intersectionZ:f})}}lookupSymbolFeatures(e,t,n,r,i,a,o,s){let c={};this.loadVTLayers();let l=ts(i.filterSpec,`queryRenderedFeatures symbol filter`,i.globalState);for(let i of e)this.loadMatchingFeature(c,n,r,i,l,a,o,s,t);return c}hasLayer(e){for(let t of this.bucketLayerIDs)for(let n of t)if(e===n)return!0;return!1}getId(e,t){let n=e.id;if(this.promoteId){let r=typeof this.promoteId==`string`?this.promoteId:this.promoteId[t];n=e.properties[r],typeof n==`boolean`&&(n=Number(n)),n===void 0&&e.properties?.cluster&&this.promoteId&&(n=Number(e.properties.cluster_id))}return n}};H(`FeatureIndex`,zC,{omit:[`rawTileData`,`sourceLayerCoder`]});function BC(e){return typeof e==`object`&&!!e&&`evaluate`in e}function VC(e,t,n,r,i){return jt(e,(e,a)=>{let o=t instanceof nl?t.get(a):null;return BC(o)?o.evaluate(n,r,void 0,i):o})}function HC(e,t){return t-e}var UC=class{constructor(e,t){this.max=e,this.onRemove=t,this.reset()}reset(){for(let e in this.data)for(let t of this.data[e])t.timeout&&clearTimeout(t.timeout),this.onRemove(t.value);return this.data={},this.order=[],this}add(e,t,n){let r=e.wrapped().key;this.data[r]===void 0&&(this.data[r]=[]);let i={value:t,timeout:void 0};if(n!==void 0&&(i.timeout=setTimeout(()=>{this.remove(e,i)},n)),this.data[r].push(i),this.order.push(r),this.order.length>this.max){let e=this._getAndRemoveByKey(this.order[0]);e&&this.onRemove(e)}return this}has(e){return e.wrapped().key in this.data}getAndRemove(e){return this.has(e)?this._getAndRemoveByKey(e.wrapped().key):null}_getAndRemoveByKey(e){let t=this.data[e].shift();return t.timeout&&clearTimeout(t.timeout),this.data[e].length===0&&delete this.data[e],this.order.splice(this.order.indexOf(e),1),t.value}getByKey(e){let t=this.data[e];return t?t[0].value:null}get(e){return this.has(e)?this.data[e.wrapped().key][0].value:null}remove(e,t){if(!this.has(e))return this;let n=e.wrapped().key,r=t===void 0?0:this.data[n].indexOf(t),i=this.data[n][r];return this.data[n].splice(r,1),i.timeout&&clearTimeout(i.timeout),this.data[n].length===0&&delete this.data[n],this.onRemove(i.value),this.order.splice(this.order.indexOf(n),1),this}setMaxSize(e){for(this.max=e;this.order.length>this.max;){let e=this._getAndRemoveByKey(this.order[0]);e&&this.onRemove(e)}return this}filter(e){let t=[];for(let n in this.data)for(let r of this.data[n])e(r.value)||t.push(r);for(let e of t)this.remove(e.value.tileID,e)}},WC=class{constructor(e){this.maxEntries=e,this.map=new Map}get(e){let t=this.map.get(e);return t!==void 0&&(this.map.delete(e),this.map.set(e,t)),t}set(e,t){if(this.map.has(e))this.map.delete(e);else if(this.map.size>=this.maxEntries){let e=this.map.keys().next().value;this.map.delete(e)}this.map.set(e,t)}clear(){this.map.clear()}};function GC(e,t,n,r,i){let a=[];for(let o of e){let e;for(let s=0;s=r&&u.x>=r)&&(c.x>=r?c=new l(r,c.y+(u.y-c.y)*((r-c.x)/(u.x-c.x)))._round():u.x>=r&&(u=new l(r,c.y+(u.y-c.y)*((r-c.x)/(u.x-c.x)))._round()),!(c.y>=i&&u.y>=i)&&(c.y>=i?c=new l(c.x+(u.x-c.x)*((i-c.y)/(u.y-c.y)),i)._round():u.y>=i&&(u=new l(c.x+(u.x-c.x)*((i-c.y)/(u.y-c.y)),i)._round()),(!e||!c.equals(e[e.length-1]))&&(e=[c],a.push(e)),e.push(u)))))}}return a}function KC(e,t,n,r,i,a){let o=qC(e,t,n,i,0);return o=qC(o,t,r,a,1),o}function qC(e,t,n,r,i){switch(t){case 1:return JC(e,n,r,i);case 2:return XC(e,n,r,i,!1);case 3:return XC(e,n,r,i,!0)}return[]}function JC(e,t,n,r){let i=[];for(let a of e)for(let e of a){let a=r===0?e.x:e.y;a>=t&&a<=n&&i.push([e])}return i}function YC(e,t,n,r,i){let a=r===0?ZC:QC,o=[],s=[];for(let c=0;ct&&o.push(a(l,u,t)):d>n?f=t&&(o.push(a(l,u,t)),p=!0),f>n&&d<=n&&(o.push(a(l,u,n)),p=!0),!i&&p&&(s.push(o),o=[])}let c=e.length-1,u=r===0?e[c].x:e[c].y;return u>=t&&u<=n&&o.push(e[c]),i&&o.length>0&&!o[0].equals(o[o.length-1])&&o.push(new l(o[0].x,o[0].y)),o.length>0&&s.push(o),s}function XC(e,t,n,r,i){let a=[];for(let o of e){let e=YC(o,t,n,r,i);e.length>0&&a.push(...e)}return a}function ZC(e,t,n){let r=(n-e.x)/(t.x-e.x);return new l(n,e.y+(t.y-e.y)*r)}function QC(e,t,n){let r=(n-e.y)/(t.y-e.y);return new l(e.x+(t.x-e.x)*r,n)}var $C=class e extends l{constructor(e,t,n,r){super(e,t),this.angle=n,r!==void 0&&(this.segment=r)}clone(){return new e(this.x,this.y,this.angle,this.segment)}};H(`Anchor`,$C);function ew(e,t,n,r,i){if(t.segment===void 0||n===0)return!0;let a=t,o=t.segment+1,s=0;for(;s>-n/2;){if(o--,o<0)return!1;s-=e[o].dist(a),a=e[o]}s+=e[o].dist(e[o+1]),o++;let c=[],l=0;for(;sr;)l-=c.shift().angleDelta;if(l>i)return!1;o++,s+=n.dist(a)}return!0}function tw(e){let t=0;for(let n=0;nl){let u=(l-c)/a,d=new $C(ti.number(r.x,i.x,u),ti.number(r.y,i.y,u),i.angleTo(r),n);return d._round(),!o||ew(e,d,s,o,t)?d:void 0}c+=a}}function aw(e,t,n,r,i,a,o,s,c){let l=nw(r,a,o),u=rw(r,i),d=u*o,f=e[0].x===0||e[0].x===c||e[0].y===0||e[0].y===c;t-d=0&&_=0&&v=0&&f+l<=u){let n=new $C(_,v,h,t);n._round(),(!r||ew(e,n,a,r,i))&&p.push(n)}}d+=m}return!s&&!p.length&&!o&&(p=ow(e,d/2,n,r,i,a,o,!0,c)),p}function sw(e,t,n,r){let i=[],a=e.image,o=a.pixelRatio,s=a.paddedRect.w-2,c=a.paddedRect.h-2,u={x1:e.left,y1:e.top,x2:e.right,y2:e.bottom},d=a.stretchX||[[0,s]],f=a.stretchY||[[0,c]],p=(e,t)=>e+t[1]-t[0],m=d.reduce(p,0),h=f.reduce(p,0),g=s-m,_=c-h,v=0,y=m,b=0,x=h,S=0,C=g,w=0,T=_;if(a.content&&r){let t=a.content,n=t[2]-t[0],r=t[3]-t[1];(a.textFitWidth||a.textFitHeight)&&(u=iv(e)),v=cw(d,0,t[0]),b=cw(f,0,t[1]),y=cw(d,t[0],t[2]),x=cw(f,t[1],t[3]),S=t[0]-v,w=t[1]-b,C=n-y,T=r-x}let E=u.x1,D=u.y1,O=u.x2-E,k=u.y2-D,A=(e,r,i,s)=>{let c=uw(e.stretch-v,y,O,E),u=dw(e.fixed-S,C,e.stretch,m),d=uw(r.stretch-b,x,k,D),f=dw(r.fixed-w,T,r.stretch,h),p=uw(i.stretch-v,y,O,E),g=dw(i.fixed-S,C,i.stretch,m),_=uw(s.stretch-b,x,k,D),A=dw(s.fixed-w,T,s.stretch,h),ee=new l(c,d),te=new l(p,d),ne=new l(p,_),re=new l(c,_),ie=new l(u/o,f/o),ae=new l(g/o,A/o),oe=t*Math.PI/180;if(oe){let e=Math.sin(oe),t=Math.cos(oe),n=[t,-e,e,t];ee._matMult(n),te._matMult(n),re._matMult(n),ne._matMult(n)}let se=e.stretch+e.fixed,ce=i.stretch+i.fixed,le=r.stretch+r.fixed,ue=s.stretch+s.fixed;return{tl:ee,tr:te,bl:re,br:ne,tex:{x:a.paddedRect.x+1+se,y:a.paddedRect.y+1+le,w:ce-se,h:ue-le},writingMode:void 0,glyphOffset:[0,0],sectionIndex:0,pixelOffsetTL:ie,pixelOffsetBR:ae,minFontScaleX:C/o/O,minFontScaleY:T/o/k,isSDF:n}};if(!r||!a.stretchX&&!a.stretchY)i.push(A({fixed:0,stretch:-1},{fixed:0,stretch:-1},{fixed:0,stretch:s+1},{fixed:0,stretch:c+1}));else{let e=lw(d,g,m),t=lw(f,_,h);for(let n=0;n0&&(r=Math.max(10,r),this.circleDiameter=r)}else{let c=a.image?.content&&(a.image.textFitWidth||a.image.textFitHeight)?iv(a):{x1:a.left,y1:a.top,x2:a.right,y2:a.bottom};c.y1=c.y1*o-s[0],c.y2=c.y2*o+s[2],c.x1=c.x1*o-s[3],c.x2=c.x2*o+s[1];let d=a.collisionPadding;if(d&&(c.x1-=d[0]*o,c.y1-=d[1]*o,c.x2+=d[2]*o,c.y2+=d[3]*o),u){let e=new l(c.x1,c.y1),t=new l(c.x2,c.y1),n=new l(c.x1,c.y2),r=new l(c.x2,c.y2),i=u*Math.PI/180;e._rotate(i),t._rotate(i),n._rotate(i),r._rotate(i),c.x1=Math.min(e.x,t.x,n.x,r.x),c.x2=Math.max(e.x,t.x,n.x,r.x),c.y1=Math.min(e.y,t.y,n.y,r.y),c.y2=Math.max(e.y,t.y,n.y,r.y)}e.emplaceBack(t.x,t.y,c.x1,c.y1,c.x2,c.y2,n,r,i)}this.boxEndIndex=e.length}},mw=class{constructor(e=[],t=(e,t)=>et)){if(this.data=e,this.length=this.data.length,this.compare=t,this.length>0)for(let e=(this.length>>1)-1;e>=0;e--)this._down(e)}push(e){this.data.push(e),this._up(this.length++)}pop(){if(this.length===0)return;let e=this.data[0],t=this.data.pop();return--this.length>0&&(this.data[0]=t,this._down(0)),e}peek(){return this.data[0]}_up(e){let{data:t,compare:n}=this,r=t[e];for(;e>0;){let i=e-1>>1,a=t[i];if(n(r,a)>=0)break;t[e]=a,e=i}t[e]=r}_down(e){let{data:t,compare:n}=this,r=this.length>>1,i=t[e];for(;e=0)break;t[e]=t[r],e=r}t[e]=i}};function hw(e,t=1){let n=Wp.fromPoints(e[0]),r=Math.min(n.width(),n.height()),i=r/2,a=new mw([],gw),{minX:o,minY:s,maxX:c,maxY:u}=n;if(r===0)return new l(o,s);for(let t=o;tf.d||!f.d)&&(f=n),!(n.max-f.d<=t)&&(i=n.h/2,a.push(new _w(n.p.x-i,n.p.y-i,i,e)),a.push(new _w(n.p.x+i,n.p.y-i,i,e)),a.push(new _w(n.p.x-i,n.p.y+i,i,e)),a.push(new _w(n.p.x+i,n.p.y+i,i,e)))}return d.d>0&&f.d-d.d<=t?d.p:f.p}function gw(e,t){return t.max-e.max}var _w=class{constructor(e,t,n,r){this.p=new l(e,t),this.h=n,this.d=vw(this.p,r),this.max=this.d+this.h*Math.SQRT2}};function vw(e,t){let n=!1,r=1/0;for(let i of t)for(let t=0,a=i.length,o=a-1;te.y!=s.y>e.y&&e.x<(s.x-a.x)*(e.y-a.y)/(s.y-a.y)+a.x&&(n=!n),r=Math.min(r,xd(e,a,s))}return(n?1:-1)*Math.sqrt(r)}function yw(e){let t=0,n=0,r=0,i=e[0];for(let e=0,a=i.length,o=a-1;ee*24);r.startsWith(`top`)?i[1]-=7:r.startsWith(`bottom`)&&(i[1]+=7),t[n+1]=i}return new zr(t)}let a=r.get(`text-variable-anchor`);if(a){let i;i=e._unevaluatedLayout.getValue(`text-radial-offset`)===void 0?r.get(`text-offset`).evaluate(t,{},n).map(e=>e*24):[r.get(`text-radial-offset`).evaluate(t,{},n)*24,xw];let o=[];for(let e of a)o.push(e,Sw(e,i));return new zr(o)}return null}function ww(e){e.bucket.createArrays();let t=512*e.bucket.overscaling;e.bucket.tilePixelRatio=j/t,e.bucket.compareText={},e.bucket.iconsNeedLinear=!1;let n=e.bucket.layers[0],r=n.layout,i=n._unevaluatedLayout._values,a={layoutIconSize:i[`icon-size`].possiblyEvaluate(new U(e.bucket.zoom+1),e.canonical),layoutTextSize:i[`text-size`].possiblyEvaluate(new U(e.bucket.zoom+1),e.canonical),textMaxSize:i[`text-size`].possiblyEvaluate(new U(18))};if(e.bucket.textSizeData.kind===`composite`){let{minZoom:t,maxZoom:n}=e.bucket.textSizeData;a.compositeTextSizes=[i[`text-size`].possiblyEvaluate(new U(t),e.canonical),i[`text-size`].possiblyEvaluate(new U(n),e.canonical)]}if(e.bucket.iconSizeData.kind===`composite`){let{minZoom:t,maxZoom:n}=e.bucket.iconSizeData;a.compositeIconSizes=[i[`icon-size`].possiblyEvaluate(new U(t),e.canonical),i[`icon-size`].possiblyEvaluate(new U(n),e.canonical)]}let o=r.get(`text-line-height`)*24,s=r.get(`text-rotation-alignment`)!==`viewport`&&r.get(`symbol-placement`)!==`point`,c=r.get(`text-keep-upright`),l=r.get(`text-size`);for(let t of e.bucket.features){let i=r.get(`text-font`).evaluate(t,{},e.canonical).join(`,`),u=l.evaluate(t,{},e.canonical),d=a.layoutTextSize.evaluate(t,{},e.canonical),f=a.layoutIconSize.evaluate(t,{},e.canonical),p={horizontal:{},vertical:void 0},m=t.text,h=[0,0];if(m){let a=m.toString(),l=r.get(`text-letter-spacing`).evaluate(t,{},e.canonical)*24,f=Fc(a)?l:0,g=r.get(`text-anchor`).evaluate(t,{},e.canonical),_=Cw(n,t,e.canonical);if(!_){let n=r.get(`text-radial-offset`).evaluate(t,{},e.canonical);h=n?Sw(g,[n*24,xw]):r.get(`text-offset`).evaluate(t,{},e.canonical).map(e=>e*24)}let v=s?`center`:r.get(`text-justify`).evaluate(t,{},e.canonical),y=r.get(`symbol-placement`)===`point`?r.get(`text-max-width`).evaluate(t,{},e.canonical)*24:1/0,b=()=>{e.bucket.allowVerticalPlacement&&Pc(a)&&(p.vertical=z_(m,e.glyphMap,e.glyphPositions,e.imagePositions,i,y,o,g,`left`,f,h,2,!0,d,u))};if(!s&&_){let t=new Set;if(v===`auto`)for(let e=0;e<_.values.length;e+=2)t.add(Tw(_.values[e]));else t.add(v);let n=!1;for(let r of t)if(!p.horizontal[r]){if(n)p.horizontal[r]=p.horizontal[0];else{let t=z_(m,e.glyphMap,e.glyphPositions,e.imagePositions,i,y,o,`center`,r,f,h,1,!1,d,u);t&&(p.horizontal[r]=t,n=t.positionedLines.length===1)}}b()}else{v===`auto`&&(v=Tw(g));let t=z_(m,e.glyphMap,e.glyphPositions,e.imagePositions,i,y,o,g,v,f,h,1,!1,d,u);t&&(p.horizontal[v]=t),b(),Pc(a)&&s&&c&&(p.vertical=z_(m,e.glyphMap,e.glyphPositions,e.imagePositions,i,y,o,g,v,f,h,2,!1,d,u))}}let g,_=!1;if(t.icon?.name){let n=e.imageMap[t.icon.name];n&&(g=rv(e.imagePositions[t.icon.name],r.get(`icon-offset`).evaluate(t,{},e.canonical),r.get(`icon-anchor`).evaluate(t,{},e.canonical)),_=!!n.sdf,e.bucket.sdfIcons===void 0?e.bucket.sdfIcons=_:e.bucket.sdfIcons!==_&&It(`Style sheet warning: Cannot mix SDF and non-SDF icons in one buffer`),n.pixelRatio===e.bucket.pixelRatio?r.get(`icon-rotate`).constantOr(1)!==0&&(e.bucket.iconsNeedLinear=!0):e.bucket.iconsNeedLinear=!0)}let v=kw(p.horizontal)||p.vertical;e.bucket.iconsInText||=v?v.iconsInText:!1,(v||g)&&Ew(e.bucket,t,p,g,e.imageMap,a,d,f,h,_,e.canonical,e.subdivisionGranularity)}e.showCollisionBoxes&&e.bucket.generateCollisionDebugBuffers()}function Tw(e){switch(e){case`right`:case`top-right`:case`bottom-right`:return`right`;case`left`:case`top-left`:case`bottom-left`:return`left`}return`center`}function Ew(e,t,n,r,i,a,o,s,c,l,u,d){let f=a.textMaxSize.evaluate(t,{});f===void 0&&(f=o);let p=e.layers[0].layout,m=p.get(`icon-offset`).evaluate(t,{},u),h=kw(n.horizontal),g=o/24,_=e.tilePixelRatio*g,v=e.tilePixelRatio*f/24,y=e.tilePixelRatio*s,b=e.tilePixelRatio*p.get(`symbol-spacing`),x=p.get(`text-padding`)*e.tilePixelRatio,S=jv(p,t,u,e.tilePixelRatio),C=p.get(`text-max-angle`)/180*Math.PI,w=p.get(`text-rotation-alignment`)!==`viewport`&&p.get(`symbol-placement`)!==`point`,T=p.get(`icon-rotation-alignment`).constantOr(`viewport`)===`map`&&p.get(`symbol-placement`)!==`point`,E=p.get(`symbol-placement`),D=b/2,O=p.get(`icon-text-fit`),k;r&&O!==`none`&&(e.allowVerticalPlacement&&n.vertical&&(k=av(r,n.vertical,O,p.get(`icon-text-fit-padding`),m,g)),h&&(r=av(r,h,O,p.get(`icon-text-fit-padding`),m,g)));let A=u?d.line.getGranularityForZoomLevel(u.z):1,ee=(s,d)=>{d.x<0||d.x>=8192||d.y<0||d.y>=8192||Aw(e,d,s,n,r,i,k,e.layers[0],e.collisionBoxArray,t.index,t.sourceLayerIndex,e.index,_,[x,x,x,x],w,c,y,S,T,m,t,a,l,u,o)};if(E===`line`)for(let i of GC(t.geometry,0,0,j,j)){let t=Tp(i,A),a=aw(t,b,C,n.vertical||h,r,24,v,e.overscaling,j);for(let n of a){let r=h;(!r||!jw(e,r.text,D,n))&&ee(t,n)}}else if(E===`line-center`){for(let e of t.geometry)if(e.length>1){let t=Tp(e,A),i=iw(t,C,n.vertical||h,r,24,v);i&&ee(t,i)}}else if(t.type===`Polygon`)for(let e of oi(t.geometry,0)){let t=hw(e,16);ee(Tp(e[0],A,!0),new $C(t.x,t.y,0))}else if(t.type===`LineString`)for(let e of t.geometry){let t=Tp(e,A);ee(t,new $C(t[0].x,t[0].y,0))}else if(t.type===`Point`)for(let e of t.geometry)for(let t of e)ee([t],new $C(t.x,t.y,0))}function Dw(e,t){let n=e.length,r=t?.values;if(r?.length>0)for(let t=0;t32640&&It(`${e.layerIds[0]}: Value for "text-size" is >= 255. Reduce your "text-size".`)):_.kind===`composite`&&(v=[128*m.compositeTextSizes[0].evaluate(o,{},h),128*m.compositeTextSizes[1].evaluate(o,{},h)],(v[0]>32640||v[1]>32640)&&It(`${e.layerIds[0]}: Value for "text-size" is >= 255. Reduce your "text-size".`)),e.addSymbols(e.text,g,v,s,a,o,u,t,l.lineStartIndex,l.lineLength,p,h,c);for(let t of d)f[t]=e.text.placedSymbolArray.length-1;return g.length*4}function kw(e){for(let t in e)return e[t];return null}function Aw(e,t,n,r,i,a,o,s,c,l,u,d,f,p,m,h,g,_,v,y,b,x,S,C,w){let T=e.addToLineVertexArray(t,n),E=s.layout.get(`symbol-height-offset`).evaluate(b,{},C),D,O,k,A,ee=0,te=0,ne=0,re=0,ie=-1,ae=-1,oe={},se=(0,ju.default)(``);if(e.allowVerticalPlacement&&r.vertical){let e=s.layout.get(`text-rotate`).evaluate(b,{},C)+90,n=r.vertical;k=new pw(c,t,l,u,d,n,f,p,m,e),o&&(A=new pw(c,t,l,u,d,o,g,_,m,e))}if(i){let n=s.layout.get(`icon-rotate`).evaluate(b,{}),r=s.layout.get(`icon-text-fit`)!==`none`,a=sw(i,n,S,r),f=o?sw(o,n,S,r):void 0;O=new pw(c,t,l,u,d,i,g,_,!1,n),ee=a.length*4;let p=e.iconSizeData,m=null;p.kind===`source`?(m=[128*s.layout.get(`icon-size`).evaluate(b,{})],m[0]>32640&&It(`${e.layerIds[0]}: Value for "icon-size" is >= 255. Reduce your "icon-size".`)):p.kind===`composite`&&(m=[128*x.compositeIconSizes[0].evaluate(b,{},C),128*x.compositeIconSizes[1].evaluate(b,{},C)],(m[0]>32640||m[1]>32640)&&It(`${e.layerIds[0]}: Value for "icon-size" is >= 255. Reduce your "icon-size".`)),e.addSymbols(e.icon,a,m,y,v,b,0,t,T.lineStartIndex,T.lineLength,-1,C,E),ie=e.icon.placedSymbolArray.length-1,f&&(te=f.length*4,e.addSymbols(e.icon,f,m,y,v,b,2,t,T.lineStartIndex,T.lineLength,-1,C,E),ae=e.icon.placedSymbolArray.length-1)}let ce=Object.keys(r.horizontal);for(let n of ce){let i=r.horizontal[n];D||=(se=(0,ju.default)(i.text),new pw(c,t,l,u,d,i,f,p,m,s.layout.get(`text-rotate`).evaluate(b,{},C)));let o=i.positionedLines.length===1;if(ne+=Ow(e,t,i,a,s,m,b,h,E,T,r.vertical?1:3,o?ce:[n],oe,ie,x,C),o)break}r.vertical&&(re+=Ow(e,t,r.vertical,a,s,m,b,h,E,T,2,[`vertical`],oe,ae,x,C));let le=D?D.boxStartIndex:e.collisionBoxArray.length,ue=D?D.boxEndIndex:e.collisionBoxArray.length,de=k?k.boxStartIndex:e.collisionBoxArray.length,fe=k?k.boxEndIndex:e.collisionBoxArray.length,pe=O?O.boxStartIndex:e.collisionBoxArray.length,me=O?O.boxEndIndex:e.collisionBoxArray.length,he=A?A.boxStartIndex:e.collisionBoxArray.length,ge=A?A.boxEndIndex:e.collisionBoxArray.length,_e=-1,ve=(e,t)=>e?.circleDiameter?Math.max(e.circleDiameter,t):t;_e=ve(D,_e),_e=ve(k,_e),_e=ve(O,_e),_e=ve(A,_e);let ye=+(_e>-1);ye&&(_e*=w/24),e.glyphOffsetArray.length>=xv.MAX_GLYPHS&&It(`Too many glyphs being rendered in a tile. See https://github.com/mapbox/mapbox-gl-js/issues/2907`),b.sortKey!==void 0&&e.addToSortKeyRanges(e.symbolInstances.length,b.sortKey);let be=Cw(s,b,C),[xe,Se]=Dw(e.textAnchorOffsets,be);e.symbolInstances.emplaceBack(t.x,t.y,oe.right>=0?oe.right:-1,oe.center>=0?oe.center:-1,oe.left>=0?oe.left:-1,oe.vertical||-1,ie,ae,se,le,ue,de,fe,pe,me,he,ge,l,ne,re,ee,te,ye,0,f,_e,xe,Se,E)}function jw(e,t,n,r){let i=e.compareText;if(!(t in i))i[t]=[];else{let e=i[t];for(let t=e.length-1;t>=0;t--)if(r.dist(e[t])this._layers[e.id]),n=t[0];if(n.isHidden())continue;let r=n.source||``,i=this.familiesBySource[r];i||=this.familiesBySource[r]={};let a=n.sourceLayer||`_geojsonTileLayer`,o=i[a];o||=i[a]=[],o.push(t)}}},G=class{constructor(e){let t={},n=[];for(let r in e){let i=e[r],a=t[r]={};for(let e in i){let t=i[e];if(!t||t.bitmap.width===0||t.bitmap.height===0)continue;let r={x:0,y:0,w:t.bitmap.width+2,h:t.bitmap.height+2};n.push(r),a[e]={rect:r,metrics:t.metrics}}}let{w:r,h:i}=c(n),a=new d({width:r||1,height:i||1});for(let n in e){let r=e[n];for(let e in r){let i=r[e];if(!i||i.bitmap.width===0||i.bitmap.height===0)continue;let o=t[n][e].rect;d.copy(i.bitmap,a,{x:0,y:0},{x:o.x+1,y:o.y+1},i.bitmap)}}this.image=a,this.positions=t}};I(`GlyphAtlas`,G);var K=class{constructor(e){this.tileID=new T(e.tileID.overscaledZ,e.tileID.wrap,e.tileID.canonical.z,e.tileID.canonical.x,e.tileID.canonical.y),this.uid=e.uid,this.zoom=e.zoom,this.pixelRatio=e.pixelRatio,this.tileSize=e.tileSize,this.source=e.source,this.overscaling=this.tileID.overscaleFactor(),this.showCollisionBoxes=e.showCollisionBoxes,this.collectResourceTiming=!!e.collectResourceTiming,this.returnDependencies=!!e.returnDependencies,this.promoteId=e.promoteId,this.inFlightDependencies=[]}async parse(e,t,n,i,a){this.data=e,this.collisionBoxArray=new _;let o=new S(Object.keys(e.layers).sort()),s=new x(this.tileID,this.promoteId);s.bucketLayerIDs=[];let c={},l={featureIndex:s,iconDependencies:{},patternDependencies:{},glyphDependencies:{},dashDependencies:{},availableImages:n,subdivisionGranularity:a},u=t.familiesBySource[this.source];for(let t in u){let r=e.layers[t];if(!r)continue;r.version===1&&m(`Vector tile source "${this.source}" layer "${t}" does not use vector tile spec v2 and therefore may have some rendering errors.`);let i=o.encode(t),a=[];for(let e=0;ee.id)))}}let d=b(l.glyphDependencies,e=>Object.keys(e));for(let e of this.inFlightDependencies)e?.abort();this.inFlightDependencies=[];let p=Promise.resolve({});if(Object.keys(d).length){let e=new AbortController;this.inFlightDependencies.push(e),p=i.sendAsync({type:`GG`,data:{stacks:d,source:this.source,tileID:this.tileID,type:`glyphs`}},e)}let h=Object.keys(l.iconDependencies),g=Promise.resolve({});if(h.length){let e=new AbortController;this.inFlightDependencies.push(e),g=i.sendAsync({type:`GI`,data:{icons:h,source:this.source,tileID:this.tileID,type:`icons`}},e)}let y=Object.keys(l.patternDependencies),C=Promise.resolve({});if(y.length){let e=new AbortController;this.inFlightDependencies.push(e),C=i.sendAsync({type:`GI`,data:{icons:y,source:this.source,tileID:this.tileID,type:`patterns`}},e)}let w=l.dashDependencies,T=Promise.resolve({});if(Object.keys(w).length){let e=new AbortController;this.inFlightDependencies.push(e),T=i.sendAsync({type:`GDA`,data:{dashes:w}},e)}let[E,D,O,k]=await Promise.all([p,g,C,T]),A=new G(E),j=new f(D,O);for(let e in c){let t=c[e];t instanceof r?(q(t.layers,this.zoom,n),te({bucket:t,glyphMap:E,glyphPositions:A.positions,imageMap:D,imagePositions:j.iconPositions,showCollisionBoxes:this.showCollisionBoxes,canonical:this.tileID.canonical,subdivisionGranularity:l.subdivisionGranularity})):t.hasDependencies&&(t instanceof ee||t instanceof N||t instanceof v)&&(q(t.layers,this.zoom,n),t.addFeatures(l,this.tileID.canonical,j.patternPositions,k))}return{buckets:Object.values(c).filter(e=>!e.isEmpty()),featureIndex:s,collisionBoxArray:this.collisionBoxArray,glyphAtlasImage:A.image,imageAtlas:j,dashPositions:k,glyphMap:this.returnDependencies?E:null,iconMap:this.returnDependencies?D:null,glyphPositions:this.returnDependencies?A.positions:null}}};function q(e,t,n){let r=new P(t);for(let t of e)t.recalculate(r,n)}var J=class{constructor(){this.loading={},this.loaded={},this.parsing={}}startLoading(e,t){this.loading[e]=t}finishLoading(e){delete this.loading[e]}abort(e){let t=this.loading[e];t?.abort&&(t.abort.abort(),delete this.loading[e])}getParsing(e){return this.parsing[e]}setParsing(e,t){this.parsing[e]=t}removeParsing(e){delete this.parsing[e]}markLoaded(e,t){this.loaded[e]=t}getLoaded(e){let t=this.loaded[e];if(t)return t}removeLoaded(e){delete this.loaded[e]}clearLoaded(){this.loaded={}}},Y=class{constructor(e){this.start=`${e}#start`,this.end=`${e}#end`,this.measure=e,performance.mark(this.start)}finish(){performance.mark(this.end);let e=performance.getEntriesByName(this.measure);return e.length===0&&(performance.measure(this.measure,this.start,this.end),e=performance.getEntriesByName(this.measure),performance.clearMarks(this.start),performance.clearMarks(this.end),performance.clearMeasures(this.measure)),e}},ae=class{constructor(e,t,n,r,i){this.type=e,this.properties=n||{},this.extent=i,this.pointsArray=t,this.id=r}loadGeometry(){return this.pointsArray.map(e=>e.map(e=>new n(e.x,e.y)))}},oe=class{constructor(e,t,n){this.version=2,this._myFeatures=e,this.name=t,this.length=e.length,this.extent=n}feature(e){return this._myFeatures[e]}},se=class{constructor(){this.layers={}}addLayer(e){this.layers[e.name]=e}};function ce(e,t,n){let{extent:r}=e,i=2**(n.z-t.z),a=(n.x-t.x*i)*r,o=(n.y-t.y*i)*r,s=[];for(let t=0;t0&&c.addLayer(i)}let u={vectorTile:c,rawData:A(c).buffer};return this.overzoomedTileResultCache.set(o,u),u}async reloadTile(e){let t=e.uid,n=this.tileState.getLoaded(t);if(!n)throw Error(`Should not be trying to reload a tile that was never loaded or has been removed`);if(n.vectorTile)return n.showCollisionBoxes=e.showCollisionBoxes,await this._parseWorkerTile(n,e)}async abortTile(e){this.tileState.abort(e.uid)}async removeTile(e){this.tileState.removeLoaded(e.uid)}},X=class{constructor(){this.loaded={}}async loadTile(e){let{uid:t,encoding:n,rawImageData:r,redFactor:i,greenFactor:a,blueFactor:o,baseShift:s}=e,c=r.width+2,l=r.height+2,u=M(r)?new O({width:c,height:l},await C(r,-1,-1,c,l)):r,d=new g(t,u,n,i,a,o,s);return this.loaded||={},this.loaded[t]=d,d}removeTile(e){let t=this.loaded,n=e.uid;t?.[n]&&delete t[n]}},ue=class{constructor(e,t,n,r=de){this.actor=e,this.layerIndex=t,this.availableImages=n,this.tileState=new J,this._createGeoJSONIndex=r}loadVectorTile(e){if(!this._geoJSONIndex)throw Error(`Unable to parse the data into a cluster or geojson`);let{z:t,x:n,y:r}=e.tileID.canonical,i=this._geoJSONIndex.getTile(t,n,r);if(!i)return null;let a=new re(i.features,{version:2,extent:s});return{vectorTile:a,rawData:A(a,B).buffer}}async loadTile(e){let{uid:t}=e,n=new K(e);n.abort=new AbortController;try{let r=this.loadVectorTile(e);if(!r)return null;let{vectorTile:i,rawData:a}=r;n.vectorTile=i,this.tileState.markLoaded(t,n);let o={rawData:a};return this.tileState.setParsing(t,o),await this._parseWorkerTile(n,e)}catch(e){throw this.tileState.markLoaded(t,n),e}}async _parseWorkerTile(e,t){let n=this.tileState.getParsing(e.uid),r=await e.parse(e.vectorTile,this.layerIndex,this.availableImages,this.actor,t.subdivisionGranularity);if(n){let{rawData:t}=n;r=y({rawTileData:t.slice(0),encoding:`mvt`},r),this.tileState.removeParsing(e.uid)}return r}async abortTile(e){this.tileState.abort(e.uid)}async removeTile(e){this.tileState.removeLoaded(e.uid)}async loadData(e){this._pendingRequest?.abort();let t=this._startRequestTiming(e);this._pendingRequest=new AbortController;try{await this.loadAndProcessGeoJSON(e,this._pendingRequest),delete this._pendingRequest,this.tileState.clearLoaded();let n={};return e.request&&(n.data=e.data),this._finishRequestTiming(t,e,n),n}catch(e){if(delete this._pendingRequest,!l(e))throw e;return{abandoned:!0}}}_startRequestTiming(e){if(e.request?.collectResourceTiming)return new Y(e.request.url)}_finishRequestTiming(e,t,n){let r=e?.finish();r&&(n.resourceTiming={[t.source]:JSON.parse(JSON.stringify(r))})}async reloadTile(e){let t=e.uid,n=this.tileState.getLoaded(t);if(!n)return await this.loadTile(e);if(n.vectorTile)return n.showCollisionBoxes=e.showCollisionBoxes,await this._parseWorkerTile(n,e)}async loadAndProcessGeoJSON(e,t){if(e.request&&(e.data=(await i(e.request,t)).data),e.data){e.data=this._filterGeoJSON(e.data,e.filter,e.source),this._geoJSONIndex=this._createGeoJSONIndex(e.data,e);return}if(e.dataDiff){this._geoJSONIndex??=this._createGeoJSONIndex({type:`FeatureCollection`,features:[]},e),this._geoJSONIndex.updateData(e.dataDiff,this._getFilterPredicate(e.filter,e.source));return}if(e.updateCluster&&this._geoJSONIndex.updateClusterOptions(e.geojsonVtOptions.cluster,Z(e)),this._geoJSONIndex==null)throw Error(`Input data given to '${e.source}' is not a valid GeoJSON object.`)}_filterGeoJSON(e,t,n){if(e.type!==`FeatureCollection`)return e;let r=this._getFilterPredicate(t,n);return r?{type:`FeatureCollection`,features:e.features.filter(e=>r(e))}:e}_getFilterPredicate(e,t){if(typeof e!=`boolean`&&!e?.length)return;let n=j(e,`sources.${t}.filter`,{type:`boolean`,"property-type":`data-driven`,overridable:!1,transition:!1});if(n.result===`error`)throw Error(n.value.map(e=>`${e.key}: ${e.message}`).join(`, `));return e=>n.value.evaluate({zoom:0},e)}async removeSource(e){this._pendingRequest?.abort()}getClusterExpansionZoom(e){return this._geoJSONIndex.getClusterExpansionZoom(e.clusterId)}getClusterChildren(e){return this._geoJSONIndex.getClusterChildren(e.clusterId)}getClusterLeaves(e){return this._geoJSONIndex.getClusterLeaves(e.clusterId,e.limit,e.offset)}};function de(e,t){let n=y(t.geojsonVtOptions||{},{updateable:!0,clusterOptions:Z(t)});return new o(e,n)}function Z({geojsonVtOptions:e,clusterProperties:t,source:n}){if(!t||!e.clusterOptions)return e.clusterOptions;let r={},i={},a={accumulated:null,zoom:0},o={properties:null},s=Object.keys(t);for(let e of s){let[a,o]=t[e],s=j(o,`sources.${n}.clusterProperties.${e}[1]`),c=j(typeof a==`string`?[a,[`accumulated`],[`get`,e]]:a,`sources.${n}.clusterProperties.${e}[0]`);r[e]=s.value,i[e]=c.value}return e.clusterOptions.map=e=>{o.properties=e;let t={};for(let e of s)t[e]=r[e].evaluate(a,o);return t},e.clusterOptions.reduce=(e,t)=>{o.properties=t;for(let t of s)a.accumulated=e[t],e[t]=i[t].evaluate(a,o)},e.clusterOptions}async function Q(e){if(e.endsWith(`.mjs`)){await import(e);return}let t=await fetch(e,{credentials:`same-origin`});if(!t.ok)throw Error(`Failed to load ${e}: ${t.status}`);let n=await t.text();if(/^[ \t]*(import|export)\s/m.test(n)){let e=URL.createObjectURL(new Blob([n],{type:`text/javascript`}));try{await import(e)}finally{URL.revokeObjectURL(e)}return}globalThis.eval(n)}var $=class{constructor(t){this.self=t,this.actor=new R(t),this.layerIndexes={},this.availableImages={},this.workerSources={},this.demWorkerSources={},this.externalWorkerSourceTypes={},this.globalStates=new Map,this.self.registerWorkerSource=(e,t)=>{if(this.externalWorkerSourceTypes[e])throw Error(`Worker source with name "${e}" already registered.`);this.externalWorkerSourceTypes[e]=t},this.self.addProtocol=u,this.self.removeProtocol=p,this.self.registerRTLTextPlugin=e=>{D.setMethods(e)},this.self.makeRequest=e,this.actor.registerMessageHandler(`LDT`,(e,t)=>this._getDEMWorkerSource(e,t.source).loadTile(t)),this.actor.registerMessageHandler(`RDT`,async(e,t)=>{this._getDEMWorkerSource(e,t.source).removeTile(t)}),this.actor.registerMessageHandler(`GCEZ`,async(e,t)=>this._getWorkerSource(e,t.type,t.source).getClusterExpansionZoom(t)),this.actor.registerMessageHandler(`GCC`,async(e,t)=>this._getWorkerSource(e,t.type,t.source).getClusterChildren(t)),this.actor.registerMessageHandler(`GCL`,async(e,t)=>this._getWorkerSource(e,t.type,t.source).getClusterLeaves(t)),this.actor.registerMessageHandler(`LD`,(e,t)=>this._getWorkerSource(e,t.type,t.source).loadData(t)),this.actor.registerMessageHandler(`LT`,(e,t)=>this._getWorkerSource(e,t.type,t.source).loadTile(t)),this.actor.registerMessageHandler(`RT`,(e,t)=>this._getWorkerSource(e,t.type,t.source).reloadTile(t)),this.actor.registerMessageHandler(`AT`,(e,t)=>this._getWorkerSource(e,t.type,t.source).abortTile(t)),this.actor.registerMessageHandler(`RMT`,(e,t)=>this._getWorkerSource(e,t.type,t.source).removeTile(t)),this.actor.registerMessageHandler(`RS`,async(e,t)=>{if(!this.workerSources[e]?.[t.type]?.[t.source])return;let n=this.workerSources[e][t.type][t.source];delete this.workerSources[e][t.type][t.source],n.removeSource!==void 0&&n.removeSource(t)}),this.actor.registerMessageHandler(`RM`,async e=>{delete this.layerIndexes[e],delete this.availableImages[e],delete this.workerSources[e],delete this.demWorkerSources[e],this.globalStates.delete(e)}),this.actor.registerMessageHandler(`SR`,async(e,t)=>{this.referrer=t}),this.actor.registerMessageHandler(`SRPS`,(e,t)=>this._syncRTLPluginState(e,t)),this.actor.registerMessageHandler(`IS`,async(e,t)=>{await Q(t)}),this.actor.registerMessageHandler(`SI`,(e,t)=>this._setImages(e,t)),this.actor.registerMessageHandler(`UL`,async(e,t)=>{this._getLayerIndex(e).update(t.layers,t.removedIds,this._getGlobalState(e))}),this.actor.registerMessageHandler(`UGS`,async(e,t)=>{let n=this._getGlobalState(e);for(let e in t)n[e]=t[e]}),this.actor.registerMessageHandler(`SL`,async(e,t)=>{this._getLayerIndex(e).replace(t,this._getGlobalState(e))})}_getGlobalState(e){let t=this.globalStates.get(e);return t||(t={},this.globalStates.set(e,t)),t}async _setImages(e,t){this.availableImages[e]=t;for(let n in this.workerSources[e]){let r=this.workerSources[e][n];for(let e in r)r[e].availableImages=t}}async _syncRTLPluginState(e,t){return await D.syncState(t,Q)}_getAvailableImages(e){let t=this.availableImages[e];return t||=[],t}_getLayerIndex(e){let t=this.layerIndexes[e];return t||=this.layerIndexes[e]=new W,t}_getWorkerSource(e,t,n){if(this.workerSources[e]||={},this.workerSources[e][t]||={},!this.workerSources[e][t][n]){let r={sendAsync:(t,n)=>(t.targetMapId=e,this.actor.sendAsync(t,n))};switch(t){case`vector`:this.workerSources[e][t][n]=new le(r,this._getLayerIndex(e),this._getAvailableImages(e));break;case`geojson`:this.workerSources[e][t][n]=new ue(r,this._getLayerIndex(e),this._getAvailableImages(e));break;default:this.workerSources[e][t][n]=new this.externalWorkerSourceTypes[t](r,this._getLayerIndex(e),this._getAvailableImages(e))}}return this.workerSources[e][t][n]}_getDEMWorkerSource(e,t){return this.demWorkerSources[e]||={},this.demWorkerSources[e][t]||=new X,this.demWorkerSources[e][t]}};L(self)&&(self.worker=new $(self));export{$ as default};
+//# sourceMappingURL=maplibre-gl-worker.mjs.map
\ No newline at end of file
diff --git a/web/vendor/maplibre/maplibre-gl.css b/web/vendor/maplibre/maplibre-gl.css
new file mode 100644
index 000000000..2c85b53a0
--- /dev/null
+++ b/web/vendor/maplibre/maplibre-gl.css
@@ -0,0 +1 @@
+.maplibregl-map{font:12px/20px Helvetica Neue,Arial,Helvetica,sans-serif;overflow:hidden;position:relative;-webkit-tap-highlight-color:rgb(0 0 0/0)}.maplibregl-canvas{position:absolute;left:0;top:0}.maplibregl-map:fullscreen{width:100%;height:100%}.maplibregl-ctrl-group button.maplibregl-ctrl-compass{touch-action:none}.maplibregl-canvas-container.maplibregl-interactive,.maplibregl-ctrl-group button.maplibregl-ctrl-compass{cursor:grab;-webkit-user-select:none;-moz-user-select:none;user-select:none}.maplibregl-canvas-container.maplibregl-interactive.maplibregl-track-pointer{cursor:pointer}.maplibregl-canvas-container.maplibregl-interactive:active,.maplibregl-ctrl-group button.maplibregl-ctrl-compass:active{cursor:grabbing}.maplibregl-canvas-container.maplibregl-touch-zoom-rotate,.maplibregl-canvas-container.maplibregl-touch-zoom-rotate .maplibregl-canvas{touch-action:pan-x pan-y}.maplibregl-canvas-container.maplibregl-touch-drag-pan,.maplibregl-canvas-container.maplibregl-touch-drag-pan .maplibregl-canvas{touch-action:pinch-zoom}.maplibregl-canvas-container.maplibregl-touch-zoom-rotate.maplibregl-touch-drag-pan,.maplibregl-canvas-container.maplibregl-touch-zoom-rotate.maplibregl-touch-drag-pan .maplibregl-canvas{touch-action:none}.maplibregl-canvas-container.maplibregl-touch-drag-pan.maplibregl-cooperative-gestures,.maplibregl-canvas-container.maplibregl-touch-drag-pan.maplibregl-cooperative-gestures .maplibregl-canvas{touch-action:pan-x pan-y}.maplibregl-ctrl-bottom-left,.maplibregl-ctrl-bottom-right,.maplibregl-ctrl-top-left,.maplibregl-ctrl-top-right{position:absolute;pointer-events:none;z-index:2}.maplibregl-ctrl-top-left{top:0;left:0}.maplibregl-ctrl-top-right{top:0;right:0}.maplibregl-ctrl-bottom-left{bottom:0;left:0}.maplibregl-ctrl-bottom-right{right:0;bottom:0}.maplibregl-ctrl{clear:both;pointer-events:auto;transform:translate(0)}.maplibregl-ctrl-top-left .maplibregl-ctrl{margin:10px 0 0 10px;float:left}.maplibregl-ctrl-top-right .maplibregl-ctrl{margin:10px 10px 0 0;float:right}.maplibregl-ctrl-bottom-left .maplibregl-ctrl{margin:0 0 10px 10px;float:left}.maplibregl-ctrl-bottom-right .maplibregl-ctrl{margin:0 10px 10px 0;float:right}.maplibregl-ctrl-group{border-radius:4px;background:#fff}.maplibregl-ctrl-group:not(:empty){box-shadow:0 0 0 2px rgba(0,0,0,.1)}@media (forced-colors:active){.maplibregl-ctrl-group:not(:empty){box-shadow:0 0 0 2px ButtonText}}.maplibregl-ctrl-group button{width:29px;height:29px;display:block;padding:0;outline:none;border:0;box-sizing:border-box;background-color:transparent;cursor:pointer}.maplibregl-ctrl-group button+button{border-top:1px solid #ddd}.maplibregl-ctrl button .maplibregl-ctrl-icon{display:block;width:100%;height:100%;background-repeat:no-repeat;background-position:50%}@media (forced-colors:active){.maplibregl-ctrl-icon{background-color:transparent}.maplibregl-ctrl-group button+button{border-top:1px solid ButtonText}}.maplibregl-ctrl button::-moz-focus-inner{border:0;padding:0}.maplibregl-ctrl-attrib-button:focus,.maplibregl-ctrl-group button:focus{box-shadow:0 0 2px 2px #0096ff}.maplibregl-ctrl button:disabled{cursor:not-allowed}.maplibregl-ctrl button:disabled .maplibregl-ctrl-icon{opacity:.25}@media (hover:hover){.maplibregl-ctrl button:not(:disabled):hover{background-color:rgba(0,0,0,.05)}}.maplibregl-ctrl button:not(:disabled):active{background-color:rgba(0,0,0,.05)}.maplibregl-ctrl-group button:focus:focus-visible{box-shadow:0 0 2px 2px #0096ff}.maplibregl-ctrl-group button:focus:not(:focus-visible){box-shadow:none}.maplibregl-ctrl-group button:focus:first-child{border-radius:4px 4px 0 0}.maplibregl-ctrl-group button:focus:last-child{border-radius:0 0 4px 4px}.maplibregl-ctrl-group button:focus:only-child{border-radius:inherit}.maplibregl-ctrl button.maplibregl-ctrl-zoom-out .maplibregl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2229%22%20height%3D%2229%22%20fill%3D%22%23333%22%20viewBox%3D%220%200%2029%2029%22%3E%3Cpath%20d%3D%22M10%2013c-.75%200-1.5.75-1.5%201.5S9.25%2016%2010%2016h9c.75%200%201.5-.75%201.5-1.5S19.75%2013%2019%2013z%22%2F%3E%3C%2Fsvg%3E")}.maplibregl-ctrl button.maplibregl-ctrl-zoom-in .maplibregl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2229%22%20height%3D%2229%22%20fill%3D%22%23333%22%20viewBox%3D%220%200%2029%2029%22%3E%3Cpath%20d%3D%22M14.5%208.5c-.75%200-1.5.75-1.5%201.5v3h-3c-.75%200-1.5.75-1.5%201.5S9.25%2016%2010%2016h3v3c0%20.75.75%201.5%201.5%201.5S16%2019.75%2016%2019v-3h3c.75%200%201.5-.75%201.5-1.5S19.75%2013%2019%2013h-3v-3c0-.75-.75-1.5-1.5-1.5%22%2F%3E%3C%2Fsvg%3E")}@media (forced-colors:active){.maplibregl-ctrl button.maplibregl-ctrl-zoom-out .maplibregl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2229%22%20height%3D%2229%22%20fill%3D%22%23fff%22%20viewBox%3D%220%200%2029%2029%22%3E%3Cpath%20d%3D%22M10%2013c-.75%200-1.5.75-1.5%201.5S9.25%2016%2010%2016h9c.75%200%201.5-.75%201.5-1.5S19.75%2013%2019%2013z%22%2F%3E%3C%2Fsvg%3E")}.maplibregl-ctrl button.maplibregl-ctrl-zoom-in .maplibregl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2229%22%20height%3D%2229%22%20fill%3D%22%23fff%22%20viewBox%3D%220%200%2029%2029%22%3E%3Cpath%20d%3D%22M14.5%208.5c-.75%200-1.5.75-1.5%201.5v3h-3c-.75%200-1.5.75-1.5%201.5S9.25%2016%2010%2016h3v3c0%20.75.75%201.5%201.5%201.5S16%2019.75%2016%2019v-3h3c.75%200%201.5-.75%201.5-1.5S19.75%2013%2019%2013h-3v-3c0-.75-.75-1.5-1.5-1.5%22%2F%3E%3C%2Fsvg%3E")}}@media (forced-colors:active) and (prefers-color-scheme:light){.maplibregl-ctrl button.maplibregl-ctrl-zoom-out .maplibregl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2229%22%20height%3D%2229%22%20viewBox%3D%220%200%2029%2029%22%3E%3Cpath%20d%3D%22M10%2013c-.75%200-1.5.75-1.5%201.5S9.25%2016%2010%2016h9c.75%200%201.5-.75%201.5-1.5S19.75%2013%2019%2013z%22%2F%3E%3C%2Fsvg%3E")}.maplibregl-ctrl button.maplibregl-ctrl-zoom-in .maplibregl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2229%22%20height%3D%2229%22%20viewBox%3D%220%200%2029%2029%22%3E%3Cpath%20d%3D%22M14.5%208.5c-.75%200-1.5.75-1.5%201.5v3h-3c-.75%200-1.5.75-1.5%201.5S9.25%2016%2010%2016h3v3c0%20.75.75%201.5%201.5%201.5S16%2019.75%2016%2019v-3h3c.75%200%201.5-.75%201.5-1.5S19.75%2013%2019%2013h-3v-3c0-.75-.75-1.5-1.5-1.5%22%2F%3E%3C%2Fsvg%3E")}}.maplibregl-ctrl button.maplibregl-ctrl-fullscreen .maplibregl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2229%22%20height%3D%2229%22%20fill%3D%22%23333%22%20viewBox%3D%220%200%2029%2029%22%3E%3Cpath%20d%3D%22M24%2016v5.5c0%201.75-.75%202.5-2.5%202.5H16v-1l3-1.5-4-5.5%201-1%205.5%204%201.5-3zM6%2016l1.5%203%205.5-4%201%201-4%205.5%203%201.5v1H7.5C5.75%2024%205%2023.25%205%2021.5V16zm7-11v1l-3%201.5%204%205.5-1%201-5.5-4L6%2013H5V7.5C5%205.75%205.75%205%207.5%205zm11%202.5c0-1.75-.75-2.5-2.5-2.5H16v1l3%201.5-4%205.5%201%201%205.5-4%201.5%203h1z%22%2F%3E%3C%2Fsvg%3E")}.maplibregl-ctrl button.maplibregl-ctrl-shrink .maplibregl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2229%22%20height%3D%2229%22%20viewBox%3D%220%200%2029%2029%22%3E%3Cpath%20d%3D%22M18.5%2016c-1.75%200-2.5.75-2.5%202.5V24h1l1.5-3%205.5%204%201-1-4-5.5%203-1.5v-1zM13%2018.5c0-1.75-.75-2.5-2.5-2.5H5v1l3%201.5L4%2024l1%201%205.5-4%201.5%203h1zm3-8c0%201.75.75%202.5%202.5%202.5H24v-1l-3-1.5L25%205l-1-1-5.5%204L17%205h-1zM10.5%2013c1.75%200%202.5-.75%202.5-2.5V5h-1l-1.5%203L5%204%204%205l4%205.5L5%2012v1z%22%2F%3E%3C%2Fsvg%3E")}@media (forced-colors:active){.maplibregl-ctrl button.maplibregl-ctrl-fullscreen .maplibregl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2229%22%20height%3D%2229%22%20fill%3D%22%23fff%22%20viewBox%3D%220%200%2029%2029%22%3E%3Cpath%20d%3D%22M24%2016v5.5c0%201.75-.75%202.5-2.5%202.5H16v-1l3-1.5-4-5.5%201-1%205.5%204%201.5-3zM6%2016l1.5%203%205.5-4%201%201-4%205.5%203%201.5v1H7.5C5.75%2024%205%2023.25%205%2021.5V16zm7-11v1l-3%201.5%204%205.5-1%201-5.5-4L6%2013H5V7.5C5%205.75%205.75%205%207.5%205zm11%202.5c0-1.75-.75-2.5-2.5-2.5H16v1l3%201.5-4%205.5%201%201%205.5-4%201.5%203h1z%22%2F%3E%3C%2Fsvg%3E")}.maplibregl-ctrl button.maplibregl-ctrl-shrink .maplibregl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2229%22%20height%3D%2229%22%20fill%3D%22%23fff%22%20viewBox%3D%220%200%2029%2029%22%3E%3Cpath%20d%3D%22M18.5%2016c-1.75%200-2.5.75-2.5%202.5V24h1l1.5-3%205.5%204%201-1-4-5.5%203-1.5v-1zM13%2018.5c0-1.75-.75-2.5-2.5-2.5H5v1l3%201.5L4%2024l1%201%205.5-4%201.5%203h1zm3-8c0%201.75.75%202.5%202.5%202.5H24v-1l-3-1.5L25%205l-1-1-5.5%204L17%205h-1zM10.5%2013c1.75%200%202.5-.75%202.5-2.5V5h-1l-1.5%203L5%204%204%205l4%205.5L5%2012v1z%22%2F%3E%3C%2Fsvg%3E")}}@media (forced-colors:active) and (prefers-color-scheme:light){.maplibregl-ctrl button.maplibregl-ctrl-fullscreen .maplibregl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2229%22%20height%3D%2229%22%20viewBox%3D%220%200%2029%2029%22%3E%3Cpath%20d%3D%22M24%2016v5.5c0%201.75-.75%202.5-2.5%202.5H16v-1l3-1.5-4-5.5%201-1%205.5%204%201.5-3zM6%2016l1.5%203%205.5-4%201%201-4%205.5%203%201.5v1H7.5C5.75%2024%205%2023.25%205%2021.5V16zm7-11v1l-3%201.5%204%205.5-1%201-5.5-4L6%2013H5V7.5C5%205.75%205.75%205%207.5%205zm11%202.5c0-1.75-.75-2.5-2.5-2.5H16v1l3%201.5-4%205.5%201%201%205.5-4%201.5%203h1z%22%2F%3E%3C%2Fsvg%3E")}.maplibregl-ctrl button.maplibregl-ctrl-shrink .maplibregl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2229%22%20height%3D%2229%22%20viewBox%3D%220%200%2029%2029%22%3E%3Cpath%20d%3D%22M18.5%2016c-1.75%200-2.5.75-2.5%202.5V24h1l1.5-3%205.5%204%201-1-4-5.5%203-1.5v-1zM13%2018.5c0-1.75-.75-2.5-2.5-2.5H5v1l3%201.5L4%2024l1%201%205.5-4%201.5%203h1zm3-8c0%201.75.75%202.5%202.5%202.5H24v-1l-3-1.5L25%205l-1-1-5.5%204L17%205h-1zM10.5%2013c1.75%200%202.5-.75%202.5-2.5V5h-1l-1.5%203L5%204%204%205l4%205.5L5%2012v1z%22%2F%3E%3C%2Fsvg%3E")}}.maplibregl-ctrl button.maplibregl-ctrl-compass .maplibregl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2229%22%20height%3D%2229%22%20fill%3D%22%23333%22%20viewBox%3D%220%200%2029%2029%22%3E%3Cpath%20d%3D%22m10.5%2014%204-8%204%208z%22%2F%3E%3Cpath%20fill%3D%22%23ccc%22%20d%3D%22m10.5%2016%204%208%204-8z%22%2F%3E%3C%2Fsvg%3E")}@media (forced-colors:active){.maplibregl-ctrl button.maplibregl-ctrl-compass .maplibregl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2229%22%20height%3D%2229%22%20fill%3D%22%23fff%22%20viewBox%3D%220%200%2029%2029%22%3E%3Cpath%20d%3D%22m10.5%2014%204-8%204%208z%22%2F%3E%3Cpath%20fill%3D%22%23ccc%22%20d%3D%22m10.5%2016%204%208%204-8z%22%2F%3E%3C%2Fsvg%3E")}}@media (forced-colors:active) and (prefers-color-scheme:light){.maplibregl-ctrl button.maplibregl-ctrl-compass .maplibregl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2229%22%20height%3D%2229%22%20viewBox%3D%220%200%2029%2029%22%3E%3Cpath%20d%3D%22m10.5%2014%204-8%204%208z%22%2F%3E%3Cpath%20fill%3D%22%23ccc%22%20d%3D%22m10.5%2016%204%208%204-8z%22%2F%3E%3C%2Fsvg%3E")}}.maplibregl-ctrl button.maplibregl-ctrl-globe .maplibregl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2222%22%20height%3D%2222%22%20fill%3D%22none%22%20stroke%3D%22%23333%22%20viewBox%3D%220%200%2022%2022%22%3E%3Ccircle%20cx%3D%2211%22%20cy%3D%2211%22%20r%3D%228.5%22%2F%3E%3Cpath%20d%3D%22M17.5%2011c0%204.819-3.02%208.5-6.5%208.5S4.5%2015.819%204.5%2011%207.52%202.5%2011%202.5s6.5%203.681%206.5%208.5Z%22%2F%3E%3Cpath%20d%3D%22M13.5%2011c0%202.447-.331%204.64-.853%206.206-.262.785-.562%201.384-.872%201.777-.314.399-.58.517-.775.517s-.461-.118-.775-.517c-.31-.393-.61-.992-.872-1.777C8.831%2015.64%208.5%2013.446%208.5%2011s.331-4.64.853-6.206c.262-.785.562-1.384.872-1.777.314-.399.58-.517.775-.517s.461.118.775.517c.31.393.61.992.872%201.777.522%201.565.853%203.76.853%206.206Z%22%2F%3E%3Cpath%20d%3D%22M11%207.5c-1.909%200-3.622-.166-4.845-.428-.616-.132-1.08-.283-1.379-.434a1.3%201.3%200%200%201-.224-.138q.07-.058.224-.138c.299-.151.763-.302%201.379-.434C7.378%205.666%209.091%205.5%2011%205.5s3.622.166%204.845.428c.616.132%201.08.283%201.379.434.105.053.177.1.224.138q-.07.058-.224.138c-.299.151-.763.302-1.379.434-1.223.262-2.936.428-4.845.428Zm0%209c-1.909%200-3.622-.166-4.845-.428-.616-.132-1.08-.283-1.379-.434a1.3%201.3%200%200%201-.224-.138%201.3%201.3%200%200%201%20.224-.138c.299-.151.763-.302%201.379-.434C7.378%2014.666%209.091%2014.5%2011%2014.5s3.622.166%204.845.428c.616.132%201.08.283%201.379.434.105.053.177.1.224.138a1.3%201.3%200%200%201-.224.138c-.299.151-.763.302-1.379.434-1.223.262-2.936.428-4.845.428Zm0-4c-2.46%200-4.672-.222-6.255-.574-.796-.177-1.406-.38-1.805-.59a1.5%201.5%200%200%201-.39-.272.3.3%200%200%201-.047-.064.3.3%200%200%201%20.048-.064c.066-.073.189-.167.389-.272.399-.21%201.009-.413%201.805-.59C6.328%209.722%208.54%209.5%2011%209.5s4.672.222%206.256.574c.795.177%201.405.38%201.804.59.2.105.323.2.39.272a.3.3%200%200%201%20.047.064.3.3%200%200%201-.048.064%201.4%201.4%200%200%201-.389.272c-.399.21-1.009.413-1.804.59-1.584.352-3.796.574-6.256.574Zm-8.501-1.51v.002zm0%20.018v.002zm17.002.002v-.002zm0-.018v-.002z%22%2F%3E%3C%2Fsvg%3E")}.maplibregl-ctrl button.maplibregl-ctrl-globe-enabled .maplibregl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2222%22%20height%3D%2222%22%20fill%3D%22none%22%20stroke%3D%22%2333b5e5%22%20viewBox%3D%220%200%2022%2022%22%3E%3Ccircle%20cx%3D%2211%22%20cy%3D%2211%22%20r%3D%228.5%22%2F%3E%3Cpath%20d%3D%22M17.5%2011c0%204.819-3.02%208.5-6.5%208.5S4.5%2015.819%204.5%2011%207.52%202.5%2011%202.5s6.5%203.681%206.5%208.5Z%22%2F%3E%3Cpath%20d%3D%22M13.5%2011c0%202.447-.331%204.64-.853%206.206-.262.785-.562%201.384-.872%201.777-.314.399-.58.517-.775.517s-.461-.118-.775-.517c-.31-.393-.61-.992-.872-1.777C8.831%2015.64%208.5%2013.446%208.5%2011s.331-4.64.853-6.206c.262-.785.562-1.384.872-1.777.314-.399.58-.517.775-.517s.461.118.775.517c.31.393.61.992.872%201.777.522%201.565.853%203.76.853%206.206Z%22%2F%3E%3Cpath%20d%3D%22M11%207.5c-1.909%200-3.622-.166-4.845-.428-.616-.132-1.08-.283-1.379-.434a1.3%201.3%200%200%201-.224-.138q.07-.058.224-.138c.299-.151.763-.302%201.379-.434C7.378%205.666%209.091%205.5%2011%205.5s3.622.166%204.845.428c.616.132%201.08.283%201.379.434.105.053.177.1.224.138q-.07.058-.224.138c-.299.151-.763.302-1.379.434-1.223.262-2.936.428-4.845.428Zm0%209c-1.909%200-3.622-.166-4.845-.428-.616-.132-1.08-.283-1.379-.434a1.3%201.3%200%200%201-.224-.138%201.3%201.3%200%200%201%20.224-.138c.299-.151.763-.302%201.379-.434C7.378%2014.666%209.091%2014.5%2011%2014.5s3.622.166%204.845.428c.616.132%201.08.283%201.379.434.105.053.177.1.224.138a1.3%201.3%200%200%201-.224.138c-.299.151-.763.302-1.379.434-1.223.262-2.936.428-4.845.428Zm0-4c-2.46%200-4.672-.222-6.255-.574-.796-.177-1.406-.38-1.805-.59a1.5%201.5%200%200%201-.39-.272.3.3%200%200%201-.047-.064.3.3%200%200%201%20.048-.064c.066-.073.189-.167.389-.272.399-.21%201.009-.413%201.805-.59C6.328%209.722%208.54%209.5%2011%209.5s4.672.222%206.256.574c.795.177%201.405.38%201.804.59.2.105.323.2.39.272a.3.3%200%200%201%20.047.064.3.3%200%200%201-.048.064%201.4%201.4%200%200%201-.389.272c-.399.21-1.009.413-1.804.59-1.584.352-3.796.574-6.256.574Zm-8.501-1.51v.002zm0%20.018v.002zm17.002.002v-.002zm0-.018v-.002z%22%2F%3E%3C%2Fsvg%3E")}.maplibregl-ctrl button.maplibregl-ctrl-terrain .maplibregl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2222%22%20height%3D%2222%22%20fill%3D%22%23333%22%20viewBox%3D%220%200%2022%2022%22%3E%3Cpath%20d%3D%22m1.754%2013.406%204.453-4.851%203.09%203.09%203.281%203.277.969-.969-3.309-3.312%203.844-4.121%206.148%206.886h1.082v-.855l-7.207-8.07-4.84%205.187L6.169%206.57l-5.48%205.965v.871ZM.688%2016.844h20.625v1.375H.688Zm0%200%22%2F%3E%3C%2Fsvg%3E")}.maplibregl-ctrl button.maplibregl-ctrl-terrain-enabled .maplibregl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2222%22%20height%3D%2222%22%20fill%3D%22%2333b5e5%22%20viewBox%3D%220%200%2022%2022%22%3E%3Cpath%20d%3D%22m1.754%2013.406%204.453-4.851%203.09%203.09%203.281%203.277.969-.969-3.309-3.312%203.844-4.121%206.148%206.886h1.082v-.855l-7.207-8.07-4.84%205.187L6.169%206.57l-5.48%205.965v.871ZM.688%2016.844h20.625v1.375H.688Zm0%200%22%2F%3E%3C%2Fsvg%3E")}.maplibregl-ctrl button.maplibregl-ctrl-geolocate .maplibregl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2229%22%20height%3D%2229%22%20fill%3D%22%23333%22%20viewBox%3D%220%200%2020%2020%22%3E%3Cpath%20d%3D%22M10%204C9%204%209%205%209%205v.1A5%205%200%200%200%205.1%209H5s-1%200-1%201%201%201%201%201h.1A5%205%200%200%200%209%2014.9v.1s0%201%201%201%201-1%201-1v-.1a5%205%200%200%200%203.9-3.9h.1s1%200%201-1-1-1-1-1h-.1A5%205%200%200%200%2011%205.1V5s0-1-1-1m0%202.5a3.5%203.5%200%201%201%200%207%203.5%203.5%200%201%201%200-7%22%2F%3E%3Ccircle%20cx%3D%2210%22%20cy%3D%2210%22%20r%3D%222%22%2F%3E%3C%2Fsvg%3E")}.maplibregl-ctrl button.maplibregl-ctrl-geolocate:disabled .maplibregl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2229%22%20height%3D%2229%22%20fill%3D%22%23aaa%22%20viewBox%3D%220%200%2020%2020%22%3E%3Cpath%20d%3D%22M10%204C9%204%209%205%209%205v.1A5%205%200%200%200%205.1%209H5s-1%200-1%201%201%201%201%201h.1A5%205%200%200%200%209%2014.9v.1s0%201%201%201%201-1%201-1v-.1a5%205%200%200%200%203.9-3.9h.1s1%200%201-1-1-1-1-1h-.1A5%205%200%200%200%2011%205.1V5s0-1-1-1m0%202.5a3.5%203.5%200%201%201%200%207%203.5%203.5%200%201%201%200-7%22%2F%3E%3Ccircle%20cx%3D%2210%22%20cy%3D%2210%22%20r%3D%222%22%2F%3E%3Cpath%20fill%3D%22red%22%20d%3D%22m14%205%201%201-9%209-1-1z%22%2F%3E%3C%2Fsvg%3E")}.maplibregl-ctrl button.maplibregl-ctrl-geolocate.maplibregl-ctrl-geolocate-active .maplibregl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2229%22%20height%3D%2229%22%20fill%3D%22%2333b5e5%22%20viewBox%3D%220%200%2020%2020%22%3E%3Cpath%20d%3D%22M10%204C9%204%209%205%209%205v.1A5%205%200%200%200%205.1%209H5s-1%200-1%201%201%201%201%201h.1A5%205%200%200%200%209%2014.9v.1s0%201%201%201%201-1%201-1v-.1a5%205%200%200%200%203.9-3.9h.1s1%200%201-1-1-1-1-1h-.1A5%205%200%200%200%2011%205.1V5s0-1-1-1m0%202.5a3.5%203.5%200%201%201%200%207%203.5%203.5%200%201%201%200-7%22%2F%3E%3Ccircle%20cx%3D%2210%22%20cy%3D%2210%22%20r%3D%222%22%2F%3E%3C%2Fsvg%3E")}.maplibregl-ctrl button.maplibregl-ctrl-geolocate.maplibregl-ctrl-geolocate-active-error .maplibregl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2229%22%20height%3D%2229%22%20fill%3D%22%23e58978%22%20viewBox%3D%220%200%2020%2020%22%3E%3Cpath%20d%3D%22M10%204C9%204%209%205%209%205v.1A5%205%200%200%200%205.1%209H5s-1%200-1%201%201%201%201%201h.1A5%205%200%200%200%209%2014.9v.1s0%201%201%201%201-1%201-1v-.1a5%205%200%200%200%203.9-3.9h.1s1%200%201-1-1-1-1-1h-.1A5%205%200%200%200%2011%205.1V5s0-1-1-1m0%202.5a3.5%203.5%200%201%201%200%207%203.5%203.5%200%201%201%200-7%22%2F%3E%3Ccircle%20cx%3D%2210%22%20cy%3D%2210%22%20r%3D%222%22%2F%3E%3C%2Fsvg%3E")}.maplibregl-ctrl button.maplibregl-ctrl-geolocate.maplibregl-ctrl-geolocate-background .maplibregl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2229%22%20height%3D%2229%22%20fill%3D%22%2333b5e5%22%20viewBox%3D%220%200%2020%2020%22%3E%3Cpath%20d%3D%22M10%204C9%204%209%205%209%205v.1A5%205%200%200%200%205.1%209H5s-1%200-1%201%201%201%201%201h.1A5%205%200%200%200%209%2014.9v.1s0%201%201%201%201-1%201-1v-.1a5%205%200%200%200%203.9-3.9h.1s1%200%201-1-1-1-1-1h-.1A5%205%200%200%200%2011%205.1V5s0-1-1-1m0%202.5a3.5%203.5%200%201%201%200%207%203.5%203.5%200%201%201%200-7%22%2F%3E%3C%2Fsvg%3E")}.maplibregl-ctrl button.maplibregl-ctrl-geolocate.maplibregl-ctrl-geolocate-background-error .maplibregl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2229%22%20height%3D%2229%22%20fill%3D%22%23e54e33%22%20viewBox%3D%220%200%2020%2020%22%3E%3Cpath%20d%3D%22M10%204C9%204%209%205%209%205v.1A5%205%200%200%200%205.1%209H5s-1%200-1%201%201%201%201%201h.1A5%205%200%200%200%209%2014.9v.1s0%201%201%201%201-1%201-1v-.1a5%205%200%200%200%203.9-3.9h.1s1%200%201-1-1-1-1-1h-.1A5%205%200%200%200%2011%205.1V5s0-1-1-1m0%202.5a3.5%203.5%200%201%201%200%207%203.5%203.5%200%201%201%200-7%22%2F%3E%3C%2Fsvg%3E")}.maplibregl-ctrl button.maplibregl-ctrl-geolocate.maplibregl-ctrl-geolocate-waiting .maplibregl-ctrl-icon{animation:maplibregl-spin 2s linear infinite}@media (forced-colors:active){.maplibregl-ctrl button.maplibregl-ctrl-geolocate .maplibregl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2229%22%20height%3D%2229%22%20fill%3D%22%23fff%22%20viewBox%3D%220%200%2020%2020%22%3E%3Cpath%20d%3D%22M10%204C9%204%209%205%209%205v.1A5%205%200%200%200%205.1%209H5s-1%200-1%201%201%201%201%201h.1A5%205%200%200%200%209%2014.9v.1s0%201%201%201%201-1%201-1v-.1a5%205%200%200%200%203.9-3.9h.1s1%200%201-1-1-1-1-1h-.1A5%205%200%200%200%2011%205.1V5s0-1-1-1m0%202.5a3.5%203.5%200%201%201%200%207%203.5%203.5%200%201%201%200-7%22%2F%3E%3Ccircle%20cx%3D%2210%22%20cy%3D%2210%22%20r%3D%222%22%2F%3E%3C%2Fsvg%3E")}.maplibregl-ctrl button.maplibregl-ctrl-geolocate:disabled .maplibregl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2229%22%20height%3D%2229%22%20fill%3D%22%23999%22%20viewBox%3D%220%200%2020%2020%22%3E%3Cpath%20d%3D%22M10%204C9%204%209%205%209%205v.1A5%205%200%200%200%205.1%209H5s-1%200-1%201%201%201%201%201h.1A5%205%200%200%200%209%2014.9v.1s0%201%201%201%201-1%201-1v-.1a5%205%200%200%200%203.9-3.9h.1s1%200%201-1-1-1-1-1h-.1A5%205%200%200%200%2011%205.1V5s0-1-1-1m0%202.5a3.5%203.5%200%201%201%200%207%203.5%203.5%200%201%201%200-7%22%2F%3E%3Ccircle%20cx%3D%2210%22%20cy%3D%2210%22%20r%3D%222%22%2F%3E%3Cpath%20fill%3D%22red%22%20d%3D%22m14%205%201%201-9%209-1-1z%22%2F%3E%3C%2Fsvg%3E")}.maplibregl-ctrl button.maplibregl-ctrl-geolocate.maplibregl-ctrl-geolocate-active .maplibregl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2229%22%20height%3D%2229%22%20fill%3D%22%2333b5e5%22%20viewBox%3D%220%200%2020%2020%22%3E%3Cpath%20d%3D%22M10%204C9%204%209%205%209%205v.1A5%205%200%200%200%205.1%209H5s-1%200-1%201%201%201%201%201h.1A5%205%200%200%200%209%2014.9v.1s0%201%201%201%201-1%201-1v-.1a5%205%200%200%200%203.9-3.9h.1s1%200%201-1-1-1-1-1h-.1A5%205%200%200%200%2011%205.1V5s0-1-1-1m0%202.5a3.5%203.5%200%201%201%200%207%203.5%203.5%200%201%201%200-7%22%2F%3E%3Ccircle%20cx%3D%2210%22%20cy%3D%2210%22%20r%3D%222%22%2F%3E%3C%2Fsvg%3E")}.maplibregl-ctrl button.maplibregl-ctrl-geolocate.maplibregl-ctrl-geolocate-active-error .maplibregl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2229%22%20height%3D%2229%22%20fill%3D%22%23e58978%22%20viewBox%3D%220%200%2020%2020%22%3E%3Cpath%20d%3D%22M10%204C9%204%209%205%209%205v.1A5%205%200%200%200%205.1%209H5s-1%200-1%201%201%201%201%201h.1A5%205%200%200%200%209%2014.9v.1s0%201%201%201%201-1%201-1v-.1a5%205%200%200%200%203.9-3.9h.1s1%200%201-1-1-1-1-1h-.1A5%205%200%200%200%2011%205.1V5s0-1-1-1m0%202.5a3.5%203.5%200%201%201%200%207%203.5%203.5%200%201%201%200-7%22%2F%3E%3Ccircle%20cx%3D%2210%22%20cy%3D%2210%22%20r%3D%222%22%2F%3E%3C%2Fsvg%3E")}.maplibregl-ctrl button.maplibregl-ctrl-geolocate.maplibregl-ctrl-geolocate-background .maplibregl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2229%22%20height%3D%2229%22%20fill%3D%22%2333b5e5%22%20viewBox%3D%220%200%2020%2020%22%3E%3Cpath%20d%3D%22M10%204C9%204%209%205%209%205v.1A5%205%200%200%200%205.1%209H5s-1%200-1%201%201%201%201%201h.1A5%205%200%200%200%209%2014.9v.1s0%201%201%201%201-1%201-1v-.1a5%205%200%200%200%203.9-3.9h.1s1%200%201-1-1-1-1-1h-.1A5%205%200%200%200%2011%205.1V5s0-1-1-1m0%202.5a3.5%203.5%200%201%201%200%207%203.5%203.5%200%201%201%200-7%22%2F%3E%3C%2Fsvg%3E")}.maplibregl-ctrl button.maplibregl-ctrl-geolocate.maplibregl-ctrl-geolocate-background-error .maplibregl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2229%22%20height%3D%2229%22%20fill%3D%22%23e54e33%22%20viewBox%3D%220%200%2020%2020%22%3E%3Cpath%20d%3D%22M10%204C9%204%209%205%209%205v.1A5%205%200%200%200%205.1%209H5s-1%200-1%201%201%201%201%201h.1A5%205%200%200%200%209%2014.9v.1s0%201%201%201%201-1%201-1v-.1a5%205%200%200%200%203.9-3.9h.1s1%200%201-1-1-1-1-1h-.1A5%205%200%200%200%2011%205.1V5s0-1-1-1m0%202.5a3.5%203.5%200%201%201%200%207%203.5%203.5%200%201%201%200-7%22%2F%3E%3C%2Fsvg%3E")}}@media (forced-colors:active) and (prefers-color-scheme:light){.maplibregl-ctrl button.maplibregl-ctrl-geolocate .maplibregl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2229%22%20height%3D%2229%22%20viewBox%3D%220%200%2020%2020%22%3E%3Cpath%20d%3D%22M10%204C9%204%209%205%209%205v.1A5%205%200%200%200%205.1%209H5s-1%200-1%201%201%201%201%201h.1A5%205%200%200%200%209%2014.9v.1s0%201%201%201%201-1%201-1v-.1a5%205%200%200%200%203.9-3.9h.1s1%200%201-1-1-1-1-1h-.1A5%205%200%200%200%2011%205.1V5s0-1-1-1m0%202.5a3.5%203.5%200%201%201%200%207%203.5%203.5%200%201%201%200-7%22%2F%3E%3Ccircle%20cx%3D%2210%22%20cy%3D%2210%22%20r%3D%222%22%2F%3E%3C%2Fsvg%3E")}.maplibregl-ctrl button.maplibregl-ctrl-geolocate:disabled .maplibregl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2229%22%20height%3D%2229%22%20fill%3D%22%23666%22%20viewBox%3D%220%200%2020%2020%22%3E%3Cpath%20d%3D%22M10%204C9%204%209%205%209%205v.1A5%205%200%200%200%205.1%209H5s-1%200-1%201%201%201%201%201h.1A5%205%200%200%200%209%2014.9v.1s0%201%201%201%201-1%201-1v-.1a5%205%200%200%200%203.9-3.9h.1s1%200%201-1-1-1-1-1h-.1A5%205%200%200%200%2011%205.1V5s0-1-1-1m0%202.5a3.5%203.5%200%201%201%200%207%203.5%203.5%200%201%201%200-7%22%2F%3E%3Ccircle%20cx%3D%2210%22%20cy%3D%2210%22%20r%3D%222%22%2F%3E%3Cpath%20fill%3D%22red%22%20d%3D%22m14%205%201%201-9%209-1-1z%22%2F%3E%3C%2Fsvg%3E")}}@keyframes maplibregl-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}a.maplibregl-ctrl-logo{width:88px;height:23px;margin:0 0 -4px -4px;display:block;background-repeat:no-repeat;cursor:pointer;overflow:hidden;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2288%22%20height%3D%2223%22%20fill%3D%22none%22%3E%3Cpath%20fill%3D%22%23000%22%20fill-opacity%3D%22.4%22%20fill-rule%3D%22evenodd%22%20d%3D%22M17.408%2016.796h-1.827l2.501-12.095h.198l3.324%206.533.988%202.19.988-2.19%203.258-6.533h.181l2.6%2012.095h-1.81l-1.218-5.644-.362-1.71-.658%201.71-2.929%205.644h-.098l-2.914-5.644-.757-1.71-.345%201.71zm1.958-3.42-.726%203.663a1.255%201.255%200%200%201-1.232%201.011h-1.827a1.255%201.255%200%200%201-1.229-1.509l2.501-12.095a1.255%201.255%200%200%201%201.23-1.001h.197a1.25%201.25%200%200%201%201.12.685l3.19%206.273%203.125-6.263a1.25%201.25%200%200%201%201.123-.695h.181a1.255%201.255%200%200%201%201.227.991l1.443%206.71a5%205%200%200%201%20.314-.787l.009-.016a4.6%204.6%200%200%201%201.777-1.887c.782-.46%201.668-.667%202.611-.667a4.6%204.6%200%200%201%201.7.32l.306.134c.21-.16.474-.256.759-.256h1.694a1.255%201.255%200%200%201%201.212.925%201.255%201.255%200%200%201%201.212-.925h1.711c.284%200%20.545.094.755.252.613-.3%201.312-.45%202.075-.45%201.356%200%202.557.445%203.482%201.4q.47.48.763%201.064V4.701a1.255%201.255%200%200%201%201.255-1.255h1.86A1.255%201.255%200%200%201%2054.44%204.7v9.194h2.217c.19%200%20.37.043.532.118v-4.77c0-.356.147-.678.385-.906a2.42%202.42%200%200%201-.682-1.71c0-.665.267-1.253.735-1.7a2.45%202.45%200%200%201%201.722-.674%202.43%202.43%200%200%201%201.705.675q.318.302.504.683V4.7a1.255%201.255%200%200%201%201.255-1.255h1.744A1.255%201.255%200%200%201%2065.812%204.7v3.335a4.8%204.8%200%200%201%201.526-.246c.938%200%201.817.214%202.59.69a4.47%204.47%200%200%201%201.67%201.743v-.98a1.255%201.255%200%200%201%201.256-1.256h1.777c.233%200%20.451.064.639.174a3.4%203.4%200%200%201%201.567-.372c.346%200%20.861.02%201.285.232a1.25%201.25%200%200%201%20.689%201.004%204.7%204.7%200%200%201%20.853-.588c.795-.44%201.675-.647%202.61-.647%201.385%200%202.65.39%203.525%201.396.836.938%201.168%202.173%201.168%203.528q-.001.515-.056%201.051a1.255%201.255%200%200%201-.947%201.09l.408.952a1.255%201.255%200%200%201-.477%201.552c-.418.268-.92.463-1.458.612-.613.171-1.304.244-2.049.244-1.06%200-2.043-.207-2.886-.698l-.015-.008c-.798-.48-1.419-1.135-1.818-1.963l-.004-.008a5.8%205.8%200%200%201-.548-2.512q0-.429.053-.843a1.3%201.3%200%200%201-.333-.086l-.166-.004c-.223%200-.426.062-.643.228-.03.024-.142.139-.142.59v3.883a1.255%201.255%200%200%201-1.256%201.256h-1.777a1.255%201.255%200%200%201-1.256-1.256V15.69l-.032.057a4.8%204.8%200%200%201-1.86%201.833%205.04%205.04%200%200%201-2.484.634%204.5%204.5%200%200%201-1.935-.424%201.25%201.25%200%200%201-.764.258h-1.71a1.255%201.255%200%200%201-1.256-1.255V7.687a2.4%202.4%200%200%201-.428.625c.253.23.412.561.412.93v7.553a1.255%201.255%200%200%201-1.256%201.255h-1.843a1.25%201.25%200%200%201-.894-.373c-.228.23-.544.373-.894.373H51.32a1.255%201.255%200%200%201-1.256-1.255v-1.251l-.061.117a4.7%204.7%200%200%201-1.782%201.884%204.77%204.77%200%200%201-2.485.67%205.6%205.6%200%200%201-1.485-.188l.009%202.764a1.255%201.255%200%200%201-1.255%201.259h-1.729a1.255%201.255%200%200%201-1.255-1.255v-3.537a1.255%201.255%200%200%201-1.167.793h-1.679a1.25%201.25%200%200%201-.77-.263%204.5%204.5%200%200%201-1.945.429c-.885%200-1.724-.21-2.495-.632l-.017-.01a5%205%200%200%201-1.081-.836%201.255%201.255%200%200%201-1.254%201.312h-1.81a1.255%201.255%200%200%201-1.228-.99l-.782-3.625-2.044%203.939a1.25%201.25%200%200%201-1.115.676h-.098a1.25%201.25%200%200%201-1.116-.68l-2.061-3.994zM35.92%2016.63l.207-.114.223-.15q.493-.356.735-.785l.061-.118.033%201.332h1.678V9.242h-1.694l-.033%201.267q-.133-.329-.526-.658l-.032-.028a3.2%203.2%200%200%200-.668-.428l-.27-.12a3.3%203.3%200%200%200-1.235-.23q-1.136-.001-1.974.493a3.36%203.36%200%200%200-1.3%201.382q-.445.89-.444%202.074%200%201.2.51%202.107a3.8%203.8%200%200%200%201.382%201.381%203.9%203.9%200%200%200%201.893.477q.795%200%201.455-.33zm-2.789-5.38q-.576.675-.575%201.762%200%201.102.559%201.794.576.675%201.645.675a2.25%202.25%200%200%200%20.934-.19%202.2%202.2%200%200%200%20.468-.29l.178-.161a2.2%202.2%200%200%200%20.397-.561q.244-.5.244-1.15v-.115q0-.708-.296-1.267l-.043-.077a2.2%202.2%200%200%200-.633-.709l-.13-.086-.047-.028a2.1%202.1%200%200%200-1.073-.285q-1.052%200-1.629.692zm2.316%202.706c.163-.17.28-.407.28-.83v-.114c0-.292-.06-.508-.15-.68a.96.96%200%200%200-.353-.389.85.85%200%200%200-.464-.127c-.4%200-.56.114-.664.239l-.01.012c-.148.174-.275.45-.275.945%200%20.506.122.801.27.99.097.11.266.224.68.224.303%200%20.504-.09.687-.269zm7.545%201.705a2.6%202.6%200%200%200%20.331.423q.319.33.755.548l.173.074q.65.255%201.49.255%201.02%200%201.844-.493a3.45%203.45%200%200%200%201.316-1.4q.493-.904.493-2.089%200-1.909-.988-2.913-.988-1.02-2.584-1.02-.898%200-1.575.347a3%203%200%200%200-.415.262l-.199.166a3.4%203.4%200%200%200-.64.82V9.242h-1.712v11.553h1.729l-.017-5.134zm.53-1.138q.206.29.48.5l.155.11.053.034q.51.296%201.119.297%201.07%200%201.645-.675.577-.69.576-1.762%200-1.119-.576-1.777-.558-.675-1.645-.675-.435%200-.835.16a2%202%200%200%200-.284.136%202%202%200%200%200-.363.254%202.2%202.2%200%200%200-.46.569l-.082.162a2.6%202.6%200%200%200-.213%201.072v.115q0%20.707.296%201.267l.135.211zm.964-.818a1.1%201.1%200%200%200%20.367.385.94.94%200%200%200%20.476.118c.423%200%20.59-.117.687-.23.159-.194.28-.478.28-.95%200-.53-.133-.8-.266-.952l-.021-.025c-.078-.094-.231-.221-.68-.221a1%201%200%200%200-.503.135l-.012.007a.86.86%200%200%200-.335.343c-.073.133-.132.324-.132.614v.115a1.4%201.4%200%200%200%20.14.66zm15.7-6.222q.347-.346.346-.856a1.05%201.05%200%200%200-.345-.79%201.18%201.18%200%200%200-.84-.329q-.51%200-.855.33a1.05%201.05%200%200%200-.346.79q0%20.51.346.855.345.346.856.346.51%200%20.839-.346zm4.337%209.314.033-1.332q.191.403.59.747l.098.081a4%204%200%200%200%20.316.224l.223.122a3.2%203.2%200%200%200%201.44.322%203.8%203.8%200%200%200%201.875-.477%203.5%203.5%200%200%200%201.382-1.366q.527-.89.526-2.09%200-1.184-.444-2.073a3.24%203.24%200%200%200-1.283-1.399q-.823-.51-1.942-.51a3.5%203.5%200%200%200-1.527.344l-.086.043-.165.09a3%203%200%200%200-.33.214q-.432.315-.656.707a2%202%200%200%200-.099.198l.082-1.283V4.701h-1.744v12.095zm.473-2.509a2.5%202.5%200%200%200%20.566.7q.117.098.245.18l.144.08a2.1%202.1%200%200%200%20.975.232q1.07%200%201.645-.675.576-.69.576-1.778%200-1.102-.576-1.777-.56-.691-1.645-.692a2.2%202.2%200%200%200-1.015.235q-.22.113-.415.282l-.15.142a2.1%202.1%200%200%200-.42.594q-.223.479-.223%201.1v.115q0%20.705.293%201.26zm2.616-.293c.157-.191.28-.479.28-.967%200-.51-.13-.79-.276-.961l-.021-.026c-.082-.1-.232-.225-.67-.225a.87.87%200%200%200-.681.279l-.012.011c-.154.155-.274.38-.274.807v.115c0%20.285.057.499.144.669a1.1%201.1%200%200%200%20.367.405c.137.082.28.123.455.123.423%200%20.59-.118.686-.23zm8.266-3.013q.345-.13.724-.14l.069-.002q.493%200%20.642.099l.247-1.794q-.196-.099-.717-.099a2.3%202.3%200%200%200-.545.063%202%202%200%200%200-.411.148%202.2%202.2%200%200%200-.4.249%202.5%202.5%200%200%200-.485.499%202.7%202.7%200%200%200-.32.581l-.05.137v-1.48h-1.778v7.553h1.777v-3.884q0-.546.159-.943a1.5%201.5%200%200%201%20.466-.636%202.5%202.5%200%200%201%20.399-.253%202%202%200%200%201%20.224-.099zm9.784%202.656.05-.922q0-1.743-.856-2.698-.838-.97-2.584-.97-1.119-.001-2.007.493a3.46%203.46%200%200%200-1.4%201.382q-.493.906-.493%202.106%200%201.07.428%201.975.428.89%201.332%201.432.906.526%202.255.526.973%200%201.668-.185l.044-.012.135-.04q.613-.184.984-.421l-.542-1.267q-.3.162-.642.274l-.297.087q-.51.131-1.3.131-.954%200-1.497-.444a1.6%201.6%200%200%201-.192-.193q-.366-.44-.512-1.234l-.004-.021zm-5.427-1.256-.003.022h3.752v-.138q-.011-.727-.288-1.118a1%201%200%200%200-.156-.176q-.46-.428-1.316-.428-.986%200-1.494.604-.379.45-.494%201.234zm-27.053%202.77V4.7h-1.86v12.095h5.333V15.15zm7.103-5.908v7.553h-1.843V9.242h1.843z%22%2F%3E%3Cpath%20fill%3D%22%23fff%22%20d%3D%22m19.63%2011.151-.757-1.71-.345%201.71-1.12%205.644h-1.827L18.083%204.7h.197l3.325%206.533.988%202.19.988-2.19L26.839%204.7h.181l2.6%2012.095h-1.81l-1.218-5.644-.362-1.71-.658%201.71-2.93%205.644h-.098l-2.913-5.644zm14.836%205.81q-1.02%200-1.893-.478a3.8%203.8%200%200%201-1.381-1.382q-.51-.906-.51-2.106%200-1.185.444-2.074a3.36%203.36%200%200%201%201.3-1.382q.839-.494%201.974-.494a3.3%203.3%200%200%201%201.234.231%203.3%203.3%200%200%201%20.97.575q.396.33.527.659l.033-1.267h1.694v7.553H37.18l-.033-1.332q-.279.593-1.02%201.053a3.17%203.17%200%200%201-1.662.444zm.296-1.482q.938%200%201.58-.642.642-.66.642-1.711v-.115q0-.708-.296-1.267a2.2%202.2%200%200%200-.807-.872%202.1%202.1%200%200%200-1.119-.313q-1.053%200-1.629.692-.575.675-.575%201.76%200%201.103.559%201.795.577.675%201.645.675zm6.521-6.237h1.711v1.4q.906-1.597%202.83-1.597%201.596%200%202.584%201.02.988%201.005.988%202.914%200%201.185-.493%202.09a3.46%203.46%200%200%201-1.316%201.399%203.5%203.5%200%200%201-1.844.493q-.954%200-1.662-.329a2.67%202.67%200%200%201-1.086-.97l.017%205.134h-1.728zm4.048%206.22q1.07%200%201.645-.674.577-.69.576-1.762%200-1.119-.576-1.777-.558-.675-1.645-.675-.592%200-1.12.296-.51.28-.822.823-.296.527-.296%201.234v.115q0%20.708.296%201.267.313.543.823.855.51.296%201.119.297z%22%2F%3E%3Cpath%20fill%3D%22%23e1e3e9%22%20d%3D%22M51.325%204.7h1.86v10.45h3.473v1.646h-5.333zm7.12%204.542h1.843v7.553h-1.843zm.905-1.415a1.16%201.16%200%200%201-.856-.346%201.17%201.17%200%200%201-.346-.856%201.05%201.05%200%200%201%20.346-.79q.346-.329.856-.329.494%200%20.839.33a1.05%201.05%200%200%201%20.345.79%201.16%201.16%200%200%201-.345.855q-.33.346-.84.346zm7.875%209.133a3.17%203.17%200%200%201-1.662-.444q-.723-.46-1.004-1.053l-.033%201.332h-1.71V4.701h1.743v4.657l-.082%201.283q.279-.658%201.086-1.119a3.5%203.5%200%200%201%201.778-.477q1.119%200%201.942.51a3.24%203.24%200%200%201%201.283%201.4q.445.888.444%202.072%200%201.201-.526%202.09a3.5%203.5%200%200%201-1.382%201.366%203.8%203.8%200%200%201-1.876.477zm-.296-1.481q1.069%200%201.645-.675.577-.69.577-1.778%200-1.102-.577-1.776-.56-.691-1.645-.692a2.12%202.12%200%200%200-1.58.659q-.642.641-.642%201.694v.115q0%20.71.296%201.267a2.4%202.4%200%200%200%20.807.872%202.1%202.1%200%200%200%201.119.313zm5.927-6.237h1.777v1.481q.263-.757.856-1.217a2.14%202.14%200%200%201%201.349-.46q.527%200%20.724.098l-.247%201.794q-.149-.099-.642-.099-.774%200-1.416.494-.626.493-.626%201.58v3.883h-1.777V9.242zm9.534%207.718q-1.35%200-2.255-.526-.904-.543-1.332-1.432a4.6%204.6%200%200%201-.428-1.975q0-1.2.493-2.106a3.46%203.46%200%200%201%201.4-1.382q.889-.495%202.007-.494%201.744%200%202.584.97.855.956.856%202.7%200%20.444-.05.92h-5.43q.18%201.005.708%201.45.542.443%201.497.443.79%200%201.3-.131a4%204%200%200%200%20.938-.362l.542%201.267q-.411.263-1.119.46-.708.198-1.711.197zm1.596-4.558q.016-1.02-.444-1.432-.46-.428-1.316-.428-1.728%200-1.991%201.86z%22%2F%3E%3Cpath%20d%3D%22M5.074%2015.948a.484.657%200%200%200-.486.659v1.84a.484.657%200%200%200%20.486.659h4.101a.484.657%200%200%200%20.486-.659v-1.84a.484.657%200%200%200-.486-.659zm3.56%201.16H5.617v.838h3.017z%22%20style%3D%22fill%3A%23fff%3Bfill-rule%3Aevenodd%3Bstroke-width%3A1.03600001%22%2F%3E%3Cg%20style%3D%22stroke-width%3A1.12603545%22%3E%3Cpath%20d%3D%22M-9.408-1.416c-3.833-.025-7.056%202.912-7.08%206.615-.02%203.08%201.653%204.832%203.107%206.268.903.892%201.721%201.74%202.32%202.902l-.525-.004c-.543-.003-.992.304-1.24.639a1.87%201.87%200%200%200-.362%201.121l-.011%201.877c-.003.402.104.787.347%201.125.244.338.688.653%201.23.656l4.142.028c.542.003.99-.306%201.238-.641a1.87%201.87%200%200%200%20.363-1.121l.012-1.875a1.87%201.87%200%200%200-.348-1.127c-.243-.338-.688-.653-1.23-.656l-.518-.004c.597-1.145%201.425-1.983%202.348-2.87%201.473-1.414%203.18-3.149%203.2-6.226-.016-3.59-2.923-6.684-6.993-6.707m-.006%201.1v.002c3.274.02%205.92%202.532%205.9%205.6-.017%202.706-1.39%204.026-2.863%205.44-1.034.994-2.118%202.033-2.814%203.633-.018.041-.052.055-.075.065q-.013.004-.02.01a.34.34%200%200%201-.226.084.34.34%200%200%201-.224-.086l-.092-.077c-.699-1.615-1.768-2.669-2.781-3.67-1.454-1.435-2.797-2.762-2.78-5.478.02-3.067%202.7-5.545%205.975-5.523m-.02%202.826c-1.62-.01-2.944%201.315-2.955%202.96-.01%201.646%201.295%202.988%202.916%202.999h.002c1.621.01%202.943-1.316%202.953-2.961.011-1.646-1.294-2.988-2.916-2.998m-.005%201.1c1.017.006%201.829.83%201.822%201.89s-.83%201.874-1.848%201.867c-1.018-.006-1.829-.83-1.822-1.89s.83-1.874%201.848-1.868m-2.155%2011.857%204.14.025c.271.002.49.305.487.676l-.013%201.875c-.003.37-.224.67-.495.668l-4.14-.025c-.27-.002-.487-.306-.485-.676l.012-1.875c.003-.37.224-.67.494-.668%22%20style%3D%22color%3A%23000%3Bfont-style%3Anormal%3Bfont-variant%3Anormal%3Bfont-weight%3A400%3Bfont-stretch%3Anormal%3Bfont-size%3Amedium%3Bline-height%3Anormal%3Bfont-family%3Asans-serif%3Bfont-variant-ligatures%3Anormal%3Bfont-variant-position%3Anormal%3Bfont-variant-caps%3Anormal%3Bfont-variant-numeric%3Anormal%3Bfont-variant-alternates%3Anormal%3Bfont-feature-settings%3Anormal%3Btext-indent%3A0%3Btext-align%3Astart%3Btext-decoration%3Anone%3Btext-decoration-line%3Anone%3Btext-decoration-style%3Asolid%3Btext-decoration-color%3A%23000%3Bletter-spacing%3Anormal%3Bword-spacing%3Anormal%3Btext-transform%3Anone%3Bwriting-mode%3Alr-tb%3Bdirection%3Altr%3Btext-orientation%3Amixed%3Bdominant-baseline%3Aauto%3Bbaseline-shift%3Abaseline%3Btext-anchor%3Astart%3Bwhite-space%3Anormal%3Bshape-padding%3A0%3Bclip-rule%3Aevenodd%3Bdisplay%3Ainline%3Boverflow%3Avisible%3Bvisibility%3Avisible%3Bopacity%3A1%3Bisolation%3Aauto%3Bmix-blend-mode%3Anormal%3Bcolor-interpolation%3AsRGB%3Bcolor-interpolation-filters%3AlinearRGB%3Bsolid-color%3A%23000%3Bsolid-opacity%3A1%3Bvector-effect%3Anone%3Bfill%3A%23000%3Bfill-opacity%3A.4%3Bfill-rule%3Aevenodd%3Bstroke%3Anone%3Bstroke-width%3A2.47727823%3Bstroke-linecap%3Abutt%3Bstroke-linejoin%3Amiter%3Bstroke-miterlimit%3A4%3Bstroke-dasharray%3Anone%3Bstroke-dashoffset%3A0%3Bstroke-opacity%3A1%3Bcolor-rendering%3Aauto%3Bimage-rendering%3Aauto%3Bshape-rendering%3Aauto%3Btext-rendering%3Aauto%22%20transform%3D%22translate(15.553%202.85)scale(.88807)%22%2F%3E%3Cpath%20d%3D%22M-9.415-.316C-12.69-.338-15.37%202.14-15.39%205.207c-.017%202.716%201.326%204.041%202.78%205.477%201.013%201%202.081%202.055%202.78%203.67l.092.076a.34.34%200%200%200%20.225.086.34.34%200%200%200%20.227-.083l.019-.01c.022-.009.057-.024.074-.064.697-1.6%201.78-2.64%202.814-3.634%201.473-1.414%202.847-2.733%202.864-5.44.02-3.067-2.627-5.58-5.901-5.601m-.057%208.784c1.621.011%202.944-1.315%202.955-2.96.01-1.646-1.295-2.988-2.916-2.999-1.622-.01-2.945%201.315-2.955%202.96s1.295%202.989%202.916%203%22%20style%3D%22clip-rule%3Aevenodd%3Bfill%3A%23e1e3e9%3Bfill-opacity%3A1%3Bfill-rule%3Aevenodd%3Bstroke%3Anone%3Bstroke-width%3A2.47727823%3Bstroke-miterlimit%3A4%3Bstroke-dasharray%3Anone%3Bstroke-opacity%3A.4%22%20transform%3D%22translate(15.553%202.85)scale(.88807)%22%2F%3E%3Cpath%20d%3D%22M-11.594%2015.465c-.27-.002-.492.297-.494.668l-.012%201.876c-.003.371.214.673.485.675l4.14.027c.271.002.492-.298.495-.668l.012-1.877c.003-.37-.215-.672-.485-.674z%22%20style%3D%22clip-rule%3Aevenodd%3Bfill%3A%23fff%3Bfill-opacity%3A1%3Bfill-rule%3Aevenodd%3Bstroke%3Anone%3Bstroke-width%3A2.47727823%3Bstroke-miterlimit%3A4%3Bstroke-dasharray%3Anone%3Bstroke-opacity%3A.4%22%20transform%3D%22translate(15.553%202.85)scale(.88807)%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E")}a.maplibregl-ctrl-logo.maplibregl-compact{width:14px}@media (forced-colors:active){a.maplibregl-ctrl-logo{background-color:transparent;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2288%22%20height%3D%2223%22%20fill%3D%22none%22%3E%3Cpath%20fill%3D%22%23000%22%20fill-opacity%3D%22.4%22%20fill-rule%3D%22evenodd%22%20d%3D%22M17.408%2016.796h-1.827l2.501-12.095h.198l3.324%206.533.988%202.19.988-2.19%203.258-6.533h.181l2.6%2012.095h-1.81l-1.218-5.644-.362-1.71-.658%201.71-2.929%205.644h-.098l-2.914-5.644-.757-1.71-.345%201.71zm1.958-3.42-.726%203.663a1.255%201.255%200%200%201-1.232%201.011h-1.827a1.255%201.255%200%200%201-1.229-1.509l2.501-12.095a1.255%201.255%200%200%201%201.23-1.001h.197a1.25%201.25%200%200%201%201.12.685l3.19%206.273%203.125-6.263a1.25%201.25%200%200%201%201.123-.695h.181a1.255%201.255%200%200%201%201.227.991l1.443%206.71a5%205%200%200%201%20.314-.787l.009-.016a4.6%204.6%200%200%201%201.777-1.887c.782-.46%201.668-.667%202.611-.667a4.6%204.6%200%200%201%201.7.32l.306.134c.21-.16.474-.256.759-.256h1.694a1.255%201.255%200%200%201%201.212.925%201.255%201.255%200%200%201%201.212-.925h1.711c.284%200%20.545.094.755.252.613-.3%201.312-.45%202.075-.45%201.356%200%202.557.445%203.482%201.4q.47.48.763%201.064V4.701a1.255%201.255%200%200%201%201.255-1.255h1.86A1.255%201.255%200%200%201%2054.44%204.7v9.194h2.217c.19%200%20.37.043.532.118v-4.77c0-.356.147-.678.385-.906a2.42%202.42%200%200%201-.682-1.71c0-.665.267-1.253.735-1.7a2.45%202.45%200%200%201%201.722-.674%202.43%202.43%200%200%201%201.705.675q.318.302.504.683V4.7a1.255%201.255%200%200%201%201.255-1.255h1.744A1.255%201.255%200%200%201%2065.812%204.7v3.335a4.8%204.8%200%200%201%201.526-.246c.938%200%201.817.214%202.59.69a4.47%204.47%200%200%201%201.67%201.743v-.98a1.255%201.255%200%200%201%201.256-1.256h1.777c.233%200%20.451.064.639.174a3.4%203.4%200%200%201%201.567-.372c.346%200%20.861.02%201.285.232a1.25%201.25%200%200%201%20.689%201.004%204.7%204.7%200%200%201%20.853-.588c.795-.44%201.675-.647%202.61-.647%201.385%200%202.65.39%203.525%201.396.836.938%201.168%202.173%201.168%203.528q-.001.515-.056%201.051a1.255%201.255%200%200%201-.947%201.09l.408.952a1.255%201.255%200%200%201-.477%201.552c-.418.268-.92.463-1.458.612-.613.171-1.304.244-2.049.244-1.06%200-2.043-.207-2.886-.698l-.015-.008c-.798-.48-1.419-1.135-1.818-1.963l-.004-.008a5.8%205.8%200%200%201-.548-2.512q0-.429.053-.843a1.3%201.3%200%200%201-.333-.086l-.166-.004c-.223%200-.426.062-.643.228-.03.024-.142.139-.142.59v3.883a1.255%201.255%200%200%201-1.256%201.256h-1.777a1.255%201.255%200%200%201-1.256-1.256V15.69l-.032.057a4.8%204.8%200%200%201-1.86%201.833%205.04%205.04%200%200%201-2.484.634%204.5%204.5%200%200%201-1.935-.424%201.25%201.25%200%200%201-.764.258h-1.71a1.255%201.255%200%200%201-1.256-1.255V7.687a2.4%202.4%200%200%201-.428.625c.253.23.412.561.412.93v7.553a1.255%201.255%200%200%201-1.256%201.255h-1.843a1.25%201.25%200%200%201-.894-.373c-.228.23-.544.373-.894.373H51.32a1.255%201.255%200%200%201-1.256-1.255v-1.251l-.061.117a4.7%204.7%200%200%201-1.782%201.884%204.77%204.77%200%200%201-2.485.67%205.6%205.6%200%200%201-1.485-.188l.009%202.764a1.255%201.255%200%200%201-1.255%201.259h-1.729a1.255%201.255%200%200%201-1.255-1.255v-3.537a1.255%201.255%200%200%201-1.167.793h-1.679a1.25%201.25%200%200%201-.77-.263%204.5%204.5%200%200%201-1.945.429c-.885%200-1.724-.21-2.495-.632l-.017-.01a5%205%200%200%201-1.081-.836%201.255%201.255%200%200%201-1.254%201.312h-1.81a1.255%201.255%200%200%201-1.228-.99l-.782-3.625-2.044%203.939a1.25%201.25%200%200%201-1.115.676h-.098a1.25%201.25%200%200%201-1.116-.68l-2.061-3.994zM35.92%2016.63l.207-.114.223-.15q.493-.356.735-.785l.061-.118.033%201.332h1.678V9.242h-1.694l-.033%201.267q-.133-.329-.526-.658l-.032-.028a3.2%203.2%200%200%200-.668-.428l-.27-.12a3.3%203.3%200%200%200-1.235-.23q-1.136-.001-1.974.493a3.36%203.36%200%200%200-1.3%201.382q-.445.89-.444%202.074%200%201.2.51%202.107a3.8%203.8%200%200%200%201.382%201.381%203.9%203.9%200%200%200%201.893.477q.795%200%201.455-.33zm-2.789-5.38q-.576.675-.575%201.762%200%201.102.559%201.794.576.675%201.645.675a2.25%202.25%200%200%200%20.934-.19%202.2%202.2%200%200%200%20.468-.29l.178-.161a2.2%202.2%200%200%200%20.397-.561q.244-.5.244-1.15v-.115q0-.708-.296-1.267l-.043-.077a2.2%202.2%200%200%200-.633-.709l-.13-.086-.047-.028a2.1%202.1%200%200%200-1.073-.285q-1.052%200-1.629.692zm2.316%202.706c.163-.17.28-.407.28-.83v-.114c0-.292-.06-.508-.15-.68a.96.96%200%200%200-.353-.389.85.85%200%200%200-.464-.127c-.4%200-.56.114-.664.239l-.01.012c-.148.174-.275.45-.275.945%200%20.506.122.801.27.99.097.11.266.224.68.224.303%200%20.504-.09.687-.269zm7.545%201.705a2.6%202.6%200%200%200%20.331.423q.319.33.755.548l.173.074q.65.255%201.49.255%201.02%200%201.844-.493a3.45%203.45%200%200%200%201.316-1.4q.493-.904.493-2.089%200-1.909-.988-2.913-.988-1.02-2.584-1.02-.898%200-1.575.347a3%203%200%200%200-.415.262l-.199.166a3.4%203.4%200%200%200-.64.82V9.242h-1.712v11.553h1.729l-.017-5.134zm.53-1.138q.206.29.48.5l.155.11.053.034q.51.296%201.119.297%201.07%200%201.645-.675.577-.69.576-1.762%200-1.119-.576-1.777-.558-.675-1.645-.675-.435%200-.835.16a2%202%200%200%200-.284.136%202%202%200%200%200-.363.254%202.2%202.2%200%200%200-.46.569l-.082.162a2.6%202.6%200%200%200-.213%201.072v.115q0%20.707.296%201.267l.135.211zm.964-.818a1.1%201.1%200%200%200%20.367.385.94.94%200%200%200%20.476.118c.423%200%20.59-.117.687-.23.159-.194.28-.478.28-.95%200-.53-.133-.8-.266-.952l-.021-.025c-.078-.094-.231-.221-.68-.221a1%201%200%200%200-.503.135l-.012.007a.86.86%200%200%200-.335.343c-.073.133-.132.324-.132.614v.115a1.4%201.4%200%200%200%20.14.66zm15.7-6.222q.347-.346.346-.856a1.05%201.05%200%200%200-.345-.79%201.18%201.18%200%200%200-.84-.329q-.51%200-.855.33a1.05%201.05%200%200%200-.346.79q0%20.51.346.855.345.346.856.346.51%200%20.839-.346zm4.337%209.314.033-1.332q.191.403.59.747l.098.081a4%204%200%200%200%20.316.224l.223.122a3.2%203.2%200%200%200%201.44.322%203.8%203.8%200%200%200%201.875-.477%203.5%203.5%200%200%200%201.382-1.366q.527-.89.526-2.09%200-1.184-.444-2.073a3.24%203.24%200%200%200-1.283-1.399q-.823-.51-1.942-.51a3.5%203.5%200%200%200-1.527.344l-.086.043-.165.09a3%203%200%200%200-.33.214q-.432.315-.656.707a2%202%200%200%200-.099.198l.082-1.283V4.701h-1.744v12.095zm.473-2.509a2.5%202.5%200%200%200%20.566.7q.117.098.245.18l.144.08a2.1%202.1%200%200%200%20.975.232q1.07%200%201.645-.675.576-.69.576-1.778%200-1.102-.576-1.777-.56-.691-1.645-.692a2.2%202.2%200%200%200-1.015.235q-.22.113-.415.282l-.15.142a2.1%202.1%200%200%200-.42.594q-.223.479-.223%201.1v.115q0%20.705.293%201.26zm2.616-.293c.157-.191.28-.479.28-.967%200-.51-.13-.79-.276-.961l-.021-.026c-.082-.1-.232-.225-.67-.225a.87.87%200%200%200-.681.279l-.012.011c-.154.155-.274.38-.274.807v.115c0%20.285.057.499.144.669a1.1%201.1%200%200%200%20.367.405c.137.082.28.123.455.123.423%200%20.59-.118.686-.23zm8.266-3.013q.345-.13.724-.14l.069-.002q.493%200%20.642.099l.247-1.794q-.196-.099-.717-.099a2.3%202.3%200%200%200-.545.063%202%202%200%200%200-.411.148%202.2%202.2%200%200%200-.4.249%202.5%202.5%200%200%200-.485.499%202.7%202.7%200%200%200-.32.581l-.05.137v-1.48h-1.778v7.553h1.777v-3.884q0-.546.159-.943a1.5%201.5%200%200%201%20.466-.636%202.5%202.5%200%200%201%20.399-.253%202%202%200%200%201%20.224-.099zm9.784%202.656.05-.922q0-1.743-.856-2.698-.838-.97-2.584-.97-1.119-.001-2.007.493a3.46%203.46%200%200%200-1.4%201.382q-.493.906-.493%202.106%200%201.07.428%201.975.428.89%201.332%201.432.906.526%202.255.526.973%200%201.668-.185l.044-.012.135-.04q.613-.184.984-.421l-.542-1.267q-.3.162-.642.274l-.297.087q-.51.131-1.3.131-.954%200-1.497-.444a1.6%201.6%200%200%201-.192-.193q-.366-.44-.512-1.234l-.004-.021zm-5.427-1.256-.003.022h3.752v-.138q-.011-.727-.288-1.118a1%201%200%200%200-.156-.176q-.46-.428-1.316-.428-.986%200-1.494.604-.379.45-.494%201.234zm-27.053%202.77V4.7h-1.86v12.095h5.333V15.15zm7.103-5.908v7.553h-1.843V9.242h1.843z%22%2F%3E%3Cpath%20fill%3D%22%23fff%22%20d%3D%22m19.63%2011.151-.757-1.71-.345%201.71-1.12%205.644h-1.827L18.083%204.7h.197l3.325%206.533.988%202.19.988-2.19L26.839%204.7h.181l2.6%2012.095h-1.81l-1.218-5.644-.362-1.71-.658%201.71-2.93%205.644h-.098l-2.913-5.644zm14.836%205.81q-1.02%200-1.893-.478a3.8%203.8%200%200%201-1.381-1.382q-.51-.906-.51-2.106%200-1.185.444-2.074a3.36%203.36%200%200%201%201.3-1.382q.839-.494%201.974-.494a3.3%203.3%200%200%201%201.234.231%203.3%203.3%200%200%201%20.97.575q.396.33.527.659l.033-1.267h1.694v7.553H37.18l-.033-1.332q-.279.593-1.02%201.053a3.17%203.17%200%200%201-1.662.444zm.296-1.482q.938%200%201.58-.642.642-.66.642-1.711v-.115q0-.708-.296-1.267a2.2%202.2%200%200%200-.807-.872%202.1%202.1%200%200%200-1.119-.313q-1.053%200-1.629.692-.575.675-.575%201.76%200%201.103.559%201.795.577.675%201.645.675zm6.521-6.237h1.711v1.4q.906-1.597%202.83-1.597%201.596%200%202.584%201.02.988%201.005.988%202.914%200%201.185-.493%202.09a3.46%203.46%200%200%201-1.316%201.399%203.5%203.5%200%200%201-1.844.493q-.954%200-1.662-.329a2.67%202.67%200%200%201-1.086-.97l.017%205.134h-1.728zm4.048%206.22q1.07%200%201.645-.674.577-.69.576-1.762%200-1.119-.576-1.777-.558-.675-1.645-.675-.592%200-1.12.296-.51.28-.822.823-.296.527-.296%201.234v.115q0%20.708.296%201.267.313.543.823.855.51.296%201.119.297z%22%2F%3E%3Cpath%20fill%3D%22%23e1e3e9%22%20d%3D%22M51.325%204.7h1.86v10.45h3.473v1.646h-5.333zm7.12%204.542h1.843v7.553h-1.843zm.905-1.415a1.16%201.16%200%200%201-.856-.346%201.17%201.17%200%200%201-.346-.856%201.05%201.05%200%200%201%20.346-.79q.346-.329.856-.329.494%200%20.839.33a1.05%201.05%200%200%201%20.345.79%201.16%201.16%200%200%201-.345.855q-.33.346-.84.346zm7.875%209.133a3.17%203.17%200%200%201-1.662-.444q-.723-.46-1.004-1.053l-.033%201.332h-1.71V4.701h1.743v4.657l-.082%201.283q.279-.658%201.086-1.119a3.5%203.5%200%200%201%201.778-.477q1.119%200%201.942.51a3.24%203.24%200%200%201%201.283%201.4q.445.888.444%202.072%200%201.201-.526%202.09a3.5%203.5%200%200%201-1.382%201.366%203.8%203.8%200%200%201-1.876.477zm-.296-1.481q1.069%200%201.645-.675.577-.69.577-1.778%200-1.102-.577-1.776-.56-.691-1.645-.692a2.12%202.12%200%200%200-1.58.659q-.642.641-.642%201.694v.115q0%20.71.296%201.267a2.4%202.4%200%200%200%20.807.872%202.1%202.1%200%200%200%201.119.313zm5.927-6.237h1.777v1.481q.263-.757.856-1.217a2.14%202.14%200%200%201%201.349-.46q.527%200%20.724.098l-.247%201.794q-.149-.099-.642-.099-.774%200-1.416.494-.626.493-.626%201.58v3.883h-1.777V9.242zm9.534%207.718q-1.35%200-2.255-.526-.904-.543-1.332-1.432a4.6%204.6%200%200%201-.428-1.975q0-1.2.493-2.106a3.46%203.46%200%200%201%201.4-1.382q.889-.495%202.007-.494%201.744%200%202.584.97.855.956.856%202.7%200%20.444-.05.92h-5.43q.18%201.005.708%201.45.542.443%201.497.443.79%200%201.3-.131a4%204%200%200%200%20.938-.362l.542%201.267q-.411.263-1.119.46-.708.198-1.711.197zm1.596-4.558q.016-1.02-.444-1.432-.46-.428-1.316-.428-1.728%200-1.991%201.86z%22%2F%3E%3Cpath%20d%3D%22M5.074%2015.948a.484.657%200%200%200-.486.659v1.84a.484.657%200%200%200%20.486.659h4.101a.484.657%200%200%200%20.486-.659v-1.84a.484.657%200%200%200-.486-.659zm3.56%201.16H5.617v.838h3.017z%22%20style%3D%22fill%3A%23fff%3Bfill-rule%3Aevenodd%3Bstroke-width%3A1.03600001%22%2F%3E%3Cg%20style%3D%22stroke-width%3A1.12603545%22%3E%3Cpath%20d%3D%22M-9.408-1.416c-3.833-.025-7.056%202.912-7.08%206.615-.02%203.08%201.653%204.832%203.107%206.268.903.892%201.721%201.74%202.32%202.902l-.525-.004c-.543-.003-.992.304-1.24.639a1.87%201.87%200%200%200-.362%201.121l-.011%201.877c-.003.402.104.787.347%201.125.244.338.688.653%201.23.656l4.142.028c.542.003.99-.306%201.238-.641a1.87%201.87%200%200%200%20.363-1.121l.012-1.875a1.87%201.87%200%200%200-.348-1.127c-.243-.338-.688-.653-1.23-.656l-.518-.004c.597-1.145%201.425-1.983%202.348-2.87%201.473-1.414%203.18-3.149%203.2-6.226-.016-3.59-2.923-6.684-6.993-6.707m-.006%201.1v.002c3.274.02%205.92%202.532%205.9%205.6-.017%202.706-1.39%204.026-2.863%205.44-1.034.994-2.118%202.033-2.814%203.633-.018.041-.052.055-.075.065q-.013.004-.02.01a.34.34%200%200%201-.226.084.34.34%200%200%201-.224-.086l-.092-.077c-.699-1.615-1.768-2.669-2.781-3.67-1.454-1.435-2.797-2.762-2.78-5.478.02-3.067%202.7-5.545%205.975-5.523m-.02%202.826c-1.62-.01-2.944%201.315-2.955%202.96-.01%201.646%201.295%202.988%202.916%202.999h.002c1.621.01%202.943-1.316%202.953-2.961.011-1.646-1.294-2.988-2.916-2.998m-.005%201.1c1.017.006%201.829.83%201.822%201.89s-.83%201.874-1.848%201.867c-1.018-.006-1.829-.83-1.822-1.89s.83-1.874%201.848-1.868m-2.155%2011.857%204.14.025c.271.002.49.305.487.676l-.013%201.875c-.003.37-.224.67-.495.668l-4.14-.025c-.27-.002-.487-.306-.485-.676l.012-1.875c.003-.37.224-.67.494-.668%22%20style%3D%22color%3A%23000%3Bfont-style%3Anormal%3Bfont-variant%3Anormal%3Bfont-weight%3A400%3Bfont-stretch%3Anormal%3Bfont-size%3Amedium%3Bline-height%3Anormal%3Bfont-family%3Asans-serif%3Bfont-variant-ligatures%3Anormal%3Bfont-variant-position%3Anormal%3Bfont-variant-caps%3Anormal%3Bfont-variant-numeric%3Anormal%3Bfont-variant-alternates%3Anormal%3Bfont-feature-settings%3Anormal%3Btext-indent%3A0%3Btext-align%3Astart%3Btext-decoration%3Anone%3Btext-decoration-line%3Anone%3Btext-decoration-style%3Asolid%3Btext-decoration-color%3A%23000%3Bletter-spacing%3Anormal%3Bword-spacing%3Anormal%3Btext-transform%3Anone%3Bwriting-mode%3Alr-tb%3Bdirection%3Altr%3Btext-orientation%3Amixed%3Bdominant-baseline%3Aauto%3Bbaseline-shift%3Abaseline%3Btext-anchor%3Astart%3Bwhite-space%3Anormal%3Bshape-padding%3A0%3Bclip-rule%3Aevenodd%3Bdisplay%3Ainline%3Boverflow%3Avisible%3Bvisibility%3Avisible%3Bopacity%3A1%3Bisolation%3Aauto%3Bmix-blend-mode%3Anormal%3Bcolor-interpolation%3AsRGB%3Bcolor-interpolation-filters%3AlinearRGB%3Bsolid-color%3A%23000%3Bsolid-opacity%3A1%3Bvector-effect%3Anone%3Bfill%3A%23000%3Bfill-opacity%3A.4%3Bfill-rule%3Aevenodd%3Bstroke%3Anone%3Bstroke-width%3A2.47727823%3Bstroke-linecap%3Abutt%3Bstroke-linejoin%3Amiter%3Bstroke-miterlimit%3A4%3Bstroke-dasharray%3Anone%3Bstroke-dashoffset%3A0%3Bstroke-opacity%3A1%3Bcolor-rendering%3Aauto%3Bimage-rendering%3Aauto%3Bshape-rendering%3Aauto%3Btext-rendering%3Aauto%22%20transform%3D%22translate(15.553%202.85)scale(.88807)%22%2F%3E%3Cpath%20d%3D%22M-9.415-.316C-12.69-.338-15.37%202.14-15.39%205.207c-.017%202.716%201.326%204.041%202.78%205.477%201.013%201%202.081%202.055%202.78%203.67l.092.076a.34.34%200%200%200%20.225.086.34.34%200%200%200%20.227-.083l.019-.01c.022-.009.057-.024.074-.064.697-1.6%201.78-2.64%202.814-3.634%201.473-1.414%202.847-2.733%202.864-5.44.02-3.067-2.627-5.58-5.901-5.601m-.057%208.784c1.621.011%202.944-1.315%202.955-2.96.01-1.646-1.295-2.988-2.916-2.999-1.622-.01-2.945%201.315-2.955%202.96s1.295%202.989%202.916%203%22%20style%3D%22clip-rule%3Aevenodd%3Bfill%3A%23e1e3e9%3Bfill-opacity%3A1%3Bfill-rule%3Aevenodd%3Bstroke%3Anone%3Bstroke-width%3A2.47727823%3Bstroke-miterlimit%3A4%3Bstroke-dasharray%3Anone%3Bstroke-opacity%3A.4%22%20transform%3D%22translate(15.553%202.85)scale(.88807)%22%2F%3E%3Cpath%20d%3D%22M-11.594%2015.465c-.27-.002-.492.297-.494.668l-.012%201.876c-.003.371.214.673.485.675l4.14.027c.271.002.492-.298.495-.668l.012-1.877c.003-.37-.215-.672-.485-.674z%22%20style%3D%22clip-rule%3Aevenodd%3Bfill%3A%23fff%3Bfill-opacity%3A1%3Bfill-rule%3Aevenodd%3Bstroke%3Anone%3Bstroke-width%3A2.47727823%3Bstroke-miterlimit%3A4%3Bstroke-dasharray%3Anone%3Bstroke-opacity%3A.4%22%20transform%3D%22translate(15.553%202.85)scale(.88807)%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E")}}@media (forced-colors:active) and (prefers-color-scheme:light){a.maplibregl-ctrl-logo{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2288%22%20height%3D%2223%22%20fill%3D%22none%22%3E%3Cpath%20fill%3D%22%23000%22%20fill-opacity%3D%22.4%22%20fill-rule%3D%22evenodd%22%20d%3D%22M17.408%2016.796h-1.827l2.501-12.095h.198l3.324%206.533.988%202.19.988-2.19%203.258-6.533h.181l2.6%2012.095h-1.81l-1.218-5.644-.362-1.71-.658%201.71-2.929%205.644h-.098l-2.914-5.644-.757-1.71-.345%201.71zm1.958-3.42-.726%203.663a1.255%201.255%200%200%201-1.232%201.011h-1.827a1.255%201.255%200%200%201-1.229-1.509l2.501-12.095a1.255%201.255%200%200%201%201.23-1.001h.197a1.25%201.25%200%200%201%201.12.685l3.19%206.273%203.125-6.263a1.25%201.25%200%200%201%201.123-.695h.181a1.255%201.255%200%200%201%201.227.991l1.443%206.71a5%205%200%200%201%20.314-.787l.009-.016a4.6%204.6%200%200%201%201.777-1.887c.782-.46%201.668-.667%202.611-.667a4.6%204.6%200%200%201%201.7.32l.306.134c.21-.16.474-.256.759-.256h1.694a1.255%201.255%200%200%201%201.212.925%201.255%201.255%200%200%201%201.212-.925h1.711c.284%200%20.545.094.755.252.613-.3%201.312-.45%202.075-.45%201.356%200%202.557.445%203.482%201.4q.47.48.763%201.064V4.701a1.255%201.255%200%200%201%201.255-1.255h1.86A1.255%201.255%200%200%201%2054.44%204.7v9.194h2.217c.19%200%20.37.043.532.118v-4.77c0-.356.147-.678.385-.906a2.42%202.42%200%200%201-.682-1.71c0-.665.267-1.253.735-1.7a2.45%202.45%200%200%201%201.722-.674%202.43%202.43%200%200%201%201.705.675q.318.302.504.683V4.7a1.255%201.255%200%200%201%201.255-1.255h1.744A1.255%201.255%200%200%201%2065.812%204.7v3.335a4.8%204.8%200%200%201%201.526-.246c.938%200%201.817.214%202.59.69a4.47%204.47%200%200%201%201.67%201.743v-.98a1.255%201.255%200%200%201%201.256-1.256h1.777c.233%200%20.451.064.639.174a3.4%203.4%200%200%201%201.567-.372c.346%200%20.861.02%201.285.232a1.25%201.25%200%200%201%20.689%201.004%204.7%204.7%200%200%201%20.853-.588c.795-.44%201.675-.647%202.61-.647%201.385%200%202.65.39%203.525%201.396.836.938%201.168%202.173%201.168%203.528q-.001.515-.056%201.051a1.255%201.255%200%200%201-.947%201.09l.408.952a1.255%201.255%200%200%201-.477%201.552c-.418.268-.92.463-1.458.612-.613.171-1.304.244-2.049.244-1.06%200-2.043-.207-2.886-.698l-.015-.008c-.798-.48-1.419-1.135-1.818-1.963l-.004-.008a5.8%205.8%200%200%201-.548-2.512q0-.429.053-.843a1.3%201.3%200%200%201-.333-.086l-.166-.004c-.223%200-.426.062-.643.228-.03.024-.142.139-.142.59v3.883a1.255%201.255%200%200%201-1.256%201.256h-1.777a1.255%201.255%200%200%201-1.256-1.256V15.69l-.032.057a4.8%204.8%200%200%201-1.86%201.833%205.04%205.04%200%200%201-2.484.634%204.5%204.5%200%200%201-1.935-.424%201.25%201.25%200%200%201-.764.258h-1.71a1.255%201.255%200%200%201-1.256-1.255V7.687a2.4%202.4%200%200%201-.428.625c.253.23.412.561.412.93v7.553a1.255%201.255%200%200%201-1.256%201.255h-1.843a1.25%201.25%200%200%201-.894-.373c-.228.23-.544.373-.894.373H51.32a1.255%201.255%200%200%201-1.256-1.255v-1.251l-.061.117a4.7%204.7%200%200%201-1.782%201.884%204.77%204.77%200%200%201-2.485.67%205.6%205.6%200%200%201-1.485-.188l.009%202.764a1.255%201.255%200%200%201-1.255%201.259h-1.729a1.255%201.255%200%200%201-1.255-1.255v-3.537a1.255%201.255%200%200%201-1.167.793h-1.679a1.25%201.25%200%200%201-.77-.263%204.5%204.5%200%200%201-1.945.429c-.885%200-1.724-.21-2.495-.632l-.017-.01a5%205%200%200%201-1.081-.836%201.255%201.255%200%200%201-1.254%201.312h-1.81a1.255%201.255%200%200%201-1.228-.99l-.782-3.625-2.044%203.939a1.25%201.25%200%200%201-1.115.676h-.098a1.25%201.25%200%200%201-1.116-.68l-2.061-3.994zM35.92%2016.63l.207-.114.223-.15q.493-.356.735-.785l.061-.118.033%201.332h1.678V9.242h-1.694l-.033%201.267q-.133-.329-.526-.658l-.032-.028a3.2%203.2%200%200%200-.668-.428l-.27-.12a3.3%203.3%200%200%200-1.235-.23q-1.136-.001-1.974.493a3.36%203.36%200%200%200-1.3%201.382q-.445.89-.444%202.074%200%201.2.51%202.107a3.8%203.8%200%200%200%201.382%201.381%203.9%203.9%200%200%200%201.893.477q.795%200%201.455-.33zm-2.789-5.38q-.576.675-.575%201.762%200%201.102.559%201.794.576.675%201.645.675a2.25%202.25%200%200%200%20.934-.19%202.2%202.2%200%200%200%20.468-.29l.178-.161a2.2%202.2%200%200%200%20.397-.561q.244-.5.244-1.15v-.115q0-.708-.296-1.267l-.043-.077a2.2%202.2%200%200%200-.633-.709l-.13-.086-.047-.028a2.1%202.1%200%200%200-1.073-.285q-1.052%200-1.629.692zm2.316%202.706c.163-.17.28-.407.28-.83v-.114c0-.292-.06-.508-.15-.68a.96.96%200%200%200-.353-.389.85.85%200%200%200-.464-.127c-.4%200-.56.114-.664.239l-.01.012c-.148.174-.275.45-.275.945%200%20.506.122.801.27.99.097.11.266.224.68.224.303%200%20.504-.09.687-.269zm7.545%201.705a2.6%202.6%200%200%200%20.331.423q.319.33.755.548l.173.074q.65.255%201.49.255%201.02%200%201.844-.493a3.45%203.45%200%200%200%201.316-1.4q.493-.904.493-2.089%200-1.909-.988-2.913-.988-1.02-2.584-1.02-.898%200-1.575.347a3%203%200%200%200-.415.262l-.199.166a3.4%203.4%200%200%200-.64.82V9.242h-1.712v11.553h1.729l-.017-5.134zm.53-1.138q.206.29.48.5l.155.11.053.034q.51.296%201.119.297%201.07%200%201.645-.675.577-.69.576-1.762%200-1.119-.576-1.777-.558-.675-1.645-.675-.435%200-.835.16a2%202%200%200%200-.284.136%202%202%200%200%200-.363.254%202.2%202.2%200%200%200-.46.569l-.082.162a2.6%202.6%200%200%200-.213%201.072v.115q0%20.707.296%201.267l.135.211zm.964-.818a1.1%201.1%200%200%200%20.367.385.94.94%200%200%200%20.476.118c.423%200%20.59-.117.687-.23.159-.194.28-.478.28-.95%200-.53-.133-.8-.266-.952l-.021-.025c-.078-.094-.231-.221-.68-.221a1%201%200%200%200-.503.135l-.012.007a.86.86%200%200%200-.335.343c-.073.133-.132.324-.132.614v.115a1.4%201.4%200%200%200%20.14.66zm15.7-6.222q.347-.346.346-.856a1.05%201.05%200%200%200-.345-.79%201.18%201.18%200%200%200-.84-.329q-.51%200-.855.33a1.05%201.05%200%200%200-.346.79q0%20.51.346.855.345.346.856.346.51%200%20.839-.346zm4.337%209.314.033-1.332q.191.403.59.747l.098.081a4%204%200%200%200%20.316.224l.223.122a3.2%203.2%200%200%200%201.44.322%203.8%203.8%200%200%200%201.875-.477%203.5%203.5%200%200%200%201.382-1.366q.527-.89.526-2.09%200-1.184-.444-2.073a3.24%203.24%200%200%200-1.283-1.399q-.823-.51-1.942-.51a3.5%203.5%200%200%200-1.527.344l-.086.043-.165.09a3%203%200%200%200-.33.214q-.432.315-.656.707a2%202%200%200%200-.099.198l.082-1.283V4.701h-1.744v12.095zm.473-2.509a2.5%202.5%200%200%200%20.566.7q.117.098.245.18l.144.08a2.1%202.1%200%200%200%20.975.232q1.07%200%201.645-.675.576-.69.576-1.778%200-1.102-.576-1.777-.56-.691-1.645-.692a2.2%202.2%200%200%200-1.015.235q-.22.113-.415.282l-.15.142a2.1%202.1%200%200%200-.42.594q-.223.479-.223%201.1v.115q0%20.705.293%201.26zm2.616-.293c.157-.191.28-.479.28-.967%200-.51-.13-.79-.276-.961l-.021-.026c-.082-.1-.232-.225-.67-.225a.87.87%200%200%200-.681.279l-.012.011c-.154.155-.274.38-.274.807v.115c0%20.285.057.499.144.669a1.1%201.1%200%200%200%20.367.405c.137.082.28.123.455.123.423%200%20.59-.118.686-.23zm8.266-3.013q.345-.13.724-.14l.069-.002q.493%200%20.642.099l.247-1.794q-.196-.099-.717-.099a2.3%202.3%200%200%200-.545.063%202%202%200%200%200-.411.148%202.2%202.2%200%200%200-.4.249%202.5%202.5%200%200%200-.485.499%202.7%202.7%200%200%200-.32.581l-.05.137v-1.48h-1.778v7.553h1.777v-3.884q0-.546.159-.943a1.5%201.5%200%200%201%20.466-.636%202.5%202.5%200%200%201%20.399-.253%202%202%200%200%201%20.224-.099zm9.784%202.656.05-.922q0-1.743-.856-2.698-.838-.97-2.584-.97-1.119-.001-2.007.493a3.46%203.46%200%200%200-1.4%201.382q-.493.906-.493%202.106%200%201.07.428%201.975.428.89%201.332%201.432.906.526%202.255.526.973%200%201.668-.185l.044-.012.135-.04q.613-.184.984-.421l-.542-1.267q-.3.162-.642.274l-.297.087q-.51.131-1.3.131-.954%200-1.497-.444a1.6%201.6%200%200%201-.192-.193q-.366-.44-.512-1.234l-.004-.021zm-5.427-1.256-.003.022h3.752v-.138q-.011-.727-.288-1.118a1%201%200%200%200-.156-.176q-.46-.428-1.316-.428-.986%200-1.494.604-.379.45-.494%201.234zm-27.053%202.77V4.7h-1.86v12.095h5.333V15.15zm7.103-5.908v7.553h-1.843V9.242h1.843z%22%2F%3E%3Cpath%20fill%3D%22%23fff%22%20d%3D%22m19.63%2011.151-.757-1.71-.345%201.71-1.12%205.644h-1.827L18.083%204.7h.197l3.325%206.533.988%202.19.988-2.19L26.839%204.7h.181l2.6%2012.095h-1.81l-1.218-5.644-.362-1.71-.658%201.71-2.93%205.644h-.098l-2.913-5.644zm14.836%205.81q-1.02%200-1.893-.478a3.8%203.8%200%200%201-1.381-1.382q-.51-.906-.51-2.106%200-1.185.444-2.074a3.36%203.36%200%200%201%201.3-1.382q.839-.494%201.974-.494a3.3%203.3%200%200%201%201.234.231%203.3%203.3%200%200%201%20.97.575q.396.33.527.659l.033-1.267h1.694v7.553H37.18l-.033-1.332q-.279.593-1.02%201.053a3.17%203.17%200%200%201-1.662.444zm.296-1.482q.938%200%201.58-.642.642-.66.642-1.711v-.115q0-.708-.296-1.267a2.2%202.2%200%200%200-.807-.872%202.1%202.1%200%200%200-1.119-.313q-1.053%200-1.629.692-.575.675-.575%201.76%200%201.103.559%201.795.577.675%201.645.675zm6.521-6.237h1.711v1.4q.906-1.597%202.83-1.597%201.596%200%202.584%201.02.988%201.005.988%202.914%200%201.185-.493%202.09a3.46%203.46%200%200%201-1.316%201.399%203.5%203.5%200%200%201-1.844.493q-.954%200-1.662-.329a2.67%202.67%200%200%201-1.086-.97l.017%205.134h-1.728zm4.048%206.22q1.07%200%201.645-.674.577-.69.576-1.762%200-1.119-.576-1.777-.558-.675-1.645-.675-.592%200-1.12.296-.51.28-.822.823-.296.527-.296%201.234v.115q0%20.708.296%201.267.313.543.823.855.51.296%201.119.297z%22%2F%3E%3Cpath%20fill%3D%22%23e1e3e9%22%20d%3D%22M51.325%204.7h1.86v10.45h3.473v1.646h-5.333zm7.12%204.542h1.843v7.553h-1.843zm.905-1.415a1.16%201.16%200%200%201-.856-.346%201.17%201.17%200%200%201-.346-.856%201.05%201.05%200%200%201%20.346-.79q.346-.329.856-.329.494%200%20.839.33a1.05%201.05%200%200%201%20.345.79%201.16%201.16%200%200%201-.345.855q-.33.346-.84.346zm7.875%209.133a3.17%203.17%200%200%201-1.662-.444q-.723-.46-1.004-1.053l-.033%201.332h-1.71V4.701h1.743v4.657l-.082%201.283q.279-.658%201.086-1.119a3.5%203.5%200%200%201%201.778-.477q1.119%200%201.942.51a3.24%203.24%200%200%201%201.283%201.4q.445.888.444%202.072%200%201.201-.526%202.09a3.5%203.5%200%200%201-1.382%201.366%203.8%203.8%200%200%201-1.876.477zm-.296-1.481q1.069%200%201.645-.675.577-.69.577-1.778%200-1.102-.577-1.776-.56-.691-1.645-.692a2.12%202.12%200%200%200-1.58.659q-.642.641-.642%201.694v.115q0%20.71.296%201.267a2.4%202.4%200%200%200%20.807.872%202.1%202.1%200%200%200%201.119.313zm5.927-6.237h1.777v1.481q.263-.757.856-1.217a2.14%202.14%200%200%201%201.349-.46q.527%200%20.724.098l-.247%201.794q-.149-.099-.642-.099-.774%200-1.416.494-.626.493-.626%201.58v3.883h-1.777V9.242zm9.534%207.718q-1.35%200-2.255-.526-.904-.543-1.332-1.432a4.6%204.6%200%200%201-.428-1.975q0-1.2.493-2.106a3.46%203.46%200%200%201%201.4-1.382q.889-.495%202.007-.494%201.744%200%202.584.97.855.956.856%202.7%200%20.444-.05.92h-5.43q.18%201.005.708%201.45.542.443%201.497.443.79%200%201.3-.131a4%204%200%200%200%20.938-.362l.542%201.267q-.411.263-1.119.46-.708.198-1.711.197zm1.596-4.558q.016-1.02-.444-1.432-.46-.428-1.316-.428-1.728%200-1.991%201.86z%22%2F%3E%3Cpath%20d%3D%22M5.074%2015.948a.484.657%200%200%200-.486.659v1.84a.484.657%200%200%200%20.486.659h4.101a.484.657%200%200%200%20.486-.659v-1.84a.484.657%200%200%200-.486-.659zm3.56%201.16H5.617v.838h3.017z%22%20style%3D%22fill%3A%23fff%3Bfill-rule%3Aevenodd%3Bstroke-width%3A1.03600001%22%2F%3E%3Cg%20style%3D%22stroke-width%3A1.12603545%22%3E%3Cpath%20d%3D%22M-9.408-1.416c-3.833-.025-7.056%202.912-7.08%206.615-.02%203.08%201.653%204.832%203.107%206.268.903.892%201.721%201.74%202.32%202.902l-.525-.004c-.543-.003-.992.304-1.24.639a1.87%201.87%200%200%200-.362%201.121l-.011%201.877c-.003.402.104.787.347%201.125.244.338.688.653%201.23.656l4.142.028c.542.003.99-.306%201.238-.641a1.87%201.87%200%200%200%20.363-1.121l.012-1.875a1.87%201.87%200%200%200-.348-1.127c-.243-.338-.688-.653-1.23-.656l-.518-.004c.597-1.145%201.425-1.983%202.348-2.87%201.473-1.414%203.18-3.149%203.2-6.226-.016-3.59-2.923-6.684-6.993-6.707m-.006%201.1v.002c3.274.02%205.92%202.532%205.9%205.6-.017%202.706-1.39%204.026-2.863%205.44-1.034.994-2.118%202.033-2.814%203.633-.018.041-.052.055-.075.065q-.013.004-.02.01a.34.34%200%200%201-.226.084.34.34%200%200%201-.224-.086l-.092-.077c-.699-1.615-1.768-2.669-2.781-3.67-1.454-1.435-2.797-2.762-2.78-5.478.02-3.067%202.7-5.545%205.975-5.523m-.02%202.826c-1.62-.01-2.944%201.315-2.955%202.96-.01%201.646%201.295%202.988%202.916%202.999h.002c1.621.01%202.943-1.316%202.953-2.961.011-1.646-1.294-2.988-2.916-2.998m-.005%201.1c1.017.006%201.829.83%201.822%201.89s-.83%201.874-1.848%201.867c-1.018-.006-1.829-.83-1.822-1.89s.83-1.874%201.848-1.868m-2.155%2011.857%204.14.025c.271.002.49.305.487.676l-.013%201.875c-.003.37-.224.67-.495.668l-4.14-.025c-.27-.002-.487-.306-.485-.676l.012-1.875c.003-.37.224-.67.494-.668%22%20style%3D%22color%3A%23000%3Bfont-style%3Anormal%3Bfont-variant%3Anormal%3Bfont-weight%3A400%3Bfont-stretch%3Anormal%3Bfont-size%3Amedium%3Bline-height%3Anormal%3Bfont-family%3Asans-serif%3Bfont-variant-ligatures%3Anormal%3Bfont-variant-position%3Anormal%3Bfont-variant-caps%3Anormal%3Bfont-variant-numeric%3Anormal%3Bfont-variant-alternates%3Anormal%3Bfont-feature-settings%3Anormal%3Btext-indent%3A0%3Btext-align%3Astart%3Btext-decoration%3Anone%3Btext-decoration-line%3Anone%3Btext-decoration-style%3Asolid%3Btext-decoration-color%3A%23000%3Bletter-spacing%3Anormal%3Bword-spacing%3Anormal%3Btext-transform%3Anone%3Bwriting-mode%3Alr-tb%3Bdirection%3Altr%3Btext-orientation%3Amixed%3Bdominant-baseline%3Aauto%3Bbaseline-shift%3Abaseline%3Btext-anchor%3Astart%3Bwhite-space%3Anormal%3Bshape-padding%3A0%3Bclip-rule%3Aevenodd%3Bdisplay%3Ainline%3Boverflow%3Avisible%3Bvisibility%3Avisible%3Bopacity%3A1%3Bisolation%3Aauto%3Bmix-blend-mode%3Anormal%3Bcolor-interpolation%3AsRGB%3Bcolor-interpolation-filters%3AlinearRGB%3Bsolid-color%3A%23000%3Bsolid-opacity%3A1%3Bvector-effect%3Anone%3Bfill%3A%23000%3Bfill-opacity%3A.4%3Bfill-rule%3Aevenodd%3Bstroke%3Anone%3Bstroke-width%3A2.47727823%3Bstroke-linecap%3Abutt%3Bstroke-linejoin%3Amiter%3Bstroke-miterlimit%3A4%3Bstroke-dasharray%3Anone%3Bstroke-dashoffset%3A0%3Bstroke-opacity%3A1%3Bcolor-rendering%3Aauto%3Bimage-rendering%3Aauto%3Bshape-rendering%3Aauto%3Btext-rendering%3Aauto%22%20transform%3D%22translate(15.553%202.85)scale(.88807)%22%2F%3E%3Cpath%20d%3D%22M-9.415-.316C-12.69-.338-15.37%202.14-15.39%205.207c-.017%202.716%201.326%204.041%202.78%205.477%201.013%201%202.081%202.055%202.78%203.67l.092.076a.34.34%200%200%200%20.225.086.34.34%200%200%200%20.227-.083l.019-.01c.022-.009.057-.024.074-.064.697-1.6%201.78-2.64%202.814-3.634%201.473-1.414%202.847-2.733%202.864-5.44.02-3.067-2.627-5.58-5.901-5.601m-.057%208.784c1.621.011%202.944-1.315%202.955-2.96.01-1.646-1.295-2.988-2.916-2.999-1.622-.01-2.945%201.315-2.955%202.96s1.295%202.989%202.916%203%22%20style%3D%22clip-rule%3Aevenodd%3Bfill%3A%23e1e3e9%3Bfill-opacity%3A1%3Bfill-rule%3Aevenodd%3Bstroke%3Anone%3Bstroke-width%3A2.47727823%3Bstroke-miterlimit%3A4%3Bstroke-dasharray%3Anone%3Bstroke-opacity%3A.4%22%20transform%3D%22translate(15.553%202.85)scale(.88807)%22%2F%3E%3Cpath%20d%3D%22M-11.594%2015.465c-.27-.002-.492.297-.494.668l-.012%201.876c-.003.371.214.673.485.675l4.14.027c.271.002.492-.298.495-.668l.012-1.877c.003-.37-.215-.672-.485-.674z%22%20style%3D%22clip-rule%3Aevenodd%3Bfill%3A%23fff%3Bfill-opacity%3A1%3Bfill-rule%3Aevenodd%3Bstroke%3Anone%3Bstroke-width%3A2.47727823%3Bstroke-miterlimit%3A4%3Bstroke-dasharray%3Anone%3Bstroke-opacity%3A.4%22%20transform%3D%22translate(15.553%202.85)scale(.88807)%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E")}}.maplibregl-ctrl.maplibregl-ctrl-attrib{padding:0 5px;background-color:hsla(0,0%,100%,.5);margin:0}@media screen{.maplibregl-ctrl-attrib.maplibregl-compact{min-height:20px;padding:2px 24px 2px 0;margin:10px;position:relative;background-color:#fff;color:#000;border-radius:12px;box-sizing:content-box}.maplibregl-ctrl-attrib.maplibregl-compact-show{padding:2px 28px 2px 8px;visibility:visible}.maplibregl-ctrl-bottom-left>.maplibregl-ctrl-attrib.maplibregl-compact-show,.maplibregl-ctrl-top-left>.maplibregl-ctrl-attrib.maplibregl-compact-show{padding:2px 8px 2px 28px;border-radius:12px}.maplibregl-ctrl-attrib.maplibregl-compact .maplibregl-ctrl-attrib-inner{display:none}.maplibregl-ctrl-attrib-button{display:none;cursor:pointer;position:absolute;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20fill-rule%3D%22evenodd%22%20viewBox%3D%220%200%2020%2020%22%3E%3Cpath%20d%3D%22M4%2010a6%206%200%201%200%2012%200%206%206%200%201%200-12%200m5-3a1%201%200%201%200%202%200%201%201%200%201%200-2%200m0%203a1%201%200%201%201%202%200v3a1%201%200%201%201-2%200%22%2F%3E%3C%2Fsvg%3E");background-color:hsla(0,0%,100%,.5);width:24px;height:24px;box-sizing:border-box;border-radius:12px;outline:none;top:0;right:0;border:0}.maplibregl-ctrl-attrib summary.maplibregl-ctrl-attrib-button{-webkit-appearance:none;-moz-appearance:none;appearance:none;list-style:none}.maplibregl-ctrl-attrib summary.maplibregl-ctrl-attrib-button::-webkit-details-marker{display:none}.maplibregl-ctrl-bottom-left .maplibregl-ctrl-attrib-button,.maplibregl-ctrl-top-left .maplibregl-ctrl-attrib-button{left:0}.maplibregl-ctrl-attrib.maplibregl-compact .maplibregl-ctrl-attrib-button,.maplibregl-ctrl-attrib.maplibregl-compact-show .maplibregl-ctrl-attrib-inner{display:block}.maplibregl-ctrl-attrib.maplibregl-compact-show .maplibregl-ctrl-attrib-button{background-color:rgba(0,0,0,.05)}.maplibregl-ctrl-bottom-right>.maplibregl-ctrl-attrib.maplibregl-compact:after{bottom:0;right:0}.maplibregl-ctrl-top-right>.maplibregl-ctrl-attrib.maplibregl-compact:after{top:0;right:0}.maplibregl-ctrl-top-left>.maplibregl-ctrl-attrib.maplibregl-compact:after{top:0;left:0}.maplibregl-ctrl-bottom-left>.maplibregl-ctrl-attrib.maplibregl-compact:after{bottom:0;left:0}}@media screen and (forced-colors:active){.maplibregl-ctrl-attrib.maplibregl-compact:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20fill%3D%22%23fff%22%20fill-rule%3D%22evenodd%22%20viewBox%3D%220%200%2020%2020%22%3E%3Cpath%20d%3D%22M4%2010a6%206%200%201%200%2012%200%206%206%200%201%200-12%200m5-3a1%201%200%201%200%202%200%201%201%200%201%200-2%200m0%203a1%201%200%201%201%202%200v3a1%201%200%201%201-2%200%22%2F%3E%3C%2Fsvg%3E")}}@media screen and (forced-colors:active) and (prefers-color-scheme:light){.maplibregl-ctrl-attrib.maplibregl-compact:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20fill-rule%3D%22evenodd%22%20viewBox%3D%220%200%2020%2020%22%3E%3Cpath%20d%3D%22M4%2010a6%206%200%201%200%2012%200%206%206%200%201%200-12%200m5-3a1%201%200%201%200%202%200%201%201%200%201%200-2%200m0%203a1%201%200%201%201%202%200v3a1%201%200%201%201-2%200%22%2F%3E%3C%2Fsvg%3E")}}.maplibregl-ctrl-attrib a{color:rgba(0,0,0,.75);text-decoration:none}.maplibregl-ctrl-attrib a:hover{color:inherit;text-decoration:underline}.maplibregl-attrib-empty{display:none}.maplibregl-ctrl-scale{background-color:hsla(0,0%,100%,.75);font-size:10px;white-space:nowrap;border-color:#333;border-style:none solid solid;border-width:medium 2px 2px;padding:0 5px;color:#333;box-sizing:border-box}.maplibregl-popup{position:absolute;top:0;left:0;display:flex;will-change:transform;pointer-events:none}.maplibregl-popup-anchor-top,.maplibregl-popup-anchor-top-left,.maplibregl-popup-anchor-top-right{flex-direction:column}.maplibregl-popup-anchor-bottom,.maplibregl-popup-anchor-bottom-left,.maplibregl-popup-anchor-bottom-right{flex-direction:column-reverse}.maplibregl-popup-anchor-left{flex-direction:row}.maplibregl-popup-anchor-right{flex-direction:row-reverse}.maplibregl-popup-tip{width:0;height:0;border:10px solid transparent;z-index:1}.maplibregl-popup-anchor-top .maplibregl-popup-tip{align-self:center;border-top:none;border-bottom-color:#fff}.maplibregl-popup-anchor-top-left .maplibregl-popup-tip{align-self:flex-start;border-top:none;border-left:none;border-bottom-color:#fff}.maplibregl-popup-anchor-top-right .maplibregl-popup-tip{align-self:flex-end;border-top:none;border-right:none;border-bottom-color:#fff}.maplibregl-popup-anchor-bottom .maplibregl-popup-tip{align-self:center;border-bottom:none;border-top-color:#fff}.maplibregl-popup-anchor-bottom-left .maplibregl-popup-tip{align-self:flex-start;border-bottom:none;border-left:none;border-top-color:#fff}.maplibregl-popup-anchor-bottom-right .maplibregl-popup-tip{align-self:flex-end;border-bottom:none;border-right:none;border-top-color:#fff}.maplibregl-popup-anchor-left .maplibregl-popup-tip{align-self:center;border-left:none;border-right-color:#fff}.maplibregl-popup-anchor-right .maplibregl-popup-tip{align-self:center;border-right:none;border-left-color:#fff}[dir=rtl] .maplibregl-popup-anchor-left{flex-direction:row-reverse}[dir=rtl] .maplibregl-popup-anchor-right{flex-direction:row}[dir=rtl] .maplibregl-popup-anchor-top-left .maplibregl-popup-tip{align-self:flex-end}[dir=rtl] .maplibregl-popup-anchor-top-right .maplibregl-popup-tip{align-self:flex-start}[dir=rtl] .maplibregl-popup-anchor-bottom-left .maplibregl-popup-tip{align-self:flex-end}[dir=rtl] .maplibregl-popup-anchor-bottom-right .maplibregl-popup-tip{align-self:flex-start}.maplibregl-popup-close-button{position:absolute;right:0;top:0;border:0;border-radius:0 3px 0 0;cursor:pointer;background-color:transparent}.maplibregl-popup-close-button:hover{background-color:rgba(0,0,0,.05)}.maplibregl-popup-content{position:relative;background:#fff;border-radius:3px;box-shadow:0 1px 2px rgba(0,0,0,.1);padding:15px 10px;pointer-events:auto}.maplibregl-popup-anchor-top-left .maplibregl-popup-content{border-top-left-radius:0}.maplibregl-popup-anchor-top-right .maplibregl-popup-content{border-top-right-radius:0}.maplibregl-popup-anchor-bottom-left .maplibregl-popup-content{border-bottom-left-radius:0}.maplibregl-popup-anchor-bottom-right .maplibregl-popup-content{border-bottom-right-radius:0}.maplibregl-popup-track-pointer{display:none}.maplibregl-popup-track-pointer *{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.maplibregl-map:hover .maplibregl-popup-track-pointer{display:flex}.maplibregl-map:active .maplibregl-popup-track-pointer{display:none}.maplibregl-marker{position:absolute;top:0;left:0;will-change:transform;transition:opacity .2s}.maplibregl-marker-draggable{cursor:grab}.maplibregl-user-location-dot,.maplibregl-user-location-dot:before{background-color:#1da1f2;width:15px;height:15px;border-radius:50%}.maplibregl-user-location-dot:before{content:"";position:absolute;animation:maplibregl-user-location-dot-pulse 2s infinite}.maplibregl-user-location-dot:after{border-radius:50%;border:2px solid #fff;content:"";height:19px;left:-2px;position:absolute;top:-2px;width:19px;box-sizing:border-box;box-shadow:0 0 3px rgba(0,0,0,.35)}@media (prefers-reduced-motion:reduce){.maplibregl-user-location-dot:before{animation:none}}@keyframes maplibregl-user-location-dot-pulse{0%{transform:scale(1);opacity:1}70%{transform:scale(3);opacity:0}to{transform:scale(1);opacity:0}}.maplibregl-user-location-dot-stale{background-color:#aaa}.maplibregl-user-location-dot-stale:after{display:none}.maplibregl-user-location-accuracy-circle{background-color:#1da1f233;width:1px;height:1px;border-radius:100%}.maplibregl-crosshair,.maplibregl-crosshair .maplibregl-interactive,.maplibregl-crosshair .maplibregl-interactive:active{cursor:crosshair}.maplibregl-boxzoom{position:absolute;top:0;left:0;width:0;height:0;background:#fff;border:2px dotted #202020;opacity:.5}.maplibregl-cooperative-gesture-screen{background:rgba(0,0,0,.4);position:absolute;inset:0;display:flex;justify-content:center;align-items:center;color:#fff;padding:1rem;font-size:1.4em;line-height:1.2;opacity:0;pointer-events:none;transition:opacity 1s ease 1s;z-index:99999}.maplibregl-cooperative-gesture-screen.maplibregl-show{opacity:1;transition:opacity .05s}.maplibregl-cooperative-gesture-screen .maplibregl-mobile-message{display:none}@media (hover:none),(pointer:coarse){.maplibregl-cooperative-gesture-screen .maplibregl-desktop-message{display:none}.maplibregl-cooperative-gesture-screen .maplibregl-mobile-message{display:block}}.maplibregl-pseudo-fullscreen{position:fixed!important;width:100%!important;height:100%!important;top:0!important;left:0!important;z-index:99999}
\ No newline at end of file
diff --git a/web/vendor/maplibre/maplibre-gl.mjs b/web/vendor/maplibre/maplibre-gl.mjs
new file mode 100644
index 000000000..16c40880e
--- /dev/null
+++ b/web/vendor/maplibre/maplibre-gl.mjs
@@ -0,0 +1,806 @@
+/**
+* MapLibre GL JS
+* @license 3-Clause BSD. Full text of license: https://github.com/maplibre/maplibre-gl-js/blob/v6.7.0/LICENSE.txt
+*/
+import{$ as e,$n as t,$r as n,$t as r,A as i,Ai as a,An as o,Ar as s,At as c,Bi as l,Bn as u,Br as d,Bt as f,C as p,Ci as m,Cn as h,Cr as g,Ct as _,D as v,Di as y,Dn as b,Dr as x,Dt as S,E as C,Ei as w,En as T,Er as E,Et as D,F as ee,Fi as O,Fn as k,Fr as A,Ft as j,Gn as M,Gr as te,Gt as ne,H as re,Hn as ie,Hr as N,Ht as ae,I as oe,Ii as se,In as ce,Ir as le,It as ue,J as de,Jn as fe,Jr as pe,Jt as me,K as he,Kn as ge,Kr as _e,Kt as ve,L as ye,Li as be,Ln as xe,Lr as Se,Lt as Ce,Mi as we,Mn as Te,Mr as Ee,Mt as De,N as Oe,Ni as ke,Nn as Ae,Nr as je,Nt as P,O as Me,Oi as Ne,On as Pe,Or as Fe,Ot as Ie,Pi as Le,Pn as Re,Pr as ze,Pt as F,Q as Be,Qn as Ve,Qr as He,Qt as Ue,R as We,Ri as Ge,Rn as Ke,Rr as I,Rt as qe,S as Je,Si as Ye,Sn as Xe,Sr as Ze,T as Qe,Ti as $e,Tn as et,Tr as tt,Tt as nt,U as rt,Un as it,Ur as at,Ut as ot,V as st,Vn as ct,Vr as lt,Vt as ut,Wn as dt,Wr as ft,Wt as pt,X as mt,Xn as L,Xr as ht,Xt as gt,Y as _t,Yn as vt,Yr as yt,Yt as bt,Z as xt,Zn as St,Zr as Ct,Zt as wt,_ as Tt,_i as Et,_n as R,_r as Dt,_t as Ot,a as kt,ai as At,an as jt,ar as z,at as Mt,b as Nt,bi as Pt,bn as Ft,br as It,bt as Lt,ci as Rt,cn as zt,cr as Bt,ct as Vt,di as Ht,dn as Ut,dt as Wt,ei as Gt,en as Kt,er as qt,et as Jt,f as Yt,fi as Xt,fn as Zt,fr as Qt,g as $t,gi as en,gn as tn,gr as nn,h as rn,hi as an,hn as on,hr as sn,ht as cn,ii as ln,ir as un,it as dn,j as fn,ji as pn,jn as mn,jr as hn,jt as gn,k as _n,ki as vn,kn as yn,kr as bn,kt as xn,li as Sn,ln as Cn,lr as wn,lt as Tn,mi as En,mr as Dn,mt as On,ni as kn,nn as An,nr as jn,nt as Mn,oi as Nn,on as Pn,or as Fn,ot as In,pi as Ln,pn as Rn,pr as zn,pt as Bn,qn as Vn,qr as Hn,qt as Un,r as Wn,ri as Gn,rn as Kn,rr as qn,rt as B,s as Jn,si as Yn,sr as Xn,st as Zn,t as Qn,ti as $n,tn as er,tr,tt as nr,u as rr,ui as ir,un as ar,ur as or,ut as V,v as sr,vi as cr,vn as lr,vr as ur,vt as dr,w as fr,wi as pr,wn as mr,wr as hr,wt as gr,x as _r,xi as vr,xn as H,xr as yr,xt as br,y as xr,yi as Sr,yn as Cr,yr as wr,yt as Tr,z as Er,zi as Dr,zr as Or,zt as kr}from"./maplibre-gl-shared.mjs";var Ar=`6.7.0`;function jr(){var e=new be(4);return be!=Float32Array&&(e[1]=0,e[2]=0),e[0]=1,e[3]=1,e}function Mr(e,t){var n=t[0],r=t[1],i=t[2],a=t[3],o=n*a-i*r;return o?(o=1/o,e[0]=a*o,e[1]=-r*o,e[2]=-i*o,e[3]=n*o,e):null}function Nr(e){return e[0]*e[3]-e[2]*e[1]}function Pr(e,t,n){var r=t[0],i=t[1],a=t[2],o=t[3],s=Math.sin(n),c=Math.cos(n);return e[0]=r*c+a*s,e[1]=i*c+o*s,e[2]=r*-s+a*c,e[3]=i*-s+o*c,e}let Fr,Ir,Lr;const Rr={frame(e,t,n,r){let i=r||window,a=i.requestAnimationFrame(e=>{o(),t(e)}),{unsubscribe:o}=ze(e.signal,`abort`,()=>{o(),i.cancelAnimationFrame(a),n(new ce(e.signal.reason))},!1)},frameAsync(e,t){return new Promise((n,r)=>{this.frame(e,n,r,t)})},getImageData(e,t=0){return this.getImageCanvasContext(e).getImageData(-t,-t,e.width+2*t,e.height+2*t)},getImageCanvasContext(e){let t=window.document.createElement(`canvas`),n=t.getContext(`2d`,{willReadFrequently:!0});if(!n)throw Error(`failed to create canvas 2d context`);return t.width=e.width,t.height=e.height,n.drawImage(e,0,0,e.width,e.height),n},resolveURL(e){return Fr||=document.createElement(`a`),Fr.href=e,Fr.href},get hardwareConcurrency(){return typeof navigator<`u`&&navigator.hardwareConcurrency||4},get prefersReducedMotion(){return Lr===void 0?matchMedia?(Ir??=matchMedia(`(prefers-reduced-motion: reduce)`),Ir.matches):!1:Lr},set prefersReducedMotion(e){Lr=e}},zr=new class{constructor(){this._frozenAt=null}getCurrentTime(){return this._frozenAt===null?performance.now():this._frozenAt}setNow(e){this._frozenAt=e}restoreNow(){this._frozenAt=null}isFrozen(){return this._frozenAt!==null}};function U(){return zr.getCurrentTime()}function Br(e){zr.setNow(e)}function Vr(){zr.restoreNow()}function Hr(){return zr.isFrozen()}var W=class e{static{this.docStyle=typeof window<`u`&&window.document?.documentElement.style}static{this.selectProp=!e.docStyle||`userSelect`in e.docStyle?`userSelect`:`webkitUserSelect`}static create(e,t,n){let r=window.document.createElement(e);return t!==void 0&&(r.className=t),n&&n.appendChild(r),r}static createNS(e,t){return window.document.createElementNS(e,t)}static disableDrag(){e.docStyle&&e.selectProp&&(e.userSelect=e.docStyle[e.selectProp],e.docStyle[e.selectProp]=`none`)}static enableDrag(){e.docStyle&&e.selectProp&&(e.docStyle[e.selectProp]=e.userSelect)}static suppressClickInternal(t){t.preventDefault(),t.stopPropagation(),window.removeEventListener(`click`,e.suppressClickInternal,!0)}static suppressClick(){window.addEventListener(`click`,e.suppressClickInternal,!0),window.setTimeout(()=>{window.removeEventListener(`click`,e.suppressClickInternal,!0)},0)}static getScale(e){let t=e.getBoundingClientRect();return{x:t.width/e.offsetWidth||1,y:t.height/e.offsetHeight||1,boundingClientRect:t}}static getPoint(e,t,n){let r=t.boundingClientRect;return new l((n.clientX-r.left)/t.x-e.clientLeft,(n.clientY-r.top)/t.y-e.clientTop)}static mousePos(t,n){let r=e.getScale(t);return e.getPoint(t,r,n)}static touchPos(t,n){let r=[],i=e.getScale(t);for(let a of n)r.push(e.getPoint(t,i,a));return r}static sanitize(t){let n=new DOMParser().parseFromString(t,`text/html`).body||document.createElement(`body`),r=n.querySelectorAll(`script`);for(let e of r)e.remove();return e.clean(n),n.innerHTML}static isPossiblyDangerous(e,t){let n=t.replace(/\s+/g,``).toLowerCase();if([`src`,`href`,`xlink:href`].includes(e)&&(n.includes(`javascript:`)||n.includes(`data:`))||e.startsWith(`on`))return!0}static clean(t){let n=t.children;for(let t of n)e.removeAttributes(t),e.clean(t)}static removeAttributes(t){for(let{name:n,value:r}of Array.from(t.attributes))e.isPossiblyDangerous(n,r)&&t.removeAttribute(n)}};let Ur;(function(e){let t,n,r,i;e.resetRequestQueue=()=>{t=[],n=0,r=0,i={}},e.addThrottleControl=e=>{let t=r++;return i[t]=e,t},e.removeThrottleControl=e=>{delete i[e],u()};let a=()=>{for(let e of Object.keys(i))if(i[e]())return!0;return!1};async function s(e,t,n,r,i=!0,a){let o=await e.transformRequest(t,n);return Ke(r.signal),Ur.getImage(o,r,i,a)}e.transformAndGetImage=s,e.getImage=(e,n,r=!0,i)=>new Promise((a,o)=>{e.headers||={},e.headers.accept=`image/webp,*/*`,z(e,{type:`image`});let s={abortController:n,requestParameters:e,supportImageRefresh:r,imageBitmapOptions:i,state:`queued`,onError:e=>{o(e)},onSuccess:e=>{a(e)}};t.push(s),u()});let c=(e,t)=>typeof createImageBitmap==`function`?it(e,t):ie(e),l=async e=>{e.state=`running`;let{requestParameters:t,supportImageRefresh:r,imageBitmapOptions:i,onError:a,onSuccess:s,abortController:l}=e,f=r===!1&&!i&&!ur(self)&&!Ae(t.url)&&(!t.headers||Object.keys(t.headers).reduce((e,t)=>e&&t===`accept`,!0));n++;let p=f?d(t,l):o(t,l);try{let t=await p;delete e.abortController,e.state=`completed`,t.data instanceof HTMLImageElement||zn(t.data)?s(t):t.data&&s({data:await c(t.data,i),cacheControl:t.cacheControl,expires:t.expires})}catch(t){delete e.abortController,a(qn(t))}finally{n--,u()}},u=()=>{let e=a()?k.MAX_PARALLEL_IMAGE_REQUESTS_PER_FRAME:k.MAX_PARALLEL_IMAGE_REQUESTS;for(let r=n;r0;r++){let e=t.shift();if(e.abortController.signal.aborted){r--;continue}l(e)}},d=(e,t)=>new Promise((n,r)=>{let i=new Image,a=e.url,o=e.credentials;o&&o===`include`?i.crossOrigin=`use-credentials`:(o&&o===`same-origin`||!mn(a))&&(i.crossOrigin=`anonymous`),t.signal.addEventListener(`abort`,()=>{i.src=``,r(new ce(t.signal.reason))}),i.fetchPriority=`high`,i.onload=()=>{i.onerror=i.onload=null,n({data:i})},i.onerror=()=>{i.onerror=i.onload=null,!t.signal.aborted&&r(Error(`Could not load image. Please make sure to use a supported image type such as PNG or JPEG. Note that SVGs are not supported.`))},i.src=a})})(Ur||={}),Ur.resetRequestQueue();var Wr=class{constructor(e){this._transformRequestFn=e??null}transformRequest(e,t){return this._transformRequestFn&&this._transformRequestFn(e,t)||{url:e}}setTransformRequest(e){this._transformRequestFn=e}},Gr=class extends Xe{},G=class extends Gr{},Kr=class extends Gr{constructor(e={}){super(`style.load`,e)}},qr=class extends Gr{constructor(e,t={}){super(e,t),this.dataType=`style`}},K=class extends Gr{constructor(e,t={}){super(e,t),this.dataType=`source`}},Jr=class extends Gr{preventDefault(){this._defaultPrevented=!0}get defaultPrevented(){return this._defaultPrevented}constructor(e,t,n,r={}){n=n instanceof MouseEvent?n:new MouseEvent(e,n);let i=W.mousePos(t.getCanvas(),n),a=t.unproject(i);super(e,z({point:i,lngLat:a,originalEvent:n},r)),this._defaultPrevented=!1,this.target=t}},Yr=class extends Gr{preventDefault(){this._defaultPrevented=!0}get defaultPrevented(){return this._defaultPrevented}constructor(e,t,n){let r=e===`touchend`?n.changedTouches:n.touches,i=W.touchPos(t.getCanvasContainer(),r),a=i.map(e=>t.unproject(e)),o=i.reduce((e,t,n,r)=>e.add(t.div(r.length)),new l(0,0)),s=t.unproject(o);super(e,{points:i,point:o,lngLats:a,lngLat:s,originalEvent:n}),this._defaultPrevented=!1}},Xr=class extends Gr{preventDefault(){this._defaultPrevented=!0}get defaultPrevented(){return this._defaultPrevented}constructor(e,t){super(`wheel`,{originalEvent:t}),this._defaultPrevented=!1}},Zr=class extends Gr{},Qr=class extends Gr{constructor(e={}){super(`terrain`,e)}},$r=class extends Gr{constructor(e={}){super(`projectiontransition`,e)}},ei=class extends Gr{},ti=class extends Gr{constructor(e={}){super(`styleimagemissing`,e)}};function ni(e,t){let n={};for(let t in e)t!==`ref`&&(n[t]=e[t]);return Cr.forEach(e=>{e in t&&(n[e]=t[e])}),n}function ri(e){e=e.slice();let t=Object.create(null);for(let n=0;n{`source`in e&&r[e.source]?n.push({command:`removeLayer`,args:[e.id]}):a.push(e)}),n=n.concat(i),pi(a,t.layers,n)}catch(e){console.warn(`Unable to compute style diff:`,e),n=[{command:`setStyle`,args:[t]}]}return n}function hi(){let e={},t=Ft.$version;for(let n in Ft.$root){let r=Ft.$root[n];if(r.required){let i=null;i=n===`version`?t:r.type===`array`?[]:{},i!=null&&(e[n]=i)}}return e}function gi(e){let t=[];if(typeof e==`string`)t.push({id:`default`,url:e});else if(e&&e.length>0){let n=[];for(let{id:r,url:i}of e){let e=`${r}${i}`;n.includes(e)||(n.push(e),t.push({id:r,url:i}))}}return t}function _i(e,t,n){try{let r=new URL(e);return r.pathname+=`${t}${n}`,r.toString()}catch{throw Error(`Invalid sprite URL "${e}", must be absolute. Modify style specification directly or use TransformStyleFunction to correct the issue dynamically`)}}async function vi(e,t,n,r){let i=gi(e),a=n>1?`@2x`:``,o={},s={};for(let{id:e,url:n}of i){let i=await t.transformRequest(_i(n,a,`.json`),`SpriteJSON`);o[e]=b(i,r);let c=await t.transformRequest(_i(n,a,`.png`),`SpriteImage`);s[e]=Ur.getImage(c,r)}return await Promise.all([...Object.values(o),...Object.values(s)]),yi(o,s)}async function yi(e,t){let n={};for(let r in e){n[r]={};let i=Rr.getImageCanvasContext((await t[r]).data),a=(await e[r]).data;for(let e in a){let{width:t,height:o,x:s,y:c,sdf:l,pixelRatio:u,stretchX:d,stretchY:f,content:p,textFitWidth:m,textFitHeight:h}=a[e],g={width:t,height:o,x:s,y:c,context:i};n[r][e]={data:null,pixelRatio:u,sdf:l,stretchX:d,stretchY:f,content:p,textFitWidth:m,textFitHeight:h,spriteData:g}}}return n}var bi=class extends h{constructor(){super(),this.images={},this.updateVersion=0,this.loaded=!1,this.requestors=[],this.missingImageResolver=null,this._spriteImagesIds={},this._imagesIds=null,this._renderCallbacksDispatchedThisFrame={}}destroy(){for(let e of Object.keys(this.images))this.removeImage(e);this._spriteImagesIds={}}isLoaded(){return this.loaded}setLoaded(e){if(this.loaded!==e&&(this.loaded=e,e)){for(let{ids:e,promiseResolve:t}of this.requestors)t(this._getImagesForIds(e));this.requestors=[]}}getImage(e){let t=this.images[e];if(t&&!t.data&&t.spriteData){let e=t.spriteData;t.data=new xn({width:e.width,height:e.height},e.context.getImageData(e.x,e.y,e.width,e.height).data),t.spriteData=null}return t}addImage(e,t){if(this.images[e])throw Error(`Image id ${e} already exist, use updateImage instead`);this._validate(e,t)&&(this.images[e]=t,this._imagesIds=null,t.isWebGLImage&&this.updateImage(e,t,!1))}_validate(e,t){let n=!0,r=t.data||t.spriteData;return this._validateStretch(t.stretchX,r?.width)||(this.fire(new H(Error(`Image "${e}" has invalid "stretchX" value`))),n=!1),this._validateStretch(t.stretchY,r?.height)||(this.fire(new H(Error(`Image "${e}" has invalid "stretchY" value`))),n=!1),this._validateContent(t.content,t)||(this.fire(new H(Error(`Image "${e}" has invalid "content" value`))),n=!1),n}_validateStretch(e,t){if(!e)return!0;let n=0;for(let r of e){if(r[0]=e[1]}updateImage(e,t,n=!0){let r=this.images[e];if(n){let e=r.data||r.spriteData;if(e.width!==t.data.width||e.height!==t.data.height)throw Error(`size mismatch between old image (${e.width}x${e.height}) and new image (${t.data.width}x${t.data.height}).`)}t.version=(r.version??0)+1,this.images[e]=t,this.updateVersion++}removeImage(e){let t=this.images[e];t&&(delete this.images[e],this._imagesIds=null,t.userImage?.onRemove&&t.userImage.onRemove())}listImages(){return this._imagesIds??=Object.keys(this.images),this._imagesIds}_getSpriteImageId(e,t){return e==="default"?t:`${e}:${t}`}setSpriteImages(e,t){let n=this._spriteImagesIds[e]??[],r=[];for(let n in t){let i=this._getSpriteImageId(e,n);r.push(i),i in this.images?this.updateImage(i,t[n],!1):this.addImage(i,t[n])}let i=new Set(r),a=n.filter(e=>!i.has(e));for(let e of a)this.removeImage(e);return this._spriteImagesIds[e]=r,{loaded:r,removed:a}}removeSpriteImages(e){let t=this._spriteImagesIds[e]??[];for(let e of t)this.removeImage(e);return delete this._spriteImagesIds[e],t}removeAllSpriteImages(){let e=Object.values(this._spriteImagesIds).flat();for(let t of e)this.removeImage(t);return this._spriteImagesIds={},e}setMissingImageResolver(e){this.missingImageResolver=e}getImages(e){return new Promise((t,n)=>{let r=!0;if(!this.isLoaded())for(let t of e)this.images[t]||(r=!1);this.isLoaded()||r?t(this._getImagesForIds(e)):this.requestors.push({ids:e,promiseResolve:t})})}async _getImagesForIds(e){let t=new Set(e.filter(e=>!this.getImage(e))),n=this.missingImageResolver;n&&await Promise.allSettled(Array.from(t,e=>n(e)));let r={};for(let n of e){let e=this.getImage(n);e&&(t.delete(n),r[n]={data:e.data.clone(),pixelRatio:e.pixelRatio,sdf:e.sdf,version:e.version,stretchX:e.stretchX,stretchY:e.stretchY,content:e.content,textFitWidth:e.textFitWidth,textFitHeight:e.textFitHeight,hasRenderCallback:!!e.userImage?.render,isWebGLImage:e.isWebGLImage})}for(let e of t)this.fire(new ti({id:e})),I(`Image "${e}" could not be loaded. Please make sure you have added the image before it is needed with map.addImage(), resolved it with map.setMissingStyleImageResolver(), or included it in a "sprite" property in your style.`);return r}beginFrame(){this._renderCallbacksDispatchedThisFrame={}}dispatchRenderCallbacks(e){for(let t of e){if(this._renderCallbacksDispatchedThisFrame[t])continue;this._renderCallbacksDispatchedThisFrame[t]=!0;let e=this.getImage(t);e||I(`Image with ID: "${t}" was not found`),We(e)&&this.updateImage(t,e)}}cloneImages(){let e={};for(let t in this.images){let n=this.images[t];e[t]={...n,data:n.data?n.data.clone():null}}return e}},xi=class{constructor(e){this._imageManager=e,this._entries={},this._image=new xn({width:1,height:1}),this._dirty=!0}destroy(){this._texture&&=(this._texture.destroy(),null),this._entries={},this._image=new xn({width:1,height:1}),this._dirty=!0}getPixelSize(){let{width:e,height:t}=this._image;return{width:e,height:t}}getPattern(e){let t=this._imageManager.getImage(e);if(!t)return null;let n=this._entries[e];if(n?.image!==t){let n={w:t.data.width+2,h:t.data.height+2,x:0,y:0};this._entries[e]={bin:n,position:new ee(n,t),image:t}}else if(n.position.version!==t.version)n.position.version=t.version;else return n.position;return this._update(),this._entries[e].position}bind(e){let t=e.gl;this._texture?this._dirty&&=(this._texture.update(this._image),!1):(this._texture=new _(e,this._image,t.RGBA),this._dirty=!1),this._texture.bind(t.LINEAR,t.CLAMP_TO_EDGE)}_update(){for(let e in this._entries)this._imageManager.getImage(e)||delete this._entries[e];let e=[];for(let t in this._entries)e.push(this._entries[t].bin);let{w:t,h:n}=oe(e),r=this._image;r.resize({width:t||1,height:n||1});for(let e in this._entries){let{bin:t}=this._entries[e],n=t.x+1,i=t.y+1,a=this._entries[e].image.data,o=a.width,s=a.height;xn.copy(a,r,{x:0,y:0},{x:n,y:i},{width:o,height:s}),xn.copy(a,r,{x:0,y:s-1},{x:n,y:i-1},{width:o,height:1}),xn.copy(a,r,{x:0,y:0},{x:n,y:i+s},{width:o,height:1}),xn.copy(a,r,{x:o-1,y:0},{x:n-1,y:i},{width:1,height:s}),xn.copy(a,r,{x:0,y:0},{x:n+o,y:i},{width:1,height:s})}this._dirty=!0}};const Si=1114111,Ci={start:0,end:Si};let wi=0;function Ti(e){let t=/^u\+([0-9a-f]*)(\?+)$/i.exec(e);if(t){let[,e,n]=t;return e.length+n.length>6?null:Ei(parseInt(`${e}${`0`.repeat(n.length)}`,16),parseInt(`${e}${`f`.repeat(n.length)}`,16))}let n=/^u\+([0-9a-f]{1,6})(?:-([0-9a-f]{1,6}))?$/i.exec(e);if(!n)return null;let r=parseInt(n[1],16);return Ei(r,n[2]===void 0?r:parseInt(n[2],16))}function Ei(e,t){return e>t||e>Si?null:{start:e,end:Math.min(t,Si)}}function Di(e,t){return e.ranges.some(({start:e,end:n})=>t>=e&&t<=n)}var Oi=class{constructor(e){this.requestManager=e,this._faces={},this._registered=new Set}setFontFaces(e){this._unregisterAll(),this._faces={};for(let[t,n]of Object.entries(e??{})){let e=Array.isArray(n)?n:[n];this._faces[t]=e.map(e=>this._declareFontFace(t,e)).filter(e=>e!==null)}}hasFontFaces(){return Object.keys(this._faces).length>0}async getFontFamily(e,t){for(let n of e.split(`,`))for(let e of this._faces[n.trim()]??[])if(Di(e,t)&&(e.loaded??=this._loadFontFace(e),await e.loaded))return e.family;return null}_declareFontFace(e,t){let n=typeof t==`string`?{url:t}:t;if(typeof n?.url!=`string`)return I(`Ignoring the font face declared for "${e}": it has no URL.`),null;let r=`maplibre-gl-font-face-${wi++}`,i=n[`unicode-range`];if(!i?.length)return{url:n.url,ranges:[Ci],family:r};let a=[];for(let e of i){let t=Ti(e);if(!t){I(`Ignoring the unicode range "${e}" of the font face at ${n.url}: it is not a valid range.`);continue}a.push(t)}return a.length?{url:n.url,ranges:a,family:r}:null}async _loadFontFace(e){if(typeof FontFace>`u`||typeof document>`u`||!document.fonts)return I(`Ignoring the font face at ${e.url}: this environment has no CSS Font Loading API.`),!1;let t;try{return t=new FontFace(e.family,await this._downloadFontFile(e.url)),Object.values(this._faces).some(t=>t.includes(e))?(document.fonts.add(t),this._registered.add(t),await t.load(),!0):!1}catch(n){return t&&this._unregister(t),I(`Ignoring the font face at ${e.url}: ${qn(n).message}`),!1}}async _downloadFontFile(e){let t=await this.requestManager.transformRequest(e,`Glyphs`),n=await T(t,new AbortController);if(!n?.data)throw Error(`the response was empty for the font file at ${e}`);return n.data}_unregister(e){document.fonts?.delete(e),this._registered.delete(e)}_unregisterAll(){for(let e of this._registered)document.fonts?.delete(e);this._registered.clear()}destroy(){this._unregisterAll(),this._faces={}}};const ki=0x56bc75e2d63100000,Ai=new Float64Array(256);for(let e=0;e<256;e++){let t=.5-(e/255)**(1/2.2);Ai[e]=t*Math.abs(t)}Ai[255]=-0x56bc75e2d63100000;var ji=class{constructor({fontSize:e=24,buffer:t=3,radius:n=8,cutoff:r=.25,fontFamily:i=`sans-serif`,fontWeight:a=`normal`,fontStyle:o=`normal`,lang:s=null}={}){this.buffer=t,this.radius=n,this.cutoff=r,this.lang=s;let c=this.size=e+t*4,l=this._createCanvas(c),u=this.ctx=l.getContext(`2d`,{willReadFrequently:!0});u.font=`${o} ${a} ${e}px ${i}`,u.textBaseline=`alphabetic`,u.textAlign=`left`,u.fillStyle=`black`,this.gridOuter=new Float64Array(c*c),this.gridInner=new Float64Array(c*c),this.f=new Float64Array(c),this.z=new Float64Array(c+1),this.v=new Uint16Array(c)}_createCanvas(e){if(typeof OffscreenCanvas<`u`)return new OffscreenCanvas(e,e);let t=document.createElement(`canvas`);return t.width=t.height=e,t}draw(e){let{width:t,actualBoundingBoxAscent:n,actualBoundingBoxDescent:r,actualBoundingBoxLeft:i,actualBoundingBoxRight:a}=this.ctx.measureText(e),o=Math.ceil(n),s=Math.floor(-i),c=Math.max(0,Math.min(this.size-this.buffer,Math.ceil(a)-s)),l=Math.max(0,Math.min(this.size-this.buffer,o+Math.ceil(r))),u=c+2*this.buffer,d=l+2*this.buffer,f=Math.max(u*d,0),p=new Uint8ClampedArray(f),m={data:p,width:u,height:d,glyphWidth:c,glyphHeight:l,glyphTop:o,glyphLeft:s,glyphAdvance:t};if(c===0||l===0)return m;let{ctx:h,buffer:g,gridInner:_,gridOuter:v}=this;this.lang&&(h.lang=this.lang),h.clearRect(g,g,c,l),h.fillText(e,g-s,g+o);let y=h.getImageData(g,g,c,l);v.fill(ki,0,f),_.fill(0,0,f);let b=3;for(let e=0;e-1);c++,a[c]=s,o[c]=l,o[c+1]=ki}for(let s=0,c=0;s{let n=new ji(e);return n.buffer=t,n};var Ii=class{constructor(e,t,n,r=Fi){this.requestManager=e,this.localIdeographFontFamily=t,this.entries={},this.lang=n,this.fontFaceManager=new Oi(e),this.createRasterizer=r}setURL(e){this.url=e}setFontFaces(e){this.fontFaceManager.setFontFaces(e),this.entries={}}async getGlyphs(e){let t=[];for(let n in e)for(let r of e[n])t.push(this._getAndCacheGlyphsPromise(n,r));let n=await Promise.all(t),r={};for(let{stack:e,id:t,glyph:i}of n)r[e]||={},r[e][t]=i&&{id:i.id,bitmap:i.bitmap.clone(),metrics:i.metrics};return r}async _getAndCacheGlyphsPromise(e,t){this.entries[e]??={glyphs:{},requests:{},ranges:{}};let n=this.entries[e],r=n.glyphs[t];if(r!==void 0)return{stack:e,id:t,glyph:r};let i=t.codePointAt(0),a=this.fontFaceManager.hasFontFaces()?await this.fontFaceManager.getFontFamily(e,i):null;return a?(r=n.glyphs[t]=await this._drawGlyph(n,e,t,a),{stack:e,id:t,glyph:r}):st(t)?(r=n.glyphs[t]=null,{stack:e,id:t,glyph:r}):!this.url||this._charUsesLocalIdeographFontFamily(i)?(r=n.glyphs[t]=await this._drawGlyph(n,e,t),{stack:e,id:t,glyph:r}):await this._downloadAndCacheRangePromise(e,t)}async _downloadAndCacheRangePromise(e,t){let n=t.codePointAt(0),r=this.entries[e],i=Math.floor(n/256);if(r.ranges[i])return{stack:e,id:t,glyph:null};r.requests[i]||=this._loadGlyphRange(e,i);try{let a=await r.requests[i];for(let e in a)r.glyphs[String.fromCodePoint(+e)]=a[+e];return r.ranges[i]=!0,{stack:e,id:t,glyph:a[n]||null}}catch(a){let o=r.glyphs[t]=await this._drawGlyph(r,e,t);return this._warnOnMissingGlyphRange(o,i,n,qn(a)),{stack:e,id:t,glyph:o}}}async _loadGlyphRange(e,t){let n=t*256,r=n+255,i=await this.requestManager.transformRequest(this.url.replace(`{fontstack}`,e).replace(`{range}`,`${n}-${r}`),`Glyphs`),a=await T(i,new AbortController);if(!a?.data)throw Error(`Could not load glyph range. range: ${t}, ${n}-${r}`);let o={};for(let e of Er(a.data))o[e.id]=e;return o}_warnOnMissingGlyphRange(e,t,n,r){let i=t*256,a=i+255,o=n.toString(16).padStart(4,`0`).toUpperCase();I(`Unable to load glyph range ${t}, ${i}-${a}. Rendering codepoint U+${o} locally instead. ${r}`)}_charUsesLocalIdeographFontFamily(e){return!!this.localIdeographFontFamily&&jt(e)}async _drawGlyph(e,t,n,r){let i=(await this._getTinySDF(e,t,n,r)).draw(n),a=/^\p{gc=Cf}+$/u.test(n);return{id:n.codePointAt(0),bitmap:new Ie({width:i.width||60,height:i.height||60},i.data),metrics:{width:a?0:i.glyphWidth/2||24,height:i.glyphHeight/2||24,left:i.glyphLeft/2+.5||0,top:i.glyphTop/2-27.5||-8,advance:a?0:i.glyphAdvance/2||24,isDoubleResolution:!0}}}_getTinySDF(e,t,n,r){if(r){let t=st(n),i=t?`clusterTinySDFs`:`fontFaceTinySDFs`;return e[i]??={},e[i][r]||=this._createTinySDF(r,!1,t?3:1),e[i][r]}let i=t===Pi&&this.localIdeographFontFamily!==``&&this._charUsesLocalIdeographFontFamily(n.codePointAt(0)),a=i?`ideographTinySDF`:`tinySDF`;return e[a]||=this._createTinySDF(i?this.localIdeographFontFamily:t),e[a]}async _createTinySDF(e,t=!0,n=1){let r=e?e.split(`,`):[];r.push(`sans-serif`);let i=r.map(e=>/[-\w]+/.test(e)?e:`'${CSS.escape(e)}'`).join(`,`),a=t?this._fontWeight(r[0]):void 0,o=t?this._fontStyle(r[0]):`normal`;if(typeof document<`u`&&document.fonts?.load)try{await document.fonts.load(`${o} ${a||`normal`} 48px ${i}`)}catch(e){I(`Failed to load font "${i}": ${qn(e).message}`)}return this.createRasterizer({fontSize:48,buffer:Math.max(6,Math.ceil(48*(n-1)/4)),radius:16,cutoff:.25,fontFamily:i,fontWeight:a,fontStyle:o,lang:this.lang},6)}_fontStyle(e){return/italic/i.test(e)?`italic`:/oblique/i.test(e)?`oblique`:`normal`}_fontWeight(e){let t={thin:100,hairline:100,"extra light":200,"ultra light":200,light:300,normal:400,regular:400,medium:500,semibold:600,demibold:600,bold:700,"extra bold":800,"ultra bold":800,black:900,heavy:900,"extra black":950,"ultra black":950},n;for(let[r,i]of Object.entries(t))RegExp(`\\b${r}\\b`,`i`).test(e)&&(n=`${i}`);return n}destroy(){for(let e in this.entries){let t=this.entries[e];t.tinySDF=null,t.ideographTinySDF=null,t.fontFaceTinySDFs={},t.glyphs={},t.requests={},t.ranges={}}this.entries={},this.fontFaceManager.destroy()}};let Li;const Ri=()=>Li||=new Kt({anchor:new r(Ft.light.anchor,`anchor`),position:new r(Ft.light.position,`position`),color:new r(Ft.light.color,`color`),intensity:new r(Ft.light.intensity,`intensity`)});var zi=class extends h{constructor(e,t){super(),this._transitionable=new An(Ri(),`light`,t),this.setLight(e),this._transitioning=this._transitionable.untransitioned()}getLight(){return this._transitionable.serialize()}getCartesianPosition(){return je(this.properties.get(`position`))}setLight(e,t={}){if(!this._validate(Ut.light,e,t))for(let t in e){let n=e[t];t.endsWith(`-transition`)?this._transitionable.setTransition(t.slice(0,-er.length),n):this._transitionable.setValue(t,n)}}updateTransitions(e){this._transitioning=this._transitionable.transitioned(e,this._transitioning)}hasTransition(){return this._transitioning.hasTransition()}recalculate(e){this.properties=this._transitioning.possiblyEvaluate(e)}_validate(e,t,n){return ar(this,e,{value:t},n)}};let Bi;const Vi=()=>Bi||=new Kt({"sky-color":new r(Ft.sky[`sky-color`],`sky-color`),"horizon-color":new r(Ft.sky[`horizon-color`],`horizon-color`),"fog-color":new r(Ft.sky[`fog-color`],`fog-color`),"fog-ground-blend":new r(Ft.sky[`fog-ground-blend`],`fog-ground-blend`),"horizon-fog-blend":new r(Ft.sky[`horizon-fog-blend`],`horizon-fog-blend`),"sky-horizon-blend":new r(Ft.sky[`sky-horizon-blend`],`sky-horizon-blend`),"atmosphere-blend":new r(Ft.sky[`atmosphere-blend`],`atmosphere-blend`)});var Hi=class extends h{constructor(e,t){super(),this._transitionable=new An(Vi(),`sky`,t),this.setSky(e),this._transitioning=this._transitionable.untransitioned(),this.recalculate(new Kn(0))}setSky(e,t={}){if(!this._validate(Ut.sky,e,t)){e||={"sky-color":`transparent`,"horizon-color":`transparent`,"fog-color":`transparent`,"fog-ground-blend":1,"atmosphere-blend":0};for(let t in e){let n=e[t];t.endsWith(`-transition`)?this._transitionable.setTransition(t.slice(0,-er.length),n):this._transitionable.setValue(t,n)}}}getSky(){return this._transitionable.serialize()}updateTransitions(e){this._transitioning=this._transitionable.transitioned(e,this._transitioning)}hasTransition(){return this._transitioning.hasTransition()}recalculate(e){this.properties=this._transitioning.possiblyEvaluate(e)}_validate(e,t,n={}){return ar(this,e,{value:t},n)}calculateFogBlendOpacity(e){return e<60?0:e<70?(e-60)/10:1}},Ui=class{constructor(e,t){this.width=e,this.height=t,this.nextRow=0,this.data=new Uint8Array(this.width*this.height),this.dashEntry={}}getDash(e,t){let n=e.join(`,`)+String(t);return this.dashEntry[n]||=this.addDash(e,t),this.dashEntry[n]}getDashRanges(e,t,n){let r=e.length%2==1,i=[],a=r?-e[e.length-1]*n:0,o=e[0]*n,s=!0;i.push({left:a,right:o,isDash:s,zeroLength:e[0]===0});let c=e[0];for(let t=1;t1&&(s=e[++o]);let c=Math.abs(i-s.left),l=Math.abs(i-s.right),u=Math.min(c,l),d,f=t/n*(r+1);if(s.isDash){let e=r-Math.abs(f);d=Math.sqrt(u*u+e*e)}else d=r-Math.sqrt(u*u+f*f);this.data[a+i]=Math.max(0,Math.min(255,d+128))}}}addRegularDash(e){for(let t=e.length-1;t>=0;--t){let n=e[t],r=e[t+1];n.zeroLength?e.splice(t,1):r?.isDash===n.isDash&&(r.left=n.left,e.splice(t,1))}let t=e[0],n=e[e.length-1];t.isDash===n.isDash&&(t.left=n.left-this.width,n.right=t.right+this.width);let r=this.width*this.nextRow,i=0,a=e[i];for(let t=0;t1&&(a=e[++i]);let n=Math.abs(t-a.left),o=Math.abs(t-a.right),s=Math.min(n,o),c=a.isDash?s:-s;this.data[r+t]=Math.max(0,Math.min(255,c+128))}}addDash(e,t){let n=t?7:0,r=2*n+1;if(this.nextRow+r>this.height)return I(`LineAtlas out of space`),null;let i=0;for(let t of e)i+=t;if(i!==0){let r=this.width/i,a=this.getDashRanges(e,this.width,r);t?this.addRoundDash(a,r,n):this.addRegularDash(a)}let a={y:this.nextRow+n,height:2*n,width:i};return this.nextRow+=r,this.dirty=!0,a}bind(e){let t=e.gl;this.texture?(t.bindTexture(t.TEXTURE_2D,this.texture),this.dirty&&(this.dirty=!1,t.texSubImage2D(t.TEXTURE_2D,0,0,0,this.width,this.height,t.ALPHA,t.UNSIGNED_BYTE,this.data))):(this.texture=t.createTexture(),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.REPEAT),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.REPEAT),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.LINEAR),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.LINEAR),t.texImage2D(t.TEXTURE_2D,0,t.ALPHA,this.width,this.height,0,t.ALPHA,t.UNSIGNED_BYTE,this.data))}};function Wi(e){if(!e)return!1;let t=globalThis.location;if(!t)return!1;try{return new URL(e,t.href).origin!==t.origin}catch{return!1}}function Gi(){let e=import.meta.url;if(!/^https?:/.test(e))return``;let t=e.endsWith(`-dev.mjs`)?`maplibre-gl-worker-dev.mjs`:`maplibre-gl-worker.mjs`;return new URL(`./${t}`,e).href}function Ki(e,t){if(t)try{return new Worker(e,{type:`module`})}catch(e){console.warn(`Module worker not supported, falling back to classic worker`,e)}return new Worker(e)}async function qi(e){let t=await fetch(e);if(!t.ok)throw Error(`Failed to fetch worker script (${t.status}): ${e}`);let n=await t.text(),r=new Blob([n],{type:`text/javascript`});return URL.createObjectURL(r)}function Ji(e){let t=new Blob([`import ${JSON.stringify(new URL(e,import.meta.url).href)}`],{type:`text/javascript`});return URL.createObjectURL(t)}async function Yi(){let e=k.WORKER_URL||Gi(),t=!e?.endsWith(`.cjs`);if(!Wi(e))return Ki(e,t);if(t){let n=Ji(e);try{return Ki(n,t)}finally{URL.revokeObjectURL(n)}}let n=await qi(e);try{return Ki(n,t)}finally{URL.revokeObjectURL(n)}}const Xi=`maplibre_preloaded_worker_pool`;var Zi=class e{constructor(){this.active={},this.workersPromise=null}async acquire(t){if(this.active[t]=!0,!this.workersPromise){let t=[];for(;t.length{for(let t of e)t.terminate()})}}isPreloaded(){return!!this.active[Xi]}numActive(){return Object.keys(this.active).length}};const Qi=Math.floor(Rr.hardwareConcurrency/2);Zi.workerCount=sn(globalThis)?Math.max(Math.min(Qi,3),1):1;let $i;function ea(){return $i||=new Zi,$i}function ta(){ea().acquire(Xi)}function na(){let e=$i;e&&(e.isPreloaded()&&e.numActive()===1?(e.release(Xi),$i=null):console.warn(`Could not clear WebWorkers since there are active Map instances that still reference it. The pre-warmed WebWorker pool can only be cleared when all map instances have been removed with map.remove()`))}var ra=class{constructor(e,t){this.workerPool=e,this.actors=[],this.currentActor=0,this.id=t,this.removed=!1,this.actorsPromise=this.initActors(t)}async initActors(e){let t=await this.workerPool.acquire(e);if(this.removed)return[];if(this.actors=t.map((t,n)=>{let r=new _r(t,e);return r.name=`Worker ${n}`,r}),!this.actors.length)throw Error(`No actors found`);return this.actors}async broadcast(e,t){let n=await this.actorsPromise;return Promise.all(n.map(n=>n.sendAsync({type:e,data:t})))}async getActor(){let e=await this.actorsPromise;return this.currentActor=(this.currentActor+1)%e.length,e[this.currentActor]}async waitForInitComplete(){this.actors.length===0&&await this.actorsPromise}getReadyActor(){return this.currentActor=(this.currentActor+1)%this.actors.length,this.actors[this.currentActor]}remove(e=!0){this.removed=!0;for(let e of this.actors)e.remove();this.actors=[],e&&this.workerPool.release(this.id)}async registerMessageHandler(e,t){let n=await this.actorsPromise;for(let r of n)r.registerMessageHandler(e,t)}async unregisterMessageHandler(e){let t=await this.actorsPromise;for(let n of t)n.unregisterMessageHandler(e)}};let ia;function aa(){return ia||(ia=new ra(ea(),et),ia.registerMessageHandler(`GR`,(e,t,n)=>o(t,n))),ia}function oa(e,t){let n=vr();return Le(n,n,[1,1,0]),ke(n,n,[e.width*.5,e.height*.5,1]),e.calculatePosMatrix?y(n,n,e.calculatePosMatrix(t.toUnwrapped())):n}function sa(e,t,n){if(e)for(let r of e){let e=t[r];if(e?.source===n&&e.type===`fill-extrusion`)return!0}else for(let e in t){let r=t[e];if(r.source===n&&r.type===`fill-extrusion`)return!0}return!1}function ca(e,t,n,r,i,a,o){let s=sa(i?.layers??null,t,e.id),c=a.maxPitchScaleFactor(),l=e.tilesIn(r,c,s);l.sort(da);let u=[];for(let r of l)u.push({wrappedTileID:r.tileID.wrapped().key,queryResults:r.tile.queryRenderedFeatures(t,n,e.getState(),r.queryGeometry,r.cameraQueryGeometry,r.scale,i,a,c,oa(a,r.tileID),o?(e,t)=>o(r.tileID,e,t):void 0)});return pa(fa(u),e)}function la(e,t,n,r,i,a,o){let s={},c=a.queryRenderedSymbols(r),l=[];for(let e of Object.keys(c).map(Number))l.push(o[e]);l.sort(da);for(let n of l){let r=n.featureIndex.lookupSymbolFeatures(c[n.bucketInstanceId],t,n.bucketIndex,n.sourceLayerIndex,{filterSpec:i.filter,globalState:i.globalState},i.layers,i.availableImages,e);for(let e in r){s[e]||=[];let t=r[e];t.sort((e,t)=>{let r=n.featureSortOrder;if(r){let n=r.indexOf(e.featureIndex);return r.indexOf(t.featureIndex)-n}return t.featureIndex-e.featureIndex});for(let n of t)s[e].push(n)}}return ma(s,e,n)}function ua(e,t){let n=e.getRenderableIds().map(t=>e.getTileByID(t)),r=[],i={};for(let e of n){let n=e.tileID.canonical.key;i[n]||(i[n]=!0,e.querySourceFeatures(r,t))}return r}function da(e,t){let n=e.tileID,r=t.tileID;return n.overscaledZ-r.overscaledZ||n.canonical.y-r.canonical.y||n.wrap-r.wrap||n.canonical.x-r.canonical.x}function fa(e){let t={},n={};for(let{queryResults:r,wrappedTileID:i}of e){n[i]||={};let e=n[i];for(let n in r){let i=r[n];e[n]||={};let a=e[n];t[n]||=[];for(let e of i)a[e.featureIndex]||(a[e.featureIndex]=!0,t[n].push(e))}}return t}function pa(e,t){for(let n in e)for(let r of e[n])ha(r,t);return e}function ma(e,t,n){for(let r in e)for(let i of e[r]){let e=n[t[r].source];ha(i,e)}return e}function ha(e,t){let n=e.feature,r=t.getFeatureState(n.layer[`source-layer`],n.id);n.source=n.layer.source,n.layer[`source-layer`]&&(n.sourceLayer=n.layer[`source-layer`]),n.state=r}async function ga(e,t,n,r){let i=e;if(e.url?i=(await b(await t.transformRequest(e.url,`Source`),n)).data:await Rr.frameAsync(n,r),!i)return null;let a=hr(z(i,e),[`tiles`,`minzoom`,`maxzoom`,`attribution`,`bounds`,`scheme`,`tileSize`,`encoding`]);return`vector_layers`in i&&i.vector_layers&&(a.vectorLayerIds=i.vector_layers.map(e=>e.id)),a}var _a=class e{constructor(e,t){e&&(t?this.setSouthWest(e).setNorthEast(t):Array.isArray(e)&&(e.length===4?this.setSouthWest([e[0],e[1]]).setNorthEast([e[2],e[3]]):this.setSouthWest(e[0]).setNorthEast(e[1])))}setNorthEast(e){return this._ne=e instanceof V?new V(e.lng,e.lat):V.convert(e),this}setSouthWest(e){return this._sw=e instanceof V?new V(e.lng,e.lat):V.convert(e),this}extend(t){let n=this._sw,r=this._ne,i,a;if(t instanceof V)i=t,a=t;else if(t instanceof e){if(i=t._sw,a=t._ne,!i||!a)return this}else{if(Array.isArray(t)){if(t.length===4||t.every(Array.isArray)){let n=t;return this.extend(e.convert(n))}{let e=t;return this.extend(V.convert(e))}}return t&&(`lng`in t||`lon`in t)&&`lat`in t?this.extend(V.convert(t)):this}return!n&&!r?(this._sw=new V(i.lng,i.lat),this._ne=new V(a.lng,a.lat)):(n.lng=Math.min(i.lng,n.lng),n.lat=Math.min(i.lat,n.lat),r.lng=Math.max(a.lng,r.lng),r.lat=Math.max(a.lat,r.lat)),this}getCenter(){return new V((this._sw.lng+this._ne.lng)/2,(this._sw.lat+this._ne.lat)/2)}getSouthWest(){return this._sw}getNorthEast(){return this._ne}getNorthWest(){return new V(this.getWest(),this.getNorth())}getSouthEast(){return new V(this.getEast(),this.getSouth())}getWest(){return this._sw.lng}getSouth(){return this._sw.lat}getEast(){return this._ne.lng}getNorth(){return this._ne.lat}toArray(){return[this._sw.toArray(),this._ne.toArray()]}toString(){return`LngLatBounds(${this._sw.toString()}, ${this._ne.toString()})`}isEmpty(){return!(this._sw&&this._ne)}contains(e){let{lng:t,lat:n}=V.convert(e),r=this._sw.lat<=n&&n<=this._ne.lat,i=this._sw.lng<=t&&t<=this._ne.lng;return this._sw.lng>this._ne.lng&&(i=this._sw.lng>=t&&t>=this._ne.lng),r&&i}intersects(t){if(t=e.convert(t),!(t.getNorth()>=this.getSouth()&&t.getSouth()<=this.getNorth()))return!1;let n=Math.abs(this.getEast()-this.getWest()),r=Math.abs(t.getEast()-t.getWest());if(n>=360||r>=360)return!0;let i=Or(this.getWest(),-180,180),a=Or(this.getEast(),-180,180),o=Or(t.getWest(),-180,180),s=Or(t.getEast(),-180,180),c=i>a,l=o>s;return c&&l?!0:c?s>=i||o<=a:l?a>=o||i<=s:o<=a&&s>=i}static convert(t){return t instanceof e||!t?t:new e(t)}static fromLngLat(t,n=0){let r=360*n/40075017,i=r/Math.cos(Math.PI/180*t.lat);return new e(new V(t.lng-i,t.lat-r),new V(t.lng+i,t.lat+r))}adjustAntiMeridian(){let t=new V(this._sw.lng,this._sw.lat),n=new V(this._ne.lng,this._ne.lat);return t.lng>n.lng?new e(t,new V(n.lng+360,n.lat)):new e(t,n)}},va=class{constructor(e,t,n){this.bounds=_a.convert(this.validateBounds(e)),this.minzoom=t||0,this.maxzoom=n||24}validateBounds(e){return!Array.isArray(e)||e.length!==4?[-180,-90,180,90]:[Math.max(-180,e[0]),Math.max(-90,e[1]),Math.min(180,e[2]),Math.min(90,e[3])]}contains(e){let t=2**e.z,n={minX:Math.floor(Zn(this.bounds.getWest())*t),minY:Math.floor(Vt(this.bounds.getNorth())*t),maxX:Math.ceil(Zn(this.bounds.getEast())*t),maxY:Math.ceil(Vt(this.bounds.getSouth())*t)};return e.x>=n.minX&&e.x=n.minY&&e.y{this._options.tiles=e}),this}setUrl(e){return this.setSourceProperty(()=>{this.url=e,this._options.url=e}),this}onRemove(){this._tileJSONRequest&&=(this._tileJSONRequest.abort(),null)}serialize(){return z({},this._options)}async loadTile(e){let t=e.tileID.canonical.url(this.tiles,this.map.getPixelRatio(),this.scheme),n={request:await this.map._requestManager.transformRequest(t,`Tile`),uid:e.uid,tileID:e.tileID,zoom:e.tileID.overscaledZ,tileSize:this.tileSize*e.tileID.overscaleFactor(),type:this.type,source:this.id,pixelRatio:this.map.getPixelRatio(),showCollisionBoxes:this.map.showCollisionBoxes,promoteId:this.promoteId,subdivisionGranularity:this.map.style.projection.subdivisionGranularity,encoding:this.encoding,overzoomParameters:await this._getOverzoomParameters(e),etag:e.etag};n.request.collectResourceTiming=this._collectResourceTiming,await this.dispatcher.waitForInitComplete();let r=`RT`;if(!e.actor||e.state===`expired`)e.actor=this.dispatcher.getReadyActor(),r=`LT`;else if(e.state===`loading`)return new Promise((t,n)=>{e.reloadPromise={resolve:t,reject:n}});e.abortController=new AbortController;try{let t=await e.actor.sendAsync({type:r,data:n},e.abortController);if(delete e.abortController,e.aborted)return;this._afterTileLoadWorkerResponse(e,t);let i={};return t?.etagUnmodified&&(i.unmodified=!0),i}catch(t){if(delete e.abortController,e.aborted||xe(t))return;if(t&&t.status!==404)throw t;this._afterTileLoadWorkerResponse(e,null)}}async _getOverzoomParameters(e){if(e.tileID.canonical.z<=this.maxzoom||this.map._zoomLevelsToOverscale===void 0)return;let t=e.tileID.scaledTo(this.maxzoom).canonical,n=t.url(this.tiles,this.map.getPixelRatio(),this.scheme);return{maxZoomTileID:t,overzoomRequest:await this.map._requestManager.transformRequest(n,`Tile`)}}_afterTileLoadWorkerResponse(e,t){if(t?.resourceTiming&&(e.resourceTiming=t.resourceTiming),t&&this.map._refreshExpiredTiles&&e.setExpiryData(t),e.etag=t?.etag,e.loadVectorData(t,this.map.painter),e.reloadPromise){let t=e.reloadPromise;e.reloadPromise=null,this.loadTile(e).then(t.resolve).catch(t.reject)}}async abortTile(e){e.abortController&&(e.abortController.abort(),delete e.abortController),e.actor&&await e.actor.sendAsync({type:`AT`,data:{uid:e.uid,type:this.type,source:this.id}})}async unloadTile(e){e.unloadVectorData(),e.actor&&await e.actor.sendAsync({type:`RMT`,data:{uid:e.uid,type:this.type,source:this.id}})}hasTransition(){return!1}},ba=class extends h{constructor(e,t,n,r){super(),this.id=e,this.dispatcher=n,this.setEventedParent(r),this.type=`raster`,this.minzoom=0,this.maxzoom=22,this.roundZoom=!0,this.scheme=`xyz`,this.tileSize=512,this._loaded=!1,this._premultiplyAlpha=!0,this._options=z({type:`raster`},t),z(this,hr(t,[`url`,`scheme`,`tileSize`]))}async load(e=!1){this._loaded=!1,this.fire(new K(`dataloading`)),this._tileJSONRequest=new AbortController;try{let t=await ga(this._options,this.map._requestManager,this._tileJSONRequest,this.map._ownerWindow);this._tileJSONRequest=null,this._loaded=!0,t&&(z(this,t),t.bounds&&(this.tileBounds=new va(t.bounds,this.minzoom,this.maxzoom)),this.fire(new K(`data`,{sourceDataType:`metadata`})),this.fire(new K(`data`,{sourceDataType:`content`,sourceDataChanged:e})))}catch(e){this._tileJSONRequest=null,this._loaded=!0,xe(e)||this.fire(new H(qn(e)))}}loaded(){return this._loaded}onAdd(e){this.map=e,this.load()}onRemove(){this._tileJSONRequest&&=(this._tileJSONRequest.abort(),null)}setSourceProperty(e){this._tileJSONRequest&&=(this._tileJSONRequest.abort(),null),e(),this.load(!0)}setTiles(e){return this.setSourceProperty(()=>{this._options.tiles=e}),this}setUrl(e){return this.setSourceProperty(()=>{this.url=e,this._options.url=e}),this}serialize(){return z({},this._options)}setPremultiplyAlpha(e){return this._premultiplyAlpha===e||this.setSourceProperty(()=>{this._premultiplyAlpha=e}),this}hasTile(e){return!this.tileBounds||this.tileBounds.contains(e.canonical)}async loadTile(e){let t=e.tileID.canonical.url(this.tiles,this.map.getPixelRatio(),this.scheme),n=this._premultiplyAlpha,r=n?void 0:{premultiplyAlpha:`none`};e.abortController=new AbortController;try{let i=await Ur.transformAndGetImage(this.map._requestManager,t,`Tile`,e.abortController,this.map._refreshExpiredTiles,r);if(delete e.abortController,e.aborted){e.state=`unloaded`;return}if(i?.data){this.map._refreshExpiredTiles&&(i.cacheControl||i.expires)&&e.setExpiryData({cacheControl:i.cacheControl,expires:i.expires});let t=this.map.painter.context,r=t.gl,a=i.data;e.texture=this.map.painter.getTileTexture(a.width),e.texture?e.texture.update(a,{useMipmap:!0,premultiply:n}):(e.texture=new _(t,a,r.RGBA,{useMipmap:!0,premultiply:n}),e.texture.bind(r.LINEAR,r.CLAMP_TO_EDGE,r.LINEAR_MIPMAP_NEAREST)),e.state=`loaded`}}catch(t){if(delete e.abortController,e.aborted)e.state=`unloaded`;else if(t)throw e.state=`errored`,t}}async abortTile(e){e.abortController&&(e.abortController.abort(),delete e.abortController)}async unloadTile(e){e.texture&&this.map.painter.saveTileTexture(e.texture)}hasTransition(){return!1}},xa=class extends ba{constructor(e,t,n,r){super(e,t,n,r),this.type=`raster-dem`,this.maxzoom=22,this._options=z({type:`raster-dem`},t),this.encoding=t.encoding||`mapbox`,this.redFactor=t.redFactor,this.greenFactor=t.greenFactor,this.blueFactor=t.blueFactor,this.baseShift=t.baseShift}async loadTile(e){let t=e.tileID.canonical.url(this.tiles,this.map.getPixelRatio(),this.scheme);e.neighboringTiles=this._getNeighboringTiles(e.tileID),e.abortController=new AbortController;try{let n=await Ur.transformAndGetImage(this.map._requestManager,t,`Tile`,e.abortController,this.map._refreshExpiredTiles,{colorSpaceConversion:`none`});if(delete e.abortController,e.aborted){e.state=`unloaded`;return}if(n?.data){let t=n.data;this.map._refreshExpiredTiles&&(n.cacheControl||n.expires)&&e.setExpiryData({cacheControl:n.cacheControl,expires:n.expires});let r=zn(t)&&Dr()?t:await this.readImageNow(t),i={type:this.type,uid:e.uid,source:this.id,rawImageData:r,encoding:this.encoding,redFactor:this.redFactor,greenFactor:this.greenFactor,blueFactor:this.blueFactor,baseShift:this.baseShift};if(e.actor&&e.state!==`expired`&&e.state!==`reloading`)return;await this.dispatcher.waitForInitComplete(),(!e.actor||e.state===`expired`)&&(e.actor=this.dispatcher.getReadyActor()),e.dem=await e.actor.sendAsync({type:`LDT`,data:i}),e.needsHillshadePrepare=!0,e.needsTerrainPrepare=!0,e.needsColorReliefPrepare=!0,e.state=`loaded`}}catch(t){if(delete e.abortController,e.aborted)e.state=`unloaded`;else if(t)throw e.state=`errored`,t}}async readImageNow(e){if(typeof VideoFrame<`u`&&Ge()){let t=e.width+2,n=e.height+2;try{return new xn({width:t,height:n},await Fe(e,-1,-1,t,n))}catch{}}return Rr.getImageData(e,1)}_getNeighboringTiles(e){let t=e.canonical,n=2**t.z,r=(t.x-1+n)%n,i=t.x===0?e.wrap-1:e.wrap,a=(t.x+1+n)%n,o=t.x+1===n?e.wrap+1:e.wrap,s={};return s[new $t(e.overscaledZ,i,t.z,r,t.y).key]={backfilled:!1},s[new $t(e.overscaledZ,o,t.z,a,t.y).key]={backfilled:!1},t.y>0&&(s[new $t(e.overscaledZ,i,t.z,r,t.y-1).key]={backfilled:!1},s[new $t(e.overscaledZ,e.wrap,t.z,t.x,t.y-1).key]={backfilled:!1},s[new $t(e.overscaledZ,o,t.z,a,t.y-1).key]={backfilled:!1}),t.y+10||n.addOrUpdateProperties?.length>0;if(!i&&!a)continue;r.push(t.geometry);let o={...t};if(e.set(n.id,o),i&&(r.push(n.newGeometry),o.geometry=n.newGeometry),a){if(o.properties=n.removeAllProperties?{}:{...o.properties||{}},n.removeProperties)for(let e of n.removeProperties)delete o.properties[e];if(n.addOrUpdateProperties)for(let{key:e,value:t}of n.addOrUpdateProperties)o.properties[e]=t}}return r}function Ta(e,t,n){if(!e)return t||{};if(!t)return e||{};n&&(Oa(e.add,n),Oa(t.add,n));let r=Aa(e),i=Aa(t);Ea(r,i);let a={};if((r.removeAll||i.removeAll)&&(a.removeAll=!0),a.remove=new Set([...r.remove,...i.remove]),a.add=new Map([...r.add,...i.add]),a.update=new Map([...r.update,...i.update]),a.remove.size&&a.add.size)for(let e of a.add.keys())a.remove.delete(e);let o=ja(a);return n&&ka(o.add,n),o}function Ea(e,t){t.removeAll&&(e.add.clear(),e.update.clear(),e.remove.clear(),t.remove.clear());for(let n of t.remove)e.add.delete(n),e.update.delete(n);for(let[n,r]of t.update){let i=e.update.get(n);i&&(t.update.set(n,Da(i,r)),e.update.delete(n))}}function Da(e,t){let n={id:e.id};if(t.removeAllProperties&&(delete e.removeProperties,delete e.addOrUpdateProperties,delete t.removeProperties),t.removeProperties)for(let n of t.removeProperties){let t=e.addOrUpdateProperties.findIndex(e=>e.key===n);t>-1&&e.addOrUpdateProperties.splice(t,1)}return(e.removeAllProperties||t.removeAllProperties)&&(n.removeAllProperties=!0),(e.removeProperties||t.removeProperties)&&(n.removeProperties=[...e.removeProperties||[],...t.removeProperties||[]]),(e.addOrUpdateProperties||t.addOrUpdateProperties)&&(n.addOrUpdateProperties=[...e.addOrUpdateProperties||[],...t.addOrUpdateProperties||[]]),(e.newGeometry||t.newGeometry)&&(n.newGeometry=t.newGeometry||e.newGeometry),n}function Oa(e,t){if(e)for(let n of e){let e=Sa(n,t);e!=null&&(n.id=e)}}function ka(e,t){if(e)for(let n of e)Sa(n,t)!=null&&delete n.id}function Aa(e){if(!e)return{};let t={};return t.removeAll=e.removeAll,t.remove=new Set(e.remove||[]),t.add=new Map(e.add?.map(e=>[e.id,e])),t.update=new Map(e.update?.map(e=>[e.id,e])),t}function ja(e){let t={};return e.removeAll&&(t.removeAll=e.removeAll),e.remove&&(t.remove=Array.from(e.remove)),e.add&&(t.add=Array.from(e.add.values())),e.update&&(t.update=Array.from(e.update.values())),t}function Ma(e){return!e||e.length===0?[]:typeof e[0]==`number`?[e]:e.flatMap(e=>Ma(e))}function Na(e){return e.type===`GeometryCollection`?e.geometries.flatMap(e=>Na(e)):Ma(e.coordinates)}function Pa(e){let t=new _a,n;switch(e.type){case`FeatureCollection`:n=e.features.flatMap(e=>Na(e.geometry));break;case`Feature`:n=Na(e.geometry);break;default:n=Na(e)}if(n.length===0)return t;for(let e of n){let[n,r]=e;t.extend([n,r])}return t}function Fa({x:e,y:t,z:n},r=0){let i=In((e-r)/2**n),a=Mt((t+1+r)/2**n),o=In((e+1+r)/2**n),s=Mt((t-r)/2**n);return new _a([i,a],[o,s])}var Ia=class extends h{constructor(e,t,n,r){super(),this.id=e,this.type=`geojson`,this.minzoom=0,this.maxzoom=18,this.tileSize=512,this.isTileClipped=!0,this.reparseOverscaled=!0,this._removed=!1,this._isUpdatingWorker=!1,this._pendingWorkerUpdate={data:t.data},this.actorPromise=n.getActor(),this.setEventedParent(r),this._data=typeof t.data==`string`?{url:t.data}:{geojson:t.data},this._options=z({},t),this._collectResourceTiming=t.collectResourceTiming,t.maxzoom!==void 0&&(this.maxzoom=t.maxzoom),t.type&&(this.type=t.type),t.attribution&&(this.attribution=t.attribution),this.promoteId=t.promoteId,t.clusterMaxZoom!==void 0&&this.maxzoom<=t.clusterMaxZoom&&I(`The maxzoom value "${this.maxzoom}" is expected to be greater than the clusterMaxZoom value "${t.clusterMaxZoom}".`),this.workerOptions=z({source:this.id,geojsonVtOptions:{buffer:this._pixelsToTileUnits(t.buffer===void 0?128:t.buffer),tolerance:this._pixelsToTileUnits(t.tolerance===void 0?.375:t.tolerance),extent:N,maxZoom:this.maxzoom,lineMetrics:t.lineMetrics||!1,generateId:t.generateId||!1,promoteId:typeof t.promoteId==`string`?t.promoteId:void 0,cluster:t.cluster||!1,clusterOptions:{maxZoom:this._getClusterMaxZoom(t.clusterMaxZoom),minPoints:Math.max(2,t.clusterMinPoints||2),extent:N,radius:this._pixelsToTileUnits(t.clusterRadius||50),log:!1,generateId:t.generateId||!1}},clusterProperties:t.clusterProperties,filter:t.filter},t.workerOptions)}_hasPendingWorkerUpdate(){return this._pendingWorkerUpdate.data!==void 0||this._pendingWorkerUpdate.diff!==void 0||this._pendingWorkerUpdate.updateCluster}_pixelsToTileUnits(e){return e*(N/this.tileSize)}_tileUnitsToPixels(e){return e/(N/this.tileSize)}_getClusterMaxZoom(e){let t=e?Math.round(e):this.maxzoom-1;return Number.isInteger(e)||e===void 0||I(`Integer expected for option 'clusterMaxZoom': provided value "${e}" rounded to "${t}"`),t}async load(){await this._updateWorkerData()}onAdd(e){this.map=e,this.load()}setData(e){return this._data=typeof e==`string`?{url:e}:{geojson:e},this._pendingWorkerUpdate={data:e},this._updateWorkerData()}updateData(e){return this._pendingWorkerUpdate.diff=Ta(this._pendingWorkerUpdate.diff,e),this._updateWorkerData()}async getData(){return this._data.url&&await this.once(`data`),this._data.geojson?this._data.geojson:{type:`FeatureCollection`,features:Array.from(this._data.updateable.values())}}async getBounds(){return Pa(await this.getData())}setClusterOptions(e){return this.workerOptions.geojsonVtOptions.cluster=e.cluster,e.clusterRadius!==void 0&&(this.workerOptions.geojsonVtOptions.clusterOptions.radius=this._pixelsToTileUnits(e.clusterRadius)),e.clusterMaxZoom!==void 0&&(this.workerOptions.geojsonVtOptions.clusterOptions.maxZoom=this._getClusterMaxZoom(e.clusterMaxZoom)),this._pendingWorkerUpdate.updateCluster=!0,this._updateWorkerData()}getClusterOptions(){let{cluster:e,clusterOptions:t}=this.workerOptions.geojsonVtOptions;return{cluster:e,clusterMaxZoom:t.maxZoom,clusterRadius:this._tileUnitsToPixels(t.radius)}}async getClusterExpansionZoom(e){return(await this.actorPromise).sendAsync({type:`GCEZ`,data:{type:this.type,clusterId:e,source:this.id}})}async getClusterChildren(e){return(await this.actorPromise).sendAsync({type:`GCC`,data:{type:this.type,clusterId:e,source:this.id}})}async getClusterLeaves(e,t,n){return(await this.actorPromise).sendAsync({type:`GCL`,data:{type:this.type,source:this.id,clusterId:e,limit:t,offset:n}})}async _updateWorkerData(){if(this._isUpdatingWorker)return this._updatePromise;if(!this._hasPendingWorkerUpdate()){I(`No pending worker updates for GeoJSONSource ${this.id}.`);return}let{data:e,diff:t,updateCluster:n}=this._pendingWorkerUpdate,r=this._getLoadGeoJSONParameters(e,t,n);e===void 0?t?this._pendingWorkerUpdate.diff=void 0:n&&(this._pendingWorkerUpdate.updateCluster=void 0):this._pendingWorkerUpdate.data=void 0,this._updatePromise=this._dispatchWorkerUpdate(r),await this._updatePromise}async _getLoadGeoJSONParameters(e,t,n){let r=z({type:this.type,source:this.id},this.workerOptions);if(typeof e==`string`)return r.request=await this.map._requestManager.transformRequest(Rr.resolveURL(e),`Source`),r.request.collectResourceTiming=this._collectResourceTiming,r;if(e!==void 0)return r.data=e,r;if(t)return r.dataDiff=t,r;if(n)return r.updateCluster=!0,r}async _dispatchWorkerUpdate(e){this._isUpdatingWorker=!0,this.fire(new K(`dataloading`));try{let t=await e,n=await(await this.actorPromise).sendAsync({type:`LD`,data:t});if(this._isUpdatingWorker=!1,this._removed||n.abandoned){this.fire(new K(`dataabort`));return}n.data&&(this._data={geojson:n.data});let r=this._applyDiffToSource(t.dataDiff),i=this._getShouldReloadTileOptions(r),a={};this._applyResourceTiming(a,n),this.fire(new K(`data`,{...a,sourceDataType:`metadata`})),this.fire(new K(`data`,{...a,sourceDataType:`content`,shouldReloadTileOptions:i}))}catch(e){if(this._isUpdatingWorker=!1,this._removed){this.fire(new K(`dataabort`));return}this.fire(new H(qn(e)))}finally{this._hasPendingWorkerUpdate()&&await this._updateWorkerData()}}_applyResourceTiming(e,t){if(!this._collectResourceTiming)return;let n=t.resourceTiming?.[this.id];if(!n)return;let r=n.slice(0);r?.length&&z(e,{resourceTiming:r})}_applyDiffToSource(e){if(!e)return;let t=typeof this.promoteId==`string`?this.promoteId:void 0;if(!this._data.url&&!this._data.updateable){let e=Ca(this._data.geojson,t);if(!e)throw Error(`GeoJSONSource "${this.id}": GeoJSON data is not compatible with updateData`);this._data={updateable:e}}if(!this._data.updateable)return;let n=wa(this._data.updateable,e,t);if(!(e.removeAll||this._options.cluster))return n}_getShouldReloadTileOptions(e){if(e)return{affectedBounds:e.filter(Boolean).map(e=>Pa(e))}}shouldReloadTile(e,{affectedBounds:t}){if(e.state===`loading`)return!0;if(e.state===`unloaded`)return!1;let{buffer:n,extent:r}=this.workerOptions.geojsonVtOptions,i=Fa(e.tileID.canonical,n/r);for(let e of t)if(i.intersects(e))return!0;return!1}loaded(){return!this._isUpdatingWorker&&!this._hasPendingWorkerUpdate()}async loadTile(e){let t=e.actor?`RT`:`LT`;e.actor=await this.actorPromise;let n={type:this.type,uid:e.uid,tileID:e.tileID,zoom:e.tileID.overscaledZ,maxZoom:this.maxzoom,tileSize:this.tileSize,source:this.id,pixelRatio:this.map.getPixelRatio(),showCollisionBoxes:this.map.showCollisionBoxes,promoteId:this.promoteId,subdivisionGranularity:this.map.style.projection.subdivisionGranularity};e.abortController=new AbortController;try{let r=await(await this.actorPromise).sendAsync({type:t,data:n},e.abortController);delete e.abortController,e.unloadVectorData(),e.aborted||e.loadVectorData(r,this.map.painter,t===`RT`)}catch(t){if(delete e.abortController,e.aborted||xe(t))return;throw t}}async abortTile(e){e.abortController&&(e.abortController.abort(),delete e.abortController),e.aborted=!0}async unloadTile(e){e.unloadVectorData(),await(await this.actorPromise).sendAsync({type:`RMT`,data:{uid:e.uid,type:this.type,source:this.id}})}onRemove(){this._removed=!0,this.actorPromise.then(e=>e.sendAsync({type:`RS`,data:{type:this.type,source:this.id}}))}serialize(){return z({},this._options,{type:this.type,data:this._data.updateable?{type:`FeatureCollection`,features:Array.from(this._data.updateable.values())}:this._data.url||this._data.geojson})}hasTransition(){return!1}};const La=[0,0,1],Ra=(e,t)=>({u_tl_parent:new j(e,t.u_tl_parent),u_scale_parent:new P(e,t.u_scale_parent),u_buffer_scale:new P(e,t.u_buffer_scale),u_image_warp:new ue(e,t.u_image_warp),u_fade_t:new P(e,t.u_fade_t),u_opacity:new P(e,t.u_opacity),u_image0:new F(e,t.u_image0),u_image1:new F(e,t.u_image1),u_brightness_low:new P(e,t.u_brightness_low),u_brightness_high:new P(e,t.u_brightness_high),u_saturation_factor:new P(e,t.u_saturation_factor),u_contrast_factor:new P(e,t.u_contrast_factor),u_spin_weights:new ue(e,t.u_spin_weights),u_coords_top:new Ce(e,t.u_coords_top),u_coords_bottom:new Ce(e,t.u_coords_bottom)}),za=(e,t,n,r,i,a)=>({u_tl_parent:e,u_scale_parent:t,u_buffer_scale:1,u_image_warp:a,u_fade_t:n.mix,u_opacity:n.opacity*r.paint.get(`raster-opacity`),u_image0:0,u_image1:1,u_brightness_low:r.paint.get(`raster-brightness-min`),u_brightness_high:r.paint.get(`raster-brightness-max`),u_saturation_factor:Ha(r.paint.get(`raster-saturation`)),u_contrast_factor:Va(r.paint.get(`raster-contrast`)),u_spin_weights:Ba(r.paint.get(`raster-hue-rotate`)),u_coords_top:[i[0].x,i[0].y,i[1].x,i[1].y],u_coords_bottom:[i[3].x,i[3].y,i[2].x,i[2].y]});function Ba(e){e*=Math.PI/180;let t=Math.sin(e),n=Math.cos(e);return[(2*n+1)/3,(-Math.sqrt(3)*t-n+1)/3,(Math.sqrt(3)*t-n+1)/3]}function Va(e){return e>0?1/(1-e):1+e}function Ha(e){return e>0?1-1/(1.001-e):-e}var Ua=class{constructor(e,t,n){this.vertexBuffer=e,this.indexBuffer=t,this.segments=n}destroy(){this.vertexBuffer.destroy(),this.indexBuffer.destroy(),this.segments.destroy(),this.vertexBuffer=null,this.indexBuffer=null,this.segments=null}};const Wa=wt([{name:`a_pos`,type:`Int16`,components:2}]),Ga=N/128;function Ka(e,t){let n=qa(t,`16bit`),r=Un.deserialize({arrayBuffer:n.vertices,length:n.vertices.byteLength/2/2}),i=gt.deserialize({arrayBuffer:n.indices,length:n.indices.byteLength/2/3});return new Ua(e.createVertexBuffer(r,Wa.members),e.createIndexBuffer(i),ae.simpleSegment(0,0,r.length,i.length))}function qa(e,t){let n=e.granularity===void 0?1:Math.max(e.granularity,1),r=n+(e.generateBorders?2:0),i=n+(e.extendToNorthPole||e.generateBorders?1:0)+(e.extendToSouthPole||e.generateBorders?1:0),a=r+1,o=i+1,s=e.generateBorders?-1:0,c=e.generateBorders||e.extendToNorthPole?-1:0,l=n+ +!!e.generateBorders,u=n+(e.generateBorders||e.extendToSouthPole?1:0),d=a*o,f=r*i*6,p=a*o>65536;if(p&&t===`16bit`)throw Error(`Granularity is too large and meshes would not fit inside 16 bit vertex indices.`);let m=p||t===`32bit`,h=new Int16Array(d*2),g=0;for(let t=c;t<=u;t++)for(let r=s;r<=l;r++){let i=r/n*N;r===-1&&(i=-Ga),r===n+1&&(i=N+Ga);let a=t/n*N;t===-1&&(a=e.extendToNorthPole?Ot:-Ga),t===n+1&&(a=e.extendToSouthPole?dr:N+Ga),h[g++]=i,h[g++]=a}let _=m?new Uint32Array(f):new Uint16Array(f),v=0;for(let e=0;ethis.tileID.getTilePoint(e)._round()),this.imageWarp=Za(this.tileCoords,this._warp),this._subdividedQuad=this.imageWarp[2]>0&&!$a(this.tileCoords),this.flippedWindingOrder=Xa(this.tileCoords),this.fire(new K(`data`,{sourceDataType:`content`})),this}prepare(){if(Object.keys(this.tiles).length===0||!this.image)return;let e=this.map.painter.context,t=e.gl;this.texture?this._imageDirty&&(this.texture.update(this.image),this.texture.bind(t.LINEAR,t.CLAMP_TO_EDGE)):(this.texture=new _(e,this.image,t.RGBA),this.texture.bind(t.LINEAR,t.CLAMP_TO_EDGE)),this._imageDirty=!1;let n=!1;for(let e in this.tiles){let t=this.tiles[e];t.state!==`loaded`&&(t.state=`loaded`,t.texture=this.texture,n=!0)}n&&this.fire(new K(`data`,{sourceDataType:`idle`,sourceId:this.id}))}async loadTile(e){this.tileID?.equals(e.tileID.canonical)?(this.tiles[String(e.tileID.wrap)]=e,e.buckets={}):e.state=`errored`}serialize(){let e={type:`image`,coordinates:this.coordinates};return this.options.url!==void 0&&(e.url=this.options.url),e}hasTransition(){return!1}_getOverlappingTileRanges(e){let{minX:t,minY:n,maxX:r,maxY:i}=On.fromPoints(e),a={};for(let e=0;e<=25;e++){let o=2**e,s=Math.floor(t*o),c=Math.floor(n*o),l=Math.floor(r*o),u=Math.floor(i*o),d=(s%o+o)%o,f=l%o,p=Math.floor(s/o),m=Math.floor(l/o);a[e]={minWrap:p,maxWrap:m,minTileXWrapped:d,maxTileXWrapped:f,minTileY:c,maxTileY:u}}return a}};function Ya(e){let t=On.fromPoints(e),n=t.width(),r=t.height(),i=Math.max(0,Math.floor(-Math.log(Math.max(n,r))/Math.LN2)),a=2**i;return new rn(i,Math.floor((t.minX+t.maxX)/2*a),Math.floor((t.minY+t.maxY)/2*a))}function Xa(e){let t=e[1].x-e[0].x,n=e[1].y-e[0].y,r=e[2].x-e[0].x;return t*(e[2].y-e[0].y)-n*r<0}function Za(e,t){if(t===`flat`||$a(e))return La;let[n,r,i,a]=e,o=n.x-r.x+i.x-a.x,s=n.y-r.y+i.y-a.y,c=[r.x-i.x,r.y-i.y,a.x-i.x,a.y-i.y],[l,u,d,f]=c,p=Nr(c),m=(o*f-d*s)/p,h=(l*s-o*u)/p,g=[1,1+m,1+m+h,1+h],_=Math.max(...g)/Math.min(...g),v=t===`perspective`?0:Qa(_);return!(_>=1&&_<=512)||v>=1?La:[m,h,v]}function Qa(e){let t=(1-4/e)/(1-4/512);return Math.max(0,t)}function $a(e){let[t,n,r,i]=e;return t.x+r.x===n.x+i.x&&t.y+r.y===n.y+i.y}var eo=class extends Ja{constructor(e,t,n,r){super(e,t,n,r),this._onPlayingHandler=()=>{this.map?.triggerRepaint()},this.roundZoom=!0,this.type=`video`,this.options=t}async load(){this._loaded=!1;let e=this.options;this.urls=[];for(let t of e.urls)this.urls.push((await this.map._requestManager.transformRequest(t,`Source`)).url);try{let e=await yn(this.urls);if(this._loaded=!0,!e)return;this.video=e,this.video.loop=!0,this.video.addEventListener(`playing`,this._onPlayingHandler),this.map&&this.video.play(),this._finishLoading()}catch(e){this.fire(new H(qn(e)))}}pause(){this.video&&this.video.pause()}play(){this.video&&this.video.play()}seek(e){if(this.video){let t=this.video.seekable;et.end(0)?this.fire(new H(new lr(`sources.${this.id}`,null,`Playback for this video can be set only between the ${t.start(0)} and ${t.end(0)}-second mark.`))):this.video.currentTime=e}}getVideo(){return this.video}onAdd(e){this.map||(this.map=e,this.load(),this.video&&(this.video.play(),this.setCoordinates(this.coordinates)))}onRemove(){super.onRemove(),this.video&&(this.video.removeEventListener(`playing`,this._onPlayingHandler),this.video.pause())}prepare(){if(Object.keys(this.tiles).length===0||this.video.readyState<2)return;let e=this.map.painter.context,t=e.gl;this.texture?this.video.paused||(this.texture.bind(t.LINEAR,t.CLAMP_TO_EDGE),t.texSubImage2D(t.TEXTURE_2D,0,0,0,t.RGBA,t.UNSIGNED_BYTE,this.video)):(this.texture=new _(e,this.video,t.RGBA),this.texture.bind(t.LINEAR,t.CLAMP_TO_EDGE));let n=!1;for(let e in this.tiles){let t=this.tiles[e];t.state!==`loaded`&&(t.state=`loaded`,t.texture=this.texture,n=!0)}n&&this.fire(new K(`data`,{sourceDataType:`idle`,sourceId:this.id}))}serialize(){return{type:`video`,urls:this.urls,coordinates:this.coordinates}}hasTransition(){return this.video&&!this.video.paused}},to=class extends Ja{constructor(e,t,n,r){super(e,t,n,r),t.coordinates?(!Array.isArray(t.coordinates)||t.coordinates.length!==4||t.coordinates.some(e=>!Array.isArray(e)||e.length!==2||e.some(e=>typeof e!=`number`)))&&this.fire(new H(new lr(`sources.${e}`,null,`"coordinates" property must be an array of 4 longitude/latitude array pairs`))):this.fire(new H(new lr(`sources.${e}`,null,`missing required property "coordinates"`))),t.animate&&typeof t.animate!=`boolean`&&this.fire(new H(new lr(`sources.${e}`,null,`optional "animate" property must be a boolean value`))),t.canvas?typeof t.canvas!=`string`&&!(t.canvas instanceof HTMLCanvasElement)&&this.fire(new H(new lr(`sources.${e}`,null,`"canvas" must be either a string representing the ID of the canvas element from which to read, or an HTMLCanvasElement instance`))):this.fire(new H(new lr(`sources.${e}`,null,`missing required property "canvas"`))),this.options=t,this.animate=t.animate===void 0||t.animate}async load(){if(this._loaded=!0,this.canvas||=this.options.canvas instanceof HTMLCanvasElement?this.options.canvas:document.getElementById(this.options.canvas),this.width=this.canvas.width,this.height=this.canvas.height,this._hasInvalidDimensions()){this.fire(new H(Error(`Canvas dimensions cannot be less than or equal to zero.`)));return}this.play=function(){this._playing=!0,this.map.triggerRepaint()},this.pause=function(){this._playing&&=(this.prepare(),!1)},this._finishLoading()}getCanvas(){return this.canvas}onAdd(e){this.map=e,this.load(),this.canvas&&this.animate&&this.play()}onRemove(){this._playing=!1,super.onRemove()}prepare(){let e=!1;if(this.canvas.width!==this.width&&(this.width=this.canvas.width,e=!0),this.canvas.height!==this.height&&(this.height=this.canvas.height,e=!0),this._hasInvalidDimensions()||Object.keys(this.tiles).length===0)return;let t=this.map.painter.context,n=t.gl;this.texture?(e||this._playing)&&this.texture.update(this.canvas,{premultiply:!0}):(this.texture=new _(t,this.canvas,n.RGBA,{premultiply:!0}),this.texture.bind(n.LINEAR,n.CLAMP_TO_EDGE));let r=!1;for(let e in this.tiles){let t=this.tiles[e];t.state!==`loaded`&&(t.state=`loaded`,t.texture=this.texture,r=!0)}r&&this.fire(new K(`data`,{sourceDataType:`idle`,sourceId:this.id}))}serialize(){return{type:`canvas`,animate:this.animate,canvas:this.options.canvas,coordinates:this.coordinates}}hasTransition(){return this._playing}_hasInvalidDimensions(){for(let e of[this.canvas.width,this.canvas.height])if(isNaN(e)||e<=0)return!0;return!1}};const no={},ro=(e,t,n,r)=>{let i=new(io(t.type))(e,t,n,r);if(i.id!==e)throw Error(`Expected Source id to be ${e} instead of ${i.id}`);return i},io=e=>{switch(e){case`geojson`:return Ia;case`image`:return Ja;case`raster`:return ba;case`raster-dem`:return xa;case`vector`:return ya;case`video`:return eo;case`canvas`:return to}return no[e]},ao=(e,t)=>{no[e]=t},oo=async(e,t)=>{if(io(e))throw Error(`A source type called "${e}" already exists.`);ao(e,t)};function so(e,t){let n={};if(!t)return n;for(let r of e){let e=r.layerIds.map(e=>t.getLayer(e)).filter(Boolean);if(e.length!==0){r.layers=e,r.stateDependentLayerIds&&(r.stateDependentLayers=r.stateDependentLayerIds.map(t=>e.filter(e=>e.id===t)[0]));for(let t of e)n[t.id]=r}}return n}const co=`RTLPluginLoaded`;var lo=class extends h{constructor(...e){super(...e),this.status=`unavailable`,this.url=null,this.dispatcher=aa()}_syncState(e){return this.status=e,this.dispatcher.broadcast(`SRPS`,{pluginStatus:e,pluginURL:this.url}).catch(e=>{throw this.status=`error`,e})}getRTLTextPluginStatus(){return this.status}clearRTLTextPlugin(){this.status=`unavailable`,this.url=null}async setRTLTextPlugin(e,t=!1){if(this.url)throw Error(`setRTLTextPlugin cannot be called multiple times.`);if(this.url=Rr.resolveURL(e),!this.url)throw Error(`requested url ${e} is invalid`);if(this.status===`unavailable`){if(t)this.status=`deferred`,this._syncState(this.status);else return this._requestImport()}else if(this.status===`requested`)return this._requestImport()}async _requestImport(){await this._syncState(`loading`),this.status=`loaded`,this.fire(new Xe(co))}lazyLoad(){this.status===`unavailable`?this.status=`requested`:this.status===`deferred`&&this._requestImport()}};let uo=null;function fo(){return uo||=new lo,uo}var po=class{constructor(e,t){this.timeAdded=0,this.fadeEndTime=0,this.fadeOpacity=1,this.tileID=e,this.uid=Se(),this.uses=0,this.tileSize=t,this.buckets={},this.expirationTime=null,this.queryPadding=0,this.hasSymbolBuckets=!1,this.hasRTLText=!1,this.dependencies={},this.rttObjects=[],this.rttFingerprint={},this.expiredRequestCount=0,this.state=`loading`,this.featureStateRevision=-1}isRenderable(e){return this.hasData()&&(!this.fadeEndTime||this.fadeOpacity>0)&&(e||!this.holdingForSymbolFade())}setCrossFadeLogic({fadingRole:e,fadingDirection:t,fadingParentID:n,fadeEndTime:r}){this.resetFadeLogic(),this.fadingRole=e,this.fadingDirection=t,this.fadingParentID=n,this.fadeEndTime=r}setSelfFadeLogic(e){this.resetFadeLogic(),this.selfFading=!0,this.fadeEndTime=e}resetFadeLogic(){this.fadingRole=null,this.fadingDirection=null,this.fadingParentID=null,this.selfFading=!1,this.timeAdded=U(),this.fadeEndTime=0,this.fadeOpacity=1}wasRequested(){return this.state===`errored`||this.state===`loaded`||this.state===`reloading`}clearTextures(e){this.demTexture&&e.saveTileTexture(this.demTexture),this.demTexture=null}getRTT(e){return this.rttObjects[e]}acquireRTT(e,t,n){return this.rttObjects[t]=e.acquireRTT(n)}releaseRTT(e){if(this.rttObjects.length!==0){for(let t of this.rttObjects)t&&e.releaseRTT(t);this.rttObjects.length=0}}loadVectorData(e,t,n){if(e?.etagUnmodified===!0){this.state=`loaded`;return}if(this.hasData()&&this.unloadVectorData(),this.state=`loaded`,!e){this.collisionBoxArray=new ot;return}e.featureIndex&&(this.latestFeatureIndex=e.featureIndex,e.rawTileData?(this.latestRawTileData=e.rawTileData,this.latestEncoding=e.encoding,this.latestFeatureIndex.rawTileData=e.rawTileData,this.latestFeatureIndex.encoding=e.encoding):this.latestRawTileData&&(this.latestFeatureIndex.rawTileData=this.latestRawTileData,this.latestFeatureIndex.encoding=this.latestEncoding)),this.collisionBoxArray=e.collisionBoxArray,this.buckets=so(e.buckets,t?.style),this.hasSymbolBuckets=!1;for(let e in this.buckets){let t=this.buckets[e];if(t instanceof v){if(this.hasSymbolBuckets=!0,n)t.justReloaded=!0;else break}}if(this.hasRTLText=!1,this.hasSymbolBuckets)for(let e in this.buckets){let t=this.buckets[e];if(t instanceof v&&t.hasRTLText){this.hasRTLText=!0,fo().lazyLoad();break}}this.queryPadding=0;for(let e in this.buckets){let n=this.buckets[e];this.queryPadding=Math.max(this.queryPadding,t.style.getLayer(e).queryRadius(n))}e.imageAtlas&&(this.imageAtlas=e.imageAtlas),e.glyphAtlasImage&&(this.glyphAtlasImage=e.glyphAtlasImage),this.dashPositions=e.dashPositions}unloadVectorData(){for(let e in this.buckets)this.buckets[e].destroy();this.buckets={},this.imageAtlasTexture&&this.imageAtlasTexture.destroy(),this.glyphAtlasTexture&&this.glyphAtlasTexture.destroy(),this.imageAtlas=null,this.dashPositions=null,this.latestFeatureIndex=null,this.state=`unloaded`}getBucket(e){return this.buckets[e.id]}upload(e){for(let t in this.buckets){let n=this.buckets[t];n.uploadPending()&&n.upload(e)}let t=e.gl;this.imageAtlas&&!this.imageAtlas.uploaded&&(this.imageAtlasTexture=new _(e,this.imageAtlas.image,t.RGBA),this.imageAtlas.uploaded=!0),this.glyphAtlasImage&&=(this.glyphAtlasTexture=new _(e,this.glyphAtlasImage,t.ALPHA),null)}prepare(e){this.imageAtlas&&this.imageAtlas.patchUpdatedImages(e,this.imageAtlasTexture)}queryRenderedFeatures(e,t,n,r,i,a,o,s,c,l,u){return this.latestFeatureIndex?.rawTileData?this.latestFeatureIndex.query({queryGeometry:r,cameraQueryGeometry:i,scale:a,tileSize:this.tileSize,pixelPosMatrix:l,transform:s,params:o,queryPadding:this.queryPadding*c,getElevation:u},e,t,n):{}}querySourceFeatures(e,t){let n=this.latestFeatureIndex;if(!n?.rawTileData)return;let r=n.loadVTLayers(),i=t?.sourceLayer?t.sourceLayer:``,a=r._geojsonTileLayer||r[i];if(!a)return;let o=Rn(t?.filter,`querySourceFeatures[${i}].filter`,t?.globalState),{z:s,x:c,y:l}=this.tileID.canonical,u={z:s,x:c,y:l};for(let t=0;te)n=!1;else if(!t)n=!0;else if(this.expirationTime({zoom:0,x:0,y:0,wrap:e,fullyVisible:!1}),b=[],x=[];if(e.renderWorldCopies&&s.allowWorldCopies())for(let e=1;e<=3;e++)b.push(y(-e)),b.push(y(e));for(b.push(y(0));b.length>0;){let p=b.pop(),g=p.x,y=p.y,S=p.fullyVisible,C={x:g,y,z:p.zoom},w=s.getTileBoundingVolume(C,p.wrap,o,t);if(!S){let e=go(n,w,r);if(e===0)continue;S=e===2}let T=s.distanceToTile2d(i.x,i.y,C,w),E=l;c&&(E=(t.calculateTileZoom||yo)(e.zoom+Ee(e.tileSize/t.tileSize),T,_,v,e.fov)),E=(t.roundZoom?Math.round:Math.floor)(E),E=Math.max(0,E);let D=Math.min(E,d);if(p.wrap=s.getWrap(a,C,p.wrap),p.zoom>=D){if(p.zoom>1),r=p.zoom+1;b.push({zoom:r,x:t,y:n,wrap:p.wrap,fullyVisible:S})}}return x.sort((e,t)=>e.distanceSq-t.distanceSq).map(e=>e.tileID)}function Co(e){return e===`raster`||e===`image`||e===`video`}function wo(e,t,n,r,i,a,o){let s=U(),c=or(t);for(let l of t){let t=e.getTileById(l.key);(t.fadingDirection===0||t.fadeOpacity===0)&&t.resetFadeLogic(),!To(e,t,n,s,r,i,o)&&(Eo(e,t,n,s,a,o)||Oo(t,c,s,o)||t.resetFadeLogic())}}function To(e,t,n,r,i,a,o){if(!t.hasData())return!1;let{tileID:s,fadingRole:c,fadingDirection:l,fadingParentID:u}=t;if(c===0&&l===1&&u)return n[u.key]=u,!0;let d=Math.max(s.overscaledZ-i,a);for(let i=s.overscaledZ-1;i>=d;i--){let a=s.scaledTo(i),c=e.getLoadedTile(a);if(c)return t.setCrossFadeLogic({fadingRole:0,fadingDirection:1,fadingParentID:c.tileID,fadeEndTime:r+o}),c.setCrossFadeLogic({fadingRole:1,fadingDirection:0,fadeEndTime:r+o}),n[a.key]=a,!0}return!1}function Eo(e,t,n,r,i,a){if(!t.hasData())return!1;let o=t.tileID.children(i),s=Do(e,t,o,n,r,i,a);if(s)return!0;for(let c of o)Do(e,t,c.children(i),n,r,i,a)&&(s=!0);return s}function Do(e,t,n,r,i,a,o){if(n[0].overscaledZ>=a)return!1;let s=!1;for(let a of n){let n=e.getLoadedTile(a);if(!n)continue;let{fadingRole:c,fadingDirection:l,fadingParentID:u}=n;(c!==0||l!==0||!u)&&(n.setCrossFadeLogic({fadingRole:0,fadingDirection:0,fadingParentID:t.tileID,fadeEndTime:i+o}),t.setCrossFadeLogic({fadingRole:1,fadingDirection:1,fadeEndTime:i+o})),r[a.key]=a,s=!0}return s}function Oo(e,t,n,r){let i=e.tileID;if(e.selfFading)return!0;if(e.hasData())return!1;if(t.has(i)){let t=n+r;return e.setSelfFadeLogic(t),!0}return!1}function ko(e,t){if(t<=0)return!1;let n=U();for(let t of e.getAllTiles())if(t.fadeEndTime>=n)return!0;return!1}function Ao(e,t){let n=t.getRenderableIds();for(let r of n){if(!e.neighboringTiles?.[r])continue;let n=t.getTileById(r);e.neighboringTiles[r].backfilled||jo(e,n),!n.neighboringTiles?.[e.tileID.key]?.backfilled&&jo(n,e)}}function jo(e,t){e.needsHillshadePrepare=!0,e.needsTerrainPrepare=!0,e.needsColorReliefPrepare=!0;let n=t.tileID.canonical.x-e.tileID.canonical.x,r=t.tileID.canonical.y-e.tileID.canonical.y,i=2**e.tileID.canonical.z,a=t.tileID.key;(n!==0||r!==0)&&(Math.abs(r)>1||(Math.abs(n)>1&&(Math.abs(n+i)===1?n+=i:Math.abs(n-i)===1&&(n-=i)),!(!t.dem||!e.dem)&&(e.dem.backfillBorder(t.dem,n,r),e.neighboringTiles?.[a]&&(e.neighboringTiles[a].backfilled=!0))))}var Mo=class{constructor(){this._tiles={}}handleWrapJump(e){let t={};for(let n in this._tiles){let r=this._tiles[n];r.tileID=r.tileID.unwrapTo(r.tileID.wrap+e),t[r.tileID.key]=r}this._tiles=t}setFeatureState(e,t,n){for(let r in this._tiles)this._tiles[r].setFeatureState(e,t,n)}getAllTiles(){return Object.values(this._tiles)}getAllIds(e=!1){return e?Object.values(this._tiles).map(e=>e.tileID).sort(xr).map(e=>e.key):Object.keys(this._tiles)}getTileById(e){return this._tiles[e]}setTile(e,t){this._tiles[e]=t}deleteTileById(e){delete this._tiles[e]}getLoadedTile(e){let t=this.getTileById(e.key);return t?.hasData()?t:null}isIdRenderable(e,t=!1){return this.getTileById(e)?.isRenderable(t)}getRenderableIds(e=0,t){let n=[];for(let e of this.getAllIds())this.isIdRenderable(e,t)&&n.push(this.getTileById(e));return t?n.sort((t,n)=>{let r=t.tileID,i=n.tileID,a=new l(r.canonical.x,r.canonical.y)._rotate(-e),o=new l(i.canonical.x,i.canonical.y)._rotate(-e);return r.overscaledZ-i.overscaledZ||o.y-a.y||o.x-a.x}).map(e=>e.tileID.key):n.map(e=>e.tileID).sort(xr).map(e=>e.key)}},No=class e extends h{static{this.maxUnderzooming=10}static{this.maxOverzooming=3}constructor(e,t,n){super(),this.id=e,this.dispatcher=n,this.on(`data`,e=>{this._dataHandler(e)}),this.on(`dataloading`,()=>{this._sourceErrored=!1}),this.on(`error`,()=>{this._sourceErrored=this._source.loaded()}),this._source=ro(e,t,n,this),this._inViewTiles=new Mo,this._outOfViewCache=new Jn(0,e=>this._unloadTile(e)),this._timers={},this._maxTileCacheSize=null,this._maxTileCacheZoomLevels=null,this._rasterFadeDuration=0,this._maxFadingAncestorLevels=5,this._state=new ho,this._didEmitContent=!1,this._updated=!1}onAdd(e){this.map=e,this._maxTileCacheSize=e?e._maxTileCacheSize:null,this._maxTileCacheZoomLevels=e?e._maxTileCacheZoomLevels:null,this._source?.onAdd&&this._source.onAdd(e)}onRemove(e){for(let e of this._inViewTiles.getAllTiles())e.unloadVectorData();this.clearTiles(),this._source?.onRemove&&this._source.onRemove(e),this._inViewTiles=new Mo}loaded(){if(this._sourceErrored)return!0;if(!this._sourceLoaded||!this._source.loaded())return!1;if((this.used!==void 0||this.usedForTerrain!==void 0)&&!this.used&&!this.usedForTerrain)return!0;if(!this._updated)return!1;for(let e of this._inViewTiles.getAllTiles())if(e.state!==`loaded`&&e.state!==`errored`)return!1;return!0}getSource(){return this._source}getState(){return this._state}pause(){this._paused=!0}resume(){if(!this._paused)return;let e=this._shouldReloadOnResume;this._paused=!1,this._shouldReloadOnResume=!1,e&&this.reload(),this.transform&&this.update(this.transform,this.terrain)}async _loadTile(e,t,n,r){try{let i=await this._source.loadTile(e);this._tileLoaded(e,t,n,r,i)}catch(t){e.state=`errored`,t.status===404?this.update(this.transform,this.terrain):this._source.fire(new H(qn(t),{tile:e}))}}_unloadTile(e){this._source.unloadTile&&this._source.unloadTile(e)}_abortTile(e){this._source.abortTile&&this._source.abortTile(e),this._source.fire(new K(`dataabort`,{tile:e,coord:e.tileID}))}serialize(){return this._source.serialize()}prepare(e){this._source.prepare&&this._source.prepare(),this._state.coalesceChanges(this._inViewTiles,this.map?this.map.painter:null);for(let t of this._inViewTiles.getAllTiles())t.upload(e),t.prepare(this.map.style.imageManager)}getIds(){return this._inViewTiles.getAllIds(!0)}getRenderableIds(e){return this._inViewTiles.getRenderableIds(this.transform?.bearingInRadians,e)}hasRenderableParent(e){let t=e.overscaledZ-1;if(t>=this._source.minzoom){let n=this.getLoadedTile(e.scaledTo(t));if(n)return this._inViewTiles.isIdRenderable(n.tileID.key)}return!1}reload(e,t=void 0){if(this._paused){this._shouldReloadOnResume=!0;return}this._outOfViewCache.reset();for(let n of this._inViewTiles.getAllIds()){let r=this._inViewTiles.getTileById(n);t&&!this._source.shouldReloadTile(r,t)||(e?this._reloadTile(n,r.state===`errored`?`loading`:`expired`):r.state!==`errored`&&this._reloadTile(n,`reloading`))}}async _reloadTile(e,t){let n=this._inViewTiles.getTileById(e);if(!n)return;let r=n.hasData();n.state!==`loading`&&(n.state=t),await this._loadTile(n,e,t,r)}_tileLoaded(e,t,n,r,i){r||(e.timeAdded=U(),e.selfFading&&(e.fadeEndTime=e.timeAdded+this._rasterFadeDuration)),n===`expired`&&(e.refreshedUponExpiration=!0),this._setTileReloadTimer(t,e),!i?.unmodified&&(this.getSource().type===`raster-dem`&&e.dem&&Ao(e,this._inViewTiles),e.featureStateRevision=-1,this._state.initializeTileState(e,this.map?this.map.painter:null),e.aborted||this._source.fire(new K(`data`,{tile:e,coord:e.tileID})))}getTile(e){return this.getTileByID(e.key)}getTileByID(e){return this._inViewTiles.getTileById(e)}_retainLoadedChildren(t,n){let r=this._getLoadedDescendents(n),i=new Set;for(let a of n){let n=r[a.key];if(!n?.length){i.add(a);continue}let o=a.overscaledZ+e.maxOverzooming,s=n.filter(e=>e.tileID.overscaledZ<=o);if(!s.length){i.add(a);continue}let c=Math.min(...s.map(e=>e.tileID.overscaledZ)),l=s.filter(e=>e.tileID.overscaledZ===c).map(e=>e.tileID);for(let e of l)t[e.key]=e;this._areDescendentsComplete(l,c,a.overscaledZ)||i.add(a)}return i}_getLoadedDescendents(e){let t={};for(let n of this._inViewTiles.getAllTiles().filter(e=>e.hasData()))for(let r of e)n.tileID.isChildOf(r)&&(t[r.key]||=[],t[r.key].push(n));return t}_areDescendentsComplete(e,t,n){return e.length===1&&e[0].isOverscaled()?e[0].overscaledZ===t:4**(t-n)===e.length}getLoadedTile(e){return this._inViewTiles.getLoadedTile(e)}updateCacheSize(e){let t=(Math.ceil(e.width/this._source.tileSize)+1)*(Math.ceil(e.height/this._source.tileSize)+1),n=this._maxTileCacheZoomLevels===null?k.MAX_TILE_CACHE_ZOOM_LEVELS:this._maxTileCacheZoomLevels,r=Math.floor(t*n),i=typeof this._maxTileCacheSize==`number`?Math.min(this._maxTileCacheSize,r):r;this._outOfViewCache.setMaxSize(i)}handleWrapJump(e){let t=(e-(this._prevLng===void 0?e:this._prevLng))/360,n=Math.round(t);this._prevLng=e,n&&(this._inViewTiles.handleWrapJump(n),this._resetTileReloadTimers())}update(e,t){if(!this._sourceLoaded||this._paused)return;this.transform=e,this.terrain=t,this.updateCacheSize(e),this.handleWrapJump(this.transform.center.lng);let n;!this.used&&!this.usedForTerrain?n=[]:this._source.tileID?n=e.getVisibleUnwrappedCoordinates(this._source.tileID).map(e=>new $t(e.canonical.z,e.wrap,e.canonical.z,e.canonical.x,e.canonical.y)):(n=So(e,{tileSize:this.usedForTerrain?this.tileSize:this._source.tileSize,minzoom:this._source.minzoom,maxzoom:this._source.type===`vector`&&this.map._zoomLevelsToOverscale!==void 0?Math.max(this._source.maxzoom,e.maxZoom-this.map._zoomLevelsToOverscale):this._source.maxzoom,roundZoom:!this.usedForTerrain&&this._source.roundZoom,reparseOverscaled:this._source.reparseOverscaled,terrain:t,calculateTileZoom:this._source.calculateTileZoom}),this._source.hasTile&&(n=n.filter(e=>this._source.hasTile(e)))),this.usedForTerrain&&(n=this._addTerrainIdealTiles(n));let r=n.length===0&&!this._updated&&this._didEmitContent;this._updated=!0,r&&this.fire(new K(`data`,{sourceDataType:`idle`,sourceId:this.id}));let i=bo(e,this._source),a=this._updateRetainedTiles(n,i),o=Co(this._source.type);o&&this._rasterFadeDuration>0&&!t&&wo(this._inViewTiles,n,a,this._maxFadingAncestorLevels,this._source.minzoom,this._source.maxzoom,this._rasterFadeDuration),o?this._cleanUpRasterTiles(a):this._cleanUpVectorTiles(a)}_cleanUpRasterTiles(e){for(let t of this._inViewTiles.getAllIds())e[t]||this._removeTile(t)}_cleanUpVectorTiles(e){for(let t of this._inViewTiles.getAllIds()){let n=this._inViewTiles.getTileById(t);if(e[t]){n.clearSymbolFadeHold();continue}if(!n.hasSymbolBuckets){this._removeTile(t);continue}n.holdingForSymbolFade()?n.symbolFadeFinished()&&this._removeTile(t):n.setSymbolHoldDuration(this.map._fadeDuration)}}_addTerrainIdealTiles(e){let t=[];for(let n of e)if(n.canonical.z>this._source.minzoom){let e=n.scaledTo(n.canonical.z-1);t.push(e);let r=n.scaledTo(Math.max(this._source.minzoom,Math.min(n.canonical.z,5)));t.push(r)}return e.concat(t)}releaseSymbolFadeTiles(){for(let e of this._inViewTiles.getAllIds())this._inViewTiles.getTileById(e).holdingForSymbolFade()&&this._removeTile(e)}_updateRetainedTiles(t,n){let r=new Set;for(let e of t)this._addTile(e).hasData()||r.add(e);let i=t.reduce((e,t)=>(e[t.key]=t,e),{}),a=this._retainLoadedChildren(i,r),o={},s=Math.max(n-e.maxUnderzooming,this._source.minzoom);for(let e of a){let t=this._inViewTiles.getTileById(e.key),n=t?.wasRequested();for(let r=e.overscaledZ-1;r>=s;--r){let a=e.scaledTo(r);if(o[a.key])break;if(o[a.key]=!0,t=this.getTile(a),!t&&n&&(t=this._addTile(a)),t){let e=t.hasData();if((e||!this.map?.cancelPendingTileRequestsWhileZooming||n)&&(i[a.key]=a),n=t.wasRequested(),e)break}}}return i}_addTile(e){let t=this._inViewTiles.getTileById(e.key);if(t)return t;t=this._outOfViewCache.getAndRemove(e),t&&(t.resetFadeLogic(),this._setTileReloadTimer(e.key,t),t.tileID=e,this._state.initializeTileState(t,this.map?this.map.painter:null));let n=t;return t||(t=new po(e,this._source.tileSize*e.overscaleFactor()),this._loadTile(t,e.key,t.state,!1)),t.uses++,this._inViewTiles.setTile(e.key,t),n||this._source.fire(new K(`dataloading`,{tile:t,coord:t.tileID})),t}_setTileReloadTimer(e,t){this._clearTileReloadTimer(e);let n=t.getExpiryTimeout();if(n){let t=()=>{this._reloadTile(e,`expired`),delete this._timers[e]};this._timers[e]=setTimeout(t,n)}}_clearTileReloadTimer(e){let t=this._timers[e];t&&(clearTimeout(t),delete this._timers[e])}_resetTileReloadTimers(){for(let e in this._timers)clearTimeout(this._timers[e]),delete this._timers[e];for(let e of this._inViewTiles.getAllIds()){let t=this._inViewTiles.getTileById(e);this._setTileReloadTimer(e,t)}}refreshTiles(e){for(let t of this._inViewTiles.getAllIds()){let n=this._inViewTiles.getTileById(t);!this._inViewTiles.isIdRenderable(t)&&n.state!=`errored`||e.some(e=>e.equals(n.tileID.canonical))&&this._reloadTile(t,`expired`)}}_removeTile(e){let t=this._inViewTiles.getTileById(e);t&&(t.uses--,this._inViewTiles.deleteTileById(e),this._clearTileReloadTimer(e),!(t.uses>0)&&(t.hasData()&&t.state!==`reloading`?this._outOfViewCache.add(t.tileID,t,t.getExpiryTimeout()):(t.aborted=!0,this._abortTile(t),this._unloadTile(t))))}_dataHandler(e){if(e.dataType===`source`){if(e.sourceDataType===`metadata`){this._sourceLoaded=!0;return}e.sourceDataType!==`content`||!this._sourceLoaded||this._paused||(this.reload(e.sourceDataChanged,e.shouldReloadTileOptions),this.transform&&this.update(this.transform,this.terrain),this._didEmitContent=!0)}}clearTiles(){this._shouldReloadOnResume=!1,this._paused=!1;for(let e of this._inViewTiles.getAllIds())this._removeTile(e);this._outOfViewCache.reset()}tilesIn(e,t,n){let r=[],i=this.transform;if(!i)return r;let a=i.getCoveringTilesDetailsProvider().allowWorldCopies(),o=n?i.getCameraQueryGeometry(e):e,s=e=>i.screenPointToMercatorCoordinate(e,this.terrain),c=this.transformBbox(e,s,!a),l=this.transformBbox(o,s,!a),u=this.getIds(),d=On.fromPoints(l);for(let e of u){let n=this._inViewTiles.getTileById(e);if(n.holdingForSymbolFade())continue;let o=a?[n.tileID]:[n.tileID.unwrapTo(-1),n.tileID.unwrapTo(0)],s=2**(i.zoom-n.tileID.overscaledZ),u=t*n.queryPadding*N/n.tileSize/s;for(let e of o){let t=d.map(t=>e.getTilePoint(new B(t.x,t.y)));if(t.expandBy(u),t.intersects(Bn)){let t=c.map(t=>e.getTilePoint(t)),i=l.map(t=>e.getTilePoint(t));r.push({tile:n,tileID:a?e:e.unwrapTo(0),queryGeometry:t,cameraQueryGeometry:i,scale:s})}}}return r}transformBbox(e,t,n){let r=e.map(t);if(n){let n=On.fromPoints(e);n.shrinkBy(Math.min(n.width(),n.height())*.001);let i=n.map(t);On.fromPoints(r).covers(i)||(r=r.map(e=>e.x>.5?new B(e.x-1,e.y,e.z):e))}return r}getVisibleCoordinates(e){let t=this.getRenderableIds(e).map(e=>this._inViewTiles.getTileById(e).tileID);return this.transform&&this.transform.populateCache(t),t}hasTransition(){return this._source.hasTransition()?!0:Co(this._source.type)&&ko(this._inViewTiles,this._rasterFadeDuration)}setRasterFadeDuration(e){this._rasterFadeDuration=e}setFeatureState(e,t,n){e||=Yt,this._state.updateState(e,t,n)}removeFeatureState(e,t,n){e||=Yt,this._state.removeFeatureState(e,t,n)}getFeatureState(e,t){return e||=Yt,this._state.getState(e,t)}setDependencies(e,t,n){let r=this._inViewTiles.getTileById(e);r&&r.setDependencies(t,n)}reloadTilesForDependencies(e,t){for(let n of this._inViewTiles.getAllIds())this._inViewTiles.getTileById(n).hasDependency(e,t)&&this._reloadTile(n,`reloading`);this._outOfViewCache.filter(n=>!n.hasDependency(e,t))}areTilesLoaded(){for(let e of this._inViewTiles.getAllTiles())if(e.state!==`loaded`&&e.state!==`errored`)return!1;return!0}},Po=class{constructor(e,t){this.reset(e,t)}reset(e,t){this.points=e||[],this._distances=[0];for(let e=1;e0?(r-a)/o:0;return this.points[i].mult(1-s).add(this.points[t].mult(s))}};function Fo(e,t,n,r,i){return i?e?e(t,n)+r:r===0?void 0:r:r}function Io(e,t){let n=!0;return e===`always`||(e===`never`||t===`never`)&&(n=!1),n}var Lo=class{constructor(e,t,n){let r=this.boxCells=[],i=this.circleCells=[];this.xCellCount=Math.ceil(e/n),this.yCellCount=Math.ceil(t/n);for(let e=0;ethis.width||r<0||t>this.height)return[];let s=[];if(e<=0&&t<=0&&this.width<=n&&this.height<=r){if(i)return[{key:null,x1:e,y1:t,x2:n,y2:r}];for(let e=0;e0}hitTestCircle(e,t,n,r,i){let a=e-n,o=e+n,s=t-n,c=t+n;if(o<0||a>this.width||c<0||s>this.height)return!1;let l=[],u={hitTest:!0,overlapMode:r,circle:{x:e,y:t,radius:n},seenUids:{box:{},circle:{}}};return this._forEachCell(a,s,o,c,this._queryCellCircle,l,u,i),l.length>0}_queryCell(e,t,n,r,i,a,o,s){let{seenUids:c,hitTest:l,overlapMode:u}=o,d=this.boxCells[i],f=1e-6;if(d!==null){let i=this.bboxes;for(let o of d)if(!c.box[o]){c.box[o]=!0;let d=o*4,p=this.boxKeys[o];if(e<=i[d+2]+f&&t<=i[d+3]+f&&n>=i[d+0]-f&&r>=i[d+1]-f&&(!s||s(p))&&(!l||!Io(u,p.overlapMode))&&(a.push({key:p,x1:i[d],y1:i[d+1],x2:i[d+2],y2:i[d+3]}),l))return!0}}let p=this.circleCells[i];if(p!==null){let i=this.circles;for(let o of p)if(!c.circle[o]){c.circle[o]=!0;let d=o*3,f=this.circleKeys[o];if(this._circleAndRectCollide(i[d],i[d+1],i[d+2],e,t,n,r)&&(!s||s(f))&&(!l||!Io(u,f.overlapMode))){let e=i[d],t=i[d+1],n=i[d+2];if(a.push({key:f,x1:e-n,y1:t-n,x2:e+n,y2:t+n}),l)return!0}}}return!1}_queryCellCircle(e,t,n,r,i,a,o,s){let{circle:c,seenUids:l,overlapMode:u}=o,d=this.boxCells[i];if(d!==null){let e=this.bboxes;for(let t of d)if(!l.box[t]){l.box[t]=!0;let n=t*4,r=this.boxKeys[t];if(this._circleAndRectCollide(c.x,c.y,c.radius,e[n+0],e[n+1],e[n+2],e[n+3])&&(!s||s(r))&&!Io(u,r.overlapMode))return a.push(!0),!0}}let f=this.circleCells[i];if(f!==null){let e=this.circles;for(let t of f)if(!l.circle[t]){l.circle[t]=!0;let n=t*3,r=this.circleKeys[t];if(this._circlesCollide(e[n],e[n+1],e[n+2],c.x,c.y,c.radius)&&(!s||s(r))&&!Io(u,r.overlapMode))return a.push(!0),!0}}}_forEachCell(e,t,n,r,i,a,o,s){let c=this._convertToXCellCoord(e),l=this._convertToYCellCoord(t),u=this._convertToXCellCoord(n),d=this._convertToYCellCoord(r);for(let f=c;f<=u;f++)for(let c=l;c<=d;c++){let l=this.xCellCount*c+f;if(i.call(this,e,t,n,r,l,a,o,s))return}}_convertToXCellCoord(e){return Math.max(0,Math.min(this.xCellCount-1,Math.floor(e*this.xScale)))}_convertToYCellCoord(e){return Math.max(0,Math.min(this.yCellCount-1,Math.floor(e*this.yScale)))}_circlesCollide(e,t,n,r,i,a){let o=r-e,s=i-t,c=n+a;return c*c>o*o+s*s}_circleAndRectCollide(e,t,n,r,i,a,o){let s=(a-r)/2,c=Math.abs(e-(r+s));if(c>s+n)return!1;let l=(o-i)/2,u=Math.abs(t-(i+l));if(u>l+n)return!1;if(c<=s||u<=l)return!0;let d=c-s,f=u-l;return d*d+f*f<=n*n}};function Ro(e,t){let n=1/(t[0]*t[0]+t[1]*t[1]+t[2]*t[2]),r=1/(t[8]*t[8]+t[9]*t[9]+t[10]*t[10]),i=t[0]*n,a=t[4]*n,o=t[8]*r,s=t[1]*n,c=t[5]*n,l=t[9]*r,u=t[2]*n,d=t[6]*n,f=t[10]*r;e[0]=i,e[1]=a,e[2]=o,e[4]=s,e[5]=c,e[6]=l,e[8]=u,e[9]=d,e[10]=f;let p=t[12],m=t[13],h=t[14];return e[12]=-i*p-s*m-u*h,e[13]=-a*p-c*m-d*h,e[14]=-o*p-l*m-f*h,e[3]=0,e[7]=0,e[11]=0,e[15]=1,e}function zo(e,t){return e[0]=1/t[0],e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=1/t[5],e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=0,e[11]=1/t[14],e[12]=0,e[13]=0,e[14]=-1,e[15]=t[10]/t[14],e}function Bo(e,t){let n=1/(t[0]*t[5]-t[1]*t[4]);return e[0]=t[5]*n,e[1]=-t[1]*n,e[2]=0,e[3]=0,e[4]=-t[4]*n,e[5]=t[0]*n,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=1/t[10],e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1/t[15],e}const Vo=vr();function Ho(e,t,n){let r=vr();if(!e){let{vecSouth:e,vecEast:n}=Wo(t),i=jr();i[0]=n[0],i[1]=n[1],i[2]=e[0],i[3]=e[1],Mr(i,i),r[0]=i[0],r[1]=i[1],r[4]=i[2],r[5]=i[3]}return ke(r,r,[1/n,1/n,1]),r}function Uo(e,t,n,r){if(e){let e=vr();if(!t){let{vecSouth:t,vecEast:r}=Wo(n);e[0]=r[0],e[1]=r[1],e[4]=t[0],e[5]=t[1]}return ke(e,e,[r,r,1]),e}return n.pixelsToClipSpaceMatrix}function Wo(e){let t=Math.cos(e.rollInRadians),n=Math.sin(e.rollInRadians),r=Math.cos(e.pitchInRadians),i=Math.cos(e.bearingInRadians),a=Math.sin(e.bearingInRadians),o=at();o[0]=-i*r*n-a*t,o[1]=-a*r*n+i*t;let s=ft(o);s<1e-9?Hn(o):te(o,o,1/s);let c=at();c[0]=i*r*t-a*n,c[1]=a*r*t+i*n;let l=ft(c);return l<1e-9?Hn(c):te(c,c,1/l),{vecEast:c,vecSouth:o}}function Go(e,t,n){return Fo(e.getElevation,t,n,e.heightOffset??0,e.heightAnchorGround??!0)}function Ko(e,t,n,r){let i;r==null?(i=[e,t,0,1],ls(i,i,n)):(i=[e,t,r,1],Gt(i,i,n));let a=i[3];return{point:new l(i[0]/a,i[1]/a),signedDistanceFromCamera:a,isOccluded:!1}}function qo(e,t){return .5+e/t*.5}function Jo(e,t){return e.x>=-t[0]&&e.x<=t[0]&&e.y>=-t[1]&&e.y<=t[1]}function Yo(e,t,n,r,a,o,s,c,u,d,f,p,m){let h=n?e.textSizeData:e.iconSizeData,g=fn(h,t.transform.zoom),_=[256/t.width*2+1,256/t.height*2+1],v=n?e.text.dynamicLayoutVertexArray:e.icon.dynamicLayoutVertexArray;v.clear();let y=e.lineVertexArray,b=n?e.text.placedSymbolArray:e.icon.placedSymbolArray,x=t.transform.width/t.transform.height,S=!1;for(let n=0;nMath.abs(n.x-t.x)*r?{useVertical:!0}:(e===2?t.yn.x)?{needsFlipping:!0}:null}function Qo(e){let{projectionContext:t,pitchedLabelPlaneMatrixInverse:n,symbol:r,fontSize:i,flip:a,keepUpright:o,glyphOffsetArray:s,dynamicLayoutVertexArray:c,aspectRatio:u,rotateToLine:d}=e,f=i/24,p=r.lineOffsetX*f,m=r.lineOffsetY*f,h;if(r.numGlyphs>1){let e=r.glyphStartIndex+r.numGlyphs,i=r.lineStartIndex,c=r.lineStartIndex+r.lineLength,l=Xo(f,s,p,m,a,r,d,t);if(!l)return{notEnoughRoom:!0};let g=ns(l.first.point.x,l.first.point.y,t,n),_=ns(l.last.point.x,l.last.point.y,t,n);if(o&&!a){let e=Zo(r.writingMode,g,_,u);if(e)return e}h=[l.first];for(let n=r.glyphStartIndex+1;n0?o.point:$o(t.tileAnchorPoint,a,e,1,t),c=ns(e.x,e.y,t,n),d=ns(s.x,s.y,t,n),f=Zo(r.writingMode,c,d,u);if(f)return f}let e=os(f*s.getoffsetX(r.glyphStartIndex),p,m,a,r.segment,r.lineStartIndex,r.lineStartIndex+r.lineLength,t,d);if(!e||t.projectionCache.anyProjectionOccluded)return{notEnoughRoom:!0};h=[e]}for(let e of h)Me(c,e.point,e.angle);return{}}function $o(e,t,n,r,i){let a=e.add(e.sub(t)._unit()),o=ts(a.x,a.y,i).point,s=n.sub(o);return n.add(s._mult(r/s.mag()))}function es(e,t,n){let r=t.projectionCache;if(r.projections[e])return r.projections[e];let i=new l(t.lineVertexArray.getx(e),t.lineVertexArray.gety(e)),a=ts(i.x,i.y,t);if(a.signedDistanceFromCamera>0)return r.projections[e]=a.point,r.anyProjectionOccluded||=a.isOccluded,a.point;let o=e-n.direction,s=n.distanceFromAnchor===0?t.tileAnchorPoint:new l(t.lineVertexArray.getx(o),t.lineVertexArray.gety(o)),c=n.absOffsetX-n.distanceFromAnchor+1;return $o(s,i,n.previousVertex,c,t)}function ts(e,t,n){let r=e+n.translation[0],i=t+n.translation[1],a;return n.pitchWithMap?(a=Ko(r,i,n.pitchedLabelPlaneMatrix,Go(n,r,i)),a.isOccluded=!1):(a=n.transform.projectTileCoordinates(r,i,n.unwrappedTileID,Go(n,r,i)),a.point.x=(a.point.x*.5+.5)*n.width,a.point.y=(-a.point.y*.5+.5)*n.height),a}function ns(e,t,n,r){if(n.pitchWithMap){let i=[e,t,0,1];Gt(i,i,r);let a=i[0]/i[3],o=i[1]/i[3];return n.transform.projectTileCoordinates(a,o,n.unwrappedTileID,Go(n,a,o)).point}return{x:e/n.width*2-1,y:1-t/n.height*2}}function rs(e,t,n){return n.transform.projectTileCoordinates(e,t,n.unwrappedTileID,Go(n,e,t))}function is(e,t,n){return e._unit()._perp()._mult(t*n)}function as(e,t,n,r,i,a,o,s,c){if(s.projectionCache.offsets[e])return s.projectionCache.offsets[e];let l=n.add(t);if(e+c.direction=i)return s.projectionCache.offsets[e]=l,l;let u=es(e+c.direction,s,c),d=is(u.sub(n),o,c.direction),f=n.add(d),p=u.add(d);return s.projectionCache.offsets[e]=Xn(a,l,f,p)||l,s.projectionCache.offsets[e]}function os(e,t,n,r,i,a,o,s,c){let l=r?e-t:e+t,u=l>0?1:-1,d=0;r&&(u*=-1,d=Math.PI),u<0&&(d+=Math.PI);let f=u>0?a+i:a+i+1,p;s.projectionCache.cachedAnchorPoint?p=s.projectionCache.cachedAnchorPoint:(p=ts(s.tileAnchorPoint.x,s.tileAnchorPoint.y,s).point,s.projectionCache.cachedAnchorPoint=p);let m=p,h=p,g,_,v=0,y=0,b=Math.abs(l),x=[],S;for(;v+y<=b;){if(f+=u,f=o)return null;v+=y,h=m,_=g;let e={absOffsetX:b,direction:u,distanceFromAnchor:v,previousVertex:h};if(m=es(f,s,e),n===0)x.push(h),S=m.sub(h);else{let t,r=m.sub(h);t=r.mag()===0?is(es(f+u,s,e).sub(m),n,u):is(r,n,u),_||=h.add(t),g=as(f,t,m,a,o,_,n,s,e),x.push(_),S=g.sub(_)}y=S.mag()}let C=(b-v)/y,w=S._mult(C)._add(_||h),T=d+Math.atan2(m.y-h.y,m.x-h.x);return x.push(w),{point:w,angle:c?T:0,path:x}}const ss=new Float32Array([-1/0,-1/0,0,-1/0,-1/0,0,-1/0,-1/0,0,-1/0,-1/0,0]);function cs(e,t){for(let n=0;n{let r=Ko(e.x,e.y,n,Go(t,e.x,e.y)),i=t.transform.projectTileCoordinates(r.point.x,r.point.y,t.unwrappedTileID,Go(t,r.point.x,r.point.y));return i.point.x=(i.point.x*.5+.5)*t.width,i.point.y=(-i.point.y*.5+.5)*t.height,i})}function ds(e){let t=0,n=0,r=0,i=0;for(let a=0;an&&(n=i,t=r));return e.slice(t,t+n)}var fs=class{constructor(e,t=new Lo(e.width+200,e.height+200,25),n=new Lo(e.width+200,e.height+200,25)){this.transform=e,this.grid=t,this.ignoredGrid=n,this.pitchFactor=Math.cos(e.pitch*Math.PI/180)*e.cameraToCenterDistance,this.screenRightBoundary=e.width+100,this.screenBottomBoundary=e.height+100,this.gridRightBoundary=e.width+200,this.gridBottomBoundary=e.height+200,this.perspectiveRatioCutoff=.6}placeCollisionBox(e,t,n,r,i,a,o,s,c,l,u,d,f=0,p=!0){let m=e.anchorPointX+s[0],h=e.anchorPointY+s[1],g=this.projectAndGetPerspectiveRatio(m,h,i,Fo(l,m,h,f,p),d),_=n*g.perspectiveRatio,v;if(!a&&!o){let t=g.x+(u?u.x*_:0),n=g.y+(u?u.y*_:0);v={allPointsOccluded:!1,box:[t+e.x1*_,n+e.y1*_,t+e.x2*_,n+e.y2*_]}}else v=this._projectCollisionBox(e,_,r,i,a,o,s,g,l,u,d,f,p);let[y,b,x,S]=v.box,C=a?v.allPointsOccluded:g.isOccluded,w=C;return w||=g.perspectiveRatio=1;e--)p.push(a.path[e]);for(let e=1;ee.signedDistanceFromCamera<=0)?[]:e.map(e=>e.point)}let g=[];if(p.length>0){let e=p[0].clone(),t=p[0].clone();for(let n=1;n=n.x&&t.x<=r.x&&e.y>=n.y&&t.y<=r.y?[p]:t.xr.x||t.yr.y?[]:kt([p],n.x,n.y,r.x,r.y)}for(let n of g){i.reset(n,t*.25);let r=0;r=i.length<=.5*t?1:Math.ceil(i.paddedLength/m)+1;for(let n=0;n=this.screenRightBoundary||r<100||t>this.screenBottomBoundary}isInsideGrid(e,t,n,r){return n>=0&&e=0&&tthis.projectAndGetPerspectiveRatio(e.x,e.y,r,Fo(c,e.x,e.y,f,p),d));A=e.some(e=>!e.isOccluded),k=e.map(e=>new l(e.x,e.y))}else A=!0;return{box:Bt(k),allPointsOccluded:!A}}},ps=class{constructor(e,t,n,r){this.opacity=e?Math.max(0,Math.min(1,e.opacity+(e.placed?t:-t))):r&&n?1:0,this.placed=n}isHidden(){return this.opacity===0&&!this.placed}},ms=class{constructor(e,t,n,r,i){this.text=new ps(e?e.text:null,t,n,i),this.icon=new ps(e?e.icon:null,t,r,i)}isHidden(){return this.text.isHidden()&&this.icon.isHidden()}},hs=class{constructor(e,t,n){this.text=e,this.icon=t,this.skipFade=n}},gs=class{constructor(e,t,n,r,i){this.bucketInstanceId=e,this.featureIndex=t,this.sourceLayerIndex=n,this.bucketIndex=r,this.tileID=i}},_s=class{constructor(e){this.crossSourceCollisions=e,this.maxGroupID=0,this.collisionGroups={}}get(e){if(this.crossSourceCollisions)return{ID:0,predicate:null};if(!this.collisionGroups[e]){let t=++this.maxGroupID;this.collisionGroups[e]={ID:t,predicate:e=>e.collisionGroupID===t}}return this.collisionGroups[e]}};function vs(e,t,n,r,i){let{horizontalAlign:a,verticalAlign:o}=Oe(e),s=-(a-.5)*t,c=-(o-.5)*n;return new l(s+r[0]*i,c+r[1]*i)}var ys=class{constructor(e,t,n,r,i){this.transform=e.clone(),this.terrain=t,this.collisionIndex=new fs(this.transform),this.placements={},this.opacities={},this.variableOffsets={},this.stale=!1,this.commitTime=0,this.fadeDuration=n,this.retainedQueryData={},this.collisionGroups=new _s(r),this.collisionCircleArrays={},this.collisionBoxArrays=new Map,this.prevPlacement=i,i&&(i.prevPlacement=void 0),this.placedOrientations={}}_getTerrainElevationFunc(e){let t=this.terrain;if(t)return(n,r)=>t.getElevation(e,n,r)}getBucketParts(e,t,n,r){let i=n.getBucket(t),a=n.latestFeatureIndex;if(!i||!a||t.id!==i.layerIds[0])return;let o=n.collisionBoxArray,s=i.layers[0].layout,c=i.layers[0].paint,l=2**(this.transform.zoom-n.tileID.overscaledZ),u=n.tileSize/N,d=n.tileID.toUnwrapped(),f=s.get(`text-rotation-alignment`)===`map`,p=lt(n,1,this.transform.zoom),m=le(this.collisionIndex.transform,n,c.get(`text-translate`),c.get(`text-translate-anchor`)),h=le(this.collisionIndex.transform,n,c.get(`icon-translate`),c.get(`icon-translate-anchor`)),g=Ho(f,this.transform,p);this.retainedQueryData[i.bucketInstanceId]=new gs(i.bucketInstanceId,a,i.sourceLayerIndex,i.index,n.tileID);let _={bucket:i,layout:s,translationText:m,translationIcon:h,unwrappedTileID:d,pitchedLabelPlaneMatrix:g,scale:l,textPixelRatio:u,holdingForFade:n.holdingForSymbolFade(),collisionBoxArray:o,partiallyEvaluatedTextSize:fn(i.textSizeData,this.transform.zoom),collisionGroup:this.collisionGroups.get(i.sourceID)};if(r)for(let t of i.sortKeyRanges){let{sortKey:n,symbolInstanceStart:r,symbolInstanceEnd:i}=t;e.push({sortKey:n,symbolInstanceStart:r,symbolInstanceEnd:i,parameters:_})}else e.push({symbolInstanceStart:0,symbolInstanceEnd:i.symbolInstances.length,parameters:_})}attemptAnchorPlacement(e,t,n,r,i,a,o,s,c,l,u,d,f,p,m,h,g,_,v,y,b,x){let S=Wn[e.textAnchor],C=[e.textOffset0,e.textOffset1],w=vs(S,n,r,C,i),T=this.collisionIndex.placeCollisionBox(t,d,s,c,l,o,a,h,u.predicate,v,w,y,b,x);if(!(_&&!this.collisionIndex.placeCollisionBox(_,d,s,c,l,o,a,g,u.predicate,v,w,y,b,x).placeable)&&T.placeable){let e;if(this.prevPlacement?.variableOffsets[f.crossTileID]&&this.prevPlacement?.placements[f.crossTileID]?.text&&(e=this.prevPlacement.variableOffsets[f.crossTileID].anchor),f.crossTileID===0)throw Error(`symbolInstance.crossTileID can't be 0`);return this.variableOffsets[f.crossTileID]={textOffset:C,width:n,height:r,anchor:S,textBoxScale:i,prevAnchor:e},this.markUsedJustification(p,S,f,m),p.allowVerticalPlacement&&(this.markUsedOrientation(p,m,f),this.placedOrientations[f.crossTileID]=m),{shift:w,placedGlyphBoxes:T}}}placeLayerBucketPart(e,t,n){let{bucket:r,layout:a,translationText:o,translationIcon:s,unwrappedTileID:c,pitchedLabelPlaneMatrix:l,textPixelRatio:u,holdingForFade:d,collisionBoxArray:f,partiallyEvaluatedTextSize:p,collisionGroup:m}=e.parameters,h=a.get(`text-optional`),g=a.get(`icon-optional`),_=_n(a,`text-overlap`,`text-allow-overlap`),v=_===`always`,y=_n(a,`icon-overlap`,`icon-allow-overlap`),b=y===`always`,x=a.get(`text-rotation-alignment`)===`map`,S=a.get(`text-pitch-alignment`)===`map`,C=a.get(`icon-text-fit`)!==`none`,w=a.get(`symbol-z-order`)===`viewport-y`,T=a.get(`symbol-height-anchor`)===`ground`,E=v&&(b||!r.hasIconData()||g),D=b&&(v||!r.hasTextData()||h);!r.collisionArrays&&f&&r.deserializeCollisionBoxes(f);let ee=this.retainedQueryData[r.bucketInstanceId].tileID,O=this._getTerrainElevationFunc(ee),k=this.transform.getFastPathSimpleProjectionMatrix(ee),A=(e,f,b)=>{if(t[e.crossTileID])return;if(d){this.placements[e.crossTileID]=new hs(!1,!1,!1);return}let w=e.heightOffset,A=!1,j=!1,M=!0,te=null,ne={box:null,placeable:!1,offscreen:null,occluded:!1},re={box:null,placeable:!1,offscreen:null},ie=null,N=null,ae=null,oe=0,se=0,ce=0;f.textFeatureIndex?oe=f.textFeatureIndex:e.useRuntimeCollisionCircles&&(oe=e.featureIndex),f.verticalTextFeatureIndex&&(se=f.verticalTextFeatureIndex);let le=f.textBox;if(le){let t=t=>{let n=1;if(r.allowVerticalPlacement&&!t&&this.prevPlacement){let t=this.prevPlacement.placedOrientations[e.crossTileID];t&&(this.placedOrientations[e.crossTileID]=t,n=t,this.markUsedOrientation(r,n,e))}return n},i=(t,n)=>{if(r.allowVerticalPlacement&&e.numVerticalGlyphVertices>0&&f.verticalTextBox){for(let e of r.writingModes)if(e===2?(ne=n(),re=ne):ne=t(),ne?.placeable)break}else ne=t()},a=e.textAnchorOffsetStartIndex,l=e.textAnchorOffsetEndIndex;if(l===a){let n=(t,n)=>{let i=this.collisionIndex.placeCollisionBox(t,_,u,ee,c,S,x,o,m.predicate,O,void 0,k,w,T);return i?.placeable&&(this.markUsedOrientation(r,n,e),this.placedOrientations[e.crossTileID]=n),i};i(()=>n(le,1),()=>{let t=f.verticalTextBox;return r.allowVerticalPlacement&&e.numVerticalGlyphVertices>0&&t?n(t,2):{box:null,offscreen:null}}),t(ne?.placeable)}else{let d=Wn[this.prevPlacement?.variableOffsets[e.crossTileID]?.anchor],p=(t,i,f)=>{let p=t.x2-t.x1,h=t.y2-t.y1,g=e.textBoxScale,v=C&&y===`never`?i:null,b=null,E=_===`never`?1:2,D=`never`;d&&E++;for(let n=0;np(le,f.iconBox,1),()=>{let t=f.verticalTextBox,n=ne?.placeable;return r.allowVerticalPlacement&&!n&&e.numVerticalGlyphVertices>0&&t?p(t,f.verticalIconBox,2):{box:null,occluded:!0,offscreen:null}}),ne&&(A=ne.placeable,M=ne.offscreen);let h=t(ne?.placeable);if(!A&&this.prevPlacement){let t=this.prevPlacement.variableOffsets[e.crossTileID];t&&(this.variableOffsets[e.crossTileID]=t,this.markUsedJustification(r,t.anchor,e,h))}}}if(ie=ne,A=ie?.placeable,M=ie?.offscreen,e.useRuntimeCollisionCircles&&e.centerJustifiedTextSymbolIndex>=0){let t=r.text.placedSymbolArray.get(e.centerJustifiedTextSymbolIndex),s=i(r.textSizeData,p,t),u=a.get(`text-padding`),d=e.collisionCircleDiameter;N=this.collisionIndex.placeCollisionCircles(_,t,r.lineVertexArray,r.glyphOffsetArray,s,c,l,n,S,m.predicate,d,u,o,O),N.circles.length&&N.collisionDetected&&!n&&I(`Collisions detected, but collision boxes are not shown`),A=v||N.circles.length>0&&!N.collisionDetected,M&&=N.offscreen}if(f.iconFeatureIndex&&(ce=f.iconFeatureIndex),f.iconBox){let e=e=>this.collisionIndex.placeCollisionBox(e,y,u,ee,c,S,x,s,m.predicate,O,C&&te?te:void 0,k,w,T);re&&re.placeable&&f.verticalIconBox?(ae=e(f.verticalIconBox),j=ae.placeable):(ae=e(f.iconBox),j=ae.placeable),M&&=ae.offscreen}let ue=h||e.numHorizontalGlyphVertices===0&&e.numVerticalGlyphVertices===0,de=g||e.numIconVertices===0;!ue&&!de?j=A=j&&A:de?ue||(j&&=A):A=j&&A;let fe=A&&ie.placeable,pe=j&&ae.placeable;if(fe&&(re&&re.placeable&&se?this.collisionIndex.insertCollisionBox(ie.box,_,a.get(`text-ignore-placement`),r.bucketInstanceId,se,m.ID):this.collisionIndex.insertCollisionBox(ie.box,_,a.get(`text-ignore-placement`),r.bucketInstanceId,oe,m.ID)),pe&&this.collisionIndex.insertCollisionBox(ae.box,y,a.get(`icon-ignore-placement`),r.bucketInstanceId,ce,m.ID),N&&A&&this.collisionIndex.insertCollisionCircles(N.circles,_,a.get(`text-ignore-placement`),r.bucketInstanceId,oe,m.ID),n&&this.storeCollisionData(r.bucketInstanceId,b,f,ie,ae,N),e.crossTileID===0)throw Error(`symbolInstance.crossTileID can't be 0`);if(r.bucketInstanceId===0)throw Error(`bucket.bucketInstanceId can't be 0`);let me=(A||E)&&!ie?.occluded,he=(j||D)&&!ae?.occluded;this.placements[e.crossTileID]=new hs(me,he,M||r.justReloaded),t[e.crossTileID]=!0};if(w){if(e.symbolInstanceStart!==0)throw Error(`bucket.bucketInstanceId should be 0`);let t=r.getSortedSymbolIndexes(-this.transform.bearingInRadians);for(let e=t.length-1;e>=0;--e){let n=t[e];A(r.symbolInstances.get(n),r.collisionArrays[n],n)}}else for(let t=e.symbolInstanceStart;t=0&&(a>=0&&t!==a?e.text.placedSymbolArray.get(t).crossTileID=0:e.text.placedSymbolArray.get(t).crossTileID=n.crossTileID)}markUsedOrientation(e,t,n){let r=t===1||t===3?t:0,i=t===2?t:0,a=[n.leftJustifiedTextSymbolIndex,n.centerJustifiedTextSymbolIndex,n.rightJustifiedTextSymbolIndex];for(let t of a)e.text.placedSymbolArray.get(t).placedOrientation=r;n.verticalPlacedTextSymbolIndex&&(e.text.placedSymbolArray.get(n.verticalPlacedTextSymbolIndex).placedOrientation=i)}commit(e){this.commitTime=e,this.zoomAtLastRecencyCheck=this.transform.zoom;let t=this.prevPlacement,n=!1;this.prevZoomAdjustment=t?t.zoomAdjustment(this.transform.zoom):0;let r=t?t.symbolFadeChange(e):1,i=t?t.opacities:{},a=t?t.variableOffsets:{},o=t?t.placedOrientations:{};for(let e in this.placements){let t=this.placements[e],a=i[e];a?(this.opacities[e]=new ms(a,r,t.text,t.icon),n||=t.text!==a.text.placed,n||=t.icon!==a.icon.placed):(this.opacities[e]=new ms(null,r,t.text,t.icon,t.skipFade),n||=t.text||t.icon)}for(let e in i){let t=i[e];if(!this.opacities[e]){let i=new ms(t,r,!1,!1);i.isHidden()||(this.opacities[e]=i,n||=t.text.placed,n||=t.icon.placed)}}for(let e in a)!this.variableOffsets[e]&&this.opacities[e]&&!this.opacities[e].isHidden()&&(this.variableOffsets[e]=a[e]);for(let e in o)!this.placedOrientations[e]&&this.opacities[e]&&!this.opacities[e].isHidden()&&(this.placedOrientations[e]=o[e]);if(t&&t.lastPlacementChangeTime===void 0)throw Error(`Last placement time for previous placement is not defined`);n?this.lastPlacementChangeTime=e:typeof this.lastPlacementChangeTime!=`number`&&(this.lastPlacementChangeTime=t?t.lastPlacementChangeTime:e)}updateLayerOpacities(e,t){let n={};for(let r of t){let t=r.getBucket(e);t&&r.latestFeatureIndex&&e.id===t.layerIds[0]&&this.updateBucketOpacities(t,r.tileID,n,r.collisionBoxArray)}}updateBucketOpacities(e,t,n,r){e.hasTextData()&&(e.text.opacityVertexArray.clear(),e.text.hasVisibleVertices=!1),e.hasIconData()&&(e.icon.opacityVertexArray.clear(),e.icon.hasVisibleVertices=!1),e.hasIconCollisionBoxData()&&e.iconCollisionBox.collisionVertexArray.clear(),e.hasTextCollisionBoxData()&&e.textCollisionBox.collisionVertexArray.clear();let i=e.layers[0],a=i.layout,o=new ms(null,0,!1,!1,!0),s=a.get(`text-allow-overlap`),c=a.get(`icon-allow-overlap`),u=i._unevaluatedLayout.hasValue(`text-variable-anchor`)||i._unevaluatedLayout.hasValue(`text-variable-anchor-offset`),d=a.get(`text-rotation-alignment`)===`map`,f=a.get(`text-pitch-alignment`)===`map`,p=a.get(`icon-text-fit`)!==`none`,m=new ms(null,0,s&&(c||!e.hasIconData()||a.get(`icon-optional`)),c&&(s||!e.hasTextData()||a.get(`text-optional`)),!0);!e.collisionArrays&&r&&(e.hasIconCollisionBoxData()||e.hasTextCollisionBoxData())&&e.deserializeCollisionBoxes(r);let h=(e,t,n)=>{for(let r=0;r0||a>0,y=r.numIconVertices>0,b=this.placedOrientations[r.crossTileID],x=b===2,S=b===1||b===3;if(v){let t=Ts(_.text),n=x?Es:t;h(e.text,i,n);let o=S?Es:t;h(e.text,a,o);let s=_.text.isHidden(),c=[r.rightJustifiedTextSymbolIndex,r.centerJustifiedTextSymbolIndex,r.leftJustifiedTextSymbolIndex];for(let t of c)t>=0&&(e.text.placedSymbolArray.get(t).hidden=s||x?1:0);r.verticalPlacedTextSymbolIndex>=0&&(e.text.placedSymbolArray.get(r.verticalPlacedTextSymbolIndex).hidden=s||S?1:0);let l=this.variableOffsets[r.crossTileID];l&&this.markUsedJustification(e,l.anchor,r,b);let u=this.placedOrientations[r.crossTileID];u&&(this.markUsedJustification(e,`left`,r,u),this.markUsedOrientation(e,u,r))}if(y){let t=Ts(_.icon),n=!(p&&r.verticalPlacedIconSymbolIndex&&x);if(r.placedIconSymbolIndex>=0){let i=n?t:Es;h(e.icon,r.numIconVertices,i),e.icon.placedSymbolArray.get(r.placedIconSymbolIndex).hidden=_.icon.isHidden()}if(r.verticalPlacedIconSymbolIndex>=0){let i=n?Es:t;h(e.icon,r.numVerticalIconVertices,i),e.icon.placedSymbolArray.get(r.verticalPlacedIconSymbolIndex).hidden=_.icon.isHidden()}}let C=g?.has(t)?g.get(t):{text:null,icon:null};if(e.hasIconCollisionBoxData()||e.hasTextCollisionBoxData()){let n=e.collisionArrays[t];if(n){let t=new l(0,0);if(n.textBox||n.verticalTextBox){let r=!0;if(u){let e=this.variableOffsets[s];e?(t=vs(e.anchor,e.width,e.height,e.textOffset,e.textBoxScale),d&&t._rotate(f?-this.transform.bearingInRadians:this.transform.bearingInRadians)):r=!1}if(n.textBox||n.verticalTextBox){let i;n.textBox&&(i=x),n.verticalTextBox&&(i=S),bs(e.textCollisionBox.collisionVertexArray,_.text.placed,!r||i,C.text,t.x,t.y)}}if(n.iconBox||n.verticalIconBox){let r=!!(!S&&n.verticalIconBox),i;n.iconBox&&(i=r),n.verticalIconBox&&(i=!r),bs(e.iconCollisionBox.collisionVertexArray,_.icon.placed,i,C.icon,p?t.x:0,p?t.y:0)}}}}if(e.sortFeatures(-this.transform.bearingInRadians),this.retainedQueryData[e.bucketInstanceId]&&(this.retainedQueryData[e.bucketInstanceId].featureSortOrder=e.featureSortOrder),e.hasTextData()&&e.text.opacityVertexBuffer&&e.text.opacityVertexBuffer.updateData(e.text.opacityVertexArray),e.hasIconData()&&e.icon.opacityVertexBuffer&&e.icon.opacityVertexBuffer.updateData(e.icon.opacityVertexArray),e.hasIconCollisionBoxData()&&e.iconCollisionBox.collisionVertexBuffer&&e.iconCollisionBox.collisionVertexBuffer.updateData(e.iconCollisionBox.collisionVertexArray),e.hasTextCollisionBoxData()&&e.textCollisionBox.collisionVertexBuffer&&e.textCollisionBox.collisionVertexBuffer.updateData(e.textCollisionBox.collisionVertexArray),e.text.opacityVertexArray.length!==e.text.layoutVertexArray.length/4)throw Error(`bucket.text.opacityVertexArray.length (= ${e.text.opacityVertexArray.length}) !== bucket.text.layoutVertexArray.length (= ${e.text.layoutVertexArray.length}) / 4`);if(e.icon.opacityVertexArray.length!==e.icon.layoutVertexArray.length/4)throw Error(`bucket.icon.opacityVertexArray.length (= ${e.icon.opacityVertexArray.length}) !== bucket.icon.layoutVertexArray.length (= ${e.icon.layoutVertexArray.length}) / 4`);e.bucketInstanceId in this.collisionCircleArrays&&(e.collisionCircleArray=this.collisionCircleArrays[e.bucketInstanceId],delete this.collisionCircleArrays[e.bucketInstanceId])}symbolFadeChange(e){return this.fadeDuration===0?1:(e-this.commitTime)/this.fadeDuration+this.prevZoomAdjustment}zoomAdjustment(e){return Math.max(0,(this.transform.zoom-e)/1.5)}hasTransitions(e){return this.stale||e-this.lastPlacementChangeTimee}setStale(){this.stale=!0}};function bs(e,t,n,r,i,a){(!r||r.length===0)&&(r=[0,0,0,0]);let o=r[0]-100,s=r[1]-100,c=r[2]-100,l=r[3]-100;e.emplaceBack(+!!t,+!!n,i||0,a||0,o,s),e.emplaceBack(+!!t,+!!n,i||0,a||0,c,s),e.emplaceBack(+!!t,+!!n,i||0,a||0,c,l),e.emplaceBack(+!!t,+!!n,i||0,a||0,o,l)}const xs=2**25,Ss=2**24,Cs=2**17,ws=2**16;function Ts(e){if(e.opacity===0&&!e.placed)return 0;if(e.opacity===1&&e.placed)return 4294967295;let t=+!!e.placed,n=Math.floor(e.opacity*127);return n*xs+t*Ss+n*Cs+t*ws+n*512+t*256+n*2+t}const Es=0;var Ds=class{constructor(e){this._sortAcrossTiles=e.layout.get(`symbol-z-order`)!==`viewport-y`&&!e.layout.get(`symbol-sort-key`).isConstant(),this._currentTileIndex=0,this._currentPartIndex=0,this._seenCrossTileIDs={},this._bucketParts=[]}continuePlacement(e,t,n,r,i){let a=this._bucketParts;for(;this._currentTileIndexe.sortKey-t.sortKey));this._currentPartIndex!this._forceFullPlacement&&U()-r>2;for(;this._currentPlacementIndex>=0;){let r=t[e[this._currentPlacementIndex]],a=this.placement.collisionIndex.transform.zoom;if(C(r)&&r.layout&&(!r.minzoom||r.minzoom<=a)&&(!r.maxzoom||r.maxzoom>a)){if(this._inProgressLayer||=new Ds(r),this._inProgressLayer.continuePlacement(n[r.source],this.placement,this._showCollisionBoxes,r,i))return;delete this._inProgressLayer}this._currentPlacementIndex--}this._done=!0}commit(e){return this.placement.commit(e),this.placement}};const ks=[Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array],J=new Uint32Array(96);var As=class e{static from(t){if(!t||t.byteLength===void 0||t.buffer)throw Error(`Data must be an instance of ArrayBuffer or SharedArrayBuffer.`);let[n,r]=new Uint8Array(t,0,2);if(n!==219)throw Error(`Data does not appear to be in a KDBush format.`);let i=r>>4;if(i!==1)throw Error(`Got v${i} data when expected v1.`);let a=ks[r&15];if(!a)throw Error(`Unrecognized array type.`);let[o]=new Uint16Array(t,2,1),[s]=new Uint32Array(t,4,1);return new e(s,o,a,void 0,t)}constructor(e,t=64,n=Float64Array,r=ArrayBuffer,i){if(isNaN(e)||e<0)throw Error(`Unexpected numItems value: ${e}.`);this.numItems=+e,this.nodeSize=Math.min(Math.max(+t,2),65535),this.ArrayType=n,this.IndexArrayType=e<65536?Uint16Array:Uint32Array;let a=ks.indexOf(this.ArrayType),o=e*2*this.ArrayType.BYTES_PER_ELEMENT,s=e*this.IndexArrayType.BYTES_PER_ELEMENT,c=(8-s%8)%8;if(a<0)throw Error(`Unexpected typed array class: ${n}.`);if(i)this.data=i,this.ids=new this.IndexArrayType(i,8,e),this.coords=new n(i,8+s+c,e*2),this._pos=e*2,this._finished=!0;else{let i=this.data=new r(8+o+s+c);this.ids=new this.IndexArrayType(i,8,e),this.coords=new n(i,8+s+c,e*2),this._pos=0,this._finished=!1,new Uint8Array(i,0,2).set([219,16+a]),new Uint16Array(i,2,1)[0]=t,new Uint32Array(i,4,1)[0]=e}}add(e,t){let n=this._pos>>1;return this.ids[n]=n,this.coords[this._pos++]=e,this.coords[this._pos++]=t,n}finish(){let e=this._pos>>1;if(e!==this.numItems)throw Error(`Added ${e} items when expected ${this.numItems}.`);return js(this.ids,this.coords,this.nodeSize,0,this.numItems-1,0),this._finished=!0,this}range(e,t,n,r){if(!this._finished)throw Error(`Data not yet indexed - call index.finish().`);let{ids:i,coords:a,nodeSize:o}=this;J[0]=0,J[1]=i.length-1,J[2]=0;let s=3,c=[];for(;s>0;){let l=J[--s],u=J[--s],d=J[--s];if(u-d<=o){for(let o=d;o<=u;o++){let s=a[2*o],l=a[2*o+1];s>=e&&s<=n&&l>=t&&l<=r&&c.push(i[o])}continue}let f=d+u>>1,p=a[2*f],m=a[2*f+1];p>=e&&p<=n&&m>=t&&m<=r&&c.push(i[f]),(l===0?e<=p:t<=m)&&(J[s++]=d,J[s++]=f-1,J[s++]=1-l),(l===0?n>=p:r>=m)&&(J[s++]=f+1,J[s++]=u,J[s++]=1-l)}return c}within(e,t,n){let r=[];return this.withinInto(e,t,n,r),r}withinInto(e,t,n,r){if(!this._finished)throw Error(`Data not yet indexed - call index.finish().`);let{ids:i,coords:a,nodeSize:o}=this;J[0]=0,J[1]=i.length-1,J[2]=0;let s=3,c=0,l=n*n;for(;s>0;){let u=J[--s],d=J[--s],f=J[--s];if(d-f<=o){for(let n=f;n<=d;n++)Fs(a[2*n],a[2*n+1],e,t)<=l&&(r[c++]=i[n]);continue}let p=f+d>>1,m=a[2*p],h=a[2*p+1];Fs(m,h,e,t)<=l&&(r[c++]=i[p]),(u===0?e-n<=m:t-n<=h)&&(J[s++]=f,J[s++]=p-1,J[s++]=1-u),(u===0?e+n>=m:t+n>=h)&&(J[s++]=p+1,J[s++]=d,J[s++]=1-u)}return c}};function js(e,t,n,r,i,a){if(i-r<=n)return;let o=r+i>>1;Ms(e,t,o,r,i,a),js(e,t,n,r,o-1,1-a),js(e,t,n,o+1,i,1-a)}function Ms(e,t,n,r,i,a){for(;i>r;){if(i-r>600){let o=i-r+1,s=n-r+1,c=Math.log(o),l=.5*Math.exp(2*c/3),u=.5*Math.sqrt(c*l*(o-l)/o)*(s-o/2<0?-1:1);Ms(e,t,n,Math.max(r,Math.floor(n-s*l/o+u)),Math.min(i,Math.floor(n+(o-s)*l/o+u)),a)}let o=t[2*n+a],s=r,c=i;for(Ns(e,t,r,n),t[2*i+a]>o&&Ns(e,t,r,i);so;)c--}t[2*r+a]===o?Ns(e,t,r,c):(c++,Ns(e,t,c,i)),c<=n&&(r=c+1),n<=c&&(i=c-1)}}function Ns(e,t,n,r){Ps(e,n,r),Ps(t,2*n,2*r),Ps(t,2*n+1,2*r+1)}function Ps(e,t,n){let r=e[t];e[t]=e[n],e[n]=r}function Fs(e,t,n,r){let i=e-n,a=t-r;return i*i+a*a}const Is=512/N/2;var Ls=class{constructor(e,t,n){this.tileID=e,this.bucketInstanceId=n,this._symbolsByKey={};let r=new Map;for(let e=0;e({x:Math.floor(e.anchorX*Is),y:Math.floor(e.anchorY*Is)})),crossTileIDs:t.map(e=>e.crossTileID)};if(n.positions.length>128){let e=new As(n.positions.length,16,Uint16Array);for(let{x:t,y:r}of n.positions)e.add(t,r);e.finish(),delete n.positions,n.index=e}this._symbolsByKey[e]=n}}getScaledCoordinates(e,t){let{x:n,y:r,z:i}=this.tileID.canonical,{x:a,y:o,z:s}=t.canonical,c=s-i,l=Is/2**c,u=(a*N+e.anchorX)*l,d=(o*N+e.anchorY)*l,f=n*N*Is,p=r*N*Is;return{x:Math.floor(u-f),y:Math.floor(d-p)}}findMatches(e,t,n){let r=this.tileID.canonical.ze)}},Rs=class{constructor(){this.maxCrossTileID=0}generate(){return++this.maxCrossTileID}},zs=class{constructor(){this.indexes={},this.usedCrossTileIDs={},this.lng=0}handleWrapJump(e){let t=Math.round((e-this.lng)/360);if(t!==0)for(let e in this.indexes){let n=this.indexes[e],r={};for(let e in n){let i=n[e];i.tileID=i.tileID.unwrapTo(i.tileID.wrap+t),r[i.tileID.key]=i}this.indexes[e]=r}this.lng=e}addBucket(e,t,n){if(this.indexes[e.overscaledZ]?.[e.key]){if(this.indexes[e.overscaledZ][e.key].bucketInstanceId===t.bucketInstanceId)return!1;this.removeBucketCrossTileIDs(e.overscaledZ,this.indexes[e.overscaledZ][e.key])}for(let e=0;ee.overscaledZ)for(let n in i){let a=i[n];a.tileID.isChildOf(e)&&a.findMatches(t.symbolInstances,e,r)}else{let a=i[e.scaledTo(Number(n)).key];a&&a.findMatches(t.symbolInstances,e,r)}}for(let e=0;e> 1u)/127.0,float(packedOpacity & 1u));}vec4 decode_color(const vec2 encodedColor) {return vec4(unpack_float(encodedColor[0])/255.0,unpack_float(encodedColor[1])/255.0
+);}float unpack_mix_vec2(const vec2 packedValue,const float t) {return mix(packedValue[0],packedValue[1],t);}vec4 unpack_mix_color(const vec4 packedColors,const float t) {vec4 minColor=decode_color(vec2(packedColors[0],packedColors[1]));vec4 maxColor=decode_color(vec2(packedColors[2],packedColors[3]));return mix(minColor,maxColor,t);}vec2 get_pattern_pos(const vec2 pixel_coord_upper,const vec2 pixel_coord_lower,const vec2 pattern_size,const float tile_units_to_pixels,const vec2 pos) {vec2 offset=mod(mod(mod(pixel_coord_upper,pattern_size)*256.0,pattern_size)*256.0+pixel_coord_lower,pattern_size);return (tile_units_to_pixels*pos+offset)/pattern_size;}mat3 rotationMatrixFromAxisAngle(vec3 u,float angle) {float c=cos(angle);float s=sin(angle);float c2=1.0-c;return mat3(u.x*u.x*c2+ c,u.x*u.y*c2-u.z*s,u.x*u.z*c2+u.y*s,u.y*u.x*c2+u.z*s,u.y*u.y*c2+ c,u.y*u.z*c2-u.x*s,u.z*u.x*c2-u.y*s,u.z*u.y*c2+u.x*s,u.z*u.z*c2+ c
+);}
+#ifdef TERRAIN3D
+uniform sampler2D u_terrain;uniform float u_terrain_dim;uniform mat4 u_terrain_matrix;uniform vec4 u_terrain_unpack;uniform float u_terrain_exaggeration;uniform highp sampler2D u_depth;
+#endif
+const highp vec4 bitSh=vec4(256.*256.*256.,256.*256.,256.,1.);const highp vec4 bitShifts=vec4(1.)/bitSh;highp float unpack(highp vec4 color) {return dot(color,bitShifts);}highp float depthOpacity(vec3 frag) {
+#ifdef TERRAIN3D
+highp float d=unpack(texture(u_depth,frag.xy*0.5+0.5))+0.0001-frag.z;return 1.0-max(0.0,min(1.0,-d*500.0));
+#else
+return 1.0;
+#endif
+}float calculate_visibility(vec4 pos) {
+#ifdef TERRAIN3D
+vec3 frag=pos.xyz/pos.w;highp float d=depthOpacity(frag);if (d > 0.95) return 1.0;return (d+depthOpacity(frag+vec3(0.0,0.01,0.0)))/2.0;
+#else
+return 1.0;
+#endif
+}float ele(ivec2 pos) {
+#ifdef TERRAIN3D
+vec4 rgb=(texelFetch(u_terrain,pos,0)*255.0)*u_terrain_unpack;return rgb.r+rgb.g+rgb.b-u_terrain_unpack.a;
+#else
+return 0.0;
+#endif
+}float get_elevation(vec2 pos) {
+#ifdef TERRAIN3D
+#ifdef GLOBE
+if ((pos.y <-32767.5) || (pos.y > 32766.5)) {return 0.0;}
+#endif
+vec2 coord=(u_terrain_matrix*vec4(pos,0.0,1.0)).xy*u_terrain_dim+1.0;vec2 f=fract(coord);ivec2 c=ivec2(floor(coord));ivec2 hi=textureSize(u_terrain,0)-1;float tl=ele(clamp(c,ivec2(0),hi));float tr=ele(clamp(c+ivec2(1,0),ivec2(0),hi));float bl=ele(clamp(c+ivec2(0,1),ivec2(0),hi));float br=ele(clamp(c+ivec2(1,1),ivec2(0),hi));float elevation=mix(mix(tl,tr,f.x),mix(bl,br,f.x),f.y);return elevation*u_terrain_exaggeration;
+#else
+return 0.0;
+#endif
+}const float PI=3.141592653589793;uniform mat4 u_projection_matrix;`,Us=`uniform vec4 u_color;uniform float u_opacity;void main() {fragColor=u_color*u_opacity;
+#ifdef OVERDRAW_INSPECTOR
+fragColor=vec4(1.0);
+#endif
+}`,Ws=`layout(location=0) in vec2 a_pos;void main() {gl_Position=projectTile(a_pos);}`,Gs=`uniform vec2 u_pattern_tl_a;uniform vec2 u_pattern_br_a;uniform vec2 u_pattern_tl_b;uniform vec2 u_pattern_br_b;uniform vec2 u_texsize;uniform float u_mix;uniform float u_opacity;uniform sampler2D u_image;in vec2 v_pos_a;in vec2 v_pos_b;void main() {vec2 imagecoord=mod(v_pos_a,1.0);vec2 pos=mix(u_pattern_tl_a/u_texsize,u_pattern_br_a/u_texsize,imagecoord);vec4 color1=texture(u_image,pos);vec2 imagecoord_b=mod(v_pos_b,1.0);vec2 pos2=mix(u_pattern_tl_b/u_texsize,u_pattern_br_b/u_texsize,imagecoord_b);vec4 color2=texture(u_image,pos2);fragColor=mix(color1,color2,u_mix)*u_opacity;
+#ifdef OVERDRAW_INSPECTOR
+fragColor=vec4(1.0);
+#endif
+}`,Ks=`uniform vec2 u_pattern_size_a;uniform vec2 u_pattern_size_b;uniform vec2 u_pixel_coord_upper;uniform vec2 u_pixel_coord_lower;uniform float u_scale_a;uniform float u_scale_b;uniform float u_tile_units_to_pixels;layout(location=0) in vec2 a_pos;out vec2 v_pos_a;out vec2 v_pos_b;void main() {gl_Position=projectTile(a_pos);v_pos_a=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,u_scale_a*u_pattern_size_a,u_tile_units_to_pixels,a_pos);v_pos_b=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,u_scale_b*u_pattern_size_b,u_tile_units_to_pixels,a_pos);}`,qs=`in vec3 v_data;flat in float v_visibility;
+#pragma maplibre: define highp vec4 color
+#pragma maplibre: define mediump float radius
+#pragma maplibre: define lowp float blur
+#pragma maplibre: define lowp float opacity
+#pragma maplibre: define highp vec4 stroke_color
+#pragma maplibre: define mediump float stroke_width
+#pragma maplibre: define lowp float stroke_opacity
+void main() {
+#pragma maplibre: initialize highp vec4 color
+#pragma maplibre: initialize mediump float radius
+#pragma maplibre: initialize lowp float blur
+#pragma maplibre: initialize lowp float opacity
+#pragma maplibre: initialize highp vec4 stroke_color
+#pragma maplibre: initialize mediump float stroke_width
+#pragma maplibre: initialize lowp float stroke_opacity
+vec2 extrude=v_data.xy;float extrude_length=length(extrude);float antialiased_blur=v_data.z;float opacity_t=smoothstep(0.0,antialiased_blur,extrude_length-1.0);float color_t=stroke_width < 0.01 ? 0.0 : smoothstep(antialiased_blur,0.0,extrude_length-radius/(radius+stroke_width));fragColor=v_visibility*opacity_t*mix(color*opacity,stroke_color*stroke_opacity,color_t);const float epsilon=0.5/255.0;if (fragColor.r < epsilon && fragColor.g < epsilon && fragColor.b < epsilon && fragColor.a < epsilon) {discard;}
+#ifdef OVERDRAW_INSPECTOR
+fragColor=vec4(1.0);
+#endif
+}`,Js=`uniform bool u_scale_with_map;uniform bool u_pitch_with_map;uniform vec2 u_extrude_scale;uniform highp float u_globe_extrude_scale;uniform lowp float u_device_pixel_ratio;uniform highp float u_camera_to_center_distance;uniform vec2 u_translate;layout(location=0) in ivec2 a_pos;out vec3 v_data;flat out float v_visibility;
+#pragma maplibre: define highp vec4 color
+#pragma maplibre: define mediump float radius
+#pragma maplibre: define lowp float blur
+#pragma maplibre: define lowp float opacity
+#pragma maplibre: define highp vec4 stroke_color
+#pragma maplibre: define mediump float stroke_width
+#pragma maplibre: define lowp float stroke_opacity
+void main(void) {
+#pragma maplibre: initialize highp vec4 color
+#pragma maplibre: initialize mediump float radius
+#pragma maplibre: initialize lowp float blur
+#pragma maplibre: initialize lowp float opacity
+#pragma maplibre: initialize highp vec4 stroke_color
+#pragma maplibre: initialize mediump float stroke_width
+#pragma maplibre: initialize lowp float stroke_opacity
+ivec2 pos_raw=a_pos+32768;vec2 extrude=vec2(pos_raw & 7)/7.0*2.0-1.0;vec2 circle_center=vec2(pos_raw >> 3)+u_translate;float ele=get_elevation(circle_center);v_visibility=calculate_visibility(projectTileWithElevation(circle_center,ele));if (u_pitch_with_map) {
+#ifdef GLOBE
+vec3 center_vector=projectToSphere(circle_center);
+#endif
+float angle_scale=u_globe_extrude_scale;vec2 corner_position=circle_center;if (u_scale_with_map) {angle_scale*=(radius+stroke_width);corner_position+=extrude*u_extrude_scale*(radius+stroke_width);} else {
+#ifdef GLOBE
+vec4 projected_center=interpolateProjection(circle_center,center_vector,ele);
+#else
+vec4 projected_center=projectTileWithElevation(circle_center,ele);
+#endif
+corner_position+=extrude*u_extrude_scale*(radius+stroke_width)*(projected_center.w/u_camera_to_center_distance);angle_scale*=(radius+stroke_width)*(projected_center.w/u_camera_to_center_distance);}
+#ifdef GLOBE
+vec2 angles=extrude*angle_scale;vec3 corner_vector=globeRotateVector(center_vector,angles);gl_Position=interpolateProjection(corner_position,corner_vector,ele);
+#else
+gl_Position=projectTileWithElevation(corner_position,ele);
+#endif
+} else {gl_Position=projectTileWithElevation(circle_center,ele);if (gl_Position.z/gl_Position.w > 1.0) {gl_Position.xy=vec2(10000.0);}if (u_scale_with_map) {gl_Position.xy+=extrude*(radius+stroke_width)*u_extrude_scale*u_camera_to_center_distance;} else {gl_Position.xy+=extrude*(radius+stroke_width)*u_extrude_scale*gl_Position.w;}}float antialiasblur=-max(1.0/u_device_pixel_ratio/(radius+stroke_width),blur);v_data=vec3(extrude.x,extrude.y,antialiasblur);}`,Ys=`void main() {fragColor=vec4(1.0);}`;const Xs={prelude:Y(Vs,Hs),projectionMercator:Y(`
+void clipAntimeridian() {}`,`float projectLineThickness(float tileY) {return 1.0;}float projectCircleRadius(float tileY) {return 1.0;}vec4 projectTile(vec2 p) {vec4 result=u_projection_matrix*vec4(p,0.0,1.0);return result;}vec4 projectTile(vec2 p,vec2 rawPos) {vec4 result=u_projection_matrix*vec4(p,0.0,1.0);if (rawPos.y <-32767.5 || rawPos.y > 32766.5) {result.z=-10000000.0;}return result;}vec4 projectTileWithElevation(vec2 posInTile,float elevation) {return u_projection_matrix*vec4(posInTile,elevation,1.0);}vec4 projectTileFor3D(vec2 posInTile,float elevation) {return projectTileWithElevation(posInTile,elevation);}`),projectionGlobe:Y(`uniform bool u_projection_clip_antimeridian;in highp float v_projection_tile_x;void clipAntimeridian() {if (u_projection_clip_antimeridian && (v_projection_tile_x < 0.0 || v_projection_tile_x >=8192.0)) {discard;}}`,`#define GLOBE_RADIUS 6371008.8
+uniform highp vec4 u_projection_tile_mercator_coords;uniform highp vec4 u_projection_clipping_plane;uniform highp float u_projection_transition;uniform mat4 u_projection_fallback_matrix;out highp float v_projection_tile_x;vec3 globeRotateVector(vec3 vec,vec2 angles) {vec3 axisRight=vec3(vec.z,0.0,-vec.x);vec3 axisUp=cross(axisRight,vec);axisRight=normalize(axisRight);axisUp=normalize(axisUp);vec2 t=tan(angles);return normalize(vec+axisRight*t.x+axisUp*t.y);}mat3 globeGetRotationMatrix(vec3 spherePos) {vec3 axisRight=vec3(spherePos.z,0.0,-spherePos.x);vec3 axisDown=cross(axisRight,spherePos);axisRight=normalize(axisRight);axisDown=normalize(axisDown);return mat3(axisRight,axisDown,spherePos
+);}float circumferenceRatioAtTileY(float tileY) {float mercator_pos_y=u_projection_tile_mercator_coords.y+u_projection_tile_mercator_coords.w*tileY;float t=exp(PI-(mercator_pos_y*PI*2.0));return (2.0*t)/(t*t+1.0);}float projectLineThickness(float tileY) {float thickness=1.0/circumferenceRatioAtTileY(tileY);if (u_projection_transition < 0.999) {return mix(1.0,thickness,u_projection_transition);} else {return thickness;}}vec3 projectToSphere(vec2 translatedPos,vec2 rawPos) {vec2 mercator_pos=u_projection_tile_mercator_coords.xy+u_projection_tile_mercator_coords.zw*translatedPos;float spherical_x=mercator_pos.x*PI*2.0+PI;float t=exp(PI-(mercator_pos.y*PI*2.0));float t2=t*t;float denom=t2+1.0;float sin_sy=(t2-1.0)/denom;float cos_sy=(2.0*t)/denom;vec3 pos=vec3(sin(spherical_x)*cos_sy,sin_sy,cos(spherical_x)*cos_sy
+);if (rawPos.y <-32767.5) {pos=vec3(0.0,1.0,0.0);}if (rawPos.y > 32766.5) {pos=vec3(0.0,-1.0,0.0);}return pos;}vec3 projectToSphere(vec2 posInTile) {return projectToSphere(posInTile,vec2(0.0,0.0));}float globeComputeClippingZ(vec3 spherePos) {return (1.0-(dot(spherePos,u_projection_clipping_plane.xyz)+u_projection_clipping_plane.w));}vec4 interpolateProjection(vec2 posInTile,vec3 spherePos,float elevation) {v_projection_tile_x=posInTile.x;vec3 elevatedPos=spherePos*(1.0+elevation/GLOBE_RADIUS);vec4 globePosition=u_projection_matrix*vec4(elevatedPos,1.0);globePosition.z=globeComputeClippingZ(elevatedPos)*globePosition.w;if (u_projection_transition > 0.999) {return globePosition;}vec4 flatPosition=u_projection_fallback_matrix*vec4(posInTile,elevation,1.0);const float z_globeness_threshold=0.2;vec4 result=globePosition;result.z=mix(0.0,globePosition.z,clamp((u_projection_transition-z_globeness_threshold)/(1.0-z_globeness_threshold),0.0,1.0));result.xyw=mix(flatPosition.xyw,globePosition.xyw,u_projection_transition);if ((posInTile.y <-32767.5) || (posInTile.y > 32766.5)) {result=globePosition;const float poles_hidden_anim_percentage=0.02;result.z=mix(globePosition.z,100.0,pow(max((1.0-u_projection_transition)/poles_hidden_anim_percentage,0.0),8.0));}return result;}vec4 interpolateProjectionFor3D(vec2 posInTile,vec3 spherePos,float elevation) {v_projection_tile_x=posInTile.x;vec3 elevatedPos=spherePos*(1.0+elevation/GLOBE_RADIUS);vec4 globePosition=u_projection_matrix*vec4(elevatedPos,1.0);if (u_projection_transition > 0.999) {return globePosition;}vec4 fallbackPosition=u_projection_fallback_matrix*vec4(posInTile,elevation,1.0);return mix(fallbackPosition,globePosition,u_projection_transition);}vec4 projectTile(vec2 posInTile) {return interpolateProjection(posInTile,projectToSphere(posInTile),0.0);}vec4 projectTile(vec2 posInTile,vec2 rawPos) {return interpolateProjection(posInTile,projectToSphere(posInTile,rawPos),0.0);}vec4 projectTileWithElevation(vec2 posInTile,float elevation) {return interpolateProjection(posInTile,projectToSphere(posInTile),elevation);}vec4 projectTileFor3D(vec2 posInTile,float elevation) {vec3 spherePos=projectToSphere(posInTile,posInTile);return interpolateProjectionFor3D(posInTile,spherePos,elevation);}`),background:Y(Us,Ws),backgroundPattern:Y(Gs,Ks),circle:Y(qs,Js),clippingMask:Y(Ys,`layout(location=0) in vec2 a_pos;void main() {gl_Position=projectTile(a_pos);}`),heatmap:Y(`uniform highp float u_intensity;in vec2 v_extrude;
+#pragma maplibre: define highp float weight
+#define GAUSS_COEF 0.3989422804014327
+void main() {
+#pragma maplibre: initialize highp float weight
+float d=-0.5*3.0*3.0*dot(v_extrude,v_extrude);float val=weight*u_intensity*GAUSS_COEF*exp(d);fragColor=vec4(val,1.0,1.0,1.0);
+#ifdef OVERDRAW_INSPECTOR
+fragColor=vec4(1.0);
+#endif
+}`,`uniform float u_extrude_scale;uniform float u_opacity;uniform float u_intensity;uniform highp float u_globe_extrude_scale;layout(location=0) in ivec2 a_pos;out vec2 v_extrude;
+#pragma maplibre: define highp float weight
+#pragma maplibre: define mediump float radius
+const highp float ZERO=1.0/255.0/16.0;
+#define GAUSS_COEF 0.3989422804014327
+void main(void) {
+#pragma maplibre: initialize highp float weight
+#pragma maplibre: initialize mediump float radius
+ivec2 pos_raw=a_pos+32768;vec2 unscaled_extrude=vec2(pos_raw & 7)/7.0*2.0-1.0;float S=sqrt(-2.0*log(ZERO/weight/u_intensity/GAUSS_COEF))/3.0;v_extrude=S*unscaled_extrude;vec2 extrude=v_extrude*radius*u_extrude_scale;vec2 circle_center=vec2(pos_raw >> 3);
+#ifdef GLOBE
+vec2 angles=v_extrude*radius*u_globe_extrude_scale;vec3 center_vector=projectToSphere(circle_center);vec3 corner_vector=globeRotateVector(center_vector,angles);gl_Position=interpolateProjection(circle_center+extrude,corner_vector,0.0);
+#else
+gl_Position=projectTileFor3D(circle_center+extrude,get_elevation(circle_center));
+#endif
+}`),heatmapTexture:Y(`uniform sampler2D u_image;uniform sampler2D u_color_ramp;uniform float u_opacity;in vec2 v_pos;void main() {float t=texture(u_image,v_pos).r;vec4 color=texture(u_color_ramp,vec2(t,0.5));fragColor=color*u_opacity;
+#ifdef OVERDRAW_INSPECTOR
+fragColor=vec4(0.0);
+#endif
+}`,`uniform mat4 u_matrix;uniform vec2 u_world;layout(location=0) in vec2 a_pos;out vec2 v_pos;void main() {gl_Position=u_matrix*vec4(a_pos*u_world,0,1);v_pos.x=a_pos.x;v_pos.y=1.0-a_pos.y;}`),collisionBox:Y(`flat in float v_placed;flat in float v_notUsed;void main() {float alpha=0.5;fragColor=vec4(1.0,0.0,0.0,1.0)*alpha;if (v_placed > 0.5) {fragColor=vec4(0.0,0.0,1.0,0.5)*alpha;}if (v_notUsed > 0.5) {fragColor*=.1;}}`,`layout(location=0) in vec2 a_anchor_pos;layout(location=1) in vec2 a_placed;layout(location=2) in vec2 a_box_real;uniform vec2 u_pixel_extrude_scale;flat out float v_placed;flat out float v_notUsed;void main() {gl_Position=projectTileWithElevation(a_anchor_pos,get_elevation(a_anchor_pos));gl_Position.xy=((a_box_real+0.5)*u_pixel_extrude_scale*2.0-1.0)*vec2(1.0,-1.0)*gl_Position.w;if (gl_Position.z/gl_Position.w < 1.1) {gl_Position.z=0.5;}v_placed=a_placed.x;v_notUsed=a_placed.y;}`),collisionCircle:Y(`flat in float v_radius;in vec2 v_extrude;flat in float v_collision;void main() {float alpha=0.5;float stroke_radius=0.9;float distance_to_center=length(v_extrude);float distance_to_edge=abs(distance_to_center-v_radius);float opacity_t=smoothstep(-stroke_radius,0.0,-distance_to_edge);vec4 color=mix(vec4(0.0,0.0,1.0,0.5),vec4(1.0,0.0,0.0,1.0),v_collision);fragColor=color*alpha*opacity_t;}`,`layout(location=0) in vec2 a_pos;layout(location=1) in float a_radius;layout(location=2) in vec2 a_flags;uniform vec2 u_viewport_size;flat out float v_radius;out vec2 v_extrude;flat out float v_collision;void main() {float radius=a_radius;float collision=a_flags.x;float vertexIdx=a_flags.y;vec2 quadVertexOffset=vec2(mix(-1.0,1.0,float(vertexIdx >=2.0)),mix(-1.0,1.0,float(vertexIdx >=1.0 && vertexIdx <=2.0)));vec2 quadVertexExtent=quadVertexOffset*radius;float padding_factor=1.2;v_radius=radius;v_extrude=quadVertexExtent*padding_factor;v_collision=collision;gl_Position=vec4((a_pos/u_viewport_size*2.0-1.0)*vec2(1.0,-1.0),0.0,1.0)+vec4(quadVertexExtent*padding_factor/u_viewport_size*2.0,0.0,0.0);}`),colorRelief:Y(`#ifdef GL_ES
+precision highp float;
+#endif
+uniform sampler2D u_image;uniform vec4 u_unpack;uniform sampler2D u_elevation_stops;uniform sampler2D u_color_stops;uniform int u_color_ramp_size;uniform float u_opacity;in vec2 v_pos;float getElevation(vec2 coord) {vec4 data=texture(u_image,coord)*255.0;data.a=-1.0;return dot(data,u_unpack);}float getElevationStop(int stop) {vec4 data=texelFetch(u_elevation_stops,ivec2(stop,0),0)*255.0;data.a=-1.0;return dot(data,u_unpack);}void main() {float el=getElevation(v_pos);int r=(u_color_ramp_size-1);int l=0;float el_l=getElevationStop(l);float el_r=getElevationStop(r);while(r-l > 1){int m=(r+l)/2;float el_m=getElevationStop(m);if(el < el_m){r=m;el_r=el_m;}else
+{l=m;el_l=el_m;}}float x=(float(l)+(el-el_l)/(el_r-el_l)+0.5)/float(u_color_ramp_size);fragColor=u_opacity*texture(u_color_stops,vec2(x,0));
+#ifdef OVERDRAW_INSPECTOR
+fragColor=vec4(1.0);
+#endif
+}`,`uniform vec2 u_dimension;layout(location=0) in vec2 a_pos;out vec2 v_pos;void main() {gl_Position=projectTile(a_pos,a_pos);highp vec2 epsilon=1.0/u_dimension;float scale=(u_dimension.x-2.0)/u_dimension.x;v_pos=(a_pos/8192.0)*scale+epsilon;if (a_pos.y <-32767.5) {v_pos.y=0.0;}if (a_pos.y > 32766.5) {v_pos.y=1.0;}}`),debug:Y(`uniform highp vec4 u_color;uniform sampler2D u_overlay;in vec2 v_uv;void main() {vec4 overlay_color=texture(u_overlay,v_uv);fragColor=mix(u_color,overlay_color,overlay_color.a);}`,`layout(location=0) in vec2 a_pos;out vec2 v_uv;uniform float u_overlay_scale;void main() {v_uv=a_pos/8192.0;gl_Position=projectTileWithElevation(a_pos*u_overlay_scale,get_elevation(a_pos));}`),depth:Y(Ys,`layout(location=0) in vec2 a_pos;void main() {
+#ifdef GLOBE
+gl_Position=projectTileFor3D(a_pos,0.0);
+#else
+gl_Position=u_projection_matrix*vec4(a_pos,0.0,1.0);
+#endif
+}`),fill:Y(`#pragma maplibre: define highp vec4 color
+#pragma maplibre: define lowp float opacity
+void main() {
+#pragma maplibre: initialize highp vec4 color
+#pragma maplibre: initialize lowp float opacity
+fragColor=color*opacity;
+#ifdef OVERDRAW_INSPECTOR
+fragColor=vec4(1.0);
+#endif
+}`,`uniform vec2 u_fill_translate;layout(location=0) in vec2 a_pos;
+#pragma maplibre: define highp vec4 color
+#pragma maplibre: define lowp float opacity
+void main() {
+#pragma maplibre: initialize highp vec4 color
+#pragma maplibre: initialize lowp float opacity
+if (opacity < 0.01) {gl_Position=vec4(-2.0,-2.0,-2.0,1.0);return;}gl_Position=projectTile(a_pos+u_fill_translate,a_pos);}`),fillOutline:Y(`in vec2 v_pos;
+#ifdef GLOBE
+in float v_depth;
+#endif
+#pragma maplibre: define highp vec4 outline_color
+#pragma maplibre: define lowp float opacity
+void main() {
+#pragma maplibre: initialize highp vec4 outline_color
+#pragma maplibre: initialize lowp float opacity
+float dist=length(v_pos-gl_FragCoord.xy);float alpha=1.0-smoothstep(0.0,1.0,dist);fragColor=outline_color*(alpha*opacity);
+#ifdef GLOBE
+if (v_depth > 1.0) {discard;}
+#endif
+#ifdef OVERDRAW_INSPECTOR
+fragColor=vec4(1.0);
+#endif
+}`,`uniform vec2 u_world;uniform vec2 u_fill_translate;layout(location=0) in vec2 a_pos;out vec2 v_pos;
+#ifdef GLOBE
+out float v_depth;
+#endif
+#pragma maplibre: define highp vec4 outline_color
+#pragma maplibre: define lowp float opacity
+void main() {
+#pragma maplibre: initialize highp vec4 outline_color
+#pragma maplibre: initialize lowp float opacity
+if (opacity < 0.01) {gl_Position=vec4(-2.0,-2.0,-2.0,1.0);return;}gl_Position=projectTile(a_pos+u_fill_translate,a_pos);v_pos=(gl_Position.xy/gl_Position.w+1.0)/2.0*u_world;
+#ifdef GLOBE
+v_depth=gl_Position.z/gl_Position.w;
+#endif
+}`),fillOutlinePattern:Y(`uniform vec2 u_texsize;uniform sampler2D u_image;uniform float u_fade;in vec2 v_pos_a;in vec2 v_pos_b;in vec2 v_pos;
+#ifdef GLOBE
+in float v_depth;
+#endif
+#pragma maplibre: define lowp float opacity
+#pragma maplibre: define lowp vec4 pattern_from
+#pragma maplibre: define lowp vec4 pattern_to
+void main() {
+#pragma maplibre: initialize lowp float opacity
+#pragma maplibre: initialize mediump vec4 pattern_from
+#pragma maplibre: initialize mediump vec4 pattern_to
+vec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;vec2 imagecoord=mod(v_pos_a,1.0);vec2 pos=mix(pattern_tl_a/u_texsize,pattern_br_a/u_texsize,imagecoord);vec4 color1=texture(u_image,pos);vec2 imagecoord_b=mod(v_pos_b,1.0);vec2 pos2=mix(pattern_tl_b/u_texsize,pattern_br_b/u_texsize,imagecoord_b);vec4 color2=texture(u_image,pos2);float dist=length(v_pos-gl_FragCoord.xy);float alpha=1.0-smoothstep(0.0,1.0,dist);fragColor=mix(color1,color2,u_fade)*alpha*opacity;
+#ifdef GLOBE
+if (v_depth > 1.0) {discard;}
+#endif
+#ifdef OVERDRAW_INSPECTOR
+fragColor=vec4(1.0);
+#endif
+}`,`uniform vec2 u_world;uniform vec2 u_pixel_coord_upper;uniform vec2 u_pixel_coord_lower;uniform vec3 u_scale;uniform vec2 u_fill_translate;layout(location=0) in vec2 a_pos;out vec2 v_pos_a;out vec2 v_pos_b;out vec2 v_pos;
+#ifdef GLOBE
+out float v_depth;
+#endif
+#pragma maplibre: define lowp float opacity
+#pragma maplibre: define lowp vec4 pattern_from
+#pragma maplibre: define lowp vec4 pattern_to
+#pragma maplibre: define lowp float pixel_ratio_from
+#pragma maplibre: define lowp float pixel_ratio_to
+void main() {
+#pragma maplibre: initialize lowp float opacity
+#pragma maplibre: initialize mediump vec4 pattern_from
+#pragma maplibre: initialize mediump vec4 pattern_to
+#pragma maplibre: initialize lowp float pixel_ratio_from
+#pragma maplibre: initialize lowp float pixel_ratio_to
+if (opacity < 0.01) {gl_Position=vec4(-2.0,-2.0,-2.0,1.0);return;}vec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;float tileRatio=u_scale.x;float fromScale=u_scale.y;float toScale=u_scale.z;gl_Position=projectTile(a_pos+u_fill_translate,a_pos);vec2 display_size_a=(pattern_br_a-pattern_tl_a)/pixel_ratio_from;vec2 display_size_b=(pattern_br_b-pattern_tl_b)/pixel_ratio_to;v_pos_a=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,fromScale*display_size_a,tileRatio,a_pos);v_pos_b=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,toScale*display_size_b,tileRatio,a_pos);v_pos=(gl_Position.xy/gl_Position.w+1.0)/2.0*u_world;
+#ifdef GLOBE
+v_depth=gl_Position.z/gl_Position.w;
+#endif
+}`),fillPattern:Y(`#ifdef GL_ES
+precision highp float;
+#endif
+uniform vec2 u_texsize;uniform float u_fade;uniform sampler2D u_image;in vec2 v_pos_a;in vec2 v_pos_b;
+#pragma maplibre: define lowp float opacity
+#pragma maplibre: define lowp vec4 pattern_from
+#pragma maplibre: define lowp vec4 pattern_to
+void main() {
+#pragma maplibre: initialize lowp float opacity
+#pragma maplibre: initialize mediump vec4 pattern_from
+#pragma maplibre: initialize mediump vec4 pattern_to
+vec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;vec2 imagecoord=mod(v_pos_a,1.0);vec2 pos=mix(pattern_tl_a/u_texsize,pattern_br_a/u_texsize,imagecoord);vec4 color1=texture(u_image,pos);vec2 imagecoord_b=mod(v_pos_b,1.0);vec2 pos2=mix(pattern_tl_b/u_texsize,pattern_br_b/u_texsize,imagecoord_b);vec4 color2=texture(u_image,pos2);fragColor=mix(color1,color2,u_fade)*opacity;
+#ifdef OVERDRAW_INSPECTOR
+fragColor=vec4(1.0);
+#endif
+}`,`uniform vec2 u_pixel_coord_upper;uniform vec2 u_pixel_coord_lower;uniform vec3 u_scale;uniform vec2 u_fill_translate;layout(location=0) in vec2 a_pos;out vec2 v_pos_a;out vec2 v_pos_b;
+#pragma maplibre: define lowp float opacity
+#pragma maplibre: define lowp vec4 pattern_from
+#pragma maplibre: define lowp vec4 pattern_to
+#pragma maplibre: define lowp float pixel_ratio_from
+#pragma maplibre: define lowp float pixel_ratio_to
+void main() {
+#pragma maplibre: initialize lowp float opacity
+#pragma maplibre: initialize mediump vec4 pattern_from
+#pragma maplibre: initialize mediump vec4 pattern_to
+#pragma maplibre: initialize lowp float pixel_ratio_from
+#pragma maplibre: initialize lowp float pixel_ratio_to
+if (opacity < 0.01) {gl_Position=vec4(-2.0,-2.0,-2.0,1.0);return;}vec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;float tileZoomRatio=u_scale.x;float fromScale=u_scale.y;float toScale=u_scale.z;vec2 display_size_a=(pattern_br_a-pattern_tl_a)/pixel_ratio_from;vec2 display_size_b=(pattern_br_b-pattern_tl_b)/pixel_ratio_to;gl_Position=projectTile(a_pos+u_fill_translate,a_pos);v_pos_a=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,fromScale*display_size_a,tileZoomRatio,a_pos);v_pos_b=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,toScale*display_size_b,tileZoomRatio,a_pos);}`),fillExtrusion:Y(`in vec4 v_color;void main() {fragColor=v_color;
+#ifdef OVERDRAW_INSPECTOR
+fragColor=vec4(1.0);
+#endif
+}`,`uniform vec3 u_lightcolor;uniform lowp vec3 u_lightpos;uniform lowp vec3 u_lightpos_globe;uniform lowp float u_lightintensity;uniform float u_vertical_gradient;uniform lowp float u_opacity;uniform vec2 u_fill_translate;layout(location=0) in vec2 a_pos;layout(location=1) in ivec4 a_normal_ed;
+#ifdef TERRAIN3D
+layout(location=2) in vec2 a_centroid;
+#endif
+out vec4 v_color;
+#pragma maplibre: define highp float base
+#pragma maplibre: define highp float height
+#pragma maplibre: define highp vec4 color
+void main() {
+#pragma maplibre: initialize highp float base
+#pragma maplibre: initialize highp float height
+#pragma maplibre: initialize highp vec4 color
+vec3 normal=vec3(a_normal_ed.xyz);
+#ifdef TERRAIN3D
+float height_terrain3d_offset=get_elevation(a_centroid);float base_terrain3d_offset=height_terrain3d_offset-(base > 0.0 ? 0.0 : 10.0);
+#else
+float height_terrain3d_offset=0.0;float base_terrain3d_offset=0.0;
+#endif
+base=max(0.0,base)+base_terrain3d_offset;height=max(0.0,height)+height_terrain3d_offset;float t=float(a_normal_ed.x & 1);float elevation=t > 0.0 ? height : base;vec2 posInTile=a_pos+u_fill_translate;
+#ifdef GLOBE
+vec3 spherePos=projectToSphere(posInTile,a_pos);gl_Position=interpolateProjectionFor3D(posInTile,spherePos,elevation);
+#else
+gl_Position=u_projection_matrix*vec4(posInTile,elevation,1.0);
+#endif
+float colorvalue=color.r*0.2126+color.g*0.7152+color.b*0.0722;v_color=vec4(0.0,0.0,0.0,1.0);vec4 ambientlight=vec4(0.03,0.03,0.03,1.0);color+=ambientlight;vec3 normalForLighting=normal/16384.0;float directional=clamp(dot(normalForLighting,u_lightpos),0.0,1.0);
+#ifdef GLOBE
+mat3 rotMatrix=globeGetRotationMatrix(spherePos);normalForLighting=rotMatrix*normalForLighting;directional=mix(directional,clamp(dot(normalForLighting,u_lightpos_globe),0.0,1.0),u_projection_transition);
+#endif
+directional=mix((1.0-u_lightintensity),max((1.0-colorvalue+u_lightintensity),1.0),directional);if (normal.y !=0.0) {directional*=((1.0-u_vertical_gradient)+(u_vertical_gradient*clamp((t+base)*pow(height/150.0,0.5),mix(0.7,0.98,1.0-u_lightintensity),1.0)));}v_color.r+=clamp(color.r*directional*u_lightcolor.r,mix(0.0,0.3,1.0-u_lightcolor.r),1.0);v_color.g+=clamp(color.g*directional*u_lightcolor.g,mix(0.0,0.3,1.0-u_lightcolor.g),1.0);v_color.b+=clamp(color.b*directional*u_lightcolor.b,mix(0.0,0.3,1.0-u_lightcolor.b),1.0);v_color*=u_opacity;}`),fillExtrusionPattern:Y(`uniform vec2 u_texsize;uniform float u_fade;uniform sampler2D u_image;in vec2 v_pos_a;in vec2 v_pos_b;in vec4 v_lighting;
+#pragma maplibre: define lowp float base
+#pragma maplibre: define lowp float height
+#pragma maplibre: define lowp vec4 pattern_from
+#pragma maplibre: define lowp vec4 pattern_to
+#pragma maplibre: define lowp float pixel_ratio_from
+#pragma maplibre: define lowp float pixel_ratio_to
+void main() {
+#pragma maplibre: initialize lowp float base
+#pragma maplibre: initialize lowp float height
+#pragma maplibre: initialize mediump vec4 pattern_from
+#pragma maplibre: initialize mediump vec4 pattern_to
+#pragma maplibre: initialize lowp float pixel_ratio_from
+#pragma maplibre: initialize lowp float pixel_ratio_to
+vec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;vec2 imagecoord=mod(v_pos_a,1.0);vec2 pos=mix(pattern_tl_a/u_texsize,pattern_br_a/u_texsize,imagecoord);vec4 color1=texture(u_image,pos);vec2 imagecoord_b=mod(v_pos_b,1.0);vec2 pos2=mix(pattern_tl_b/u_texsize,pattern_br_b/u_texsize,imagecoord_b);vec4 color2=texture(u_image,pos2);vec4 mixedColor=mix(color1,color2,u_fade);fragColor=mixedColor*v_lighting;
+#ifdef OVERDRAW_INSPECTOR
+fragColor=vec4(1.0);
+#endif
+}`,`uniform vec2 u_pixel_coord_upper;uniform vec2 u_pixel_coord_lower;uniform float u_height_factor;uniform vec3 u_scale;uniform float u_vertical_gradient;uniform lowp float u_opacity;uniform vec2 u_fill_translate;uniform vec3 u_lightcolor;uniform lowp vec3 u_lightpos;uniform lowp vec3 u_lightpos_globe;uniform lowp float u_lightintensity;layout(location=0) in vec2 a_pos;layout(location=1) in ivec4 a_normal_ed;
+#ifdef TERRAIN3D
+layout(location=2) in vec2 a_centroid;
+#endif
+#ifdef GLOBE
+out vec3 v_sphere_pos;
+#endif
+out vec2 v_pos_a;out vec2 v_pos_b;out vec4 v_lighting;
+#pragma maplibre: define lowp float base
+#pragma maplibre: define lowp float height
+#pragma maplibre: define lowp vec4 pattern_from
+#pragma maplibre: define lowp vec4 pattern_to
+#pragma maplibre: define lowp float pixel_ratio_from
+#pragma maplibre: define lowp float pixel_ratio_to
+void main() {
+#pragma maplibre: initialize lowp float base
+#pragma maplibre: initialize lowp float height
+#pragma maplibre: initialize mediump vec4 pattern_from
+#pragma maplibre: initialize mediump vec4 pattern_to
+#pragma maplibre: initialize lowp float pixel_ratio_from
+#pragma maplibre: initialize lowp float pixel_ratio_to
+vec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;float tileRatio=u_scale.x;float fromScale=u_scale.y;float toScale=u_scale.z;vec3 normal=vec3(a_normal_ed.xyz);float edgedistance=float(a_normal_ed.w);vec2 display_size_a=(pattern_br_a-pattern_tl_a)/pixel_ratio_from;vec2 display_size_b=(pattern_br_b-pattern_tl_b)/pixel_ratio_to;
+#ifdef TERRAIN3D
+float height_terrain3d_offset=get_elevation(a_centroid);float base_terrain3d_offset=height_terrain3d_offset-(base > 0.0 ? 0.0 : 10.0);
+#else
+float height_terrain3d_offset=0.0;float base_terrain3d_offset=0.0;
+#endif
+base=max(0.0,base)+base_terrain3d_offset;height=max(0.0,height)+height_terrain3d_offset;float t=float(a_normal_ed.x & 1);float elevation=t > 0.0 ? height : base;vec2 posInTile=a_pos+u_fill_translate;
+#ifdef GLOBE
+vec3 spherePos=projectToSphere(posInTile,a_pos);vec3 elevatedPos=spherePos*(1.0+elevation/GLOBE_RADIUS);v_sphere_pos=elevatedPos;gl_Position=interpolateProjectionFor3D(posInTile,spherePos,elevation);
+#else
+gl_Position=u_projection_matrix*vec4(posInTile,elevation,1.0);
+#endif
+vec2 pos=a_normal_ed.x==1 && a_normal_ed.y==0 && a_normal_ed.z==16384
+? a_pos
+: vec2(edgedistance,elevation*u_height_factor);v_pos_a=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,fromScale*display_size_a,tileRatio,pos);v_pos_b=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,toScale*display_size_b,tileRatio,pos);v_lighting=vec4(0.0,0.0,0.0,1.0);float directional=clamp(dot(normal/16383.0,u_lightpos),0.0,1.0);directional=mix((1.0-u_lightintensity),max((0.5+u_lightintensity),1.0),directional);if (normal.y !=0.0) {directional*=((1.0-u_vertical_gradient)+(u_vertical_gradient*clamp((t+base)*pow(height/150.0,0.5),mix(0.7,0.98,1.0-u_lightintensity),1.0)));}v_lighting.rgb+=clamp(directional*u_lightcolor,mix(vec3(0.0),vec3(0.3),1.0-u_lightcolor),vec3(1.0));v_lighting*=u_opacity;}`),hillshadePrepare:Y(`#ifdef GL_ES
+precision highp float;
+#endif
+uniform sampler2D u_image;in vec2 v_pos;uniform vec2 u_dimension;uniform float u_zoom;uniform vec4 u_unpack;float getElevation(ivec2 texel) {vec4 data=texelFetch(u_image,texel,0)*255.0;data.a=-1.0;return dot(data,u_unpack);}void main() {ivec2 pos=ivec2(gl_FragCoord.xy)+ivec2(1);float tileSize=u_dimension.x-2.0;float a=getElevation(pos+ivec2(-1,-1));float b=getElevation(pos+ivec2(0,-1));float c=getElevation(pos+ivec2(1,-1));float d=getElevation(pos+ivec2(-1,0));float e=getElevation(pos);float f=getElevation(pos+ivec2(1,0));float g=getElevation(pos+ivec2(-1,1));float h=getElevation(pos+ivec2(0,1));float i=getElevation(pos+ivec2(1,1));float exaggerationFactor=u_zoom < 2.0 ? 0.4 : u_zoom < 4.5 ? 0.35 : 0.3;float exaggeration=u_zoom < 15.0 ? (u_zoom-15.0)*exaggerationFactor : 0.0;vec2 deriv=vec2((c+f+f+i)-(a+d+d+g),(g+h+h+i)-(a+b+b+c))*tileSize/pow(2.0,exaggeration+(28.2562-u_zoom));fragColor=clamp(vec4(deriv.x/8.0+0.5,deriv.y/8.0+0.5,1.0,1.0),0.0,1.0);
+#ifdef OVERDRAW_INSPECTOR
+fragColor=vec4(1.0);
+#endif
+}`,`uniform mat4 u_matrix;uniform vec2 u_dimension;layout(location=0) in vec2 a_pos;layout(location=1) in vec2 a_texture_pos;out vec2 v_pos;void main() {gl_Position=u_matrix*vec4(a_pos,0,1);highp vec2 epsilon=1.0/u_dimension;float scale=(u_dimension.x-2.0)/u_dimension.x;v_pos=(a_texture_pos/8192.0)*scale+epsilon;}`),hillshade:Y(`uniform sampler2D u_image;in vec2 v_pos;uniform vec2 u_latrange;uniform float u_exaggeration;uniform vec4 u_accent;uniform int u_method;uniform float u_altitudes[NUM_ILLUMINATION_SOURCES];uniform float u_azimuths[NUM_ILLUMINATION_SOURCES];uniform vec4 u_shadows[NUM_ILLUMINATION_SOURCES];uniform vec4 u_highlights[NUM_ILLUMINATION_SOURCES];
+#define PI 3.141592653589793
+#define STANDARD 0
+#define COMBINED 1
+#define IGOR 2
+#define MULTIDIRECTIONAL 3
+#define BASIC 4
+float get_aspect(vec2 deriv){return deriv.x !=0.0 ? atan(deriv.y,-deriv.x) : PI/2.0*(deriv.y > 0.0 ? 1.0 :-1.0);}void igor_hillshade(vec2 deriv){deriv=deriv*u_exaggeration*2.0;float aspect=get_aspect(deriv);float azimuth=u_azimuths[0]+PI;float slope_stength=atan(length(deriv))*2.0/PI;float aspect_strength=1.0-abs(mod((aspect+azimuth)/PI+0.5,2.0)-1.0);float shadow_strength=slope_stength*aspect_strength;float highlight_strength=slope_stength*(1.0-aspect_strength);fragColor=u_shadows[0]*shadow_strength+u_highlights[0]*highlight_strength;}void standard_hillshade(vec2 deriv){float azimuth=u_azimuths[0]+PI;float slope=atan(0.625*length(deriv));float aspect=get_aspect(deriv);float intensity=u_exaggeration;float base=1.875-intensity*1.75;float maxValue=0.5*PI;float scaledSlope=intensity !=0.5 ? ((pow(base,slope)-1.0)/(pow(base,maxValue)-1.0))*maxValue : slope;float accent=cos(scaledSlope);vec4 accent_color=(1.0-accent)*u_accent*clamp(intensity*2.0,0.0,1.0);float shade=abs(mod((aspect+azimuth)/PI+0.5,2.0)-1.0);vec4 shade_color=mix(u_shadows[0],u_highlights[0],shade)*sin(scaledSlope)*clamp(intensity*2.0,0.0,1.0);fragColor=accent_color*(1.0-shade_color.a)+shade_color;}void basic_hillshade(vec2 deriv){deriv=deriv*u_exaggeration*2.0;float azimuth=u_azimuths[0]+PI;float cos_az=cos(azimuth);float sin_az=sin(azimuth);float cos_alt=cos(u_altitudes[0]);float sin_alt=sin(u_altitudes[0]);float cang=(sin_alt-(deriv.y*cos_az*cos_alt-deriv.x*sin_az*cos_alt))/sqrt(1.0+dot(deriv,deriv));float shade=clamp(cang,0.0,1.0);if(shade > 0.5){fragColor=u_highlights[0]*(2.0*shade-1.0);}else
+{fragColor=u_shadows[0]*(1.0-2.0*shade);}}void multidirectional_hillshade(vec2 deriv){deriv=deriv*u_exaggeration*2.0;fragColor=vec4(0,0,0,0);for(int i=0; i < NUM_ILLUMINATION_SOURCES; i++){float cos_alt=cos(u_altitudes[i]);float sin_alt=sin(u_altitudes[i]);float cos_az=-cos(u_azimuths[i]);float sin_az=-sin(u_azimuths[i]);float cang=(sin_alt-(deriv.y*cos_az*cos_alt-deriv.x*sin_az*cos_alt))/sqrt(1.0+dot(deriv,deriv));float shade=clamp(cang,0.0,1.0);if(shade > 0.5){fragColor+=u_highlights[i]*(2.0*shade-1.0)/float(NUM_ILLUMINATION_SOURCES);}else
+{fragColor+=u_shadows[i]*(1.0-2.0*shade)/float(NUM_ILLUMINATION_SOURCES);}}}void combined_hillshade(vec2 deriv){deriv=deriv*u_exaggeration*2.0;float azimuth=u_azimuths[0]+PI;float cos_az=cos(azimuth);float sin_az=sin(azimuth);float cos_alt=cos(u_altitudes[0]);float sin_alt=sin(u_altitudes[0]);float cang=acos((sin_alt-(deriv.y*cos_az*cos_alt-deriv.x*sin_az*cos_alt))/sqrt(1.0+dot(deriv,deriv)));cang=clamp(cang,0.0,PI/2.0);float shade=cang*atan(length(deriv))*4.0/PI/PI;float highlight=(PI/2.0-cang)*atan(length(deriv))*4.0/PI/PI;fragColor=u_shadows[0]*shade+u_highlights[0]*highlight;}void main() {vec4 pixel=texture(u_image,v_pos);float scaleFactor=cos(radians((u_latrange[0]-u_latrange[1])*(1.0-v_pos.y)+u_latrange[1]));vec2 deriv=((pixel.rg*8.0)-4.0)/scaleFactor;if (u_method==BASIC) {basic_hillshade(deriv);} else if (u_method==COMBINED) {combined_hillshade(deriv);} else if (u_method==IGOR) {igor_hillshade(deriv);} else if (u_method==MULTIDIRECTIONAL) {multidirectional_hillshade(deriv);} else if (u_method==STANDARD) {standard_hillshade(deriv);} else {standard_hillshade(deriv);}
+#ifdef OVERDRAW_INSPECTOR
+fragColor=vec4(1.0);
+#endif
+}`,`uniform mat4 u_matrix;layout(location=0) in vec2 a_pos;out vec2 v_pos;void main() {gl_Position=projectTile(a_pos,a_pos);v_pos=a_pos/8192.0;if (a_pos.y <-32767.5) {v_pos.y=0.0;}if (a_pos.y > 32766.5) {v_pos.y=1.0;}}`),line:Y(`uniform lowp float u_device_pixel_ratio;flat in vec2 v_width2;in vec2 v_normal;in float v_gamma_scale;
+#ifdef GLOBE
+in float v_depth;
+#endif
+#pragma maplibre: define highp vec4 color
+#pragma maplibre: define lowp float blur
+#pragma maplibre: define lowp float opacity
+void main() {
+#pragma maplibre: initialize highp vec4 color
+#pragma maplibre: initialize lowp float blur
+#pragma maplibre: initialize lowp float opacity
+clipAntimeridian();float dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);fragColor=color*(alpha*opacity);
+#ifdef GLOBE
+if (v_depth > 1.0) {discard;}
+#endif
+#ifdef OVERDRAW_INSPECTOR
+fragColor=vec4(1.0);
+#endif
+}`,`
+#define scale 0.015873016
+layout(location=0) in ivec2 a_pos_normal;layout(location=1) in uvec4 a_data;uniform vec2 u_translation;uniform mediump float u_ratio;uniform vec2 u_units_to_pixels;uniform lowp float u_device_pixel_ratio;out vec2 v_normal;flat out vec2 v_width2;out float v_gamma_scale;out highp float v_linesofar;
+#ifdef GLOBE
+out float v_depth;
+#endif
+#pragma maplibre: define highp vec4 color
+#pragma maplibre: define lowp float blur
+#pragma maplibre: define lowp float opacity
+#pragma maplibre: define mediump float gapwidth
+#pragma maplibre: define lowp float offset
+#pragma maplibre: define mediump float width
+void main() {
+#pragma maplibre: initialize highp vec4 color
+#pragma maplibre: initialize lowp float blur
+#pragma maplibre: initialize lowp float opacity
+#pragma maplibre: initialize mediump float gapwidth
+#pragma maplibre: initialize lowp float offset
+#pragma maplibre: initialize mediump float width
+if (opacity < 0.01) {gl_Position=vec4(-2.0,-2.0,-2.0,1.0);return;}float ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=vec2(ivec2(a_data.xy)-128);float a_direction=float(int(a_data.z & 3u)-1);v_linesofar=float((a_data.z >> 2u)+a_data.w*64u)*2.0;vec2 pos=vec2(a_pos_normal >> 1);mediump vec2 normal=vec2(a_pos_normal & 1);normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);float adjustedThickness=projectLineThickness(pos.y);vec4 projected_no_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation);vec4 projected_with_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation+dist/u_ratio*adjustedThickness);gl_Position=projected_with_extrude;
+#ifdef GLOBE
+v_depth=gl_Position.z/gl_Position.w;
+#endif
+#ifdef TERRAIN3D
+v_gamma_scale=1.0;
+#else
+float extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length((projected_with_extrude.xy-projected_no_extrude.xy)/projected_with_extrude.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective;
+#endif
+v_width2=vec2(outset,inset);}`),lineGradient:Y(`uniform lowp float u_device_pixel_ratio;uniform sampler2D u_image;flat in vec2 v_width2;in vec2 v_normal;in float v_gamma_scale;in highp vec2 v_uv;
+#ifdef GLOBE
+in float v_depth;
+#endif
+#pragma maplibre: define lowp float blur
+#pragma maplibre: define lowp float opacity
+void main() {
+#pragma maplibre: initialize lowp float blur
+#pragma maplibre: initialize lowp float opacity
+clipAntimeridian();float dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);vec4 color=texture(u_image,v_uv);fragColor=color*(alpha*opacity);
+#ifdef GLOBE
+if (v_depth > 1.0) {discard;}
+#endif
+#ifdef OVERDRAW_INSPECTOR
+fragColor=vec4(1.0);
+#endif
+}`,`
+#define scale 0.015873016
+layout(location=0) in ivec2 a_pos_normal;layout(location=1) in uvec4 a_data;layout(location=2) in float a_uv_x;layout(location=3) in float a_split_index;uniform vec2 u_translation;uniform mediump float u_ratio;uniform lowp float u_device_pixel_ratio;uniform vec2 u_units_to_pixels;uniform float u_image_height;out vec2 v_normal;flat out vec2 v_width2;out float v_gamma_scale;out highp vec2 v_uv;
+#ifdef GLOBE
+out float v_depth;
+#endif
+#pragma maplibre: define lowp float blur
+#pragma maplibre: define lowp float opacity
+#pragma maplibre: define mediump float gapwidth
+#pragma maplibre: define lowp float offset
+#pragma maplibre: define mediump float width
+void main() {
+#pragma maplibre: initialize lowp float blur
+#pragma maplibre: initialize lowp float opacity
+#pragma maplibre: initialize mediump float gapwidth
+#pragma maplibre: initialize lowp float offset
+#pragma maplibre: initialize mediump float width
+if (opacity < 0.01) {gl_Position=vec4(-2.0,-2.0,-2.0,1.0);return;}float ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=vec2(ivec2(a_data.xy)-128);float a_direction=float(int(a_data.z & 3u)-1);highp float texel_height=1.0/u_image_height;highp float half_texel_height=0.5*texel_height;v_uv=vec2(a_uv_x,a_split_index*texel_height-half_texel_height);vec2 pos=vec2(a_pos_normal >> 1);mediump vec2 normal=vec2(a_pos_normal & 1);normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);float adjustedThickness=projectLineThickness(pos.y);vec4 projected_no_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation);vec4 projected_with_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation+dist/u_ratio*adjustedThickness);gl_Position=projected_with_extrude;
+#ifdef GLOBE
+v_depth=gl_Position.z/gl_Position.w;
+#endif
+#ifdef TERRAIN3D
+v_gamma_scale=1.0;
+#else
+float extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length((projected_with_extrude.xy-projected_no_extrude.xy)/projected_with_extrude.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective;
+#endif
+v_width2=vec2(outset,inset);}`),linePattern:Y(`#ifdef GL_ES
+precision highp float;
+#endif
+uniform lowp float u_device_pixel_ratio;uniform vec2 u_texsize;uniform float u_fade;uniform mediump vec3 u_scale;uniform sampler2D u_image;in vec2 v_normal;flat in vec2 v_width2;in float v_linesofar;in float v_gamma_scale;flat in float v_width;
+#ifdef GLOBE
+in float v_depth;
+#endif
+#pragma maplibre: define lowp vec4 pattern_from
+#pragma maplibre: define lowp vec4 pattern_to
+#pragma maplibre: define lowp float pixel_ratio_from
+#pragma maplibre: define lowp float pixel_ratio_to
+#pragma maplibre: define lowp float blur
+#pragma maplibre: define lowp float opacity
+void main() {
+#pragma maplibre: initialize mediump vec4 pattern_from
+#pragma maplibre: initialize mediump vec4 pattern_to
+#pragma maplibre: initialize lowp float pixel_ratio_from
+#pragma maplibre: initialize lowp float pixel_ratio_to
+#pragma maplibre: initialize lowp float blur
+#pragma maplibre: initialize lowp float opacity
+clipAntimeridian();vec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;float tileZoomRatio=u_scale.x;float fromScale=u_scale.y;float toScale=u_scale.z;vec2 display_size_a=(pattern_br_a-pattern_tl_a)/pixel_ratio_from;vec2 display_size_b=(pattern_br_b-pattern_tl_b)/pixel_ratio_to;vec2 pattern_size_a=vec2(display_size_a.x*fromScale/tileZoomRatio,display_size_a.y);vec2 pattern_size_b=vec2(display_size_b.x*toScale/tileZoomRatio,display_size_b.y);float aspect_a=display_size_a.y/v_width;float aspect_b=display_size_b.y/v_width;float dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);float x_a=mod(v_linesofar/pattern_size_a.x*aspect_a,1.0);float x_b=mod(v_linesofar/pattern_size_b.x*aspect_b,1.0);float y=0.5*v_normal.y+0.5;vec2 texel_size=1.0/u_texsize;vec2 pos_a=mix(pattern_tl_a*texel_size-texel_size,pattern_br_a*texel_size+texel_size,vec2(x_a,y));vec2 pos_b=mix(pattern_tl_b*texel_size-texel_size,pattern_br_b*texel_size+texel_size,vec2(x_b,y));vec4 color=mix(texture(u_image,pos_a),texture(u_image,pos_b),u_fade);fragColor=color*alpha*opacity;
+#ifdef GLOBE
+if (v_depth > 1.0) {discard;}
+#endif
+#ifdef OVERDRAW_INSPECTOR
+fragColor=vec4(1.0);
+#endif
+}`,`
+#define scale 0.015873016
+#define LINE_DISTANCE_SCALE 2.0
+layout(location=0) in ivec2 a_pos_normal;layout(location=1) in uvec4 a_data;uniform vec2 u_translation;uniform vec2 u_units_to_pixels;uniform mediump float u_ratio;uniform lowp float u_device_pixel_ratio;out vec2 v_normal;flat out vec2 v_width2;out float v_linesofar;out float v_gamma_scale;flat out float v_width;
+#ifdef GLOBE
+out float v_depth;
+#endif
+#pragma maplibre: define lowp float blur
+#pragma maplibre: define lowp float opacity
+#pragma maplibre: define lowp float offset
+#pragma maplibre: define mediump float gapwidth
+#pragma maplibre: define mediump float width
+#pragma maplibre: define lowp float floorwidth
+#pragma maplibre: define lowp vec4 pattern_from
+#pragma maplibre: define lowp vec4 pattern_to
+#pragma maplibre: define lowp float pixel_ratio_from
+#pragma maplibre: define lowp float pixel_ratio_to
+void main() {
+#pragma maplibre: initialize lowp float blur
+#pragma maplibre: initialize lowp float opacity
+#pragma maplibre: initialize lowp float offset
+#pragma maplibre: initialize mediump float gapwidth
+#pragma maplibre: initialize mediump float width
+#pragma maplibre: initialize lowp float floorwidth
+#pragma maplibre: initialize mediump vec4 pattern_from
+#pragma maplibre: initialize mediump vec4 pattern_to
+#pragma maplibre: initialize lowp float pixel_ratio_from
+#pragma maplibre: initialize lowp float pixel_ratio_to
+if (opacity < 0.01) {gl_Position=vec4(-2.0,-2.0,-2.0,1.0);return;}float ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=vec2(ivec2(a_data.xy)-128);float a_direction=float(int(a_data.z & 3u)-1);float a_linesofar=float((a_data.z >> 2u)+a_data.w*64u)*LINE_DISTANCE_SCALE;vec2 pos=vec2(a_pos_normal >> 1);mediump vec2 normal=vec2(a_pos_normal & 1);normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);float adjustedThickness=projectLineThickness(pos.y);vec4 projected_no_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation);vec4 projected_with_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation+dist/u_ratio*adjustedThickness);gl_Position=projected_with_extrude;
+#ifdef GLOBE
+v_depth=gl_Position.z/gl_Position.w;
+#endif
+#ifdef TERRAIN3D
+v_gamma_scale=1.0;
+#else
+float extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length((projected_with_extrude.xy-projected_no_extrude.xy)/projected_with_extrude.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective;
+#endif
+v_linesofar=a_linesofar;v_width2=vec2(outset,inset);v_width=floorwidth;}`),lineSDF:Y(`uniform lowp float u_device_pixel_ratio;uniform lowp float u_lineatlas_width;uniform sampler2D u_image;uniform float u_mix;in vec2 v_normal;flat in vec2 v_width2;in vec2 v_tex_a;in vec2 v_tex_b;in float v_gamma_scale;
+#ifdef GLOBE
+in float v_depth;
+#endif
+#pragma maplibre: define highp vec4 color
+#pragma maplibre: define lowp float blur
+#pragma maplibre: define lowp float opacity
+#pragma maplibre: define mediump float width
+#pragma maplibre: define lowp float floorwidth
+#pragma maplibre: define mediump vec4 dasharray_from
+#pragma maplibre: define mediump vec4 dasharray_to
+void main() {
+#pragma maplibre: initialize highp vec4 color
+#pragma maplibre: initialize lowp float blur
+#pragma maplibre: initialize lowp float opacity
+#pragma maplibre: initialize mediump float width
+#pragma maplibre: initialize lowp float floorwidth
+#pragma maplibre: initialize mediump vec4 dasharray_from
+#pragma maplibre: initialize mediump vec4 dasharray_to
+clipAntimeridian();float dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);float sdfdist_a=texture(u_image,v_tex_a).a;float sdfdist_b=texture(u_image,v_tex_b).a;float sdfdist=mix(sdfdist_a,sdfdist_b,u_mix);float sdfgamma=(u_lineatlas_width/256.0/u_device_pixel_ratio)/min(dasharray_from.w,dasharray_to.w);alpha*=smoothstep(0.5-sdfgamma/floorwidth,0.5+sdfgamma/floorwidth,sdfdist);fragColor=color*(alpha*opacity);
+#ifdef GLOBE
+if (v_depth > 1.0) {discard;}
+#endif
+#ifdef OVERDRAW_INSPECTOR
+fragColor=vec4(1.0);
+#endif
+}`,`
+#define scale 0.015873016
+#define LINE_DISTANCE_SCALE 2.0
+layout(location=0) in ivec2 a_pos_normal;layout(location=1) in uvec4 a_data;uniform vec2 u_translation;uniform mediump float u_ratio;uniform lowp float u_device_pixel_ratio;uniform vec2 u_units_to_pixels;uniform float u_tileratio;uniform float u_crossfade_from;uniform float u_crossfade_to;uniform float u_lineatlas_height;out vec2 v_normal;flat out vec2 v_width2;out vec2 v_tex_a;out vec2 v_tex_b;out float v_gamma_scale;
+#ifdef GLOBE
+out float v_depth;
+#endif
+#pragma maplibre: define highp vec4 color
+#pragma maplibre: define lowp float blur
+#pragma maplibre: define lowp float opacity
+#pragma maplibre: define mediump float gapwidth
+#pragma maplibre: define lowp float offset
+#pragma maplibre: define mediump float width
+#pragma maplibre: define lowp float floorwidth
+#pragma maplibre: define mediump vec4 dasharray_from
+#pragma maplibre: define mediump vec4 dasharray_to
+void main() {
+#pragma maplibre: initialize highp vec4 color
+#pragma maplibre: initialize lowp float blur
+#pragma maplibre: initialize lowp float opacity
+#pragma maplibre: initialize mediump float gapwidth
+#pragma maplibre: initialize lowp float offset
+#pragma maplibre: initialize mediump float width
+#pragma maplibre: initialize lowp float floorwidth
+#pragma maplibre: initialize mediump vec4 dasharray_from
+#pragma maplibre: initialize mediump vec4 dasharray_to
+if (opacity < 0.01) {gl_Position=vec4(-2.0,-2.0,-2.0,1.0);return;}float ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=vec2(ivec2(a_data.xy)-128);float a_direction=float(int(a_data.z & 3u)-1);float a_linesofar=float((a_data.z >> 2u)+a_data.w*64u)*LINE_DISTANCE_SCALE;vec2 pos=vec2(a_pos_normal >> 1);mediump vec2 normal=vec2(a_pos_normal & 1);normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);float adjustedThickness=projectLineThickness(pos.y);vec4 projected_no_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation);vec4 projected_with_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation+dist/u_ratio*adjustedThickness);gl_Position=projected_with_extrude;
+#ifdef GLOBE
+v_depth=gl_Position.z/gl_Position.w;
+#endif
+#ifdef TERRAIN3D
+v_gamma_scale=1.0;
+#else
+float extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length((projected_with_extrude.xy-projected_no_extrude.xy)/projected_with_extrude.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective;
+#endif
+float u_patternscale_a_x=u_tileratio/dasharray_from.w/u_crossfade_from;float u_patternscale_a_y=-dasharray_from.z/2.0/u_lineatlas_height;float u_patternscale_b_x=u_tileratio/dasharray_to.w/u_crossfade_to;float u_patternscale_b_y=-dasharray_to.z/2.0/u_lineatlas_height;v_tex_a=vec2(a_linesofar*u_patternscale_a_x/floorwidth,normal.y*u_patternscale_a_y+(float(dasharray_from.y)+0.5)/u_lineatlas_height);v_tex_b=vec2(a_linesofar*u_patternscale_b_x/floorwidth,normal.y*u_patternscale_b_y+(float(dasharray_to.y)+0.5)/u_lineatlas_height);v_width2=vec2(outset,inset);}`),lineGradientSDF:Y(`uniform lowp float u_device_pixel_ratio;uniform sampler2D u_image;uniform sampler2D u_image_dash;uniform float u_mix;uniform lowp float u_lineatlas_width;in vec2 v_normal;flat in vec2 v_width2;in vec2 v_tex_a;in vec2 v_tex_b;in float v_gamma_scale;in highp vec2 v_uv;
+#ifdef GLOBE
+in float v_depth;
+#endif
+#pragma maplibre: define lowp float blur
+#pragma maplibre: define lowp float opacity
+#pragma maplibre: define mediump float width
+#pragma maplibre: define lowp float floorwidth
+#pragma maplibre: define mediump vec4 dasharray_from
+#pragma maplibre: define mediump vec4 dasharray_to
+void main() {
+#pragma maplibre: initialize lowp float blur
+#pragma maplibre: initialize lowp float opacity
+#pragma maplibre: initialize mediump float width
+#pragma maplibre: initialize lowp float floorwidth
+#pragma maplibre: initialize mediump vec4 dasharray_from
+#pragma maplibre: initialize mediump vec4 dasharray_to
+clipAntimeridian();float dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);vec4 color=texture(u_image,v_uv);float sdfdist_a=texture(u_image_dash,v_tex_a).a;float sdfdist_b=texture(u_image_dash,v_tex_b).a;float sdfdist=mix(sdfdist_a,sdfdist_b,u_mix);float sdfgamma=(u_lineatlas_width/256.0)/min(dasharray_from.w,dasharray_to.w);float dash_alpha=smoothstep(0.5-sdfgamma/floorwidth,0.5+sdfgamma/floorwidth,sdfdist);fragColor=color*(alpha*dash_alpha*opacity);
+#ifdef GLOBE
+if (v_depth > 1.0) {discard;}
+#endif
+#ifdef OVERDRAW_INSPECTOR
+fragColor=vec4(1.0);
+#endif
+}`,`
+#define scale 0.015873016
+#define LINE_DISTANCE_SCALE 2.0
+layout(location=0) in ivec2 a_pos_normal;layout(location=1) in uvec4 a_data;layout(location=2) in float a_uv_x;layout(location=3) in float a_split_index;uniform vec2 u_translation;uniform mediump float u_ratio;uniform lowp float u_device_pixel_ratio;uniform vec2 u_units_to_pixels;uniform float u_image_height;uniform float u_tileratio;uniform float u_crossfade_from;uniform float u_crossfade_to;uniform float u_lineatlas_height;out vec2 v_normal;flat out vec2 v_width2;out float v_gamma_scale;out highp vec2 v_uv;out vec2 v_tex_a;out vec2 v_tex_b;
+#ifdef GLOBE
+out float v_depth;
+#endif
+#pragma maplibre: define lowp float blur
+#pragma maplibre: define lowp float opacity
+#pragma maplibre: define mediump float gapwidth
+#pragma maplibre: define lowp float offset
+#pragma maplibre: define mediump float width
+#pragma maplibre: define lowp float floorwidth
+#pragma maplibre: define mediump vec4 dasharray_from
+#pragma maplibre: define mediump vec4 dasharray_to
+void main() {
+#pragma maplibre: initialize lowp float blur
+#pragma maplibre: initialize lowp float opacity
+#pragma maplibre: initialize mediump float gapwidth
+#pragma maplibre: initialize lowp float offset
+#pragma maplibre: initialize mediump float width
+#pragma maplibre: initialize lowp float floorwidth
+#pragma maplibre: initialize mediump vec4 dasharray_from
+#pragma maplibre: initialize mediump vec4 dasharray_to
+if (opacity < 0.01) {gl_Position=vec4(-2.0,-2.0,-2.0,1.0);return;}float ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=vec2(ivec2(a_data.xy)-128);float a_direction=float(int(a_data.z & 3u)-1);float a_linesofar=float((a_data.z >> 2u)+a_data.w*64u)*LINE_DISTANCE_SCALE;float texel_height=1.0/u_image_height;float half_texel_height=0.5*texel_height;v_uv=vec2(a_uv_x,a_split_index*texel_height-half_texel_height);vec2 pos=vec2(a_pos_normal >> 1);mediump vec2 normal=vec2(a_pos_normal & 1);normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);float adjustedThickness=projectLineThickness(pos.y);vec4 projected_no_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation);vec4 projected_with_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation+dist/u_ratio*adjustedThickness);gl_Position=projected_with_extrude;
+#ifdef GLOBE
+v_depth=gl_Position.z/gl_Position.w;
+#endif
+#ifdef TERRAIN3D
+v_gamma_scale=1.0;
+#else
+float extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length((projected_with_extrude.xy-projected_no_extrude.xy)/projected_with_extrude.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective;
+#endif
+float u_patternscale_a_x=u_tileratio/dasharray_from.w/u_crossfade_from;float u_patternscale_a_y=-dasharray_from.z/2.0/u_lineatlas_height;float u_patternscale_b_x=u_tileratio/dasharray_to.w/u_crossfade_to;float u_patternscale_b_y=-dasharray_to.z/2.0/u_lineatlas_height;v_tex_a=vec2(a_linesofar*u_patternscale_a_x/floorwidth,normal.y*u_patternscale_a_y+(float(dasharray_from.y)+0.5)/u_lineatlas_height);v_tex_b=vec2(a_linesofar*u_patternscale_b_x/floorwidth,normal.y*u_patternscale_b_y+(float(dasharray_to.y)+0.5)/u_lineatlas_height);v_width2=vec2(outset,inset);}`),layerOpacity:Y(`uniform sampler2D u_image;uniform float u_opacity;in vec2 v_pos;void main() {fragColor=texture(u_image,v_pos)*u_opacity;
+#ifdef OVERDRAW_INSPECTOR
+fragColor=vec4(0.0);
+#endif
+}`,`layout(location=0) in vec2 a_pos;out vec2 v_pos;void main() {gl_Position=vec4(a_pos.x*2.0-1.0,1.0-a_pos.y*2.0,0.0,1.0);v_pos.x=a_pos.x;v_pos.y=1.0-a_pos.y;}`),raster:Y(`uniform float u_fade_t;uniform float u_opacity;uniform sampler2D u_image0;uniform sampler2D u_image1;in vec3 v_pos0;in vec3 v_pos1;uniform float u_brightness_low;uniform float u_brightness_high;uniform float u_saturation_factor;uniform float u_contrast_factor;uniform vec3 u_spin_weights;void main() {vec4 color0=texture(u_image0,v_pos0.xy/v_pos0.z);vec4 color1=texture(u_image1,v_pos1.xy/v_pos1.z);if (color0.a > 0.0) {color0.rgb=color0.rgb/color0.a;}if (color1.a > 0.0) {color1.rgb=color1.rgb/color1.a;}vec4 color=mix(color0,color1,u_fade_t);color.a*=u_opacity;vec3 rgb=color.rgb;rgb=vec3(dot(rgb,u_spin_weights.xyz),dot(rgb,u_spin_weights.zxy),dot(rgb,u_spin_weights.yzx));float average=(color.r+color.g+color.b)/3.0;rgb+=(average-rgb)*u_saturation_factor;rgb=(rgb-0.5)*u_contrast_factor+0.5;vec3 u_high_vec=vec3(u_brightness_low,u_brightness_low,u_brightness_low);vec3 u_low_vec=vec3(u_brightness_high,u_brightness_high,u_brightness_high);fragColor=vec4(mix(u_high_vec,u_low_vec,rgb)*color.a,color.a);
+#ifdef OVERDRAW_INSPECTOR
+fragColor=vec4(1.0);
+#endif
+}`,`uniform vec2 u_tl_parent;uniform float u_scale_parent;uniform float u_buffer_scale;uniform vec3 u_image_warp;uniform vec4 u_coords_top;uniform vec4 u_coords_bottom;layout(location=0) in vec2 a_pos;out vec3 v_pos0;out vec3 v_pos1;void main() {vec2 fractionalPos=a_pos/8192.0;vec2 topLeft=u_coords_top.xy;vec2 topRight=u_coords_top.zw;vec2 bottomLeft=u_coords_bottom.xy;vec2 bottomRight=u_coords_bottom.zw;vec2 bilinearPos=mix(mix(topLeft,topRight,fractionalPos.x),mix(bottomLeft,bottomRight,fractionalPos.x),fractionalPos.y);float denominator=dot(u_image_warp.xy,fractionalPos)+1.0;vec2 acrossTop=topRight-topLeft+u_image_warp.x*topRight;vec2 downLeft=bottomLeft-topLeft+u_image_warp.y*bottomLeft;vec2 projectivePos=(acrossTop*fractionalPos.x+downLeft*fractionalPos.y+topLeft)/denominator;vec2 position=mix(projectivePos,bilinearPos,u_image_warp.z);gl_Position=projectTile(position,position);vec2 texturePos=((fractionalPos-0.5)/u_buffer_scale)+0.5;
+#ifdef GLOBE
+if (a_pos.y <-32767.5) {texturePos.y=0.0;}if (a_pos.y > 32766.5) {texturePos.y=1.0;}
+#endif
+float perspectiveRatio=mix(1.0/denominator,1.0,u_image_warp.z);v_pos0=vec3(texturePos*perspectiveRatio,perspectiveRatio);vec2 parentPos=(texturePos*u_scale_parent)+u_tl_parent;v_pos1=vec3(parentPos*perspectiveRatio,perspectiveRatio);}`),symbolIcon:Y(`uniform sampler2D u_texture;in vec2 v_tex;flat in float v_total_opacity;void main() {fragColor=texture(u_texture,v_tex)*v_total_opacity;
+#ifdef OVERDRAW_INSPECTOR
+fragColor=vec4(1.0);
+#endif
+}`,`layout(location=0) in vec4 a_pos_offset;layout(location=1) in uvec4 a_data;layout(location=2) in vec4 a_pixeloffset;layout(location=3) in vec3 a_projected_pos;layout(location=4) in uint a_fade_opacity;layout(location=5) in float a_height_offset;uniform bool u_is_size_zoom_constant;uniform bool u_is_size_feature_constant;uniform highp float u_size_t;uniform highp float u_size;uniform highp float u_camera_to_center_distance;uniform highp float u_pitch;uniform bool u_rotate_symbol;uniform highp float u_aspect_ratio;uniform float u_fade_change;uniform mat4 u_label_plane_matrix;uniform mat4 u_coord_matrix;uniform bool u_is_text;uniform bool u_pitch_with_map;uniform vec2 u_texsize;uniform bool u_is_along_line;uniform bool u_is_variable_anchor;uniform vec2 u_translation;uniform float u_pitched_scale;uniform bool u_is_offset;uniform bool u_height_anchor_ground;out vec2 v_tex;flat out float v_total_opacity;
+#pragma maplibre: define lowp float opacity
+void main() {
+#pragma maplibre: initialize lowp float opacity
+vec2 a_pos=a_pos_offset.xy;vec2 a_offset=a_pos_offset.zw;vec2 a_tex=vec2(a_data.xy);vec2 a_size=vec2(a_data.zw);float a_size_min=float(a_data.z >> 1u);vec2 a_pxoffset=a_pixeloffset.xy;vec2 a_minFontScale=a_pixeloffset.zw/256.0;float ele=a_height_offset+(u_height_anchor_ground ? get_elevation(a_pos) : 0.0);highp float segment_angle=-a_projected_pos[2];float size;if (!u_is_size_zoom_constant && !u_is_size_feature_constant) {size=mix(a_size_min,a_size[1],u_size_t)/128.0;} else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {size=a_size_min/128.0;} else {size=u_size;}vec2 translated_a_pos=a_pos+u_translation;vec4 projectedPoint=projectTileWithElevation(translated_a_pos,ele);vec2 fade_opacity=unpack_opacity(a_fade_opacity);float fade_change=fade_opacity[1] > 0.5 ? u_fade_change :-u_fade_change;float visibility=calculate_visibility(projectedPoint);v_total_opacity=opacity*max(0.0,min(visibility,fade_opacity[0]+fade_change));if (v_total_opacity < 0.1){gl_Position=vec4(-2.,-2.,-2.,1.);return;}highp float camera_to_anchor_distance=projectedPoint.w;highp float distance_ratio=u_pitch_with_map ?
+camera_to_anchor_distance/u_camera_to_center_distance :
+u_camera_to_center_distance/camera_to_anchor_distance;highp float perspective_ratio=clamp(0.5+0.5*distance_ratio,0.0,4.0);if (!u_is_offset) {size*=perspective_ratio;}float fontScale=u_is_text ? size/24.0 : size;highp float symbol_rotation=0.0;if (u_rotate_symbol) {vec4 offsetProjectedPoint=projectTileWithElevation(translated_a_pos+vec2(1,0),ele);vec2 a=projectedPoint.xy/projectedPoint.w;vec2 b=offsetProjectedPoint.xy/offsetProjectedPoint.w;symbol_rotation=atan((b.y-a.y)/u_aspect_ratio,b.x-a.x);}highp float angle_sin=sin(segment_angle+symbol_rotation);highp float angle_cos=cos(segment_angle+symbol_rotation);mat2 rotation_matrix=mat2(angle_cos,-1.0*angle_sin,angle_sin,angle_cos);vec4 projected_pos;if (u_is_along_line || u_is_variable_anchor) {projected_pos=vec4(a_projected_pos.xy,ele,1.0);} else if (u_pitch_with_map) {projected_pos=u_label_plane_matrix*vec4(a_projected_pos.xy+u_translation,ele,1.0);} else {projected_pos=u_label_plane_matrix*projectTileWithElevation(a_projected_pos.xy+u_translation,ele);}float z=float(u_pitch_with_map)*projected_pos.z/projected_pos.w;float projectionScaling=1.0;
+#ifdef GLOBE
+if(u_pitch_with_map) {float anchor_pos_tile_y=(u_coord_matrix*vec4(projected_pos.xy/projected_pos.w,z,1.0)).y;projectionScaling=mix(projectionScaling,1.0/circumferenceRatioAtTileY(anchor_pos_tile_y)*u_pitched_scale,u_projection_transition);}
+#endif
+vec4 finalPos=u_coord_matrix*vec4(projected_pos.xy/projected_pos.w+rotation_matrix*(a_offset/32.0*max(a_minFontScale,fontScale)+a_pxoffset/16.0)*projectionScaling,z,1.0);if(u_pitch_with_map) {finalPos=projectTileWithElevation(finalPos.xy,finalPos.z);}gl_Position=finalPos;v_tex=a_tex/u_texsize;}`),symbolSDF:Y(`#define SDF_PX 8.0
+uniform bool u_is_halo;uniform bool u_is_plain;uniform sampler2D u_texture;uniform highp float u_gamma_scale;uniform lowp float u_device_pixel_ratio;uniform bool u_is_text;in vec2 v_data0;in vec3 v_data1;
+#pragma maplibre: define highp vec4 fill_color
+#pragma maplibre: define highp vec4 halo_color
+#pragma maplibre: define lowp float halo_width
+#pragma maplibre: define lowp float halo_blur
+void main() {
+#pragma maplibre: initialize highp vec4 fill_color
+#pragma maplibre: initialize highp vec4 halo_color
+#pragma maplibre: initialize lowp float halo_width
+#pragma maplibre: initialize lowp float halo_blur
+float EDGE_GAMMA=0.105/u_device_pixel_ratio;vec2 tex=v_data0.xy;float gamma_scale=v_data1.x;float size=v_data1.y;float total_opacity=v_data1[2];float fontScale=u_is_text ? size/24.0 : size;highp float gamma=EDGE_GAMMA/(fontScale*u_gamma_scale);lowp float inner_edge=(256.0-64.0)/256.0;lowp float dist=texture(u_texture,tex).a;lowp vec4 color_alpha_out_text,color_alpha_out_halo;if (u_is_plain){highp float gamma_scaled=gamma*gamma_scale;highp float alpha=smoothstep(inner_edge-gamma_scaled,inner_edge+gamma_scaled,dist);color_alpha_out_text=total_opacity*alpha*fill_color;}if (u_is_halo) {float gamma_halo=(halo_blur*1.19/SDF_PX+EDGE_GAMMA)/(fontScale*u_gamma_scale);float inner_edge_halo=inner_edge+gamma_halo*gamma_scale;highp float gamma_scaled_halo=gamma_halo*gamma_scale;highp float alpha_halo=smoothstep(inner_edge_halo-gamma_scaled_halo,inner_edge_halo+gamma_scaled_halo,dist);highp float halo_edge=(6.0-halo_width/fontScale)/SDF_PX;alpha_halo= min(smoothstep(halo_edge-gamma_scaled_halo,halo_edge+gamma_scaled_halo,dist),1.0-alpha_halo);color_alpha_out_halo=total_opacity*alpha_halo*halo_color;}if (u_is_plain && u_is_halo) {fragColor=color_alpha_out_text+(1.-color_alpha_out_text.a)*color_alpha_out_halo;} else if (u_is_halo){fragColor=color_alpha_out_halo;} else {fragColor=color_alpha_out_text;}
+#ifdef OVERDRAW_INSPECTOR
+fragColor=vec4(1.0);
+#endif
+}`,`layout(location=0) in vec4 a_pos_offset;layout(location=1) in uvec4 a_data;layout(location=2) in vec4 a_pixeloffset;layout(location=3) in vec3 a_projected_pos;layout(location=4) in uint a_fade_opacity;layout(location=5) in float a_height_offset;uniform bool u_is_size_zoom_constant;uniform bool u_is_size_feature_constant;uniform highp float u_size_t;uniform highp float u_size;uniform mat4 u_label_plane_matrix;uniform mat4 u_coord_matrix;uniform bool u_is_text;uniform bool u_pitch_with_map;uniform bool u_is_along_line;uniform bool u_is_variable_anchor;uniform highp float u_pitch;uniform bool u_rotate_symbol;uniform highp float u_aspect_ratio;uniform highp float u_camera_to_center_distance;uniform float u_fade_change;uniform vec2 u_texsize;uniform vec2 u_translation;uniform float u_pitched_scale;uniform bool u_is_offset;uniform bool u_height_anchor_ground;out vec2 v_data0;out vec3 v_data1;
+#pragma maplibre: define highp vec4 fill_color
+#pragma maplibre: define highp vec4 halo_color
+#pragma maplibre: define lowp float opacity
+#pragma maplibre: define lowp float halo_width
+#pragma maplibre: define lowp float halo_blur
+void main() {
+#pragma maplibre: initialize highp vec4 fill_color
+#pragma maplibre: initialize highp vec4 halo_color
+#pragma maplibre: initialize lowp float opacity
+#pragma maplibre: initialize lowp float halo_width
+#pragma maplibre: initialize lowp float halo_blur
+vec2 a_pos=a_pos_offset.xy;vec2 a_offset=a_pos_offset.zw;vec2 a_tex=vec2(a_data.xy);vec2 a_size=vec2(a_data.zw);float a_size_min=float(a_data.z >> 1u);vec2 a_pxoffset=a_pixeloffset.xy/16.0;vec2 a_minFontScale=a_pixeloffset.zw/256.0;float ele=a_height_offset+(u_height_anchor_ground ? get_elevation(a_pos) : 0.0);highp float segment_angle=-a_projected_pos[2];float size;if (!u_is_size_zoom_constant && !u_is_size_feature_constant) {size=mix(a_size_min,a_size[1],u_size_t)/128.0;} else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {size=a_size_min/128.0;} else {size=u_size;}vec2 translated_a_pos=a_pos+u_translation;vec4 projectedPoint=projectTileWithElevation(translated_a_pos,ele);vec2 fade_opacity=unpack_opacity(a_fade_opacity);float visibility=calculate_visibility(projectedPoint);float fade_change=fade_opacity[1] > 0.5 ? u_fade_change :-u_fade_change;float interpolated_fade_opacity=max(0.0,min(visibility,fade_opacity[0]+fade_change));float total_opacity=opacity*interpolated_fade_opacity;if (total_opacity < 0.1){gl_Position=vec4(-2.,-2.,-2.,1.);return;}highp float camera_to_anchor_distance=projectedPoint.w;highp float distance_ratio=u_pitch_with_map ?
+camera_to_anchor_distance/u_camera_to_center_distance :
+u_camera_to_center_distance/camera_to_anchor_distance;highp float perspective_ratio=clamp(0.5+0.5*distance_ratio,0.0,4.0);if (!u_is_offset) {size*=perspective_ratio;}float fontScale=u_is_text ? size/24.0 : size;highp float symbol_rotation=0.0;if (u_rotate_symbol) {vec4 offsetProjectedPoint=projectTileWithElevation(translated_a_pos+vec2(1,0),ele);vec2 a=projectedPoint.xy/projectedPoint.w;vec2 b=offsetProjectedPoint.xy/offsetProjectedPoint.w;symbol_rotation=atan((b.y-a.y)/u_aspect_ratio,b.x-a.x);}highp float angle_sin=sin(segment_angle+symbol_rotation);highp float angle_cos=cos(segment_angle+symbol_rotation);mat2 rotation_matrix=mat2(angle_cos,-1.0*angle_sin,angle_sin,angle_cos);vec4 projected_pos;if (u_is_along_line || u_is_variable_anchor) {projected_pos=vec4(a_projected_pos.xy,ele,1.0);} else if (u_pitch_with_map) {projected_pos=u_label_plane_matrix*vec4(a_projected_pos.xy+u_translation,ele,1.0);} else {projected_pos=u_label_plane_matrix*projectTileWithElevation(a_projected_pos.xy+u_translation,ele);}float z=float(u_pitch_with_map)*projected_pos.z/projected_pos.w;float projectionScaling=1.0;
+#ifdef GLOBE
+if(u_pitch_with_map) {float anchor_pos_tile_y=(u_coord_matrix*vec4(projected_pos.xy/projected_pos.w,z,1.0)).y;projectionScaling=mix(projectionScaling,1.0/circumferenceRatioAtTileY(anchor_pos_tile_y)*u_pitched_scale,u_projection_transition);}
+#endif
+vec4 finalPos=u_coord_matrix*vec4(projected_pos.xy/projected_pos.w+rotation_matrix*(a_offset/32.0*max(a_minFontScale,fontScale)+a_pxoffset)*projectionScaling,z,1.0);if(u_pitch_with_map) {finalPos=projectTileWithElevation(finalPos.xy,finalPos.z);}float gamma_scale=finalPos.w;gl_Position=finalPos;v_data0=a_tex/u_texsize;v_data1=vec3(gamma_scale,size,total_opacity);}`),symbolTextAndIcon:Y(`#define SDF_PX 8.0
+#define SDF 1.0
+#define ICON 0.0
+uniform bool u_is_halo;uniform bool u_is_text;uniform sampler2D u_texture;uniform sampler2D u_texture_icon;uniform highp float u_gamma_scale;uniform lowp float u_device_pixel_ratio;in vec4 v_data0;in vec3 v_data1;flat in float v_is_sdf;
+#pragma maplibre: define highp vec4 fill_color
+#pragma maplibre: define highp vec4 halo_color
+#pragma maplibre: define lowp float halo_width
+#pragma maplibre: define lowp float halo_blur
+void main() {
+#pragma maplibre: initialize highp vec4 fill_color
+#pragma maplibre: initialize highp vec4 halo_color
+#pragma maplibre: initialize lowp float halo_width
+#pragma maplibre: initialize lowp float halo_blur
+float total_opacity=v_data1[2];if (v_is_sdf==ICON) {vec2 tex_icon=v_data0.zw;fragColor=texture(u_texture_icon,tex_icon)*total_opacity;
+#ifdef OVERDRAW_INSPECTOR
+fragColor=vec4(1.0);
+#endif
+return;}vec2 tex=v_data0.xy;float EDGE_GAMMA=0.105/u_device_pixel_ratio;float gamma_scale=v_data1.x;float size=v_data1.y;float fontScale=size/24.0;highp float gamma=EDGE_GAMMA/(fontScale*u_gamma_scale);lowp float buff=(256.0-64.0)/256.0;lowp float dist=texture(u_texture,tex).a;lowp vec4 color_alpha_out,color_alpha_out_halo;if (u_is_text) {highp float gamma_scaled=gamma*gamma_scale;highp float alpha=smoothstep(buff-gamma_scaled,buff+gamma_scaled,dist);color_alpha_out=fill_color*(alpha*total_opacity);}if (u_is_halo) {highp float gamma_halo=(halo_blur*1.19/SDF_PX+EDGE_GAMMA)/(fontScale*u_gamma_scale);lowp float buff_halo=(6.0-halo_width/fontScale)/SDF_PX;highp float gamma_scaled_halo=gamma_halo*gamma_scale;highp float alpha_halo=smoothstep(buff_halo-gamma_scaled_halo,buff_halo+gamma_scaled_halo,dist);color_alpha_out_halo=halo_color*(alpha_halo*total_opacity);}if (u_is_text && u_is_halo) {fragColor=color_alpha_out+(1.-color_alpha_out.a)*color_alpha_out_halo;} else if (u_is_halo) {fragColor=color_alpha_out_halo;} else {fragColor=color_alpha_out;}
+#ifdef OVERDRAW_INSPECTOR
+fragColor=vec4(1.0);
+#endif
+}`,`layout(location=0) in vec4 a_pos_offset;layout(location=1) in uvec4 a_data;layout(location=2) in vec3 a_projected_pos;layout(location=3) in uint a_fade_opacity;layout(location=4) in float a_height_offset;uniform bool u_is_size_zoom_constant;uniform bool u_is_size_feature_constant;uniform highp float u_size_t;uniform highp float u_size;uniform mat4 u_label_plane_matrix;uniform mat4 u_coord_matrix;uniform bool u_is_text;uniform bool u_pitch_with_map;uniform highp float u_pitch;uniform bool u_rotate_symbol;uniform highp float u_aspect_ratio;uniform highp float u_camera_to_center_distance;uniform float u_fade_change;uniform vec2 u_texsize;uniform vec2 u_texsize_icon;uniform bool u_is_along_line;uniform bool u_is_variable_anchor;uniform vec2 u_translation;uniform float u_pitched_scale;uniform bool u_is_offset;uniform bool u_height_anchor_ground;out vec4 v_data0;out vec3 v_data1;flat out float v_is_sdf;
+#pragma maplibre: define highp vec4 fill_color
+#pragma maplibre: define highp vec4 halo_color
+#pragma maplibre: define lowp float opacity
+#pragma maplibre: define lowp float halo_width
+#pragma maplibre: define lowp float halo_blur
+void main() {
+#pragma maplibre: initialize highp vec4 fill_color
+#pragma maplibre: initialize highp vec4 halo_color
+#pragma maplibre: initialize lowp float opacity
+#pragma maplibre: initialize lowp float halo_width
+#pragma maplibre: initialize lowp float halo_blur
+vec2 a_pos=a_pos_offset.xy;vec2 a_offset=a_pos_offset.zw;vec2 a_tex=vec2(a_data.xy);vec2 a_size=vec2(a_data.zw);float a_size_min=float(a_data.z >> 1u);float is_sdf=float(a_data.z & 1u);float ele=a_height_offset+(u_height_anchor_ground ? get_elevation(a_pos) : 0.0);highp float segment_angle=-a_projected_pos[2];float size;if (!u_is_size_zoom_constant && !u_is_size_feature_constant) {size=mix(a_size_min,a_size[1],u_size_t)/128.0;} else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {size=a_size_min/128.0;} else {size=u_size;}vec2 translated_a_pos=a_pos+u_translation;vec4 projectedPoint=projectTileWithElevation(translated_a_pos,ele);vec2 fade_opacity=unpack_opacity(a_fade_opacity);float visibility=calculate_visibility(projectedPoint);float fade_change=fade_opacity[1] > 0.5 ? u_fade_change :-u_fade_change;float interpolated_fade_opacity=max(0.0,min(visibility,fade_opacity[0]+fade_change));float total_opacity=opacity*interpolated_fade_opacity;if (total_opacity < 0.1){gl_Position=vec4(-2.,-2.,-2.,1.);return;}highp float camera_to_anchor_distance=projectedPoint.w;highp float distance_ratio=u_pitch_with_map ?
+camera_to_anchor_distance/u_camera_to_center_distance :
+u_camera_to_center_distance/camera_to_anchor_distance;highp float perspective_ratio=clamp(0.5+0.5*distance_ratio,0.0,4.0);if (!u_is_offset) {size*=perspective_ratio;}float fontScale=size/24.0;highp float symbol_rotation=0.0;if (u_rotate_symbol) {vec4 offsetProjectedPoint=projectTileWithElevation(translated_a_pos+vec2(1,0),ele);vec2 a=projectedPoint.xy/projectedPoint.w;vec2 b=offsetProjectedPoint.xy/offsetProjectedPoint.w;symbol_rotation=atan((b.y-a.y)/u_aspect_ratio,b.x-a.x);}highp float angle_sin=sin(segment_angle+symbol_rotation);highp float angle_cos=cos(segment_angle+symbol_rotation);mat2 rotation_matrix=mat2(angle_cos,-1.0*angle_sin,angle_sin,angle_cos);vec4 projected_pos;if (u_is_along_line || u_is_variable_anchor) {projected_pos=vec4(a_projected_pos.xy,ele,1.0);} else if (u_pitch_with_map) {projected_pos=u_label_plane_matrix*vec4(a_projected_pos.xy+u_translation,ele,1.0);} else {projected_pos=u_label_plane_matrix*projectTileWithElevation(a_projected_pos.xy+u_translation,ele);}float z=float(u_pitch_with_map)*projected_pos.z/projected_pos.w;float projectionScaling=1.0;
+#ifdef GLOBE
+if(u_pitch_with_map && !u_is_along_line) {float anchor_pos_tile_y=(u_coord_matrix*vec4(projected_pos.xy/projected_pos.w,z,1.0)).y;projectionScaling=mix(projectionScaling,1.0/circumferenceRatioAtTileY(anchor_pos_tile_y)*u_pitched_scale,u_projection_transition);}
+#endif
+vec4 finalPos=u_coord_matrix*vec4(projected_pos.xy/projected_pos.w+rotation_matrix*(a_offset/32.0*fontScale)*projectionScaling,z,1.0);if(u_pitch_with_map) {finalPos=projectTileWithElevation(finalPos.xy,finalPos.z);}float gamma_scale=finalPos.w;gl_Position=finalPos;v_data0.xy=a_tex/u_texsize;v_data0.zw=a_tex/u_texsize_icon;v_data1=vec3(gamma_scale,size,total_opacity);v_is_sdf=is_sdf;}`),terrain:Y(`uniform sampler2D u_texture;uniform vec4 u_fog_color;uniform vec4 u_horizon_color;uniform float u_fog_ground_blend;uniform float u_fog_ground_blend_opacity;uniform float u_horizon_fog_blend;uniform bool u_is_globe_mode;in vec2 v_texture_pos;in float v_fog_depth;const float gamma=2.2;vec4 gammaToLinear(vec4 color) {return pow(color,vec4(gamma));}vec4 linearToGamma(vec4 color) {return pow(color,vec4(1.0/gamma));}void main() {vec4 surface_color=texture(u_texture,vec2(v_texture_pos.x,1.0-v_texture_pos.y));if (!u_is_globe_mode && u_fog_ground_blend_opacity > 0.0 && v_fog_depth > u_fog_ground_blend) {vec4 surface_color_linear=gammaToLinear(surface_color);float blend_color=smoothstep(0.0,1.0,max((v_fog_depth-u_horizon_fog_blend)/(1.0-u_horizon_fog_blend),0.0));vec4 fog_horizon_color_linear=mix(gammaToLinear(u_fog_color),gammaToLinear(u_horizon_color),blend_color);float factor_fog=max(v_fog_depth-u_fog_ground_blend,0.0)/(1.0-u_fog_ground_blend);fragColor=linearToGamma(mix(surface_color_linear,fog_horizon_color_linear,pow(factor_fog,2.0)*u_fog_ground_blend_opacity));} else {fragColor=surface_color;}}`,`layout(location=0) in vec3 a_pos3d;uniform mat4 u_fog_matrix;uniform float u_ele_delta;out vec2 v_texture_pos;out float v_fog_depth;void main() {float ele=get_elevation(a_pos3d.xy);float ele_delta=a_pos3d.z==1.0 ? u_ele_delta : 0.0;v_texture_pos=a_pos3d.xy/8192.0;gl_Position=projectTileFor3D(a_pos3d.xy,ele-ele_delta);vec4 pos=u_fog_matrix*vec4(a_pos3d.xy,ele,1.0);v_fog_depth=pos.z/pos.w*0.5+0.5;}`),terrainDepth:Y(`in float v_depth;const highp vec4 bitSh=vec4(256.*256.*256.,256.*256.,256.,1.);const highp vec4 bitMsk=vec4(0.,vec3(1./256.0));highp vec4 pack(highp float value) {highp vec4 comp=fract(value*bitSh);comp-=comp.xxyz*bitMsk;return comp;}void main() {fragColor=pack(v_depth);}`,`layout(location=0) in vec3 a_pos3d;uniform float u_ele_delta;out float v_depth;void main() {float ele=get_elevation(a_pos3d.xy);float ele_delta=a_pos3d.z==1.0 ? u_ele_delta : 0.0;gl_Position=projectTileFor3D(a_pos3d.xy,ele-ele_delta);v_depth=gl_Position.z/gl_Position.w;}`),atmosphere:Y(`#ifdef GL_ES
+precision highp float;
+#endif
+in vec3 view_direction;uniform vec3 u_sun_pos;uniform vec3 u_globe_position;uniform float u_globe_radius;uniform float u_atmosphere_blend;/**Shader use from https:*Made some change to adapt to MapLibre Globe geometry*/const float PI=3.141592653589793;const int iSteps=5;const int jSteps=3;/*radius of the planet*/const float EARTH_RADIUS=6371e3;/*radius of the atmosphere*/const float ATMOS_RADIUS=6471e3;vec2 rsi(vec3 r0,vec3 rd,float sr) {float a=dot(rd,rd);float b=2.0*dot(rd,r0);float c=dot(r0,r0)-(sr*sr);float d=(b*b)-4.0*a*c;if (d < 0.0) return vec2(1e5,-1e5);return vec2((-b-sqrt(d))/(2.0*a),(-b+sqrt(d))/(2.0*a));}vec4 atmosphere(vec3 r,vec3 r0,vec3 pSun,float iSun,float rPlanet,float rAtmos,vec3 kRlh,float kMie,float shRlh,float shMie,float g) {pSun=normalize(pSun);r=normalize(r);vec2 p=rsi(r0,r,rAtmos);if (p.x > p.y) {return vec4(0.0,0.0,0.0,1.0);}if (p.x < 0.0) {p.x=0.0;}vec3 pos=r0+r*p.x;vec2 p2=rsi(r0,r,rPlanet);if (p2.x <=p2.y && p2.x > 0.0) {p.y=min(p.y,p2.x);}float iStepSize=(p.y-p.x)/float(iSteps);float iTime=p.x+iStepSize*0.5;vec3 totalRlh=vec3(0,0,0);vec3 totalMie=vec3(0,0,0);float iOdRlh=0.0;float iOdMie=0.0;float mu=dot(r,pSun);float mumu=mu*mu;float gg=g*g;float pRlh=3.0/(16.0*PI)*(1.0+mumu);float pMie=3.0/(8.0*PI)*((1.0-gg)*(mumu+1.0))/(pow(1.0+gg-2.0*mu*g,1.5)*(2.0+gg));for (int i=0; i < iSteps; i++) {vec3 iPos=r0+r*iTime;float iHeight=length(iPos)-rPlanet;float odStepRlh=exp(-iHeight/shRlh)*iStepSize;float odStepMie=exp(-iHeight/shMie)*iStepSize;iOdRlh+=odStepRlh;iOdMie+=odStepMie;float jStepSize=rsi(iPos,pSun,rAtmos).y/float(jSteps);float jTime=jStepSize*0.5;float jOdRlh=0.0;float jOdMie=0.0;for (int j=0; j < jSteps; j++) {vec3 jPos=iPos+pSun*jTime;float jHeight=length(jPos)-rPlanet;jOdRlh+=exp(-jHeight/shRlh)*jStepSize;jOdMie+=exp(-jHeight/shMie)*jStepSize;jTime+=jStepSize;}vec3 attn=exp(-(kMie*(iOdMie+jOdMie)+kRlh*(iOdRlh+jOdRlh)));totalRlh+=odStepRlh*attn;totalMie+=odStepMie*attn;iTime+=iStepSize;}float opacity=exp(-(length(kRlh)*length(totalRlh)+kMie*length(totalMie)));vec3 color=iSun*(pRlh*kRlh*totalRlh+pMie*kMie*totalMie);return vec4(color,opacity);}void main() {vec3 scale_camera_pos=-u_globe_position*EARTH_RADIUS/u_globe_radius;vec4 color=atmosphere(normalize(view_direction),scale_camera_pos,u_sun_pos,22.0,EARTH_RADIUS,ATMOS_RADIUS,vec3(5.5e-6,13.0e-6,22.4e-6),21e-6,8e3,1.2e3,0.758
+);color.rgb=1.0-exp(-1.0*color.rgb);color=pow(color,vec4(1.0/2.2));fragColor=vec4(color.rgb,1.0-color.a)*u_atmosphere_blend;}`,`layout(location=0) in vec2 a_pos;uniform mat4 u_inv_proj_matrix;out vec3 view_direction;void main() {view_direction=(u_inv_proj_matrix*vec4(a_pos,0.0,1.0)).xyz;gl_Position=vec4(a_pos,0.0,1.0);}`),sky:Y(`uniform vec4 u_sky_color;uniform vec4 u_horizon_color;uniform vec2 u_horizon;uniform vec2 u_horizon_normal;uniform float u_sky_horizon_blend;uniform float u_sky_blend;void main() {float x=gl_FragCoord.x;float y=gl_FragCoord.y;float blend=(y-u_horizon.y)*u_horizon_normal.y+(x-u_horizon.x)*u_horizon_normal.x;if (blend > 0.0) {if (blend < u_sky_horizon_blend) {fragColor=mix(u_sky_color,u_horizon_color,pow(1.0-blend/u_sky_horizon_blend,2.0));} else {fragColor=u_sky_color;}}fragColor=mix(fragColor,vec4(vec3(0.0),0.0),u_sky_blend);}`,`layout(location=0) in vec2 a_pos;void main() {gl_Position=vec4(a_pos,1.0,1.0);}`)};function Y(e,t){let n=/#pragma maplibre: ([\w]+) ([\w]+) ([\w]+) ([\w]+)/g,r=t.match(/in ([\w]+) ([\w]+)/g),i=e.match(/uniform ([\w]+) ([\w]+)([\s]*)([\w]*)/g),a=t.match(/uniform ([\w]+) ([\w]+)([\s]*)([\w]*)/g),o=a?a.concat(i):i,s=r?r.length:0,c={};return e=e.replace(n,(e,t,n,r,i)=>(c[i]=!0,t===`define`?`
+#ifndef HAS_UNIFORM_u_${i}
+in ${n} ${r} ${i};
+#else
+uniform ${n} ${r} u_${i};
+#endif
+`:`
+#ifdef HAS_UNIFORM_u_${i}
+ ${n} ${r} ${i} = u_${i};
+#endif
+`)),t=t.replace(n,(e,t,n,r,i)=>{let a=r===`float`?`vec2`:`vec4`,o=i.match(/color/)?`color`:a;return c[i]?t===`define`?`
+#ifndef HAS_UNIFORM_u_${i}
+uniform lowp float u_${i}_t;
+layout(location = ${s++}) in ${n} ${a} a_${i};
+out ${n} ${r} ${i};
+#else
+uniform ${n} ${r} u_${i};
+#endif
+`:o===`vec4`?`
+#ifndef HAS_UNIFORM_u_${i}
+ ${i} = a_${i};
+#else
+ ${n} ${r} ${i} = u_${i};
+#endif
+`:`
+#ifndef HAS_UNIFORM_u_${i}
+ ${i} = unpack_mix_${o}(a_${i}, u_${i}_t);
+#else
+ ${n} ${r} ${i} = u_${i};
+#endif
+`:t===`define`?`
+#ifndef HAS_UNIFORM_u_${i}
+uniform lowp float u_${i}_t;
+layout(location = ${s++}) in ${n} ${a} a_${i};
+#else
+uniform ${n} ${r} u_${i};
+#endif
+`:o===`vec4`?`
+#ifndef HAS_UNIFORM_u_${i}
+ ${n} ${r} ${i} = a_${i};
+#else
+ ${n} ${r} ${i} = u_${i};
+#endif
+`:`
+#ifndef HAS_UNIFORM_u_${i}
+ ${n} ${r} ${i} = unpack_mix_${o}(a_${i}, u_${i}_t);
+#else
+ ${n} ${r} ${i} = u_${i};
+#endif
+`}),{fragmentSource:e,vertexSource:t,staticAttributes:r,staticUniforms:o}}const Zs=`#define PROJECTION_MERCATOR`,Qs=`mercator`;var $s=class{constructor(){this._cachedMesh=null}get name(){return`mercator`}get useSubdivision(){return!1}get shaderVariantName(){return Qs}get shaderDefine(){return Zs}get shaderPreludeCode(){return Xs.projectionMercator}get vertexShaderPreludeCode(){return Xs.projectionMercator.vertexSource}get subdivisionGranularity(){return Lt.noSubdivision}get useGlobeControls(){return!1}get transitionState(){return 0}destroy(){}getMeshFromTileID(e,t,n,r,i){if(this._cachedMesh)return this._cachedMesh;let a=new Un;a.emplaceBack(0,0),a.emplaceBack(N,0),a.emplaceBack(0,N),a.emplaceBack(N,N);let o=e.createVertexBuffer(a,Wa.members),s=ae.simpleSegment(0,0,4,2),c=new gt;c.emplaceBack(1,0,2),c.emplaceBack(1,2,3);let l=e.createIndexBuffer(c);return this._cachedMesh=new Ua(o,l,s),this._cachedMesh}recalculate(){}hasTransition(){return!1}},ec=class e{constructor(e=0,t=0,n=0,r=0){if(isNaN(e)||e<0||isNaN(t)||t<0||isNaN(n)||n<0||isNaN(r)||r<0)throw Error(`Invalid value for edge-insets, top, bottom, left and right must all be numbers`);this.top=e,this.bottom=t,this.left=n,this.right=r}interpolate(e,t,n){return t.top!=null&&e.top!=null&&(this.top=on.number(e.top,t.top,n)),t.bottom!=null&&e.bottom!=null&&(this.bottom=on.number(e.bottom,t.bottom,n)),t.left!=null&&e.left!=null&&(this.left=on.number(e.left,t.left,n)),t.right!=null&&e.right!=null&&(this.right=on.number(e.right,t.right,n)),this}getCenter(e,t){let n=M((this.left+e-this.right)/2,0,e),r=M((this.top+t-this.bottom)/2,0,t);return new l(n,r)}equals(e){return this.top===e.top&&this.bottom===e.bottom&&this.left===e.left&&this.right===e.right}clone(){return new e(this.top,this.bottom,this.left,this.right)}toJSON(){return{top:this.top,bottom:this.bottom,left:this.left,right:this.right}}};function tc(e,t){if(!e.renderWorldCopies||e.lngRange)return;let n=t.lng-e.center.lng;t.lng+=n>180?-360:n<-180?360:0}function nc(e){return Math.max(0,Math.floor(e))}var rc=class{constructor(e,t){this.applyConstrain=(e,t)=>this._constrainOverride===null?this._callbacks.defaultConstrain(e,t):this._constrainOverride(e,t),this._callbacks=e,this._tileSize=512,this._renderWorldCopies=t?.renderWorldCopies===void 0||!!t?.renderWorldCopies,this._minZoom=t?.minZoom||0,this._maxZoom=t?.maxZoom||22,this._minPitch=t?.minPitch===void 0||t?.minPitch===null?0:t?.minPitch,this._maxPitch=t?.maxPitch===void 0||t?.maxPitch===null?60:t?.maxPitch,this._constrainOverride=t?.constrainOverride??null,this.setMaxBounds(),this._width=0,this._height=0,this._center=new V(0,0),this._elevation=0,this._zoom=0,this._tileZoom=nc(this._zoom),this._scale=d(this._zoom),this._bearingInRadians=0,this._fovInRadians=.6435011087932844,this._pitchInRadians=0,this._rollInRadians=0,this._unmodified=!0,this._edgeInsets=new ec,this._minElevationForCurrentTile=0,this._autoCalculateNearFarZ=!0}apply(e,t,n){this._constrainOverride=e.constrainOverride,this._latRange=e.latRange,this._lngRange=e.lngRange,this._width=e.width,this._height=e.height,this._center=e.center,this._elevation=e.elevation,this._minElevationForCurrentTile=e.minElevationForCurrentTile,this._zoom=e.zoom,this._tileZoom=nc(this._zoom),this._scale=d(this._zoom),this._bearingInRadians=e.bearingInRadians,this._fovInRadians=e.fovInRadians,this._pitchInRadians=e.pitchInRadians,this._rollInRadians=e.rollInRadians,this._unmodified=e.unmodified,this._edgeInsets=new ec(e.padding.top,e.padding.bottom,e.padding.left,e.padding.right),this._minZoom=e.minZoom,this._maxZoom=e.maxZoom,this._minPitch=e.minPitch,this._maxPitch=e.maxPitch,this._renderWorldCopies=e.renderWorldCopies,this._cameraToCenterDistance=e.cameraToCenterDistance,this._nearZ=e.nearZ,this._farZ=e.farZ,this._autoCalculateNearFarZ=!n&&e.autoCalculateNearFarZ,t&&this.constrainInternal(),this._calcMatrices()}get pixelsToClipSpaceMatrix(){return this._pixelsToClipSpaceMatrix}get clipSpaceToPixelsMatrix(){return this._clipSpaceToPixelsMatrix}get minElevationForCurrentTile(){return this._minElevationForCurrentTile}setMinElevationForCurrentTile(e){this._minElevationForCurrentTile=e}get tileSize(){return this._tileSize}get tileZoom(){return this._tileZoom}get scale(){return this._scale}get width(){return this._width}get height(){return this._height}get bearingInRadians(){return this._bearingInRadians}get lngRange(){return this._lngRange}get latRange(){return this._latRange}get pixelsToGLUnits(){return this._pixelsToGLUnits}get minZoom(){return this._minZoom}setMinZoom(e){if(this._minZoom===e)return;this._minZoom=e;let t=this._unmodified;this.setZoom(this.applyConstrain(this._center,this.zoom).zoom),this._unmodified=t}get maxZoom(){return this._maxZoom}setMaxZoom(e){if(this._maxZoom===e)return;this._maxZoom=e;let t=this._unmodified;this.setZoom(this.applyConstrain(this._center,this.zoom).zoom),this._unmodified=t}get minPitch(){return this._minPitch}setMinPitch(e){if(this._minPitch===e)return;this._minPitch=e;let t=this._unmodified;this.setPitch(Math.max(this.pitch,e)),this._unmodified=t}get maxPitch(){return this._maxPitch}setMaxPitch(e){if(this._maxPitch===e)return;this._maxPitch=e;let t=this._unmodified;this.setPitch(Math.min(this.pitch,e)),this._unmodified=t}get renderWorldCopies(){return this._renderWorldCopies}setRenderWorldCopies(e){e===void 0?e=!0:e===null&&(e=!1),this._renderWorldCopies=e}get constrainOverride(){return this._constrainOverride}setConstrainOverride(e){e===void 0&&(e=null),this._constrainOverride!==e&&(this._constrainOverride=e,this.constrainInternal(),this._calcMatrices())}get worldSize(){return this._tileSize*this._scale}get centerOffset(){return this.centerPoint._sub(this.size._div(2))}get size(){return new l(this._width,this._height)}get bearing(){return this._bearingInRadians/Math.PI*180}setBearing(e){let t=Or(e,-180,180)*Math.PI/180;this._bearingInRadians!==t&&(this._unmodified=!1,this._bearingInRadians=t,this._calcMatrices(),this._rotationMatrix=jr(),Pr(this._rotationMatrix,this._rotationMatrix,-this._bearingInRadians))}get rotationMatrix(){return this._rotationMatrix}get pitchInRadians(){return this._pitchInRadians}get pitch(){return this._pitchInRadians/Math.PI*180}setPitch(e){let t=M(e,this.minPitch,this.maxPitch)/180*Math.PI;this._pitchInRadians!==t&&(this._unmodified=!1,this._pitchInRadians=t,this._calcMatrices())}get rollInRadians(){return this._rollInRadians}get roll(){return this._rollInRadians/Math.PI*180}setRoll(e){let t=e/180*Math.PI;this._rollInRadians!==t&&(this._unmodified=!1,this._rollInRadians=t,this._calcMatrices())}get fovInRadians(){return this._fovInRadians}get fov(){return E(this._fovInRadians)}setFov(e){e=M(e,.1,150),this.fov!==e&&(this._unmodified=!1,this._fovInRadians=qt(e),this._calcMatrices())}get zoom(){return this._zoom}setZoom(e){let t=this.applyConstrain(this._center,e).zoom;this._zoom!==t&&(this._unmodified=!1,this._zoom=t,this._tileZoom=Math.max(0,Math.floor(t)),this._scale=d(t),this.constrainInternal(),this._calcMatrices())}get center(){return this._center}setCenter(e){(e.lat!==this._center.lat||e.lng!==this._center.lng)&&(this._unmodified=!1,this._center=e,this.constrainInternal(),this._calcMatrices())}get elevation(){return this._elevation}setElevation(e){e!==this._elevation&&(this._elevation=e,this.constrainInternal(),this._calcMatrices())}get padding(){return this._edgeInsets.toJSON()}setPadding(e){this._edgeInsets.equals(e)||(this._unmodified=!1,this._edgeInsets.interpolate(this._edgeInsets,e,1),this._calcMatrices())}get centerPoint(){return this._edgeInsets.getCenter(this._width,this._height)}get pixelsPerMeter(){return this._pixelPerMeter}get unmodified(){return this._unmodified}get cameraToCenterDistance(){return this._cameraToCenterDistance}get nearZ(){return this._nearZ}get farZ(){return this._farZ}get autoCalculateNearFarZ(){return this._autoCalculateNearFarZ}overrideNearFarZ(e,t){this._autoCalculateNearFarZ=!1,this._nearZ=e,this._farZ=t,this._calcMatrices()}clearNearFarZOverride(){this._autoCalculateNearFarZ=!0,this._calcMatrices()}isPaddingEqual(e){return this._edgeInsets.equals(e)}interpolatePadding(e,t,n){this._unmodified=!1,this._edgeInsets.interpolate(e,t,n),this.constrainInternal(),this._calcMatrices()}resize(e,t,n=!0){this._width=e,this._height=t,n&&this.constrainInternal(),this._calcMatrices()}getMaxBounds(){return this._latRange?.length!==2||this._lngRange?.length!==2?null:new _a([this._lngRange[0],this._latRange[0]],[this._lngRange[1],this._latRange[1]])}setMaxBounds(e){e?(this._lngRange=[e.getWest(),e.getEast()],this._latRange=[e.getSouth(),e.getNorth()],this.constrainInternal()):(this._lngRange=null,this._latRange=[-u,u])}getCameraQueryGeometry(e,t){if(t.length===1)return[t[0],e];{let{minX:n,minY:r,maxX:i,maxY:a}=On.fromPoints(t).extend(e);return[new l(n,r),new l(i,r),new l(i,a),new l(n,a),new l(n,r)]}}constrainInternal(){if(!this.center||!this._width||!this._height||this._constraining)return;this._constraining=!0;let e=this._unmodified,{center:t,zoom:n}=this.applyConstrain(this.center,this.zoom);this.setCenter(t),this.setZoom(n),this._unmodified=e,this._constraining=!1}_calcMatrices(){if(this._width&&this._height){this._pixelsToGLUnits=[2/this._width,-2/this._height];let e=$e(new Float64Array(16));ke(e,e,[this._width/2,-this._height/2,1]),Le(e,e,[1,-1,0]),this._clipSpaceToPixelsMatrix=e,e=$e(new Float64Array(16)),ke(e,e,[1,-1,1]),Le(e,e,[-1,-1,0]),ke(e,e,[2/this._width,2/this._height,1]),this._pixelsToClipSpaceMatrix=e;let t=this.fovInRadians/2;this._cameraToCenterDistance=.5/Math.tan(t)*this._height}this._callbacks.calcMatrices()}calculateCenterFromCameraLngLatAlt(e,t,n,r){let i=n===void 0?this.bearing:n,a=r=r===void 0?this.pitch:r,{distanceToCenter:o,clampedElevation:s}=this._distanceToCenterFromAltElevationPitch(t,this.elevation,a),{x:c,y:l}=_t(a,i),u=B.fromLngLat(e,t),d=dn(1,u.y),f,p,m=0;do{if(m+=1,m>10)break;p=o/d;let e=c*p,t=l*p;f=new B(u.x+e,u.y+t),d=1/f.meterInMercatorCoordinateUnits()}while(Math.abs(o-p*d)>1e-12);return{center:f.toLngLat(),elevation:s,zoom:Ee(this.height/2/Math.tan(this.fovInRadians/2)/p/this.tileSize)}}recalculateZoomAndCenter(e){if(this.elevation-e===0)return;let t=1/this.worldSize,n=Tn(1,this.center.lat)*this.worldSize,r=B.fromLngLat(this.center,this.elevation),i=r.x/t,a=r.y/t,o=r.z/t,s=this.pitch,c=this.bearing,{x:l,y:u,z:d}=_t(s,c),f=this.cameraToCenterDistance,p=i+f*-l,m=a+f*-u,h=o+f*d,{distanceToCenter:g,clampedElevation:_}=this._distanceToCenterFromAltElevationPitch(h/n,e,s),v=g*n,y=p+l*v,b=m+u*v,x=new B(y*t,b*t,0).toLngLat(),S=Tn(1,x.lat),C=Ee(this.height/2/Math.tan(this.fovInRadians/2)/g/S/this.tileSize);this._elevation=_,this._center=x,this.setZoom(C)}_distanceToCenterFromAltElevationPitch(e,t,n){let r=-Math.cos(qt(n)),i=e-t,a,o=t;return r*i>=0||Math.abs(r)<.1?(a=1e4,o=e+a*r):a=-i/r,{distanceToCenter:a,clampedElevation:o}}getCameraPoint(){let e=this.pitchInRadians,t=Math.tan(e)*(this.cameraToCenterDistance||1);return this.centerPoint.add(new l(t*Math.sin(this.rollInRadians),t*Math.cos(this.rollInRadians)))}getCameraAltitude(){return Math.cos(this.pitchInRadians)*this._cameraToCenterDistance/this._pixelPerMeter+this.elevation}getCameraLngLat(){return mt(this).toLngLat()}getMercatorTileCoordinates(e){if(!e)return[0,0,1,1];let t=e.canonical.z>=0?1<this.max[0]||e.aabb.min[1]>this.max[1]||e.aabb.min[2]>this.max[2]||e.aabb.max[0]0?(t+=e[r]*this.min[r],n+=e[r]*this.max[r]):(n+=e[r]*this.min[r],t+=e[r]*this.max[r]);return t>=0?2:n<0?0:1}},ac=class{distanceToTile2d(e,t,n,r){let i=r,a=i.distanceX([e,t]),o=i.distanceY([e,t]);return Math.hypot(a,o)}getWrap(e,t,n){return n}getTileBoundingVolume(e,t,n,r){let i=Math.min(0,n),a=Math.max(0,n);if(r?.terrain){let n=new $t(e.z,t,e.z,e.x,e.y),o=r.terrain.getMinMaxElevation(n);i=o.minElevation??i,a=o.maxElevation??a}let o=1<r}allowWorldCopies(){return!0}prepareNextFrame(){}},oc=class e{constructor(e,t,n){this.points=e,this.planes=t,this.aabb=n}static fromInvProjectionMatrix(t,n=1,r=0,i,a){let o=[[-1,1,-1,1],[1,1,-1,1],[1,-1,-1,1],[-1,-1,-1,1],[-1,1,1,1],[1,1,1,1],[1,-1,1,1],[-1,-1,1,1]],s=a?[[6,5,4],[0,1,2],[0,3,7],[2,1,5],[3,2,6],[0,4,5]]:[[0,1,2],[6,5,4],[0,3,7],[2,1,5],[3,2,6],[0,4,5]],c=2**r,l=o.map(e=>sc(e,t,n,c));i&&cc(l,s[0],i,a);let u=s.map(e=>{let t=En([],l[e[0]],l[e[1]]),n=En([],l[e[2]],l[e[1]]),r=Rt([],Gn([],t,n)),i=-ln(r,l[e[1]]);return r.concat(i)}),d=[1/0,1/0,1/0],f=[-1/0,-1/0,-1/0];for(let e of l)for(let t=0;t<3;t++)d[t]=Math.min(d[t],e[t]),f[t]=Math.max(f[t],e[t]);return new e(l,u,new ic(d,f))}};function sc(e,t,n,r){let i=Gt([],e,t),a=1/i[3]/n*r;return He(i,i,[a,a,1/i[3],a])}function cc(e,t,n,r){let i=r?4:0,a=r?0:4,o=0,s=[],c=[];for(let t=0;t<4;t++){let n=En([],e[t+a],e[t+i]),r=Nn(n);Xt(n,n,1/r),s.push(r),c.push(n)}for(let t=0;t<4;t++){let r=x(e[t+i],c[t],n);o=r!==null&&r>=0?Math.max(o,r):Math.max(o,s[t])}let l=lc(e,t),u=uc(n,l);if(u!==null){let e=u/ln(c[0],l);o=Math.min(o,e)}for(let t=0;t<4;t++){let n=Math.min(o,s[t]);e[t+a]=[e[t+i][0]+c[t][0]*n,e[t+i][1]+c[t][1]*n,e[t+i][2]+c[t][2]*n,1]}}function lc(e,t){let n=En([],e[t[0]],e[t[1]]),r=En([],e[t[2]],e[t[1]]),i=[0,0,0,0];return Rt(i,Gn([],n,r)),i[3]=-ln(i,e[t[0]]),i}function uc(e,t){let r=At(e),i=n([],e,1/r),a=En([],t,Xt([],i,ln(t,i))),o=At(a);if(o>0){let e=Math.sqrt(1-i[3]*i[3]),n=Xt([],i,-i[3]),r=$n([],n,Xt([],a,e/o));return tt(t,r)}return null}const dc=wt([{name:`a_pos3d`,type:`Int16`,components:3}]);var fc=class extends h{constructor(e){super(),this._lastTilesetChange=U(),this.tileManager=e,this._tiles={},this._renderableTilesKeys=[],this._sourceTileCache={},this.minzoom=0,this.maxzoom=22,this.deltaZoom=1,this.tileSize=e._source.tileSize*2**this.deltaZoom,e.usedForTerrain=!0,e.tileSize=this.tileSize}destruct(){this.tileManager.usedForTerrain=!1,this.tileManager.tileSize=null,this.releaseAllRTT()}getSource(){return this.tileManager._source}update(e,t){this.tileManager.update(e,t),this._renderableTilesKeys=[];let n={},r=!1;for(let i of So(e,{tileSize:this.tileSize,minzoom:this.minzoom,maxzoom:this.maxzoom,reparseOverscaled:!1,terrain:t,calculateTileZoom:this.tileManager._source.calculateTileZoom}))n[i.key]=!0,this._renderableTilesKeys.push(i.key),this._tiles[i.key]||(i.terrainRttPosMatrix32f=new Float32Array(16),Ne(i.terrainRttPosMatrix32f,0,N,N,0,0,1),this._tiles[i.key]=new po(i,this.tileSize),this._lastTilesetChange=U(),r=!0);for(let e in this._tiles)n[e]||(this._tiles[e].releaseRTT(this.tileManager.map.painter),delete this._tiles[e],r=!0);return r}releaseRTT(e){for(let t in this._tiles){let n=this._tiles[t];(n.tileID.equals(e)||n.tileID.isChildOf(e)||e.isChildOf(n.tileID))&&n.releaseRTT(this.tileManager.map.painter)}}releaseAllRTT(){for(let e in this._tiles)this._tiles[e].releaseRTT(this.tileManager.map.painter)}getRenderableTiles(){return this._renderableTilesKeys.map(e=>this.getTileByID(e))}getTileByID(e){return this._tiles[e]}getTerrainCoords(e,t){return t?this._getTerrainCoordsForTileRanges(e,t):this._getTerrainCoordsForRegularTile(e)}_getTerrainCoordsForRegularTile(e){let t={};for(let n of this._renderableTilesKeys){let r=this._tiles[n].tileID,i=e.clone(),a=vt();if(r.canonical.equals(e.canonical))Ne(a,0,N,N,0,0,1);else if(r.canonical.isChildOf(e.canonical)){let t=r.canonical.z-e.canonical.z,n=r.canonical.x-(r.canonical.x>>t<>t<>t;Ne(a,0,o,o,0,0,1),Le(a,a,[-n*o,-i*o,0])}else if(e.canonical.isChildOf(r.canonical)){let t=e.canonical.z-r.canonical.z,n=e.canonical.x-(e.canonical.x>>t<>t<>t;Ne(a,0,N,N,0,0,1),Le(a,a,[n*o,i*o,0]),ke(a,a,[1/2**t,1/2**t,0])}else continue;i.terrainRttPosMatrix32f=new Float32Array(a),t[n]=i}return t}_getTerrainCoordsForTileRanges(e,t){let n={};for(let r of this._renderableTilesKeys){let i=this._tiles[r].tileID;if(!this._isWithinTileRanges(i,t))continue;let a=e.clone(),o=vt();if(i.canonical.z===e.canonical.z){let t=e.canonical.x-i.canonical.x+e.wrap*(1<e.canonical.z){let t=i.canonical.z-e.canonical.z,n=i.canonical.x-(i.canonical.x>>t<>t<>t),s=e.canonical.y-(i.canonical.y>>t),c=N>>t;Ne(o,0,c,c,0,0,1),Le(o,o,[-n*c+a*N,-r*c+s*N,0])}else{let t=e.canonical.z-i.canonical.z,n=e.canonical.x-(e.canonical.x>>t<>t<>t)-i.canonical.x,s=(e.canonical.y>>t)-i.canonical.y,c=N<n.maxzoom&&(r=n.maxzoom),r=n.minzoom&&!i?.dem;)i=this.findTileInCaches(e.scaledTo(r--).key);return i}findTileInCaches(e){let t=this.tileManager.getTileByID(e);return t||(t=this.tileManager._outOfViewCache.getByKey(e),t)}anyTilesAfterTime(e=U()){return this._lastTilesetChange>=e}_isWithinTileRanges(e,t){let n=t[e.canonical.z];return!!n&&(e.wrap>n.minWrap||e.wrap=n.minTileXWrapped&&e.canonical.x<=n.maxTileXWrapped&&e.canonical.y>=n.minTileY&&e.canonical.y<=n.maxTileY)}};const pc=N*(1-1e-12);var mc=class{constructor(e,t,n,r=`auto`){this._meshCache={},this.painter=e,this.tileManager=new fc(t),this.options=n,this.exaggeration=typeof n.exaggeration==`number`?n.exaggeration:1,this._terrainSkirtLength=r,this.qualityFactor=2,this.meshSize=128,this._demMatrixCache=new Map,this._elevationSamplerCache=new Map}destroy(){this._fbo&&=(this._fbo.destroy(),null),this._fboDepthTexture&&=(this._fboDepthTexture.destroy(),null),this._emptyDemTexture&&=(this._emptyDemTexture.destroy(),null),this._emptyDepthTexture&&=(this._emptyDepthTexture.destroy(),null);for(let e in this._meshCache)this._meshCache[e].destroy();this._meshCache={},this.tileManager.destruct()}getDEMElevation(e,t,n,r=N){let i=e.normalizeCoordinates(t,n,r);if(!i)return 0;let a=this.getElevationSampler(i.tileID);return a?a(i.x,i.y,r):0}getElevationForLngLatZoom(e,t){if(!Nt(t,e.wrap()))return 0;let{tileID:n,mercatorX:r,mercatorY:i}=this._getOverscaledTileIDFromLngLatZoom(e,t);return this.getElevation(n,r%N,i%N,N)}getElevationForLngLat(e,t){let n=this.getCoverageIndex();if(n){let t=B.fromLngLat(e),r=gc(n,this.exaggeration,t.x,t.y);if(r.demLoaded)return r.elevation}let r=So(t,{maxzoom:this.tileManager.maxzoom,minzoom:this.tileManager.minzoom,tileSize:512,terrain:this}),i=0;for(let e of r)e.canonical.z>i&&(i=Math.min(e.canonical.z,this.tileManager.maxzoom));return this.getElevationForLngLatZoom(e,i)}getElevation(e,t,n,r=N){return this.getDEMElevation(e,t,n,r)*this.exaggeration}resetElevationCache(){this._elevationSamplerCache.clear(),this._coverageIndex=void 0}getCoverageIndex(){return this._coverageIndex===void 0&&(this._coverageIndex=this._buildCoverageIndex()),this._coverageIndex}_buildCoverageIndex(){let e=[],t=new Map,n=0,r=0;for(let i of this.tileManager.getRenderableTiles()){if(!i)continue;let{canonical:a,wrap:o}=i.tileID;e.includes(a.z)||e.push(a.z);let s=this.getElevationSampler(i.tileID);t.set(`${o}/${a.z}/${a.x}/${a.y}`,s);let{minElevation:c,maxElevation:l}=this.getMinMaxElevation(i.tileID);n=Math.min(n,c??0),r=Math.max(r,l??0)}return t.size===0?null:(e.sort((e,t)=>t-e),{zooms:e,samplerPerTile:t,minElevation:n-10,maxElevation:r+10})}getElevationSampler(e){let t=e.key,n=this._elevationSamplerCache.get(t);if(n)return n;let r=this.tileManager.getSourceTile(e,!0),i=r?.dem;if(!r||!i)return null;let a=this._getDEMTileMatrix(e,r),o=a[0]*i.dim,s=a[5]*i.dim,c=a[12]*i.dim,l=a[13]*i.dim,u=(e,t,n)=>{let r=n===8192?1:N/n;return i.sampleBilinear(e*r*o+c,t*r*s+l)};return this._elevationSamplerCache.set(t,u),u}_getDEMTileMatrix(e,t){let n=`${t.tileID.key}/${e.key}`,r=this._demMatrixCache.get(n);if(r)return r;let i=this.tileManager.getSource().maxzoom,a=e.canonical.z-t.tileID.canonical.z;e.overscaledZ>e.canonical.z&&(e.canonical.z>=i?a=e.canonical.z-i:I(`cannot calculate elevation if elevation maxzoom > source.maxzoom`));let o=e.canonical.x-(e.canonical.x>>a<>a<0,n=t&&e.canonical.y===0,r=t&&e.canonical.y===(1<=1)return hc;let i=Math.floor(n),a=n-i;for(let n of e.zooms){let o=1<i;a++){let i=(n+r)/2;t(e,i)?r=i:n=i}return{lo:n,hi:r}}var yc=class t{get pixelsToClipSpaceMatrix(){return this._helper.pixelsToClipSpaceMatrix}get clipSpaceToPixelsMatrix(){return this._helper.clipSpaceToPixelsMatrix}get pixelsToGLUnits(){return this._helper.pixelsToGLUnits}get centerOffset(){return this._helper.centerOffset}get size(){return this._helper.size}get rotationMatrix(){return this._helper.rotationMatrix}get centerPoint(){return this._helper.centerPoint}get pixelsPerMeter(){return this._helper.pixelsPerMeter}setMinZoom(e){this._helper.setMinZoom(e)}setMaxZoom(e){this._helper.setMaxZoom(e)}setMinPitch(e){this._helper.setMinPitch(e)}setMaxPitch(e){this._helper.setMaxPitch(e)}setRenderWorldCopies(e){this._helper.setRenderWorldCopies(e)}setBearing(e){this._helper.setBearing(e)}setPitch(e){this._helper.setPitch(e)}setRoll(e){this._helper.setRoll(e)}setFov(e){this._helper.setFov(e)}setZoom(e){this._helper.setZoom(e)}setCenter(e){this._helper.setCenter(e)}setElevation(e){this._helper.setElevation(e)}setMinElevationForCurrentTile(e){this._helper.setMinElevationForCurrentTile(e)}setPadding(e){this._helper.setPadding(e)}interpolatePadding(e,t,n){this._helper.interpolatePadding(e,t,n)}isPaddingEqual(e){return this._helper.isPaddingEqual(e)}resize(e,t,n=!0){this._helper.resize(e,t,n)}getMaxBounds(){return this._helper.getMaxBounds()}setMaxBounds(e){this._helper.setMaxBounds(e)}setConstrainOverride(e){this._helper.setConstrainOverride(e)}overrideNearFarZ(e,t){this._helper.overrideNearFarZ(e,t)}clearNearFarZOverride(){this._helper.clearNearFarZOverride()}getCameraQueryGeometry(e){return this._helper.getCameraQueryGeometry(this.getCameraPoint(),e)}get tileSize(){return this._helper.tileSize}get tileZoom(){return this._helper.tileZoom}get scale(){return this._helper.scale}get worldSize(){return this._helper.worldSize}get width(){return this._helper.width}get height(){return this._helper.height}get lngRange(){return this._helper.lngRange}get latRange(){return this._helper.latRange}get minZoom(){return this._helper.minZoom}get maxZoom(){return this._helper.maxZoom}get zoom(){return this._helper.zoom}get center(){return this._helper.center}get minPitch(){return this._helper.minPitch}get maxPitch(){return this._helper.maxPitch}get pitch(){return this._helper.pitch}get pitchInRadians(){return this._helper.pitchInRadians}get roll(){return this._helper.roll}get rollInRadians(){return this._helper.rollInRadians}get bearing(){return this._helper.bearing}get bearingInRadians(){return this._helper.bearingInRadians}get fov(){return this._helper.fov}get fovInRadians(){return this._helper.fovInRadians}get elevation(){return this._helper.elevation}get minElevationForCurrentTile(){return this._helper.minElevationForCurrentTile}get padding(){return this._helper.padding}get unmodified(){return this._helper.unmodified}get renderWorldCopies(){return this._helper.renderWorldCopies}get cameraToCenterDistance(){return this._helper.cameraToCenterDistance}get constrainOverride(){return this._helper.constrainOverride}get nearZ(){return this._helper.nearZ}get farZ(){return this._helper.farZ}get autoCalculateNearFarZ(){return this._helper.autoCalculateNearFarZ}setTransitionState(e){}constructor(e){this._posMatrixCache=new Map,this._alignedPosMatrixCache=new Map,this._fogMatrixCacheF32=new Map,this.defaultConstrain=(e,t)=>{t=M(+t,this.minZoom,this.maxZoom);let n={center:new V(e.lng,e.lat),zoom:t},r=this._helper._lngRange;!this._helper._renderWorldCopies&&r===null&&(r=[-179.9999999999,180-1e-10]);let i=this.tileSize*d(n.zoom),a=0,o=i,s=0,c=i,u=0,f=0,{x:p,y:m}=this.size;if(this._helper._latRange){let e=this._helper._latRange;a=Vt(e[1])*i,o=Vt(e[0])*i,o-ao&&(v=o-e)}if(r){let e=(s+c)/2,t=h;this._helper._renderWorldCopies&&(t=Or(h,e-i/2,e+i/2));let n=p/2;t-nc&&(_=c-n)}if(_!==void 0||v!==void 0){let e=new l(_??h,v??g);n.center=Mn(i,e).wrap()}return n},this.applyConstrain=(e,t)=>this._helper.applyConstrain(e,t),this._helper=new rc({calcMatrices:()=>this._calcMatrices(),defaultConstrain:(e,t)=>this.defaultConstrain(e,t)},e),this._coveringTilesDetailsProvider=new ac}clone(){let e=new t;return e.apply(this,!1),e}apply(e,t,n){this._helper.apply(e,t,n)}get cameraPosition(){return this._cameraPosition}get projectionMatrix(){return this._projectionMatrix}get modelViewProjectionMatrix(){return this._viewProjMatrix}get inverseProjectionMatrix(){return this._invProjMatrix}get mercatorMatrix(){return this._mercatorMatrix}getVisibleUnwrappedCoordinates(e){let t=[new Tt(0,e)];if(this._helper._renderWorldCopies){let n=this.screenPointToMercatorCoordinate(new l(0,0)),r=this.screenPointToMercatorCoordinate(new l(this._helper._width,0)),i=this.screenPointToMercatorCoordinate(new l(this._helper._width,this._helper._height)),a=this.screenPointToMercatorCoordinate(new l(0,this._helper._height)),o=Math.floor(Math.min(n.x,r.x,i.x,a.x)),s=Math.floor(Math.max(n.x,r.x,i.x,a.x));for(let n=o-1;n<=s+1;n++)n!==0&&t.push(new Tt(n,e))}return t}getCameraFrustum(){return oc.fromInvProjectionMatrix(this._invViewProjMatrix,this.worldSize)}getClippingPlane(){return null}getCoveringTilesDetailsProvider(){return this._coveringTilesDetailsProvider}recalculateZoomAndCenter(e){let t=this.screenPointToLocation(this.centerPoint,e),n=e?e.getElevationForLngLat(t,this):0;this._helper.recalculateZoomAndCenter(n)}setLocationAtPoint(e,t,n=this.elevation){let r=n-this.elevation,i=this.screenPointToMercatorCoordinateAtZ(t,r),a=this.screenPointToMercatorCoordinateAtZ(this.centerPoint,0),o=B.fromLngLat(e),s=new B(o.x-(i.x-a.x),o.y-(i.y-a.y));this.setCenter(s?.toLngLat()),this._helper._renderWorldCopies&&this.setCenter(this.center.wrap())}locationToScreenPoint(e,t){return t?this.coordinatePoint(B.fromLngLat(e),t.getElevationForLngLat(e,this),this._pixelMatrix3D):this.coordinatePoint(B.fromLngLat(e))}screenPointToLocation(e,t){return this.screenPointToMercatorCoordinate(e,t)?.toLngLat()}screenPointToLocationAtElevation(e,t){return this.screenPointToMercatorCoordinateAtZ(e,t-this.elevation)?.toLngLat()}screenPointToMercatorCoordinate(e,t){if(t){let n=this.screenTerrainPointToMercatorCoordinate(e,t);if(n!=null)return n}return this.screenPointToMercatorCoordinateAtZ(e)}screenTerrainPointToMercatorCoordinate(e,t){let n=t.getCoverageIndex();if(!n)return null;let{near:r,far:i}=this.getRaySegmentFromPixel(e),a=this.worldSize,o=i[0]-r[0],s=i[1]-r[1],c=i[2]-r[2],l={index:n,exaggeration:t.exaggeration,near:r,dx:o,dy:s,dz:c,worldSize:a},u=0,d=1;if(c===0){if(r[2]>n.maxElevation||r[2]d)return null}let f=Math.hypot(o,s),p=M(Math.ceil(f*(d-u)/4),1,512),m=0,h=!xc(l,0);for(let e=0;e<=p;e++){let t=u+(d-u)*e/p;if(!h)h=!xc(l,t);else if(xc(l,t)){let{lo:e,hi:n}=vc(l,xc,m,t,.001/f),i=bc(l,e),u=bc(l,n),d=r[2]+e*c-i.elevation,p=r[2]+n*c-u.elevation,h=i.covered&&d>p?M(e+d*(n-e)/(d-p),e,n):n;return new B((r[0]+h*o)/a,(r[1]+h*s)/a,bc(l,h).elevation)}m=t}return null}getRaySegmentFromPixel(e){let t=[e.x,e.y,0,1],n=[e.x,e.y,1,1];Gt(t,t,this._pixelMatrixInverse),Gt(n,n,this._pixelMatrixInverse);let r=t[3],i=n[3],a=this.elevation;return{near:[t[0]/r,t[1]/r,t[2]/r+a],far:[n[0]/i,n[1]/i,n[2]/i+a]}}screenPointToMercatorCoordinateAtZ(e,t){let n=t||0,{near:r,far:i}=this.getRaySegmentFromPixel(e),a=r[2]===i[2]?0:(n+this.elevation-r[2])/(i[2]-r[2]);return new B(on.number(r[0],i[0],a)/this.worldSize,on.number(r[1],i[1],a)/this.worldSize,n)}coordinatePoint(e,t=0,n=this._pixelMatrix){let r=[e.x*this.worldSize,e.y*this.worldSize,t,1];return Gt(r,r,n),new l(r[0]/r[3],r[1]/r[3])}getBounds(){let e=Math.max(0,this._helper._height/2-Be(this));return new _a().extend(this.screenPointToLocation(new l(0,e))).extend(this.screenPointToLocation(new l(this._helper._width,e))).extend(this.screenPointToLocation(new l(this._helper._width,this._helper._height))).extend(this.screenPointToLocation(new l(0,this._helper._height)))}isPointOnMapSurface(e,t){return t?this.screenTerrainPointToMercatorCoordinate(e,t)!=null:e.y>this.height/2-Be(this)}calculatePosMatrix(e,t=!1,n=!1){let r=e.key??sr(e.wrap,e.canonical.z,e.canonical.z,e.canonical.x,e.canonical.y),i=t?this._alignedPosMatrixCache:this._posMatrixCache;if(i.has(r)){let e=i.get(r);return n?e.f32:e.f64}let a=de(e,this.worldSize);y(a,t?this._alignedProjMatrix:this._viewProjMatrix,a);let o={f64:a,f32:new Float32Array(a)};return i.set(r,o),n?o.f32:o.f64}calculateFogMatrix(e){let t=e.key,n=this._fogMatrixCacheF32;if(n.has(t))return n.get(t);let r=de(e,this.worldSize);return y(r,this._fogMatrix,r),n.set(t,new Float32Array(r)),n.get(t)}calculateCenterFromCameraLngLatAlt(e,t,n,r){return this._helper.calculateCenterFromCameraLngLatAlt(e,t,n,r)}_calculateNearFarZIfNeeded(t,n,r){if(!this._helper.autoCalculateNearFarZ)return;let i=Math.min(this.elevation,this.minElevationForCurrentTile,this.getCameraAltitude()-100),a=t-i*this._helper._pixelPerMeter/Math.cos(n),o=i<0?a:t,s=Math.PI/2+this.pitchInRadians,c=qt(this.fov)*(Math.abs(Math.cos(qt(this.roll)))*this.height+Math.abs(Math.sin(qt(this.roll)))*this.width)/this.height*(.5+r.y/this.height),l=Math.sin(c)*o/Math.sin(M(Math.PI-s-c,.01,Math.PI-.01)),u=Be(this),d=Math.atan(u/this._helper.cameraToCenterDistance),f=qt(90-e),p=d>f?2*d*(.5+r.y/(u*2)):f,m=Math.sin(p)*o/Math.sin(M(Math.PI-s-p,.01,Math.PI-.01)),h=Math.min(l,m);this._helper._farZ=(Math.cos(Math.PI/2-n)*h+o)*1.01,this._helper._nearZ=this._helper._height/50}_calcMatrices(){if(!this._helper._height)return;let t=this.centerOffset,n=Jt(this.worldSize,this.center),r=n.x,i=n.y;this._helper._pixelPerMeter=Tn(1,this.center.lat)*this.worldSize;let o=qt(Math.min(this.pitch,e)),s=Math.max(this._helper.cameraToCenterDistance/2,this._helper.cameraToCenterDistance+this._helper._elevation*this._helper._pixelPerMeter/Math.cos(o));this._calculateNearFarZIfNeeded(s,o,t);let c;c=new Float64Array(16),vn(c,this.fovInRadians,this._helper._width/this._helper._height,this._helper._nearZ,this._helper._farZ),this._invProjMatrix=new Float64Array(16),zo(this._invProjMatrix,c),c[8]=-t.x*2/this._helper._width,c[9]=t.y*2/this._helper._height,this._projectionMatrix=Sr(c),ke(c,c,[1,-1,1]),Le(c,c,[0,0,-this._helper.cameraToCenterDistance]),we(c,c,-this.rollInRadians),a(c,c,this.pitchInRadians),we(c,c,-this.bearingInRadians),Le(c,c,[-r,-i,0]),this._mercatorMatrix=ke([],c,[this.worldSize,this.worldSize,this.worldSize]),ke(c,c,[1,1,this._helper._pixelPerMeter]),this._pixelMatrix=y(new Float64Array(16),this.clipSpaceToPixelsMatrix,c),Le(c,c,[0,0,-this.elevation]),this._viewProjMatrix=c,this._invViewProjMatrix=w([],c);let l=[0,0,-1,1];Gt(l,l,this._invViewProjMatrix),this._cameraPosition=[l[0]/l[3],l[1]/l[3],l[2]/l[3]],this._fogMatrix=new Float64Array(16),vn(this._fogMatrix,this.fovInRadians,this.width/this.height,s,this._helper._farZ),this._fogMatrix[8]=-t.x*2/this.width,this._fogMatrix[9]=t.y*2/this.height,ke(this._fogMatrix,this._fogMatrix,[1,-1,1]),Le(this._fogMatrix,this._fogMatrix,[0,0,-this.cameraToCenterDistance]),we(this._fogMatrix,this._fogMatrix,-this.rollInRadians),a(this._fogMatrix,this._fogMatrix,this.pitchInRadians),we(this._fogMatrix,this._fogMatrix,-this.bearingInRadians),Le(this._fogMatrix,this._fogMatrix,[-r,-i,0]),ke(this._fogMatrix,this._fogMatrix,[1,1,this._helper._pixelPerMeter]),Le(this._fogMatrix,this._fogMatrix,[0,0,-this.elevation]),this._pixelMatrix3D=y(new Float64Array(16),this.clipSpaceToPixelsMatrix,c);let u=this._helper._width%2/2,d=this._helper._height%2/2,f=Math.cos(this.bearingInRadians),p=Math.sin(-this.bearingInRadians),m=r-Math.round(r)+f*u+p*d,h=i-Math.round(i)+f*d+p*u,g=new Float64Array(c);if(Le(g,g,[m>.5?m-1:m,h>.5?h-1:h,0]),this._alignedProjMatrix=g,c=w(new Float64Array(16),this._pixelMatrix),!c)throw Error(`failed to invert matrix`);this._pixelMatrixInverse=c,this._clearMatrixCaches()}_clearMatrixCaches(){this._posMatrixCache.clear(),this._alignedPosMatrixCache.clear(),this._fogMatrixCacheF32.clear()}maxPitchScaleFactor(){if(!this._pixelMatrixInverse)return 1;let e=this.screenPointToMercatorCoordinate(new l(0,0)),t=[e.x*this.worldSize,e.y*this.worldSize,0,1];return Gt(t,t,this._pixelMatrix)[3]/this._helper.cameraToCenterDistance}getCameraPoint(){return this._helper.getCameraPoint()}getCameraAltitude(){return this._helper.getCameraAltitude()}getCameraLngLat(){let e=Tn(1,this.center.lat)*this.worldSize,t=this._helper.cameraToCenterDistance/e;return xt(this.center,this.elevation,this.pitch,this.bearing,t).toLngLat()}lngLatToCameraDepth(e,t){let n=B.fromLngLat(e),r=[n.x*this.worldSize,n.y*this.worldSize,t,1];return Gt(r,r,this._viewProjMatrix),r[2]/r[3]}getProjectionData(e){let{overscaledTileID:t,aligned:n,applyTerrainMatrix:r}=e,i=this._helper.getMercatorTileCoordinates(t),a=t?this.calculatePosMatrix(t,n,!0):null,o;return o=t?.terrainRttPosMatrix32f&&r?t.terrainRttPosMatrix32f:a||Vn(),{mainMatrix:o,tileMercatorCoords:i,clippingPlane:[0,0,0,0],projectionTransition:0,fallbackMatrix:o,clipAntimeridian:!1}}isLocationOccluded(e){return!1}getPixelScale(){return 1}getCircleRadiusCorrection(){return 1}getPitchedTextCorrection(e,t,n){return 1}transformLightDirection(e){return kn(e)}getRayDirectionFromPixel(e){throw Error(`Not implemented.`)}projectTileCoordinates(e,t,n,r){let i=this.calculatePosMatrix(n),a;r==null?(a=[e,t,0,1],ls(a,a,i)):(a=[e,t,r,1],Gt(a,a,i));let o=a[3];return{point:new l(a[0]/o,a[1]/o),signedDistanceFromCamera:o,isOccluded:!1}}populateCache(e){for(let t of e)this.calculatePosMatrix(t)}getProjectionDataForCustomLayer(e=!0){let t=new $t(0,0,0,0,0),n=this.getProjectionData({overscaledTileID:t,applyGlobeMatrix:e}),r=de(t,this.worldSize);y(r,this._viewProjMatrix,r);let i=[N,N,this.worldSize/this._helper.pixelsPerMeter],a=vt();return ke(a,r,i),{...n,tileMercatorCoords:[0,0,1,1],fallbackMatrix:a,mainMatrix:a}}getFastPathSimpleProjectionMatrix(e){return this.calculatePosMatrix(e)}};function bc(e,t){return gc(e.index,e.exaggeration,(e.near[0]+t*e.dx)/e.worldSize,(e.near[1]+t*e.dy)/e.worldSize)}function xc(e,t){return _c(bc(e,t),e.near[2]+t*e.dz)}function Sc(){I(`Map cannot fit within canvas with the given bounds, padding, and/or offset.`)}function Cc(e){if(e.useSlerp){if(e.k<1){let t=hn(e.startEulerAngles.roll,e.startEulerAngles.pitch,e.startEulerAngles.bearing),n=hn(e.endEulerAngles.roll,e.endEulerAngles.pitch,e.endEulerAngles.bearing),r=new Float64Array(4);Ct(r,t,n,e.k);let i=Qt(r);e.tr.setRoll(i.roll),e.tr.setPitch(i.pitch),e.tr.setBearing(i.bearing)}else e.tr.setRoll(e.endEulerAngles.roll),e.tr.setPitch(e.endEulerAngles.pitch),e.tr.setBearing(e.endEulerAngles.bearing)}else e.tr.setRoll(on.number(e.startEulerAngles.roll,e.endEulerAngles.roll,e.k)),e.tr.setPitch(on.number(e.startEulerAngles.pitch,e.endEulerAngles.pitch,e.k)),e.tr.setBearing(on.number(e.startEulerAngles.bearing,e.endEulerAngles.bearing,e.k))}function wc(e,t,n,r,i){let a=i.padding,o=Jt(i.worldSize,n.getNorthWest()),s=Jt(i.worldSize,n.getNorthEast()),c=Jt(i.worldSize,n.getSouthEast()),u=Jt(i.worldSize,n.getSouthWest()),f=qt(-r),p=o.rotate(f),m=s.rotate(f),h=c.rotate(f),g=u.rotate(f),_=new l(Math.max(p.x,m.x,g.x,h.x),Math.max(p.y,m.y,g.y,h.y)),v=new l(Math.min(p.x,m.x,g.x,h.x),Math.min(p.y,m.y,g.y,h.y)),y=_.sub(v),b=i.width-(a.left+a.right+t.left+t.right),x=i.height-(a.top+a.bottom+t.top+t.bottom),S=b/y.x,C=x/y.y;if(C<0||S<0){Sc();return}let w=Math.min(Ee(i.scale*Math.min(S,C)),e.maxZoom),T=l.convert(e.offset),E=(t.left-t.right)/2,D=(t.top-t.bottom)/2,ee=new l(E,D).rotate(qt(r)),O=T.add(ee).mult(i.scale/d(w));return{center:Mn(i.worldSize,o.add(c).div(2).sub(O)),zoom:w,bearing:r}}var Tc=class{get useGlobeControls(){return!1}handlePanInertia(e,t){let n=e.mag(),r=Math.abs(Be(t));return{easingOffset:e.mult(Math.min(r*.75/n,1)),easingCenter:t.center}}handleMapControlsRollPitchBearingZoom(e,t){e.bearingDelta&&t.setBearing(t.bearing+e.bearingDelta),e.pitchDelta&&t.setPitch(t.pitch+e.pitchDelta),e.rollDelta&&t.setRoll(t.roll+e.rollDelta),e.zoomDelta&&t.setZoom(t.zoom+e.zoomDelta)}handleMapControlsPan(e,t,n){e.around.distSqr(t.centerPoint)<.01||t.setLocationAtPoint(n,e.around,e.aroundElevation)}cameraForBoxAndBearing(e,t,n,r,i){return wc(e,t,n,r,i)}handleJumpToCenterZoom(e,t){let n=t.zoom===void 0?e.zoom:+t.zoom;e.zoom!==n&&e.setZoom(+t.zoom),t.center!==void 0&&e.setCenter(V.convert(t.center))}handleEaseTo(e,t){let n=e.zoom,r=e.padding,i={roll:e.roll,pitch:e.pitch,bearing:e.bearing},a={roll:t.roll===void 0?e.roll:t.roll,pitch:t.pitch===void 0?e.pitch:t.pitch,bearing:t.bearing===void 0?e.bearing:t.bearing},o=t.zoom!==void 0,c=!e.isPaddingEqual(t.padding),l=!1,u=o?+t.zoom:e.zoom,f=e.centerPoint.add(t.offsetAsPoint),p=e.screenPointToLocation(f),{center:m,zoom:h}=e.applyConstrain(V.convert(t.center||p),u??n);tc(e,m);let g=Jt(e.worldSize,p),_=Jt(e.worldSize,m).sub(g),v=d(h-n);return l=h!==n,{easeFunc:o=>{if(l&&e.setZoom(on.number(n,h,o)),s(i,a)||Cc({startEulerAngles:i,endEulerAngles:a,tr:e,k:o,useSlerp:i.roll!=a.roll}),c&&(e.interpolatePadding(r,t.padding,o),f=e.centerPoint.add(t.offsetAsPoint)),t.around)e.setLocationAtPoint(t.around,t.aroundPoint);else{let t=d(e.zoom-n),r=(h>n?Math.min(2,v):Math.max(.5,v))**(1-o),i=Mn(e.worldSize,g.add(_.mult(o*r)).mult(t));e.setLocationAtPoint(e.renderWorldCopies?i.wrap():i,f)}},isZooming:l,elevationCenter:m}}handleFlyTo(e,t){let n=t.zoom!==void 0,r=e.zoom,i=e.applyConstrain(V.convert(t.center||t.locationAtOffset),n?+t.zoom:r),a=i.center,o=i.zoom;tc(e,a);let s=e.worldSize,c=Jt(s,t.locationAtOffset),l=Jt(s,a).sub(c),u=l.mag(),f=d(o-r),p=t.minZoom===void 0?e.minZoom:+t.minZoom,m=Math.max(p,e.minZoom),h=Math.min(m,r,o),g=e.applyConstrain(a,h).zoom;return{easeFunc:(t,n,i,u)=>{e.setZoom(t===1?o:r+Ee(n));let d=t===1?a:Mn(s,c.add(l.mult(i)));e.setLocationAtPoint(e.renderWorldCopies?d.wrap():d,u)},scaleOfZoom:f,targetCenter:a,scaleOfMinZoom:d(g-r),pixelPathLength:u}}};let Ec;const Dc=()=>Ec||=new Kt({type:new r(Ft.projection.type,`type`)}),Oc=new Lt({fill:new Tr(128,2),line:new Tr(512,0),tile:new Tr(128,32),stencil:new Tr(128,1),circle:3});var kc=class{constructor(){this._tileMeshCache={}}get name(){return`vertical-perspective`}get transitionState(){return 1}get useSubdivision(){return!0}get shaderVariantName(){return`globe`}get shaderDefine(){return`#define GLOBE`}get shaderPreludeCode(){return Xs.projectionGlobe}get vertexShaderPreludeCode(){return Xs.projectionMercator.vertexSource}get subdivisionGranularity(){return Oc}get useGlobeControls(){return!0}destroy(){}_getMeshKey(e){return`${e.granularity.toString(36)}_${e.generateBorders?`b`:``}${e.extendToNorthPole?`n`:``}${e.extendToSouthPole?`s`:``}`}getMeshFromTileID(e,t,n,r,i){let a=(i===`stencil`?Oc.stencil:Oc.tile).getGranularityForZoomLevel(t.z),o=t.y===0&&r,s=t.y===(1<0}get currentProjection(){return this.useGlobeRendering?this._verticalPerspectiveProjection:this._mercatorProjection}get name(){return`globe`}get useSubdivision(){return this.currentProjection.useSubdivision}get shaderVariantName(){return this.currentProjection.shaderVariantName}get shaderDefine(){return this.currentProjection.shaderDefine}get shaderPreludeCode(){return this.currentProjection.shaderPreludeCode}get vertexShaderPreludeCode(){return this.currentProjection.vertexShaderPreludeCode}get subdivisionGranularity(){return this.currentProjection.subdivisionGranularity}get useGlobeControls(){return this.transitionState>0}destroy(){this._mercatorProjection.destroy(),this._verticalPerspectiveProjection.destroy()}getMeshFromTileID(e,t,n,r,i){return this.currentProjection.getMeshFromTileID(e,t,n,r,i)}setProjection(e){this._transitionable.setValue(`type`,e?.type||`mercator`)}updateTransitions(e){this._transitioning=this._transitionable.transitioned(e,this._transitioning)}hasTransition(){return this._transitioning.hasTransition()||this.currentProjection.hasTransition()}recalculate(e){this.properties=this._transitioning.possiblyEvaluate(e)}};function jc(e){let t=Lc(e.worldSize,e.center.lat);return 2*Math.PI*t}function Mc(e,t,n){let r=Ic(t),i=Ic(n),a=ln(r,i),o=Math.acos(a),s=jc(e);return o/(2*Math.PI)*s}function Nc(e,t){return[yr(e*Math.PI*2+Math.PI,Math.PI*2),2*Math.atan(Math.exp(Math.PI-t*Math.PI*2))-Math.PI*.5]}function Pc(e,t){let n=Math.cos(t),r=new Float64Array(3);return r[0]=Math.sin(e)*n,r[1]=Math.sin(t),r[2]=Math.cos(e)*n,r}function Fc(e,t,n,r,i){let a=1/(1<1e-6){let r=e[0]/n,i=e[2]/n,a=Math.acos(i),o=(r>0?a:-a)/Math.PI*180;return new V(Or(o,-180,180),t)}return new V(0,t)}function zc(e,t){return pe(St(),-e.lng,-e.lat,t)}function Bc(e){let t=e[0],n=e[1],r=e[2],i=e[3];return{lng:-Math.atan2(2*(i*t+n*r),1-2*(t*t+n*n))*180/Math.PI,lat:-Math.asin(M(2*(i*n-r*t),-1,1))*180/Math.PI,bearing:Math.atan2(2*(i*r+t*n),1-2*(n*n+r*r))*180/Math.PI}}const Vc=Math.PI*.98;function Hc(e,t){let n=e.cameraPosition,r=Nn(n);if(r<=1)return e.screenPointToLocation(t);let i=L();Rt(i,n);let a=e.getRayDirectionFromPixel(t),o=-ln(a,i),s=L();Ln(s,a,i,o);let c=Nn(s);if(c<1e-9)return e.screenPointToLocation(t);let l=Math.atan2(c,o),u=Math.asin(1/r)*.9;if(l=0?90:-90,s=e.locationToScreenPoint(new V(0,o)),c=t.x-s.x,l=t.y-s.y,d=c*c+l*l,f=M(1-(u-Math.abs(a))/12,0,1),p=f*f*(3-2*f),m=yr(r-i+180,360)-180,h=0;if(p>0&&n){let e=(c*n.y-l*n.x)/Math.max(d,400);h=(o>0?1:-1)*e*180/Math.PI}return i+(1-p)*m+p*h}function Gc(e){let t=L();return t[0]=e[0]*-e[3],t[1]=e[1]*-e[3],t[2]=e[2]*-e[3],{center:t,radius:Math.sqrt(1-e[3]*e[3])}}function Kc(e,t,n){let r=L();En(r,n,e);let i=L();return Ln(i,e,r,t/At(r)),i}function qc(e){return Math.cos(e*Math.PI/180)}function Jc(e,t){let n=qc(e),r=qc(t);return Ee(r/n)}function Yc(e,t){return 360/jc({worldSize:e,center:{lat:t}})}function Xc(e,t){let n=e.rotate(t.bearingInRadians),r=t.zoom+Jc(t.center.lat,0),i=wr(1/qc(t.center.lat),1/qc(Math.min(Math.abs(t.center.lat),60)),bn(r,7,3,0,1)),a=Yc(t.worldSize,t.center.lat);return new V(t.center.lng-n.x*a*i,M(t.center.lat+n.y*a,-u,u))}function Zc(e){let t=.5*e,n=Math.sin(t),r=Math.cos(t);return Math.log(n+r)-Math.log(r-n)}function Qc(e,t,n,r){let i=e.lat+n*r;if(Math.abs(n)>1){let a=e.lat+n,o=(Math.sign(a)===Math.sign(e.lat)?Math.abs(e.lat):-Math.abs(e.lat))*Math.PI/180,s=Math.abs(e.lat+n)*Math.PI/180,c=Zc(o+r*(s-o)),l=Zc(o),u=Zc(s),d=(c-l)/(u-l),f=e.lng+t*d;return new V(f,i)}{let n=e.lng+t*r;return new V(n,i)}}function $c(e,t,n=1){let r=ln(e,t),i=n*n,a=L(),o=L();Xt(o,t,r),En(a,e,o);let s=i-ln(a,a);if(s<0)return null;let c=ln(e,e)-i,l=-r+(r<0?1:-1)*Math.sqrt(s),u=c/l,d=l;return{tMin:Math.min(u,d),tMax:Math.max(u,d)}}var el=class{constructor(e){this._cachePrevious=new Map,this._cache=new Map,this._hadAnyChanges=!1,this._boundingVolumeFactory=e}swapBuffers(){if(!this._hadAnyChanges)return;let e=this._cachePrevious;this._cachePrevious=this._cache,this._cache=e,this._cache.clear(),this._hadAnyChanges=!1}getTileBoundingVolume(e,t,n,r){let i=`${e.z}_${e.x}_${e.y}_${r?.terrain?`t`:``}_${Math.round(n)}`,a=this._cache.get(i);if(a)return a;let o=this._cachePrevious.get(i);if(o)return this._cache.set(i,o),o;let s=this._boundingVolumeFactory(e,t,n,r);return this._cache.set(i,s),this._hadAnyChanges=!0,s}},tl=class e{constructor(e,t,n,r){this.min=n,this.max=r,this.points=e,this.planes=t}static fromAabb(t,n){let r=[];for(let e=0;e<8;e++)r.push([(e>>0&1)==1?n[0]:t[0],(e>>1&1)==1?n[1]:t[1],(e>>2&1)==1?n[2]:t[2]]);return new e(r,[[-1,0,0,n[0]],[1,0,0,-t[0]],[0,-1,0,n[1]],[0,1,0,-t[1]],[0,0,-1,n[2]],[0,0,1,-t[2]]],t,n)}static fromCenterSizeAngles(t,n,r){let i=pe([],r[0],r[1],r[2]),a=Et([],[n[0],0,0],i),o=Et([],[0,n[1],0],i),s=Et([],[0,0,n[2]],i),c=[...t],l=[...t];for(let e=0;e<8;e++)for(let n=0;n<3;n++){let r=t[n]+a[n]*((e>>0&1)==1?1:-1)+o[n]*((e>>1&1)==1?1:-1)+s[n]*((e>>2&1)==1?1:-1);c[n]=Math.min(c[n],r),l[n]=Math.max(l[n],r)}let u=[];for(let e=0;e<8;e++){let n=[...t];$n(n,n,Xt([],a,(e>>0&1)==1?1:-1)),$n(n,n,Xt([],o,(e>>1&1)==1?1:-1)),$n(n,n,Xt([],s,(e>>2&1)==1?1:-1)),u.push(n)}return new e(u,[[...a,-ln(a,u[0])],[...o,-ln(o,u[0])],[...s,-ln(s,u[0])],[-a[0],-a[1],-a[2],-ln(a,u[7])],[-o[0],-o[1],-o[2],-ln(o,u[7])],[-s[0],-s[1],-s[2],-ln(s,u[7])]],c,l)}intersectsFrustum(e){let t=!0,n=this.points.length,r=this.planes.length,i=e.planes.length,a=e.points.length;for(let r=0;r=0&&a++}if(a===0)return 0;a=0&&r++}if(r===0)return 0}return 1}intersectsPlane(e){let t=this.points.length,n=0;for(let r=0;r=0&&n++}return n===t?2:n===0?0:1}};function nl(e,t,n){let r=e-t;return r<0?-r:Math.max(0,r-n)}function rl(e,t,n,r,i){let a=e-n,o;return o=a<0?Math.min(-a,1+a-i):a>i?Math.min(Math.max(a-i,0),1-a):0,Math.max(o,nl(t,r,i))}var il=class{constructor(){this._boundingVolumeCache=new el(this._computeTileBoundingVolume)}prepareNextFrame(){this._boundingVolumeCache.swapBuffers()}distanceToTile2d(e,t,n,r){let i=1<4}allowWorldCopies(){return!1}getTileBoundingVolume(e,t,n,r){return this._boundingVolumeCache.getTileBoundingVolume(e,t,n,r)}_computeTileBoundingVolume(e,t,n,r){let i=Math.min(0,n),a=Math.max(0,n);if(r?.terrain){let n=new $t(e.z,t,e.z,e.x,e.y),o=r.terrain.getMinMaxElevation(n);i=o.minElevation??i,a=o.maxElevation??a}if(i/=Wt,a/=Wt,i+=1,a+=1,e.z<=0)return tl.fromAabb([-a,-a,-a],[a,a,a]);if(e.z===1)return tl.fromAabb([e.x===0?-a:0,e.y===0?0:-a,-a],[e.x===0?0:a,e.y===0?a:0,a]);{let t=[Fc(0,0,e.x,e.y,e.z),Fc(N,0,e.x,e.y,e.z),Fc(N,N,e.x,e.y,e.z),Fc(0,N,e.x,e.y,e.z)],n=[];for(let e of t)n.push(Xt([],e,a));if(a!==i)for(let e of t)n.push(Xt([],e,i));e.y===0&&n.push([0,1,0]),e.y===(1<=(1<{let n=M(e.lat,-u,u),r=M(+t,this.minZoom+Jc(0,n),this.maxZoom);return{center:new V(e.lng,n),zoom:r}},this.applyConstrain=(e,t)=>this._helper.applyConstrain(e,t),this._helper=new rc({calcMatrices:()=>this._calcMatrices(),defaultConstrain:(e,t)=>this.defaultConstrain(e,t)},e),this._coveringTilesDetailsProvider=new il}clone(){let t=new e;return t.apply(this,!1),t}apply(e,t){this._helper.apply(e,t)}get projectionMatrix(){return this._projectionMatrix}get modelViewProjectionMatrix(){return this._globeViewProjMatrixF64}get inverseProjectionMatrix(){return this._globeProjMatrixInverted}get cameraPosition(){let e=L();return e[0]=this._cameraPosition[0],e[1]=this._cameraPosition[1],e[2]=this._cameraPosition[2],e}get cameraToCenterDistance(){return this._helper.cameraToCenterDistance}getProjectionData(e){let{overscaledTileID:t,applyGlobeMatrix:n}=e,r=this._helper.getMercatorTileCoordinates(t);return{mainMatrix:this._globeViewProjMatrix32f,tileMercatorCoords:r,clippingPlane:this._cachedClippingPlane,projectionTransition:+!!n,fallbackMatrix:this._globeViewProjMatrix32f,clipAntimeridian:t?.canonical.z===0}}_computeClippingPlane(e){let t=this.pitchInRadians,n=this.cameraToCenterDistance/e,r=Math.sin(t)*n,i=Math.cos(t)*n+1,a=1/Math.sqrt(r*r+i*i)*1,o=-r,s=i,c=Math.sqrt(o*o+s*s);o/=c,s/=c;let l=[0,o,s];Ht(l,l,[0,0,0],-this.bearingInRadians),Sn(l,l,[0,0,0],-1*this.center.lat*Math.PI/180),ir(l,l,[0,0,0],this.center.lng*Math.PI/180);let u=1/Nn(l);return Xt(l,l,u),[...l,-a*u]}isLocationOccluded(e){return!this.isSurfacePointVisible(Ic(e))}transformLightDirection(e){let t=this._helper._center.lng*Math.PI/180,n=this._helper._center.lat*Math.PI/180,r=Math.cos(n),i=[Math.sin(t)*r,Math.sin(n),Math.cos(t)*r],a=[i[2],0,-i[0]],o=[0,0,0];Gn(o,a,i),Rt(a,a),Rt(o,o);let s=[a[0]*e[0]+o[0]*e[1]+i[0]*e[2],a[1]*e[0]+o[1]*e[1]+i[1]*e[2],a[2]*e[0]+o[2]*e[1]+i[2]*e[2]],c=[0,0,0];return Rt(c,s),c}getPixelScale(){return 1/Math.cos(this._helper._center.lat*Math.PI/180)}getCircleRadiusCorrection(){return Math.cos(this._helper._center.lat*Math.PI/180)}getPitchedTextCorrection(e,t,n){let r=nr(e,t,n.canonical),i=Nc(r.x,r.y);return this.getCircleRadiusCorrection()/Math.cos(i[1])}projectTileCoordinates(e,t,n,r){let i=n.canonical,a=Fc(e,t,i.x,i.y,i.z),o=1+(r??0)/Wt,s=[a[0]*o,a[1]*o,a[2]*o,1];Gt(s,s,this._globeViewProjMatrixF64);let c=this._cachedClippingPlane,u=c[0]*a[0]+c[1]*a[1]+c[2]*a[2]+c[3]<0;return{point:new l(s[0]/s[3],s[1]/s[3]),signedDistanceFromCamera:s[3],isOccluded:u}}_calcMatrices(){if(!this._helper._width||!this._helper._height)return;let e=Lc(this.worldSize,this.center.lat),t=vt();this._helper.autoCalculateNearFarZ&&(this._helper._nearZ=.5,this._helper._farZ=this.cameraToCenterDistance+e*2),vn(t,this.fovInRadians,this.width/this.height,this._helper._nearZ,this._helper._farZ);let n=this.centerOffset;t[8]=-n.x*2/this._helper._width,t[9]=n.y*2/this._helper._height,this._projectionMatrix=Sr(t),this._globeProjMatrixInverted=vt(),w(this._globeProjMatrixInverted,t),Le(t,t,[0,0,-this.cameraToCenterDistance]),we(t,t,this.rollInRadians),a(t,t,-this.pitchInRadians),we(t,t,this.bearingInRadians),Le(t,t,[0,0,-e]);let r=L();r[0]=e,r[1]=e,r[2]=e,a(t,t,this.center.lat*Math.PI/180),pn(t,t,-this.center.lng*Math.PI/180),ke(t,t,r),this._globeViewProjMatrixF64=t,this._globeViewProjMatrix32f=new Float32Array(t),this._globeViewProjMatrixF64Inverted=vt(),w(this._globeViewProjMatrixF64Inverted,t);let i=L();this._cameraPosition=L(),this._cameraPosition[2]=this.cameraToCenterDistance/e,Ht(this._cameraPosition,this._cameraPosition,i,-this.rollInRadians),Sn(this._cameraPosition,this._cameraPosition,i,this.pitchInRadians),Ht(this._cameraPosition,this._cameraPosition,i,-this.bearingInRadians),$n(this._cameraPosition,this._cameraPosition,[0,0,1]),Sn(this._cameraPosition,this._cameraPosition,i,-this.center.lat*Math.PI/180),ir(this._cameraPosition,this._cameraPosition,i,this.center.lng*Math.PI/180),this._cachedClippingPlane=this._computeClippingPlane(e);let o=Sr(this._globeViewProjMatrixF64Inverted);ke(o,o,[1,1,-1]),this._cachedFrustum=oc.fromInvProjectionMatrix(o,1,0,this._cachedClippingPlane,!0)}calculateFogMatrix(e){I(`calculateFogMatrix is not supported on globe projection.`);let t=vt();return $e(t),t}getVisibleUnwrappedCoordinates(e){return[new Tt(0,e)]}getCameraFrustum(){return this._cachedFrustum}getClippingPlane(){return this._cachedClippingPlane}getCoveringTilesDetailsProvider(){return this._coveringTilesDetailsProvider}recalculateZoomAndCenter(e){if(e){I(`terrain is not fully supported on vertical perspective projection.`);return}this._helper.recalculateZoomAndCenter(0)}maxPitchScaleFactor(){return 1}getCameraPoint(){return this._helper.getCameraPoint()}getCameraAltitude(){return this._helper.getCameraAltitude()}getCameraLngLat(){return this._helper.getCameraLngLat()}lngLatToCameraDepth(e,t){if(!this._globeViewProjMatrixF64)return 1;let n=Ic(e);Xt(n,n,1+t/Wt);let r=St();return Gt(r,[n[0],n[1],n[2],1],this._globeViewProjMatrixF64),r[2]/r[3]}populateCache(e){}getBounds(){let e=this.width*.5,t=this.height*.5,n=[new l(0,0),new l(e,0),new l(this.width,0),new l(this.width,t),new l(this.width,this.height),new l(e,this.height),new l(0,this.height),new l(0,t)],r=[];for(let e of n)r.push(this.unprojectScreenPoint(e));let i=0,a=0,o=0,s=0,c=this.center;for(let e of r){let t=tr(c.lng,e.lng),n=tr(c.lat,e.lat);ti&&(i=t),no&&(o=n)}let u=[c.lng+a,c.lat+s,c.lng+i,c.lat+o];return this.isSurfacePointOnScreen([0,1,0])&&(u[3]=90,u[0]=-180,u[2]=180),this.isSurfacePointOnScreen([0,-1,0])&&(u[1]=-90,u[0]=-180,u[2]=180),new _a(u)}calculateCenterFromCameraLngLatAlt(e,t,n,r){return this._helper.calculateCenterFromCameraLngLatAlt(e,t,n,r)}setLocationAtPoint(e,t,n){let r=Ic(this.unprojectScreenPoint(t)),i=Ic(e),a=L();cr(a);let o=L();ir(o,r,a,-this.center.lng*Math.PI/180),Sn(o,o,a,this.center.lat*Math.PI/180);let s=i[0]*i[0]+i[2]*i[2],c=o[0]*o[0];if(s=-_&&m<=_,y=g>=-_&&g<=_,b,x;if(v&&y){let e=this.center.lng*Math.PI/180,t=this.center.lat*Math.PI/180,n=jn(d,e),r=jn(m,t),i=jn(f,e),a=jn(g,t);n+r=0}isSurfacePointOnScreen(e){if(!this.isSurfacePointVisible(e))return!1;let t=St();return Gt(t,[...e,1],this._globeViewProjMatrixF64),t[0]/=t[3],t[1]/=t[3],t[2]/=t[3],t[0]>-1&&t[0]<1&&t[1]>-1&&t[1]<1&&t[2]>-1&&t[2]<1}unprojectScreenPoint(e){let t=this._cameraPosition,n=this.getRayDirectionFromPixel(e),r=$c(t,n);if(r){let e=L();$n(e,t,[n[0]*r.tMin,n[1]*r.tMin,n[2]*r.tMin]);let i=L();return Rt(i,e),Rc(i)}let i=this._cachedClippingPlane,a=i[0]*n[0]+i[1]*n[1]+i[2]*n[2],o=-tt(i,t)/a,s=L();if(o>0)$n(s,t,[n[0]*o,n[1]*o,n[2]*o]);else{let e=L();$n(e,t,[n[0]*2,n[1]*2,n[2]*2]);let r=tt(this._cachedClippingPlane,e);En(s,e,[this._cachedClippingPlane[0]*r,this._cachedClippingPlane[1]*r,this._cachedClippingPlane[2]*r])}let c=Gc(i);return Rc(Kc(c.center,c.radius,s))}getProjectionDataForCustomLayer(e=!0){let t=this.getProjectionData({overscaledTileID:new $t(0,0,0,0,0),applyGlobeMatrix:e});return t.tileMercatorCoords=[0,0,1,1],t}getFastPathSimpleProjectionMatrix(e){}};function sl(e,t){let n=L();Ln(n,e.origin,e.direction,t);let r=Nn(n),i=L();Xt(i,n,1/r);let a=Rc(i),o=B.fromLngLat(a),s=new B(o.x,M(o.y,0,.999999999)),c=gc(e.index,e.exaggeration,s.x,s.y),l=Math.abs(a.lat)>85.051129?0:c.elevation;return{sample:{...c,elevation:l},radius:r,mercator:s}}function cl(e,t){let{sample:n,radius:r}=sl(e,t);return _c(n,(r-1)*Wt)}var ll=class e{get pixelsToClipSpaceMatrix(){return this._helper.pixelsToClipSpaceMatrix}get clipSpaceToPixelsMatrix(){return this._helper.clipSpaceToPixelsMatrix}get pixelsToGLUnits(){return this._helper.pixelsToGLUnits}get centerOffset(){return this._helper.centerOffset}get size(){return this._helper.size}get rotationMatrix(){return this._helper.rotationMatrix}get centerPoint(){return this._helper.centerPoint}get pixelsPerMeter(){return this._helper.pixelsPerMeter}setMinZoom(e){this._helper.setMinZoom(e)}setMaxZoom(e){this._helper.setMaxZoom(e)}setMinPitch(e){this._helper.setMinPitch(e)}setMaxPitch(e){this._helper.setMaxPitch(e)}setRenderWorldCopies(e){this._helper.setRenderWorldCopies(e)}setBearing(e){this._helper.setBearing(e)}setPitch(e){this._helper.setPitch(e)}setRoll(e){this._helper.setRoll(e)}setFov(e){this._helper.setFov(e)}setZoom(e){this._helper.setZoom(e)}setCenter(e){this._helper.setCenter(e)}setElevation(e){this._helper.setElevation(e)}setMinElevationForCurrentTile(e){this._helper.setMinElevationForCurrentTile(e)}setPadding(e){this._helper.setPadding(e)}interpolatePadding(e,t,n){this._helper.interpolatePadding(e,t,n)}isPaddingEqual(e){return this._helper.isPaddingEqual(e)}resize(e,t,n=!0){this._helper.resize(e,t,n)}getMaxBounds(){return this._helper.getMaxBounds()}setMaxBounds(e){this._helper.setMaxBounds(e)}setConstrainOverride(e){this._helper.setConstrainOverride(e)}overrideNearFarZ(e,t){this._helper.overrideNearFarZ(e,t)}clearNearFarZOverride(){this._helper.clearNearFarZOverride()}getCameraQueryGeometry(e){return this._helper.getCameraQueryGeometry(this.getCameraPoint(),e)}get tileSize(){return this._helper.tileSize}get tileZoom(){return this._helper.tileZoom}get scale(){return this._helper.scale}get worldSize(){return this._helper.worldSize}get width(){return this._helper.width}get height(){return this._helper.height}get lngRange(){return this._helper.lngRange}get latRange(){return this._helper.latRange}get minZoom(){return this._helper.minZoom}get maxZoom(){return this._helper.maxZoom}get zoom(){return this._helper.zoom}get center(){return this._helper.center}get minPitch(){return this._helper.minPitch}get maxPitch(){return this._helper.maxPitch}get pitch(){return this._helper.pitch}get pitchInRadians(){return this._helper.pitchInRadians}get roll(){return this._helper.roll}get rollInRadians(){return this._helper.rollInRadians}get bearing(){return this._helper.bearing}get bearingInRadians(){return this._helper.bearingInRadians}get fov(){return this._helper.fov}get fovInRadians(){return this._helper.fovInRadians}get elevation(){return this._helper.elevation}get minElevationForCurrentTile(){return this._helper.minElevationForCurrentTile}get padding(){return this._helper.padding}get unmodified(){return this._helper.unmodified}get renderWorldCopies(){return this._helper.renderWorldCopies}get cameraToCenterDistance(){return this._helper.cameraToCenterDistance}get constrainOverride(){return this._helper.constrainOverride}get nearZ(){return this._helper.nearZ}get farZ(){return this._helper.farZ}get autoCalculateNearFarZ(){return this._helper.autoCalculateNearFarZ}get isGlobeRendering(){return this._globeness>0}setTransitionState(e){this._globeness=e,this._calcMatrices(),this._verticalPerspectiveTransform.getCoveringTilesDetailsProvider().prepareNextFrame(),this._mercatorTransform.getCoveringTilesDetailsProvider().prepareNextFrame()}get currentTransform(){return this.isGlobeRendering?this._verticalPerspectiveTransform:this._mercatorTransform}constructor(e){this._globeness=1,this.defaultConstrain=(e,t)=>this.currentTransform.defaultConstrain(e,t),this.applyConstrain=(e,t)=>this._helper.applyConstrain(e,t),this._helper=new rc({calcMatrices:()=>this._calcMatrices(),defaultConstrain:(e,t)=>this.defaultConstrain(e,t)},e),this._globeness=1,this._mercatorTransform=new yc,this._verticalPerspectiveTransform=new ol}clone(){let t=new e;return t._globeness=this._globeness,t.apply(this,!1),t}apply(e,t){this._helper.apply(e,t),this._mercatorTransform.apply(this,!1),this._verticalPerspectiveTransform.apply(this,!1)}get projectionMatrix(){return this.currentTransform.projectionMatrix}get modelViewProjectionMatrix(){return this.currentTransform.modelViewProjectionMatrix}get inverseProjectionMatrix(){return this.currentTransform.inverseProjectionMatrix}get cameraPosition(){return this.currentTransform.cameraPosition}getProjectionData(e){let t=this._mercatorTransform.getProjectionData(e),n=this._verticalPerspectiveTransform.getProjectionData(e);return{mainMatrix:this.isGlobeRendering?n.mainMatrix:t.mainMatrix,clippingPlane:n.clippingPlane,tileMercatorCoords:n.tileMercatorCoords,projectionTransition:e.applyGlobeMatrix?this._globeness:0,fallbackMatrix:t.fallbackMatrix,clipAntimeridian:n.clipAntimeridian}}isLocationOccluded(e){return this.currentTransform.isLocationOccluded(e)}transformLightDirection(e){return this.currentTransform.transformLightDirection(e)}getPixelScale(){return wr(this._mercatorTransform.getPixelScale(),this._verticalPerspectiveTransform.getPixelScale(),this._globeness)}getCircleRadiusCorrection(){return wr(this._mercatorTransform.getCircleRadiusCorrection(),this._verticalPerspectiveTransform.getCircleRadiusCorrection(),this._globeness)}getPitchedTextCorrection(e,t,n){let r=this._mercatorTransform.getPitchedTextCorrection(e,t,n),i=this._verticalPerspectiveTransform.getPitchedTextCorrection(e,t,n);return wr(r,i,this._globeness)}projectTileCoordinates(e,t,n,r){return this.currentTransform.projectTileCoordinates(e,t,n,r)}_calcMatrices(){!this._helper._width||!this._helper._height||(this._verticalPerspectiveTransform.apply(this,!1),this._helper._nearZ=this._verticalPerspectiveTransform.nearZ,this._helper._farZ=this._verticalPerspectiveTransform.farZ,this._mercatorTransform.apply(this,!0,this.isGlobeRendering),this._helper._nearZ=this._mercatorTransform.nearZ,this._helper._farZ=this._mercatorTransform.farZ)}calculateFogMatrix(e){return this.currentTransform.calculateFogMatrix(e)}getVisibleUnwrappedCoordinates(e){return this.currentTransform.getVisibleUnwrappedCoordinates(e)}getCameraFrustum(){return this.currentTransform.getCameraFrustum()}getClippingPlane(){return this.currentTransform.getClippingPlane()}getCoveringTilesDetailsProvider(){return this.currentTransform.getCoveringTilesDetailsProvider()}recalculateZoomAndCenter(e){this.currentTransform.recalculateZoomAndCenter(e)}maxPitchScaleFactor(){return this._mercatorTransform.maxPitchScaleFactor()}getCameraPoint(){return this._helper.getCameraPoint()}getCameraAltitude(){return this._helper.getCameraAltitude()}getCameraLngLat(){return this._helper.getCameraLngLat()}lngLatToCameraDepth(e,t){return this.currentTransform.lngLatToCameraDepth(e,t)}populateCache(e){this._mercatorTransform.populateCache(e),this._verticalPerspectiveTransform.populateCache(e)}getBounds(){return this.currentTransform.getBounds()}calculateCenterFromCameraLngLatAlt(e,t,n,r){return this._helper.calculateCenterFromCameraLngLatAlt(e,t,n,r)}setLocationAtPoint(e,t,n){if(!this.isGlobeRendering){this._mercatorTransform.setLocationAtPoint(e,t,n),this.apply(this._mercatorTransform,!1);return}this._verticalPerspectiveTransform.setLocationAtPoint(e,t,n),this.apply(this._verticalPerspectiveTransform,!1)}locationToScreenPoint(e,t){return this.currentTransform.locationToScreenPoint(e,t)}screenPointToMercatorCoordinate(e,t){return this.currentTransform.screenPointToMercatorCoordinate(e,t)}screenTerrainPointToMercatorCoordinate(e,t){return this.currentTransform.screenTerrainPointToMercatorCoordinate(e,t)}screenPointToLocation(e,t){return this.currentTransform.screenPointToLocation(e,t)}screenPointToLocationAtElevation(e,t){return this.currentTransform.screenPointToLocationAtElevation(e,t)}isPointOnMapSurface(e,t){return this.currentTransform.isPointOnMapSurface(e,t)}getRayDirectionFromPixel(e){return this._verticalPerspectiveTransform.getRayDirectionFromPixel(e)}getProjectionDataForCustomLayer(e=!0){let t=this._mercatorTransform.getProjectionDataForCustomLayer(e);if(!this.isGlobeRendering)return t;let n=this._verticalPerspectiveTransform.getProjectionDataForCustomLayer(e);return n.fallbackMatrix=t.mainMatrix,n.projectionTransition=this._globeness,n}getFastPathSimpleProjectionMatrix(e){return this.currentTransform.getFastPathSimpleProjectionMatrix(e)}},ul=class e{get useGlobeControls(){return!0}handlePanInertia(e,t){let n=Xc(e,t);return Math.abs(n.lng-t.center.lng)>180&&(n.lng=t.center.lng+179.5*Math.sign(n.lng-t.center.lng)),{easingCenter:n,easingOffset:new l(0,0)}}handleMapControlsRollPitchBearingZoom(e,t){let n=e.around,r=t.screenPointToLocation(n);e.bearingDelta&&t.setBearing(t.bearing+e.bearingDelta),e.pitchDelta&&t.setPitch(t.pitch+e.pitchDelta),e.rollDelta&&t.setRoll(t.roll+e.rollDelta);let i=t.zoom;e.zoomDelta&&t.setZoom(t.zoom+e.zoomDelta);let a=t.zoom-i;if(a===0)return;let o=tr(t.center.lng,r.lng),s=o/(Math.abs(o/180)+1),c=tr(t.center.lat,r.lat),l=t.getRayDirectionFromPixel(n),f=t.cameraPosition,p=ln(f,l)*-1,m=L();$n(m,f,[l[0]*p,l[1]*p,l[2]*p]);let h=Nn(m),g=h-1,_=Math.exp(-Math.max(g-.3,0)*.5),v=bn(h,.95,.999,0,1),y=Lc(t.worldSize,t.center.lat)/Math.min(t.width,t.height),b=bn(y,.9,.5,1,.25),x=Math.min(_,wr(1,b,v)),S=(1-d(-a))*x,C=t.center.lat,w=t.zoom,T=new V(t.center.lng+s*S,M(t.center.lat+c*S,-u,u));t.setLocationAtPoint(r,n);let E=t.center,D=bn(Math.abs(o),45,85,0,1),ee=Math.max(D,v)**.25,O=tr(E.lng,T.lng),k=tr(E.lat,T.lat);t.setCenter(new V(E.lng+O*ee,E.lat+k*ee).wrap()),t.setZoom(w+Jc(C,t.center.lat))}handleMapControlsPan(e,t,n){e.panDelta&&Uc(t,n,t.isPointOnMapSurface(e.around)?e.around:t.centerPoint,e.panDelta)}cameraForBoxAndBearing(t,n,r,i,a){let o=wc(t,n,r,i,a),s=n.left/a.width*2-1,c=(a.width-n.right)/a.width*2-1,l=n.top/a.height*-2+1,u=(a.height-n.bottom)/a.height*-2+1,d=tr(r.getWest(),r.getEast())<0,f=d?r.getEast():r.getWest(),p=d?r.getWest():r.getEast(),m=Math.max(r.getNorth(),r.getSouth()),h=Math.min(r.getNorth(),r.getSouth()),g=f+tr(f,p)*.5,_=m+tr(m,h)*.5,v=a.clone();v.setCenter(o.center),v.setBearing(o.bearing),v.setPitch(0),v.setRoll(0),v.setZoom(o.zoom);let y=v.modelViewProjectionMatrix,b=[Ic(r.getNorthWest()),Ic(r.getNorthEast()),Ic(r.getSouthWest()),Ic(r.getSouthEast()),Ic(new V(p,_)),Ic(new V(f,_)),Ic(new V(g,m)),Ic(new V(g,h))],x=Ic(o.center),S=1/0;for(let t of b)s<0&&(S=e.getLesserNonNegativeNonNull(S,e.solveVectorScale(t,x,y,`x`,s))),c>0&&(S=e.getLesserNonNegativeNonNull(S,e.solveVectorScale(t,x,y,`x`,c))),l>0&&(S=e.getLesserNonNegativeNonNull(S,e.solveVectorScale(t,x,y,`y`,l))),u<0&&(S=e.getLesserNonNegativeNonNull(S,e.solveVectorScale(t,x,y,`y`,u)));if(!Number.isFinite(S)||S===0){Sc();return}return o.zoom=Math.min(v.zoom+Ee(S),t.maxZoom),o}handleJumpToCenterZoom(e,t){let n=e.center.lat,r=e.applyConstrain(t.center?V.convert(t.center):e.center,e.zoom).center;e.setCenter(r.wrap());let i=t.zoom===void 0?e.zoom+Jc(n,r.lat):+t.zoom;e.zoom!==i&&e.setZoom(i)}handleEaseTo(e,t){let n=e.zoom,r=e.center,i=e.padding,a={roll:e.roll,pitch:e.pitch,bearing:e.bearing},o={roll:t.roll===void 0?e.roll:t.roll,pitch:t.pitch===void 0?e.pitch:t.pitch,bearing:t.bearing===void 0?e.bearing:t.bearing},c=t.zoom!==void 0,u=!e.isPaddingEqual(t.padding),f=!1,p=t.center?V.convert(t.center):r,m=e.applyConstrain(p,n).center;tc(e,m);let h=e.clone();h.setCenter(m),h.setZoom(c?+t.zoom:n+Jc(r.lat,p.lat)),h.setBearing(t.bearing);let g=new l(M(e.centerPoint.x+t.offsetAsPoint.x,0,e.width),M(e.centerPoint.y+t.offsetAsPoint.y,0,e.height));h.setLocationAtPoint(m,g);let _=(t.offset&&t.offsetAsPoint.mag())>0?h.center:m,v=c?+t.zoom:n+Jc(r.lat,_.lat),y=n+Jc(r.lat,0),b=v+Jc(_.lat,0),x=tr(r.lng,_.lng),S=tr(r.lat,_.lat),C=d(b-y);return f=v!==n,{easeFunc:n=>{if(s(a,o)||Cc({startEulerAngles:a,endEulerAngles:o,tr:e,k:n,useSlerp:a.roll!=o.roll}),u&&e.interpolatePadding(i,t.padding,n),t.around)I(`Easing around a point is not supported under globe projection.`),e.setLocationAtPoint(t.around,t.aroundPoint);else{let t=n*(b>y?Math.min(2,C):Math.max(.5,C))**(1-n),i=Qc(r,x,S,t);e.setCenter(i.wrap())}if(f){let t=on.number(y,b,n)+Jc(0,e.center.lat);e.setZoom(t)}},isZooming:f,elevationCenter:_}}handleFlyTo(e,t){let n=t.zoom!==void 0,r=e.center,i=e.zoom,a=e.padding,o=!e.isPaddingEqual(t.padding),s=e.applyConstrain(V.convert(t.center||t.locationAtOffset),i).center,c=n?+t.zoom:e.zoom+Jc(e.center.lat,s.lat),u=e.clone();u.setCenter(s),u.setZoom(c),u.setBearing(t.bearing);let f=new l(M(e.centerPoint.x+t.offsetAsPoint.x,0,e.width),M(e.centerPoint.y+t.offsetAsPoint.y,0,e.height));u.setLocationAtPoint(s,f);let p=u.center;tc(e,p);let m=Mc(e,r,p),h=i+Jc(r.lat,0),g=c+Jc(p.lat,0),_=d(g-h),v=typeof t.minZoom==`number`?+t.minZoom:e.minZoom,y=Math.max(v,e.minZoom)+Jc(p.lat,0),b=Math.min(y,h,g)+Jc(0,p.lat),x=e.applyConstrain(p,b).zoom+Jc(p.lat,0),S=d(x-h),C=tr(r.lng,p.lng),w=tr(r.lat,p.lat);return{easeFunc:(n,i,s,l)=>{let u=Qc(r,C,w,s);o&&e.interpolatePadding(a,t.padding,n);let d=n===1?p:u;e.setCenter(d.wrap());let f=h+Ee(i);e.setZoom(n===1?c:f+Jc(0,d.lat))},scaleOfZoom:_,targetCenter:p,scaleOfMinZoom:S,pixelPathLength:m}}static solveVectorScale(e,t,n,r,i){let a=i,o=r===`x`?[n[0],n[4],n[8],n[12]]:[n[1],n[5],n[9],n[13]],s=[n[3],n[7],n[11],n[15]],c=e[0]*o[0]+e[1]*o[1]+e[2]*o[2],l=e[0]*s[0]+e[1]*s[1]+e[2]*s[2],u=t[0]*o[0]+t[1]*o[1]+t[2]*o[2],d=t[0]*s[0]+t[1]*s[1]+t[2]*s[2],f=(u+o[3]-a*d-a*s[3])/(u-c-a*d+a*l);return u+a*l===c+a*d||s[3]*(c-u)+o[3]*(d-l)+c*d===u*l?null:f}static getLesserNonNegativeNonNull(e,t){return t!==null&&t>=0&&t{for(let e in this.tileManagers){let t=this.tileManagers[e].getSource().type;(t===`vector`||t===`geojson`)&&this.tileManagers[e].reload()}},this.map=e,this.dispatcher=new ra(ea(),e._getMapId()),this.dispatcher.registerMessageHandler(`GG`,(e,t)=>this.getGlyphs(e,t)),this.dispatcher.registerMessageHandler(`GI`,(e,t)=>this.getImages(e,t)),this.dispatcher.registerMessageHandler(`GDA`,(e,t)=>this.getDashes(e,t)),this.imageManager=new bi,this.imageManager.setEventedParent(this),this.imageManager.setMissingImageResolver(e._missingStyleImageResolver),this.patternAtlas=new xi(this.imageManager);let n=e._container?.lang||typeof document<`u`&&document.documentElement?.lang||void 0;this.glyphManager=new Ii(e._requestManager,t.localIdeographFontFamily,n),this.lineAtlas=new Ui(256,512),this.crossTileSymbolIndex=new Bs,this._setInitialValues(),this._resetUpdates(),this.dispatcher.broadcast(`SR`,Pe()),fo().on(co,this._rtlPluginLoaded),this.on(`data`,e=>{if(e.dataType!==`source`||e.sourceDataType!==`metadata`)return;let t=this.tileManagers[e.sourceId];if(!t)return;let n=t.getSource();if(n?.vectorLayerIds)for(let e in this._layers){let t=this._layers[e];t.source===n.id&&this._validateLayer(t)}})}_setInitialValues(){this._layers={},this._order=[],this.tileManagers={},this.zoomHistory=new Pn,this._imagesListDirty=!1,this._globalState={},this._serializedLayers={},this.stylesheet=null,this.light=null,this.sky=null,this.projection&&(this.projection.destroy(),delete this.projection),this._loaded=!1,this._changed=!1,this._updatedLayers={},this._updatedSources={},this._changedImages={},this._glyphsDidChange=!1,this._updatedPaintProps={},this._layerOrderChanged=!1,this._symbolPlacementTriggered=!1,this._placedProjectionTransition=void 0,this.crossTileSymbolIndex=new((this.crossTileSymbolIndex?.constructor)||Object),this.pauseablePlacement=void 0,this.placement=void 0,this.z=0}setGlobalStateProperty(e,t){this._checkLoaded();let n=t===null?this.stylesheet.state?.[e]?.default??null:t;if(Ve(n,this._globalState[e]))return this;this._globalState[e]=n,this._applyGlobalStateChanges([e])}getGlobalState(){return this._globalState}setGlobalState(e){this._checkLoaded();let t=[];for(let n in e)Ve(this._globalState[n],e[n].default)||(t.push(n),this._globalState[n]=e[n].default);this._applyGlobalStateChanges(t)}_applyGlobalStateChanges(e){if(e.length===0)return;let t=new Set,n={};for(let r of e){n[r]=this._globalState[r];for(let e in this._layers){let n=this._layers[e],i=n.getLayoutAffectingGlobalStateRefs(),a=n.getPaintAffectingGlobalStateRefs(),o=n.getVisibilityAffectingGlobalStateRefs();if(i.has(r)&&t.add(n.source),a.has(r))for(let{name:e,value:t}of a.get(r))this._updatePaintProperty(n,e,t);o?.has(r)&&(n.recalculateVisibility(),this._updateLayer(n))}}this.dispatcher.broadcast(`UGS`,n);for(let e in this.tileManagers)t.has(e)&&(this._reloadSource(e),this._changed=!0)}async loadURL(e,t={},n){this.fire(new qr(`dataloading`)),t.validate=typeof t.validate!=`boolean`||t.validate,this._loadStyleRequest=new AbortController;let r=this._loadStyleRequest;try{let i=await this.map._requestManager.transformRequest(e,`Style`);Ke(r.signal);let a=await b(i,r);this._loadStyleRequest===r&&(this._loadStyleRequest=null),this._load(a.data,t,n)}catch(e){this._loadStyleRequest===r&&(this._loadStyleRequest=null),e&&!r.signal.aborted&&this.fire(new H(qn(e)))}}loadJSON(e,t={},n){this.fire(new qr(`dataloading`)),this._frameRequest=new AbortController,Rr.frameAsync(this._frameRequest,this.map._ownerWindow).then(()=>{this._frameRequest=null,t.validate=t.validate!==!1,this._load(e,t,n)}).catch(()=>{})}loadEmpty(){this.fire(new qr(`dataloading`)),this._load(pl,{validate:!1})}_load(e,t,n){let r=t.transformStyle?t.transformStyle(n,e):e;if(!(t.validate&&Zt(this,r))){r={...r},this._loaded=!0,this.stylesheet=r;for(let e in r.sources)this.addSource(e,r.sources[e],{validate:!1});r.sprite?this._loadSprite(r.sprite):this.imageManager.setLoaded(!0),this.glyphManager.setURL(r.glyphs),this.glyphManager.setFontFaces(r[`font-faces`]),this._createLayers(),this.light=new zi(this.stylesheet.light??{},this._globalState),this._setProjectionInternal(this.stylesheet.projection?.type||`mercator`),this.sky=new Hi(this.stylesheet.sky,this._globalState),this.map.setTerrain(this.stylesheet.terrain??null,{validate:!1}),this.fire(new qr(`data`)),this.fire(new Kr)}}_createLayers(){let e=ri(this.stylesheet.layers);this.setGlobalState(this.stylesheet.state??null),this.dispatcher.broadcast(`SL`,e),this._order=e.map(e=>e.id),this._layers={},this._serializedLayers=null;for(let t of e){let e=Je(t,this._globalState);if(e.setEventedParent(this,{layer:{id:t.id}}),this._layers[t.id]=e,Ue(e)&&this.tileManagers[e.source]){let n=t.paint?.[`raster-fade-duration`]??e.paint.get(`raster-fade-duration`);this.tileManagers[e.source].setRasterFadeDuration(n)}}}async _loadSprite(e,t=!1,n=void 0){this.imageManager.setLoaded(!1);let r=new AbortController;this._spriteRequest=r;let i;try{let n=await vi(e,this.map._requestManager,this.map.getPixelRatio(),r);if(!n)return;for(let e in n){let{loaded:r,removed:i}=this.imageManager.setSpriteImages(e,n[e]);this._markImagesChanged(i),t&&this._markImagesChanged(r)}}catch(e){i=e,r.signal.aborted||this.fire(new H(i))}finally{this._spriteRequest=null,this.imageManager.setLoaded(!0),t&&(this._changed=!0),this.dispatcher.broadcast(`SI`,this.imageManager.listImages()),this.fire(new qr(`data`)),n?.(i)}}_unloadSprite(){this._markImagesChanged(this.imageManager.removeAllSpriteImages()),this._imagesListDirty=!0,this._changed=!0,this.fire(new qr(`data`))}_validateLayer(e){let t=this.tileManagers[e.source];if(!t)return;let n=e.sourceLayer;if(!n)return;let r=t.getSource();(r.type===`geojson`||r.vectorLayerIds&&!r.vectorLayerIds.includes(n))&&this.fire(new H(Error(`Source layer "${n}" does not exist on source "${r.id}" as specified by style layer "${e.id}".`)))}loaded(){if(!this._loaded||Object.keys(this._updatedSources).length)return!1;for(let e in this.tileManagers)if(!this.tileManagers[e].loaded())return!1;return this.imageManager.isLoaded()}_serializeByIds(e,t=!1){let n=this._serializedAllLayers();if(!e||e.length===0)return Object.values(t?ge(n):n);let r=[];for(let i of e)if(n[i]){let e=t?ge(n[i]):n[i];r.push(e)}return r}_serializedAllLayers(){let e=this._serializedLayers;if(e)return e;e=this._serializedLayers={};let t=Object.keys(this._layers);for(let n of t){let t=this._layers[n];t.type!==`custom`&&(e[n]=t.serialize())}return e}hasTransitions(){if(this.light?.hasTransition()||this.sky?.hasTransition()||this.projection?.hasTransition())return!0;for(let e in this.tileManagers)if(this.tileManagers[e].hasTransition())return!0;for(let e in this._layers)if(this._layers[e].hasTransition())return!0;return!1}_checkLoaded(){if(!this._loaded)throw Error(`Style is not done loading.`)}update(e){if(!this._loaded)return;let t=this._changed;if(t){this._imagesListDirty&&=(this.dispatcher.broadcast(`SI`,this.imageManager.listImages()),!1);let t=Object.keys(this._updatedLayers),n=Object.keys(this._removedLayers);(t.length||n.length)&&this._updateWorkerLayers(t,n);for(let e in this._updatedSources){let t=this._updatedSources[e];if(t===`reload`)this._reloadSource(e);else if(t===`clear`)this._clearSource(e);else throw Error(`Invalid action ${t}`)}this._updateTilesForChangedImages(),this._updateTilesForChangedGlyphs();for(let t in this._updatedPaintProps)this._layers[t].updateTransitions(e);this.light.updateTransitions(e),this.sky.updateTransitions(e),this._resetUpdates()}let n={};for(let e in this.tileManagers){let t=this.tileManagers[e];n[e]=t.used,t.used=!1}let r=this.imageManager.listImages();for(let t of this._order){let n=this._layers[t];n.recalculate(e,r),!n.isHidden(e.zoom)&&n.source&&(this.tileManagers[n.source].used=!0)}for(let e in n){let t=this.tileManagers[e];!!n[e]!=!!t.used&&t.fire(new K(`data`,{sourceDataType:`visibility`,sourceId:e}))}this.light.recalculate(e),this.sky.recalculate(e),this.projection.recalculate(e),this.z=e.zoom,t&&this.fire(new qr(`data`))}_updateTilesForChangedImages(){let e=Object.keys(this._changedImages);if(e.length){for(let t in this.tileManagers)this.tileManagers[t].reloadTilesForDependencies([`icons`,`patterns`],e);this._changedImages={}}}_updateTilesForChangedGlyphs(){if(this._glyphsDidChange){for(let e in this.tileManagers)this.tileManagers[e].reloadTilesForDependencies([`glyphs`],[``]);this._glyphsDidChange=!1}}_updateWorkerLayers(e,t){this.dispatcher.broadcast(`UL`,{layers:this._serializeByIds(e,!1),removedIds:t})}_resetUpdates(){this._changed=!1,this._updatedLayers={},this._removedLayers={},this._updatedSources={},this._updatedPaintProps={},this._changedImages={},this._glyphsDidChange=!1}setState(e,t={}){this._checkLoaded();let n=this.serialize();if(e=t.transformStyle?t.transformStyle(n,e):e,(t.validate??!0)&&Zt(this,e))return!1;e=ge(e),e.layers=ri(e.layers);let r=mi(n,e),i=this._getOperationsToPerform(r);if(i.unimplemented.length>0)throw Error(`Unimplemented: ${i.unimplemented.join(`, `)}.`);if(i.operations.length===0)return!1;for(let e of i.operations)e();return this.stylesheet=e,this._serializedLayers=null,this.fire(new Kr({style:this})),!0}_getOperationsToPerform(e){let t=[],n=[];for(let r of e)switch(r.command){case`setCenter`:case`setZoom`:case`setBearing`:case`setPitch`:case`setRoll`:continue;case`addLayer`:t.push(()=>this.addLayer.apply(this,r.args));break;case`removeLayer`:t.push(()=>this.removeLayer.apply(this,r.args));break;case`setPaintProperty`:t.push(()=>this.setPaintProperty.apply(this,r.args));break;case`setLayoutProperty`:t.push(()=>this.setLayoutProperty.apply(this,r.args));break;case`setFilter`:t.push(()=>this.setFilter.apply(this,r.args));break;case`addSource`:t.push(()=>this.addSource.apply(this,r.args));break;case`removeSource`:t.push(()=>this.removeSource.apply(this,r.args));break;case`setLayerZoomRange`:t.push(()=>this.setLayerZoomRange.apply(this,r.args));break;case`setLight`:t.push(()=>this.setLight.apply(this,r.args));break;case`setGeoJSONSourceData`:t.push(()=>this.setGeoJSONSourceData.apply(this,r.args));break;case`setGlyphs`:t.push(()=>this.setGlyphs.apply(this,r.args));break;case`setFontFaces`:t.push(()=>this.setFontFaces.apply(this,r.args));break;case`setSprite`:t.push(()=>this.setSprite.apply(this,r.args));break;case`setTerrain`:t.push(()=>this.map.setTerrain.apply(this,r.args));break;case`setSky`:t.push(()=>this.setSky.apply(this,r.args));break;case`setProjection`:this.setProjection.apply(this,r.args);break;case`setGlobalState`:t.push(()=>this.setGlobalState.apply(this,r.args));break;case`setTransition`:t.push(()=>{});break;default:n.push(r.command)}return{operations:t,unimplemented:n}}addImage(e,t){if(this.getImage(e)){this.fire(new H(Error(`An image named "${e}" already exists.`)));return}this.imageManager.addImage(e,t),this._afterImageUpdated(e)}updateImage(e,t){this.imageManager.updateImage(e,t)}getImage(e){return this.imageManager.getImage(e)}setMissingImageResolver(e){this.imageManager.setMissingImageResolver(e)}removeImage(e){if(!this.getImage(e)){this.fire(new H(Error(`An image named "${e}" does not exist.`)));return}this.imageManager.removeImage(e),this._afterImageUpdated(e)}_markImagesChanged(e){for(let t of e)this._changedImages[t]=!0}_afterImageUpdated(e){this._changedImages[e]=!0,this._imagesListDirty=!0,this._changed=!0,this.fire(new qr(`data`))}listImages(){return this._checkLoaded(),this.imageManager.listImages()}addSource(e,t,n={}){if(this._checkLoaded(),this.tileManagers[e]!==void 0)throw Error(`Source "${e}" already exists.`);if(!t.type)throw Error(`The type property must be defined, but only the following properties were given: ${Object.keys(t).join(`, `)}.`);if(zt.has(t.type)&&this._validate(Ut.source,`sources.${e}`,t,null,n))return;this.map?._collectResourceTiming&&(t.collectResourceTiming=!0);let r=this.tileManagers[e]=new No(e,t,this.dispatcher);r.style=this,r.setEventedParent(this,()=>({isSourceLoaded:r.loaded(),source:r.serialize(),sourceId:e})),r.onAdd(this.map),this._changed=!0}removeSource(e){if(this._checkLoaded(),this.tileManagers[e]===void 0)throw Error(`There is no source with this ID=${e}`);for(let t in this._layers)if(this._layers[t].source===e)return this.fire(new H(Error(`Source "${e}" cannot be removed while layer "${t}" is using it.`)));let t=this.tileManagers[e];delete this.tileManagers[e],delete this._updatedSources[e],t.fire(new K(`data`,{sourceDataType:`metadata`,sourceId:e})),t.setEventedParent(null),t.onRemove(this.map),this._changed=!0}setGeoJSONSourceData(e,t){if(this._checkLoaded(),this.tileManagers[e]===void 0)throw Error(`There is no source with this ID=${e}`);let n=this.tileManagers[e].getSource();if(n.type!==`geojson`)throw Error(`geojsonSource.type is ${n.type}, which is !== 'geojson`);n.setData(t),this._changed=!0}getSource(e){return this.tileManagers[e]?.getSource()}addLayer(e,t,n={}){this._checkLoaded();let r=e.id;if(this.getLayer(r)){this.fire(new H(Error(`Layer "${r}" already exists on this map.`)));return}let i;if(e.type===`custom`){if(Cn(this,fr(e)))return;i=Je(e,this._globalState)}else{if(`source`in e&&typeof e.source==`object`&&(this.addSource(r,e.source),e=ge(e),e=z(e,{source:r})),this._validate(Ut.layer,`layers.${r}`,e,{arrayIndex:-1},n))return;i=Je(e,this._globalState),this._validateLayer(i),i.setEventedParent(this,{layer:{id:r}})}let a=t?this._order.indexOf(t):this._order.length;if(t&&a===-1){this.fire(new H(Error(`Cannot add layer "${r}" before non-existing layer "${t}".`)));return}if(this._order.splice(a,0,r),this._layerOrderChanged=!0,this._layers[r]=i,this._removedLayers[r]&&i.source&&i.type!==`custom`){let e=this._removedLayers[r];delete this._removedLayers[r],e.type===i.type?(this._updatedSources[i.source]=`reload`,this.tileManagers[i.source].pause()):this._updatedSources[i.source]=`clear`}this._updateLayer(i),i.onAdd&&i.onAdd(this.map)}moveLayer(e,t){if(this._checkLoaded(),this._changed=!0,!this._layers[e]){this.fire(new H(Error(`The layer '${e}' does not exist in the map's style and cannot be moved.`)));return}if(e===t)return;let n=this._order.indexOf(e);this._order.splice(n,1);let r=t?this._order.indexOf(t):this._order.length;if(t&&r===-1){this.fire(new H(Error(`Cannot move layer "${e}" before non-existing layer "${t}".`)));return}this._order.splice(r,0,e),this._layerOrderChanged=!0}removeLayer(e){this._checkLoaded();let t=this._layers[e];if(!t){this.fire(new H(Error(`Cannot remove non-existing layer "${e}".`)));return}t.setEventedParent(null);let n=this._order.indexOf(e);this._order.splice(n,1),this._layerOrderChanged=!0,this._changed=!0,this._removedLayers[e]=t,delete this._layers[e],this._serializedLayers&&delete this._serializedLayers[e],delete this._updatedLayers[e],delete this._updatedPaintProps[e],t.onRemove&&t.onRemove(this.map)}getLayer(e){return this._layers[e]}getLayersOrder(){return[...this._order]}hasLayer(e){return e in this._layers}setLayerZoomRange(e,t,n){this._checkLoaded();let r=this.getLayer(e);if(!r){this.fire(new H(Error(`Cannot set the zoom range of non-existing layer "${e}".`)));return}(r.minzoom!==t||r.maxzoom!==n)&&(t!=null&&(r.minzoom=t),n!=null&&(r.maxzoom=n),this._updateLayer(r))}setFilter(e,t,n={}){this._checkLoaded();let r=this.getLayer(e);if(!r){this.fire(new H(Error(`Cannot filter non-existing layer "${e}".`)));return}if(!Ve(r.filter,t)){if(t==null){r.setFilter(void 0),this._updateLayer(r);return}this._validate(Ut.filter,`layers.${r.id}.filter`,t,null,n)||(r.setFilter(ge(t)),this._updateLayer(r))}}getFilter(e){return ge(this.getLayer(e).filter)}setLayoutProperty(e,t,n,r={}){this._checkLoaded();let i=this.getLayer(e);if(!i){this.fire(new H(Error(`Cannot style non-existing layer "${e}".`)));return}Ve(i.getLayoutProperty(t),n)||(i.setLayoutProperty(t,n,r),this._updateLayer(i))}getLayoutProperty(e,t){let n=this.getLayer(e);if(!n){this.fire(new H(Error(`Cannot get style of non-existing layer "${e}".`)));return}return n.getLayoutProperty(t)}setPaintProperty(e,t,n,r={}){this._checkLoaded();let i=this.getLayer(e);if(!i){this.fire(new H(Error(`Cannot style non-existing layer "${e}".`)));return}Ve(i.getPaintProperty(t),n)||this._updatePaintProperty(i,t,n,r)}_updatePaintProperty(e,t,n,r={}){e.setPaintProperty(t,n,r)&&this._updateLayer(e),Ue(e)&&t===`raster-fade-duration`&&this.tileManagers[e.source].setRasterFadeDuration(n),this._changed=!0,this._updatedPaintProps[e.id]=!0,e.type===`symbol`&&this.triggerSymbolPlacement(),this._serializedLayers=null}getPaintProperty(e,t){return this.getLayer(e).getPaintProperty(t)}setFeatureState(e,t){this._checkLoaded();let n=e.source,r=e.sourceLayer,i=this.tileManagers[n];if(i===void 0){this.fire(new H(Error(`The source '${n}' does not exist in the map's style.`)));return}let a=i.getSource().type;if(a===`geojson`&&r){this.fire(new H(Error(`GeoJSON sources cannot have a sourceLayer parameter.`)));return}if(a===`vector`&&!r){this.fire(new H(Error(`The sourceLayer parameter must be provided for vector source types.`)));return}if(e.id===void 0){this.fire(new H(Error(`The feature id parameter must be provided.`)));return}let o=[`__proto__`,`constructor`,`prototype`];if(t&&Object.keys(t).some(e=>o.includes(e))){this.fire(new H(Error(`The feature state should not include one of the following keys: ${o}`)));return}i.setFeatureState(r,e.id,t)}removeFeatureState(e,t){this._checkLoaded();let n=e.source,r=this.tileManagers[n];if(r===void 0){this.fire(new H(Error(`The source '${n}' does not exist in the map's style.`)));return}let i=r.getSource().type,a=i===`vector`?e.sourceLayer:void 0;if(i===`vector`&&!a){this.fire(new H(Error(`The sourceLayer parameter must be provided for vector source types.`)));return}if(t&&typeof e.id!=`string`&&typeof e.id!=`number`){this.fire(new H(Error(`A feature id is required to remove its specific state property.`)));return}r.removeFeatureState(a,e.id,t)}getFeatureState(e){this._checkLoaded();let t=e.source,n=e.sourceLayer,r=this.tileManagers[t];if(r===void 0){this.fire(new H(Error(`The source '${t}' does not exist in the map's style.`)));return}if(r.getSource().type===`vector`&&!n){this.fire(new H(Error(`The sourceLayer parameter must be provided for vector source types.`)));return}return e.id===void 0&&this.fire(new H(Error(`The feature id parameter must be provided.`))),r.getFeatureState(n,e.id)}getTransition(){return z({duration:300,delay:0},this.stylesheet?.transition)}serialize(){if(!this._loaded)return;let e=It(this.tileManagers,e=>e.serialize()),t=this._serializeByIds(this._order,!0),n=this.map.getTerrain()||void 0,r=this.stylesheet;return Fn({version:r.version,name:r.name,metadata:r.metadata,light:r.light,sky:r.sky,center:r.center,zoom:r.zoom,bearing:r.bearing,pitch:r.pitch,sprite:r.sprite,glyphs:r.glyphs,"font-faces":r[`font-faces`],transition:r.transition,projection:r.projection,state:r.state,sources:e,layers:t,terrain:n},e=>e!==void 0)}_updateLayer(e){this._updatedLayers[e.id]=!0,e.source&&!this._updatedSources[e.source]&&this.tileManagers[e.source].getSource().type!==`raster`&&(this._updatedSources[e.source]=`reload`,this.tileManagers[e.source].pause()),this._serializedLayers=null,this._changed=!0}_flattenAndSortRenderedFeatures(e){let t=e=>this._layers[e].type===`fill-extrusion`,n={},r=[];for(let i=this._order.length-1;i>=0;i--){let a=this._order[i];if(t(a)){n[a]=i;for(let t of e){let e=t[a];if(e)for(let t of e)r.push(t)}}}r.sort((e,t)=>t.intersectionZ-e.intersectionZ);let i=[];for(let a=this._order.length-1;a>=0;a--){let o=this._order[a];if(t(o))for(let e=r.length-1;e>=0;e--){let t=r[e].feature;if(n[t.layer.id]this.map.terrain.getElevation(e,t,n):void 0));return this.placement&&i.push(la(this._layers,a,this.tileManagers,e,s,this.placement.collisionIndex,this.placement.retainedQueryData)),this._flattenAndSortRenderedFeatures(i)}querySourceFeatures(e,t){t?.filter&&this._validate(Ut.filter,`querySourceFeatures.filter`,t.filter,null,t);let n=this.tileManagers[e];return n?ua(n,t?{...t,globalState:this._globalState}:{globalState:this._globalState}):[]}getLight(){return this.light.getLight()}setLight(e,t={}){this._checkLoaded();let n=this.light.getLight(),r=!1;for(let t in e)if(!Ve(e[t],n[t])){r=!0;break}if(!r)return;let i={now:U(),transition:z({duration:300,delay:0},this.stylesheet.transition)};this.light.setLight(e,t),this.light.updateTransitions(i)}getProjection(){return this.stylesheet?.projection}setProjection(e){this._checkLoaded();let t=e??{type:`mercator`};if(this.stylesheet.projection=e,this.projection){if(this.projection.name===t.type)return;this.projection.destroy(),delete this.projection}this._setProjectionInternal(t.type)}getSky(){return this.stylesheet?.sky}setSky(e,t={}){this._checkLoaded();let n=this.getSky(),r=!1;if(!e&&!n)return;if(e&&!n)r=!0;else if(!e&&n)r=!0;else for(let t in e)if(!Ve(e[t],n[t])){r=!0;break}if(!r)return;let i={now:U(),transition:z({duration:300,delay:0},this.stylesheet.transition)};this.stylesheet.sky=e,this.sky.setSky(e,t),this.sky.updateTransitions(i)}_setProjectionInternal(e){let t=fl(e,this.map._camera?.transform.constrainOverride,this._globalState);this.projection=t.projection,this.map.migrateProjection(t.transform,t.cameraHelper);for(let e in this.tileManagers)this.tileManagers[e].reload()}_validate(e,t,n,r,i={}){return i.validate!==!1&&ar(this,e,{key:t,style:this.serialize(),value:n,...r},i)}_remove(e=!0){this._frameRequest&&=(this._frameRequest.abort(),null),this._loadStyleRequest&&=(this._loadStyleRequest.abort(),null),this._spriteRequest&&=(this._spriteRequest.abort(),null),fo().off(co,this._rtlPluginLoaded);for(let e in this._layers)this._layers[e].setEventedParent(null);for(let e in this.tileManagers){let t=this.tileManagers[e];t.setEventedParent(null),t.onRemove(this.map)}this.imageManager.setEventedParent(null),this.setEventedParent(null),e&&this.dispatcher.broadcast(`RM`,void 0),this.dispatcher.remove(e)}_clearSource(e){this.tileManagers[e].clearTiles()}_reloadSource(e){this.tileManagers[e].resume(),this.tileManagers[e].reload()}_updateSources(e){for(let t in this.tileManagers)this.tileManagers[t].update(e,this.map.terrain)}_generateCollisionBoxes(){for(let e in this.tileManagers)this._reloadSource(e)}triggerSymbolPlacement(){this._symbolPlacementTriggered=!0}_placementInputsChanged(e,t,n){let r=this.pauseablePlacement;return!r||this._symbolPlacementTriggered||this._placedProjectionTransition!==this.projection?.transitionState||r._showCollisionBoxes!==t||r.placement.collisionGroups.crossSourceCollisions!==n||r.placement.transform.renderWorldCopies!==e.renderWorldCopies||!m(r.placement.transform.modelViewProjectionMatrix,e.modelViewProjectionMatrix)}_updatePlacement(e,t,n,r,i=!1){let a=!1,o=!1,s={};for(let t of this._order){let n=this._layers[t];if(n.type!==`symbol`)continue;if(!s[n.source]){let e=this.tileManagers[n.source];s[n.source]=e.getRenderableIds(!0).map(t=>e.getTileByID(t)).sort((e,t)=>t.tileID.overscaledZ-e.tileID.overscaledZ||(e.tileID.isLessThan(t.tileID)?-1:1))}let r=this.crossTileSymbolIndex.addLayer(n,s[n.source],e.center.lng);a||=r}this.crossTileSymbolIndex.pruneUnusedLayers(this._order),i||=this._layerOrderChanged||n===0;let c=a||this._placementInputsChanged(e,t,r),l=this.pauseablePlacement?.isDone()&&!this.placement.stillRecent(U(),e.zoom);if((i||!this.pauseablePlacement||l&&(c||this.placement.stale))&&(this._symbolPlacementTriggered=!1,this._placedProjectionTransition=this.projection?.transitionState,this.pauseablePlacement=new Os(e,this.map.terrain,this._order,i,t,n,r,this.placement),this._layerOrderChanged=!1),this.pauseablePlacement.isDone()?c&&this.placement.setStale():(this.pauseablePlacement.continuePlacement(this._order,this._layers,s),this.pauseablePlacement.isDone()&&(this.placement=this.pauseablePlacement.commit(U()),o=!0),a&&this.pauseablePlacement.placement.setStale()),o||a)for(let e of this._order){let t=this._layers[e];t.type===`symbol`&&this.placement.updateLayerOpacities(t,s[t.source])}return!this.pauseablePlacement.isDone()||this.placement.hasTransitions(U())}_releaseSymbolFadeTiles(){for(let e in this.tileManagers)this.tileManagers[e].releaseSymbolFadeTiles()}async getImages(e,t){let n=await this.imageManager.getImages(t.icons);this._updateTilesForChangedImages();let r=this.tileManagers[t.source];return r&&r.setDependencies(t.tileID.key,t.type,t.icons),n}async getGlyphs(e,t){let n=await this.glyphManager.getGlyphs(t.stacks),r=this.tileManagers[t.source];return r&&r.setDependencies(t.tileID.key,t.type,[``]),n}getGlyphsUrl(){return this.stylesheet.glyphs||null}setGlyphs(e,t={}){this._checkLoaded(),!(e&&this._validate(Ut.glyphs,`glyphs`,e,null,t))&&(this._changed=!0,this._glyphsDidChange=!0,this.stylesheet.glyphs=e,this.glyphManager.entries={},this.glyphManager.setURL(e))}getFontFaces(){return this.stylesheet[`font-faces`]||null}setFontFaces(e){this._checkLoaded(),this._changed=!0,this._glyphsDidChange=!0,this.stylesheet[`font-faces`]=e,this.glyphManager.setFontFaces(e)}async getDashes(e,t){let n={};for(let[e,r]of Object.entries(t.dashes))n[e]=this.lineAtlas.getDash(r.dasharray,r.round);return n}addSprite(e,t,n={},r){this._checkLoaded();let i=[{id:e,url:t}],a=[...gi(this.stylesheet.sprite),...i];this._validate(Ut.sprite,`sprite`,a,null,n)||(this.stylesheet.sprite=a,this._loadSprite(i,!0,r))}removeSprite(e){this._checkLoaded();let t=gi(this.stylesheet.sprite);if(!t.find(t=>t.id===e)){this.fire(new H(Error(`Sprite "${e}" doesn't exists on this map.`)));return}let n=this.imageManager.removeSpriteImages(e);this._markImagesChanged(n),t.splice(t.findIndex(t=>t.id===e),1),this.stylesheet.sprite=t.length>0?t:void 0,this._imagesListDirty=!0,this._changed=!0,this.fire(new qr(`data`))}getSprite(){return gi(this.stylesheet.sprite)}setSprite(e,t={},n){this._checkLoaded(),!(e&&this._validate(Ut.sprite,`sprite`,e,null,t))&&(this.stylesheet.sprite=e,e?this._loadSprite(e,!0,n):(this._unloadSprite(),n&&n(null)))}destroy(){this._frameRequest&&=(this._frameRequest.abort(),null),this._loadStyleRequest&&=(this._loadStyleRequest.abort(),null),this._spriteRequest&&=(this._spriteRequest.abort(),null);for(let e in this.tileManagers){let t=this.tileManagers[e];t.setEventedParent(null),t.onRemove(this.map)}this.tileManagers={},this.imageManager&&(this.imageManager.setEventedParent(null),this.imageManager.destroy(),this.patternAtlas.destroy()),this.glyphManager&&this.glyphManager.destroy();for(let e in this._layers){let t=this._layers[e];t.setEventedParent(null),t.onRemove&&t.onRemove(this.map)}this._setInitialValues(),this.setEventedParent(null),this.dispatcher.unregisterMessageHandler(`GG`),this.dispatcher.unregisterMessageHandler(`GI`),this.dispatcher.unregisterMessageHandler(`GDA`),this.dispatcher.remove(!0),this._listeners={},this._oneTimeListeners={}}};const hl=wt([{name:`a_pos`,type:`Int16`,components:2},{name:`a_texture_pos`,type:`Int16`,components:2}]);var gl=class{constructor(){this.boundProgram=null,this.boundLayoutVertexBuffer=null,this.boundPaintVertexBuffers=[],this.boundIndexBuffer=null,this.boundVertexOffset=null,this.boundDynamicVertexBuffer=null,this.vao=null}bind(e,t,n,r,i,a,o,s,c){this.context=e;let l=this.boundPaintVertexBuffers.length!==r.length;for(let e=0;!l&&e({u_depth:new F(e,t.u_depth),u_terrain:new F(e,t.u_terrain),u_terrain_dim:new P(e,t.u_terrain_dim),u_terrain_matrix:new ut(e,t.u_terrain_matrix),u_terrain_unpack:new Ce(e,t.u_terrain_unpack),u_terrain_exaggeration:new P(e,t.u_terrain_exaggeration)}),vl=(e,t)=>({u_texture:new F(e,t.u_texture),u_ele_delta:new P(e,t.u_ele_delta),u_fog_matrix:new ut(e,t.u_fog_matrix),u_fog_color:new qe(e,t.u_fog_color),u_fog_ground_blend:new P(e,t.u_fog_ground_blend),u_fog_ground_blend_opacity:new P(e,t.u_fog_ground_blend_opacity),u_horizon_color:new qe(e,t.u_horizon_color),u_horizon_fog_blend:new P(e,t.u_horizon_fog_blend),u_is_globe_mode:new P(e,t.u_is_globe_mode)}),yl=(e,t)=>({u_ele_delta:new P(e,t.u_ele_delta)}),bl=(e,t,n,r,i)=>({u_texture:0,u_ele_delta:e,u_fog_matrix:t,u_fog_color:n?n.properties.get(`fog-color`):R.white,u_fog_ground_blend:n?n.properties.get(`fog-ground-blend`):1,u_fog_ground_blend_opacity:i?0:n?n.calculateFogBlendOpacity(r):0,u_horizon_color:n?n.properties.get(`horizon-color`):R.white,u_horizon_fog_blend:n?n.properties.get(`horizon-fog-blend`):1,u_is_globe_mode:+!!i}),xl=e=>({u_ele_delta:e}),Sl=(e,t)=>({u_projection_matrix:new ut(e,t.u_projection_matrix),u_projection_tile_mercator_coords:new Ce(e,t.u_projection_tile_mercator_coords),u_projection_clipping_plane:new Ce(e,t.u_projection_clipping_plane),u_projection_transition:new P(e,t.u_projection_transition),u_projection_fallback_matrix:new ut(e,t.u_projection_fallback_matrix),u_projection_clip_antimeridian:new F(e,t.u_projection_clip_antimeridian)}),Cl=e=>({u_projection_matrix:e.mainMatrix,u_projection_tile_mercator_coords:e.tileMercatorCoords,u_projection_clipping_plane:e.clippingPlane,u_projection_transition:e.projectionTransition,u_projection_fallback_matrix:e.fallbackMatrix,u_projection_clip_antimeridian:+!!e.clipAntimeridian});function wl(e){let t=[];for(let n of e){if(n===null)continue;let e=n.split(` `);t.push(e.pop())}return t}function Tl(e,t){let n=new Set([e.INT,e.INT_VEC2,e.INT_VEC3,e.INT_VEC4,e.UNSIGNED_INT,e.UNSIGNED_INT_VEC2,e.UNSIGNED_INT_VEC3,e.UNSIGNED_INT_VEC4]),r=new Set,i=e.getProgramParameter(t,e.ACTIVE_ATTRIBUTES);for(let a=0;a=0&&(this.attributes[e]={location:t,isInteger:T.has(e)})}l.deleteShader(C),l.deleteShader(S);for(let e of v)if(e&&!w[e]){let t=l.getUniformLocation(this.program,e);t&&(w[e]=t)}this.fixedUniforms=r(e,w),this.terrainUniforms=_l(e,w),this.projectionUniforms=Sl(e,w),this.binderUniforms=n?n.getUniforms(e,w):[]}draw(e,t,n,r,i,a,o,s,c,l,u,d,f,p,m,h,g,_,v){let y=e.gl;if(this.failedToCreate)return;if(e.program.set(this.program),e.setDepthMode(n),e.setStencilMode(r),e.setColorMode(i),e.setCullFace(a),s){e.activeTexture.set(y.TEXTURE2),y.bindTexture(y.TEXTURE_2D,s.depthTexture),e.activeTexture.set(y.TEXTURE3),y.bindTexture(y.TEXTURE_2D,s.texture);for(let e in this.terrainUniforms)this.terrainUniforms[e].set(s[e])}if(c){let e=Cl(c);for(let t in this.projectionUniforms)this.projectionUniforms[t].set(e[t])}if(o)for(let e in this.fixedUniforms)this.fixedUniforms[e].set(o[e]);h&&h.setUniforms(e,this.binderUniforms,p,{zoom:m});let b=0;switch(t){case y.LINES:b=2;break;case y.TRIANGLES:b=3;break;case y.LINE_STRIP:b=1}for(let n of f.get())n.vaos||={},n.vaos[l]||=new gl,n.vaos[l].bind(e,this,u,h?h.getPaintVertexBuffers():[],d,n.vertexOffset,g,_,v),y.drawElements(t,n.primitiveLength*b,y.UNSIGNED_SHORT,n.primitiveOffset*b*2)}};function Dl(e,t,n){let r=1/lt(n,1,t.transform.tileZoom),i=2**n.tileID.overscaledZ,a=n.tileSize*2**t.transform.tileZoom/i,o=a*(n.tileID.canonical.x+n.tileID.wrap*i),s=a*n.tileID.canonical.y;return{u_image:0,u_texsize:n.imageAtlasTexture.size,u_scale:[r,e.fromScale,e.toScale],u_fade:e.t,u_pixel_coord_upper:[o>>16,s>>16],u_pixel_coord_lower:[o&65535,s&65535]}}function Ol(e,t,n,r){let i=n.patternAtlas.getPattern(e.from.toString()),a=n.patternAtlas.getPattern(e.to.toString()),{width:o,height:s}=n.patternAtlas.getPixelSize(),c=2**r.tileID.overscaledZ,l=r.tileSize*2**n.transform.tileZoom/c,u=l*(r.tileID.canonical.x+r.tileID.wrap*c),d=l*r.tileID.canonical.y;return{u_image:0,u_pattern_tl_a:i.tl,u_pattern_br_a:i.br,u_pattern_tl_b:a.tl,u_pattern_br_b:a.br,u_texsize:[o,s],u_mix:t.t,u_pattern_size_a:i.displaySize,u_pattern_size_b:a.displaySize,u_scale_a:t.fromScale,u_scale_b:t.toScale,u_tile_units_to_pixels:1/lt(r,1,n.transform.tileZoom),u_pixel_coord_upper:[u>>16,d>>16],u_pixel_coord_lower:[u&65535,d&65535]}}const kl=(e,t)=>({u_lightpos:new ue(e,t.u_lightpos),u_lightpos_globe:new ue(e,t.u_lightpos_globe),u_lightintensity:new P(e,t.u_lightintensity),u_lightcolor:new ue(e,t.u_lightcolor),u_vertical_gradient:new P(e,t.u_vertical_gradient),u_opacity:new P(e,t.u_opacity),u_fill_translate:new j(e,t.u_fill_translate)}),Al=(e,t)=>({u_lightpos:new ue(e,t.u_lightpos),u_lightpos_globe:new ue(e,t.u_lightpos_globe),u_lightintensity:new P(e,t.u_lightintensity),u_lightcolor:new ue(e,t.u_lightcolor),u_vertical_gradient:new P(e,t.u_vertical_gradient),u_height_factor:new P(e,t.u_height_factor),u_opacity:new P(e,t.u_opacity),u_fill_translate:new j(e,t.u_fill_translate),u_image:new F(e,t.u_image),u_texsize:new j(e,t.u_texsize),u_pixel_coord_upper:new j(e,t.u_pixel_coord_upper),u_pixel_coord_lower:new j(e,t.u_pixel_coord_lower),u_scale:new ue(e,t.u_scale),u_fade:new P(e,t.u_fade)}),jl=(e,t,n,r)=>{let i=e.style.light,a=i.getCartesianPosition(),o=O();i.properties.get(`anchor`)===`viewport`&&se(o,e.transform.bearingInRadians),an(a,a,o);let s=e.transform.transformLightDirection(a),c=i.properties.get(`color`);return{u_lightpos:a,u_lightpos_globe:s,u_lightintensity:i.properties.get(`intensity`),u_lightcolor:[c.r,c.g,c.b],u_vertical_gradient:+t,u_opacity:n,u_fill_translate:r}},Ml=(e,t,n,r,i,a,o)=>z(jl(e,t,n,r),Dl(a,e,o),{u_height_factor:-(2**i.overscaledZ)/o.tileSize/8}),Nl=(e,t)=>({u_fill_translate:new j(e,t.u_fill_translate)}),Pl=(e,t)=>({u_image:new F(e,t.u_image),u_texsize:new j(e,t.u_texsize),u_pixel_coord_upper:new j(e,t.u_pixel_coord_upper),u_pixel_coord_lower:new j(e,t.u_pixel_coord_lower),u_scale:new ue(e,t.u_scale),u_fade:new P(e,t.u_fade),u_fill_translate:new j(e,t.u_fill_translate)}),Fl=(e,t)=>({u_world:new j(e,t.u_world),u_fill_translate:new j(e,t.u_fill_translate)}),Il=(e,t)=>({u_world:new j(e,t.u_world),u_image:new F(e,t.u_image),u_texsize:new j(e,t.u_texsize),u_pixel_coord_upper:new j(e,t.u_pixel_coord_upper),u_pixel_coord_lower:new j(e,t.u_pixel_coord_lower),u_scale:new ue(e,t.u_scale),u_fade:new P(e,t.u_fade),u_fill_translate:new j(e,t.u_fill_translate)}),Ll=(e,t,n,r)=>z(Dl(t,e,n),{u_fill_translate:r}),Rl=e=>({u_fill_translate:e}),zl=(e,t)=>({u_world:e,u_fill_translate:t}),Bl=(e,t,n,r,i)=>z(Ll(e,t,n,i),{u_world:r}),Vl=(e,t)=>({u_camera_to_center_distance:new P(e,t.u_camera_to_center_distance),u_scale_with_map:new F(e,t.u_scale_with_map),u_pitch_with_map:new F(e,t.u_pitch_with_map),u_extrude_scale:new j(e,t.u_extrude_scale),u_device_pixel_ratio:new P(e,t.u_device_pixel_ratio),u_globe_extrude_scale:new P(e,t.u_globe_extrude_scale),u_translate:new j(e,t.u_translate)}),Hl=(e,t,n,r,i)=>{let a=e.transform,o,s,c=0;if(n.paint.get(`circle-pitch-alignment`)===`map`){let e=lt(t,1,a.zoom);o=!0,s=[e,e],c=e/(N*2**t.tileID.overscaledZ)*2*Math.PI*i}else o=!1,s=a.pixelsToGLUnits;return{u_camera_to_center_distance:a.cameraToCenterDistance,u_scale_with_map:+(n.paint.get(`circle-pitch-scale`)===`map`),u_pitch_with_map:+o,u_device_pixel_ratio:e.pixelRatio,u_extrude_scale:s,u_globe_extrude_scale:c,u_translate:r}},Ul=(e,t)=>({u_pixel_extrude_scale:new j(e,t.u_pixel_extrude_scale)}),Wl=(e,t)=>({u_viewport_size:new j(e,t.u_viewport_size)}),Gl=e=>({u_pixel_extrude_scale:[1/e.width,1/e.height]}),Kl=e=>({u_viewport_size:[e.width,e.height]}),ql=(e,t)=>({u_color:new qe(e,t.u_color),u_overlay:new F(e,t.u_overlay),u_overlay_scale:new P(e,t.u_overlay_scale)}),Jl=(e,t=1)=>({u_color:e,u_overlay:0,u_overlay_scale:t}),Yl=(e,t)=>({u_extrude_scale:new P(e,t.u_extrude_scale),u_intensity:new P(e,t.u_intensity),u_globe_extrude_scale:new P(e,t.u_globe_extrude_scale)}),Xl=(e,t)=>({u_matrix:new ut(e,t.u_matrix),u_world:new j(e,t.u_world),u_image:new F(e,t.u_image),u_color_ramp:new F(e,t.u_color_ramp),u_opacity:new P(e,t.u_opacity)}),Zl=(e,t,n,r)=>{let i=lt(e,1,t)/(N*2**e.tileID.overscaledZ)*2*Math.PI*r;return{u_extrude_scale:lt(e,1,t),u_intensity:n,u_globe_extrude_scale:i}},Ql=(e,t,n,r)=>{let i=vr();Ne(i,0,e.width,e.height,0,0,1);let a=e.context.gl;return{u_matrix:i,u_world:[a.drawingBufferWidth,a.drawingBufferHeight],u_image:n,u_color_ramp:r,u_opacity:t.paint.get(`heatmap-opacity`)}},$l=(e,t)=>({u_image:new F(e,t.u_image),u_latrange:new j(e,t.u_latrange),u_exaggeration:new P(e,t.u_exaggeration),u_altitudes:new f(e,t.u_altitudes),u_azimuths:new f(e,t.u_azimuths),u_accent:new qe(e,t.u_accent),u_method:new F(e,t.u_method),u_shadows:new kr(e,t.u_shadows),u_highlights:new kr(e,t.u_highlights)}),eu=(e,t)=>({u_matrix:new ut(e,t.u_matrix),u_image:new F(e,t.u_image),u_dimension:new j(e,t.u_dimension),u_zoom:new P(e,t.u_zoom),u_unpack:new Ce(e,t.u_unpack)}),tu=(e,t,n)=>{let r=n.paint.get(`hillshade-accent-color`),i;switch(n.paint.get(`hillshade-method`)){case`basic`:i=4;break;case`combined`:i=1;break;case`igor`:i=2;break;case`multidirectional`:i=3;break;default:i=0}let a=n.getIlluminationProperties();for(let t=0;t{let n=t.stride,r=vr();return Ne(r,0,N,-N,0,0,1),Le(r,r,[0,-N,0]),{u_matrix:r,u_image:1,u_dimension:[n,n],u_zoom:e.overscaledZ,u_unpack:t.getUnpackVector()}};function ru(e,t){let n=2**t.canonical.z,r=t.canonical.y;return[new B(0,r/n).toLngLat().lat,new B(0,(r+1)/n).toLngLat().lat]}const iu=(e,t)=>({u_image:new F(e,t.u_image),u_unpack:new Ce(e,t.u_unpack),u_dimension:new j(e,t.u_dimension),u_elevation_stops:new F(e,t.u_elevation_stops),u_color_stops:new F(e,t.u_color_stops),u_color_ramp_size:new F(e,t.u_color_ramp_size),u_opacity:new P(e,t.u_opacity)}),au=(e,t,n=0)=>({u_image:0,u_unpack:t.getUnpackVector(),u_dimension:[t.stride,t.stride],u_elevation_stops:1,u_color_stops:4,u_color_ramp_size:n,u_opacity:e.paint.get(`color-relief-opacity`)}),ou=(e,t)=>({u_translation:new j(e,t.u_translation),u_ratio:new P(e,t.u_ratio),u_device_pixel_ratio:new P(e,t.u_device_pixel_ratio),u_units_to_pixels:new j(e,t.u_units_to_pixels)}),su=(e,t)=>({u_translation:new j(e,t.u_translation),u_ratio:new P(e,t.u_ratio),u_device_pixel_ratio:new P(e,t.u_device_pixel_ratio),u_units_to_pixels:new j(e,t.u_units_to_pixels),u_image:new F(e,t.u_image),u_image_height:new P(e,t.u_image_height)}),cu=(e,t)=>({u_translation:new j(e,t.u_translation),u_texsize:new j(e,t.u_texsize),u_ratio:new P(e,t.u_ratio),u_device_pixel_ratio:new P(e,t.u_device_pixel_ratio),u_image:new F(e,t.u_image),u_units_to_pixels:new j(e,t.u_units_to_pixels),u_scale:new ue(e,t.u_scale),u_fade:new P(e,t.u_fade)}),lu=(e,t)=>({u_translation:new j(e,t.u_translation),u_ratio:new P(e,t.u_ratio),u_device_pixel_ratio:new P(e,t.u_device_pixel_ratio),u_units_to_pixels:new j(e,t.u_units_to_pixels),u_image:new F(e,t.u_image),u_mix:new P(e,t.u_mix),u_tileratio:new P(e,t.u_tileratio),u_crossfade_from:new P(e,t.u_crossfade_from),u_crossfade_to:new P(e,t.u_crossfade_to),u_lineatlas_width:new P(e,t.u_lineatlas_width),u_lineatlas_height:new P(e,t.u_lineatlas_height)}),uu=(e,t)=>({u_translation:new j(e,t.u_translation),u_ratio:new P(e,t.u_ratio),u_device_pixel_ratio:new P(e,t.u_device_pixel_ratio),u_units_to_pixels:new j(e,t.u_units_to_pixels),u_image:new F(e,t.u_image),u_image_height:new P(e,t.u_image_height),u_tileratio:new P(e,t.u_tileratio),u_crossfade_from:new P(e,t.u_crossfade_from),u_crossfade_to:new P(e,t.u_crossfade_to),u_image_dash:new F(e,t.u_image_dash),u_mix:new P(e,t.u_mix),u_lineatlas_width:new P(e,t.u_lineatlas_width),u_lineatlas_height:new P(e,t.u_lineatlas_height)}),du=(e,t,n,r)=>{let i=e.transform;return{u_translation:_u(e,t,n),u_ratio:r/lt(t,1,i.zoom),u_device_pixel_ratio:e.pixelRatio,u_units_to_pixels:[1/i.pixelsToGLUnits[0],1/i.pixelsToGLUnits[1]]}},fu=(e,t,n,r,i)=>z(du(e,t,n,r),{u_image:0,u_image_height:i}),pu=(e,t,n,r,i)=>{let a=e.transform,o=gu(t,a);return{u_translation:_u(e,t,n),u_texsize:t.imageAtlasTexture.size,u_ratio:r/lt(t,1,a.zoom),u_device_pixel_ratio:e.pixelRatio,u_image:0,u_scale:[o,i.fromScale,i.toScale],u_fade:i.t,u_units_to_pixels:[1/a.pixelsToGLUnits[0],1/a.pixelsToGLUnits[1]]}},mu=(e,t,n,r,i)=>{let a=e.transform,o=gu(t,a);return z(du(e,t,n,r),{u_tileratio:o,u_crossfade_from:i.fromScale,u_crossfade_to:i.toScale,u_image:0,u_mix:i.t,u_lineatlas_width:e.lineAtlas.width,u_lineatlas_height:e.lineAtlas.height})},hu=(e,t,n,r,i,a)=>{let o=e.transform,s=gu(t,o);return z(du(e,t,n,r),{u_image:0,u_image_height:a,u_tileratio:s,u_crossfade_from:i.fromScale,u_crossfade_to:i.toScale,u_image_dash:1,u_mix:i.t,u_lineatlas_width:e.lineAtlas.width,u_lineatlas_height:e.lineAtlas.height})};function gu(e,t){return 1/lt(e,1,t.tileZoom)}function _u(e,t,n){return le(e.transform,t,n.paint.get(`line-translate`),n.paint.get(`line-translate-anchor`))}const vu=(e,t)=>({u_image:new F(e,t.u_image),u_opacity:new P(e,t.u_opacity)}),yu=(e,t)=>({u_image:t,u_opacity:e}),bu=(e,t)=>({u_is_size_zoom_constant:new F(e,t.u_is_size_zoom_constant),u_is_size_feature_constant:new F(e,t.u_is_size_feature_constant),u_size_t:new P(e,t.u_size_t),u_size:new P(e,t.u_size),u_camera_to_center_distance:new P(e,t.u_camera_to_center_distance),u_pitch:new P(e,t.u_pitch),u_rotate_symbol:new F(e,t.u_rotate_symbol),u_aspect_ratio:new P(e,t.u_aspect_ratio),u_fade_change:new P(e,t.u_fade_change),u_label_plane_matrix:new ut(e,t.u_label_plane_matrix),u_coord_matrix:new ut(e,t.u_coord_matrix),u_is_text:new F(e,t.u_is_text),u_pitch_with_map:new F(e,t.u_pitch_with_map),u_is_along_line:new F(e,t.u_is_along_line),u_is_variable_anchor:new F(e,t.u_is_variable_anchor),u_texsize:new j(e,t.u_texsize),u_texture:new F(e,t.u_texture),u_translation:new j(e,t.u_translation),u_pitched_scale:new P(e,t.u_pitched_scale),u_is_offset:new F(e,t.u_is_offset),u_height_anchor_ground:new F(e,t.u_height_anchor_ground)}),xu=(e,t)=>({u_is_size_zoom_constant:new F(e,t.u_is_size_zoom_constant),u_is_size_feature_constant:new F(e,t.u_is_size_feature_constant),u_size_t:new P(e,t.u_size_t),u_size:new P(e,t.u_size),u_camera_to_center_distance:new P(e,t.u_camera_to_center_distance),u_pitch:new P(e,t.u_pitch),u_rotate_symbol:new F(e,t.u_rotate_symbol),u_aspect_ratio:new P(e,t.u_aspect_ratio),u_fade_change:new P(e,t.u_fade_change),u_label_plane_matrix:new ut(e,t.u_label_plane_matrix),u_coord_matrix:new ut(e,t.u_coord_matrix),u_is_text:new F(e,t.u_is_text),u_pitch_with_map:new F(e,t.u_pitch_with_map),u_is_along_line:new F(e,t.u_is_along_line),u_is_variable_anchor:new F(e,t.u_is_variable_anchor),u_texsize:new j(e,t.u_texsize),u_texture:new F(e,t.u_texture),u_gamma_scale:new P(e,t.u_gamma_scale),u_device_pixel_ratio:new P(e,t.u_device_pixel_ratio),u_is_halo:new F(e,t.u_is_halo),u_is_plain:new F(e,t.u_is_plain),u_translation:new j(e,t.u_translation),u_pitched_scale:new P(e,t.u_pitched_scale),u_is_offset:new F(e,t.u_is_offset),u_height_anchor_ground:new F(e,t.u_height_anchor_ground)}),Su=(e,t)=>({u_is_size_zoom_constant:new F(e,t.u_is_size_zoom_constant),u_is_size_feature_constant:new F(e,t.u_is_size_feature_constant),u_size_t:new P(e,t.u_size_t),u_size:new P(e,t.u_size),u_camera_to_center_distance:new P(e,t.u_camera_to_center_distance),u_pitch:new P(e,t.u_pitch),u_rotate_symbol:new F(e,t.u_rotate_symbol),u_aspect_ratio:new P(e,t.u_aspect_ratio),u_fade_change:new P(e,t.u_fade_change),u_label_plane_matrix:new ut(e,t.u_label_plane_matrix),u_coord_matrix:new ut(e,t.u_coord_matrix),u_is_text:new F(e,t.u_is_text),u_pitch_with_map:new F(e,t.u_pitch_with_map),u_is_along_line:new F(e,t.u_is_along_line),u_is_variable_anchor:new F(e,t.u_is_variable_anchor),u_texsize:new j(e,t.u_texsize),u_texsize_icon:new j(e,t.u_texsize_icon),u_texture:new F(e,t.u_texture),u_texture_icon:new F(e,t.u_texture_icon),u_gamma_scale:new P(e,t.u_gamma_scale),u_device_pixel_ratio:new P(e,t.u_device_pixel_ratio),u_is_halo:new F(e,t.u_is_halo),u_translation:new j(e,t.u_translation),u_pitched_scale:new P(e,t.u_pitched_scale),u_is_offset:new F(e,t.u_is_offset),u_height_anchor_ground:new F(e,t.u_height_anchor_ground)}),Cu=(e,t,n,r,i,a,o,s,c,l,u,d,f,p,m)=>{let h=o.transform;return{u_is_size_zoom_constant:+(e===`constant`||e===`source`),u_is_size_feature_constant:+(e===`constant`||e===`camera`),u_size_t:t?t.uSizeT:0,u_size:t?t.uSize:0,u_camera_to_center_distance:h.cameraToCenterDistance,u_pitch:h.pitch/360*2*Math.PI,u_rotate_symbol:+n,u_aspect_ratio:h.width/h.height,u_fade_change:o.options.fadeDuration?o.symbolFadeChange:1,u_label_plane_matrix:s,u_coord_matrix:c,u_is_text:+u,u_pitch_with_map:+r,u_is_along_line:i,u_is_variable_anchor:a,u_texsize:d,u_texture:0,u_translation:l,u_pitched_scale:f,u_is_offset:p,u_height_anchor_ground:+m}},wu=(e,t,n,r,i,a,o,s,c,l,u,d,f,p,m,h)=>{let g=o.transform;return z(Cu(e,t,n,r,i,a,o,s,c,l,u,d,p,m,h),{u_gamma_scale:r?Math.cos(g.pitch*Math.PI/180)*g.cameraToCenterDistance:1,u_device_pixel_ratio:o.pixelRatio,u_is_halo:+!!f,u_is_plain:1})},Tu=(e,t,n,r,i,a,o,s,c,l,u,d,f,p,m)=>z(wu(e,t,n,r,i,a,o,s,c,l,!0,u,!0,f,p,m),{u_texsize_icon:d,u_texture_icon:1}),Eu=(e,t)=>({u_opacity:new P(e,t.u_opacity),u_color:new qe(e,t.u_color)}),Du=(e,t)=>({u_opacity:new P(e,t.u_opacity),u_image:new F(e,t.u_image),u_pattern_tl_a:new j(e,t.u_pattern_tl_a),u_pattern_br_a:new j(e,t.u_pattern_br_a),u_pattern_tl_b:new j(e,t.u_pattern_tl_b),u_pattern_br_b:new j(e,t.u_pattern_br_b),u_texsize:new j(e,t.u_texsize),u_mix:new P(e,t.u_mix),u_pattern_size_a:new j(e,t.u_pattern_size_a),u_pattern_size_b:new j(e,t.u_pattern_size_b),u_scale_a:new P(e,t.u_scale_a),u_scale_b:new P(e,t.u_scale_b),u_pixel_coord_upper:new j(e,t.u_pixel_coord_upper),u_pixel_coord_lower:new j(e,t.u_pixel_coord_lower),u_tile_units_to_pixels:new P(e,t.u_tile_units_to_pixels)}),Ou=(e,t)=>({u_opacity:e,u_color:t}),ku=(e,t,n,r,i)=>z(Ol(n,i,t,r),{u_opacity:e}),Au=(e,t)=>({u_sun_pos:new ue(e,t.u_sun_pos),u_atmosphere_blend:new P(e,t.u_atmosphere_blend),u_globe_position:new ue(e,t.u_globe_position),u_globe_radius:new P(e,t.u_globe_radius),u_inv_proj_matrix:new ut(e,t.u_inv_proj_matrix)}),ju=(e,t,n,r,i)=>({u_sun_pos:e,u_atmosphere_blend:t,u_globe_position:n,u_globe_radius:r,u_inv_proj_matrix:i}),Mu=(e,t)=>({u_sky_color:new qe(e,t.u_sky_color),u_horizon_color:new qe(e,t.u_horizon_color),u_horizon:new j(e,t.u_horizon),u_horizon_normal:new j(e,t.u_horizon_normal),u_sky_horizon_blend:new P(e,t.u_sky_horizon_blend),u_sky_blend:new P(e,t.u_sky_blend)}),Nu=(e,t,n)=>{let r=Math.cos(t.rollInRadians),i=Math.sin(t.rollInRadians),a=Be(t),o=t.getProjectionData({overscaledTileID:null,applyGlobeMatrix:!0,applyTerrainMatrix:!0}).projectionTransition;return{u_sky_color:e.properties.get(`sky-color`),u_horizon_color:e.properties.get(`horizon-color`),u_horizon:[(t.width/2-a*i)*n,(t.height/2+a*r)*n],u_horizon_normal:[-i,r],u_sky_horizon_blend:e.properties.get(`sky-horizon-blend`)*t.height/2*n,u_sky_blend:o}},Pu=(e,t)=>{},Fu={fillExtrusion:kl,fillExtrusionPattern:Al,fill:Nl,fillPattern:Pl,fillOutline:Fl,fillOutlinePattern:Il,circle:Vl,collisionBox:Ul,collisionCircle:Wl,debug:ql,depth:Pu,clippingMask:Pu,heatmap:Yl,heatmapTexture:Xl,hillshade:$l,hillshadePrepare:eu,colorRelief:iu,line:ou,lineGradient:su,linePattern:cu,lineSDF:lu,lineGradientSDF:uu,layerOpacity:vu,raster:Ra,symbolIcon:bu,symbolSDF:xu,symbolTextAndIcon:Su,background:Eu,backgroundPattern:Du,terrain:vl,terrainDepth:yl,atmosphere:Au,sky:Mu};var Iu=class{constructor(e,t,n){this.context=e;let r=e.gl;this.buffer=r.createBuffer(),this.dynamicDraw=!!n,this.context.unbindVAO(),e.bindElementBuffer.set(this.buffer),r.bufferData(r.ELEMENT_ARRAY_BUFFER,t.arrayBuffer,this.dynamicDraw?r.DYNAMIC_DRAW:r.STATIC_DRAW),this.dynamicDraw||t.freeBufferAfterUpload()}bind(){this.context.bindElementBuffer.set(this.buffer)}updateData(e){let t=this.context.gl;if(!this.dynamicDraw)throw Error(`Attempted to update data while not in dynamic mode.`);this.context.unbindVAO(),this.bind(),t.bufferSubData(t.ELEMENT_ARRAY_BUFFER,0,e.arrayBuffer)}destroy(){let e=this.context.gl;this.buffer&&(e.deleteBuffer(this.buffer),delete this.buffer)}};const Lu={Int8:`BYTE`,Uint8:`UNSIGNED_BYTE`,Int16:`SHORT`,Uint16:`UNSIGNED_SHORT`,Int32:`INT`,Uint32:`UNSIGNED_INT`,Float32:`FLOAT`};var Ru=class{constructor(e,t,n,r){this.length=t.length,this.attributes=n,this.itemSize=t.bytesPerElement,this.dynamicDraw=r,this.context=e;let i=e.gl;this.buffer=i.createBuffer(),e.bindVertexBuffer.set(this.buffer),i.bufferData(i.ARRAY_BUFFER,t.arrayBuffer,this.dynamicDraw?i.DYNAMIC_DRAW:i.STATIC_DRAW),this.dynamicDraw||t.freeBufferAfterUpload()}bind(){this.context.bindVertexBuffer.set(this.buffer)}updateData(e){if(e.length!==this.length)throw Error(`Length of new data is ${e.length}, which doesn't match current length of ${this.length}`);let t=this.context.gl;this.bind(),t.bufferSubData(t.ARRAY_BUFFER,0,e.arrayBuffer)}enableAttributes(e,t){for(let n of this.attributes){let r=t.attributes[n.name];r!==void 0&&e.enableVertexAttribArray(r.location)}}setVertexAttribPointers(e,t,n){for(let r of this.attributes){let i=t.attributes[r.name];if(i!==void 0){let t=r.offset+this.itemSize*(n||0);i.isInteger?e.vertexAttribIPointer(i.location,r.components,e[Lu[r.type]],this.itemSize,t):e.vertexAttribPointer(i.location,r.components,e[Lu[r.type]],!1,this.itemSize,t)}}}destroy(){let e=this.context.gl;this.buffer&&(e.deleteBuffer(this.buffer),delete this.buffer)}},X=class{constructor(e){this.gl=e.gl,this.default=this.getDefault(),this.current=this.default,this.dirty=!1}get(){return this.current}set(e){}getDefault(){return this.default}setDefault(){this.set(this.default)}},zu=class extends X{getDefault(){return R.transparent}set(e){let t=this.current;e.r===t.r&&e.g===t.g&&e.b===t.b&&e.a===t.a&&!this.dirty||(this.gl.clearColor(e.r,e.g,e.b,e.a),this.current=e,this.dirty=!1)}},Bu=class extends X{getDefault(){return 1}set(e){e===this.current&&!this.dirty||(this.gl.clearDepth(e),this.current=e,this.dirty=!1)}},Vu=class extends X{getDefault(){return 0}set(e){e===this.current&&!this.dirty||(this.gl.clearStencil(e),this.current=e,this.dirty=!1)}},Hu=class extends X{getDefault(){return[!0,!0,!0,!0]}set(e){let t=this.current;e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&!this.dirty||(this.gl.colorMask(e[0],e[1],e[2],e[3]),this.current=e,this.dirty=!1)}},Uu=class extends X{getDefault(){return!0}set(e){e===this.current&&!this.dirty||(this.gl.depthMask(e),this.current=e,this.dirty=!1)}},Wu=class extends X{getDefault(){return 255}set(e){e===this.current&&!this.dirty||(this.gl.stencilMask(e),this.current=e,this.dirty=!1)}},Gu=class extends X{getDefault(){return{func:this.gl.ALWAYS,ref:0,mask:255}}set(e){let t=this.current;e.func===t.func&&e.ref===t.ref&&e.mask===t.mask&&!this.dirty||(this.gl.stencilFunc(e.func,e.ref,e.mask),this.current=e,this.dirty=!1)}},Ku=class extends X{getDefault(){let e=this.gl;return[e.KEEP,e.KEEP,e.KEEP]}set(e){let t=this.current;e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&!this.dirty||(this.gl.stencilOp(e[0],e[1],e[2]),this.current=e,this.dirty=!1)}},qu=class extends X{getDefault(){return!1}set(e){if(e===this.current&&!this.dirty)return;let t=this.gl;e?t.enable(t.STENCIL_TEST):t.disable(t.STENCIL_TEST),this.current=e,this.dirty=!1}},Ju=class extends X{getDefault(){return[0,1]}set(e){let t=this.current;e[0]===t[0]&&e[1]===t[1]&&!this.dirty||(this.gl.depthRange(e[0],e[1]),this.current=e,this.dirty=!1)}},Yu=class extends X{getDefault(){return!1}set(e){if(e===this.current&&!this.dirty)return;let t=this.gl;e?t.enable(t.DEPTH_TEST):t.disable(t.DEPTH_TEST),this.current=e,this.dirty=!1}},Xu=class extends X{getDefault(){return this.gl.LESS}set(e){e===this.current&&!this.dirty||(this.gl.depthFunc(e),this.current=e,this.dirty=!1)}},Zu=class extends X{getDefault(){return!1}set(e){if(e===this.current&&!this.dirty)return;let t=this.gl;e?t.enable(t.BLEND):t.disable(t.BLEND),this.current=e,this.dirty=!1}},Qu=class extends X{getDefault(){let e=this.gl;return[e.ONE,e.ZERO]}set(e){let t=this.current;e[0]===t[0]&&e[1]===t[1]&&!this.dirty||(this.gl.blendFunc(e[0],e[1]),this.current=e,this.dirty=!1)}},$u=class extends X{getDefault(){return R.transparent}set(e){let t=this.current;e.r===t.r&&e.g===t.g&&e.b===t.b&&e.a===t.a&&!this.dirty||(this.gl.blendColor(e.r,e.g,e.b,e.a),this.current=e,this.dirty=!1)}},ed=class extends X{getDefault(){return this.gl.FUNC_ADD}set(e){e===this.current&&!this.dirty||(this.gl.blendEquation(e),this.current=e,this.dirty=!1)}},td=class extends X{getDefault(){return!1}set(e){if(e===this.current&&!this.dirty)return;let t=this.gl;e?t.enable(t.CULL_FACE):t.disable(t.CULL_FACE),this.current=e,this.dirty=!1}},nd=class extends X{getDefault(){return this.gl.BACK}set(e){e===this.current&&!this.dirty||(this.gl.cullFace(e),this.current=e,this.dirty=!1)}},rd=class extends X{getDefault(){return this.gl.CCW}set(e){e===this.current&&!this.dirty||(this.gl.frontFace(e),this.current=e,this.dirty=!1)}},id=class extends X{getDefault(){return null}set(e){e===this.current&&!this.dirty||(this.gl.useProgram(e),this.current=e,this.dirty=!1)}},ad=class extends X{getDefault(){return this.gl.TEXTURE0}set(e){e===this.current&&!this.dirty||(this.gl.activeTexture(e),this.current=e,this.dirty=!1)}},od=class extends X{getDefault(){let e=this.gl;return[0,0,e.drawingBufferWidth,e.drawingBufferHeight]}set(e){let t=this.current;e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3]&&!this.dirty||(this.gl.viewport(e[0],e[1],e[2],e[3]),this.current=e,this.dirty=!1)}},sd=class extends X{getDefault(){return null}set(e){if(e===this.current&&!this.dirty)return;let t=this.gl;t.bindFramebuffer(t.FRAMEBUFFER,e),this.current=e,this.dirty=!1}},cd=class extends X{getDefault(){return null}set(e){if(e===this.current&&!this.dirty)return;let t=this.gl;t.bindRenderbuffer(t.RENDERBUFFER,e),this.current=e,this.dirty=!1}},ld=class extends X{getDefault(){return null}set(e){if(e===this.current&&!this.dirty)return;let t=this.gl;t.bindTexture(t.TEXTURE_2D,e),this.current=e,this.dirty=!1}},ud=class extends X{getDefault(){return null}set(e){if(e===this.current&&!this.dirty)return;let t=this.gl;t.bindBuffer(t.ARRAY_BUFFER,e),this.current=e,this.dirty=!1}},dd=class extends X{getDefault(){return null}set(e){let t=this.gl;t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,e),this.current=e,this.dirty=!1}},fd=class extends X{getDefault(){return null}set(e){e===this.current&&!this.dirty||(this.gl.bindVertexArray(e),this.current=e,this.dirty=!1)}},pd=class extends X{getDefault(){return 4}set(e){if(e===this.current&&!this.dirty)return;let t=this.gl;t.pixelStorei(t.UNPACK_ALIGNMENT,e),this.current=e,this.dirty=!1}},md=class extends X{getDefault(){return!1}set(e){if(e===this.current&&!this.dirty)return;let t=this.gl;t.pixelStorei(t.UNPACK_PREMULTIPLY_ALPHA_WEBGL,e),this.current=e,this.dirty=!1}},hd=class extends X{getDefault(){return!1}set(e){if(e===this.current&&!this.dirty)return;let t=this.gl;t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,e),this.current=e,this.dirty=!1}},gd=class extends X{constructor(e,t){super(e),this.context=e,this.parent=t}getDefault(){return null}},_d=class extends gd{setDirty(){this.dirty=!0}set(e){if(e===this.current&&!this.dirty)return;this.context.bindFramebuffer.set(this.parent);let t=this.gl;t.framebufferTexture2D(t.FRAMEBUFFER,t.COLOR_ATTACHMENT0,t.TEXTURE_2D,e,0),this.current=e,this.dirty=!1}},vd=class extends gd{set(e){if(e===this.current&&!this.dirty)return;this.context.bindFramebuffer.set(this.parent);let t=this.gl;t.framebufferRenderbuffer(t.FRAMEBUFFER,t.DEPTH_ATTACHMENT,t.RENDERBUFFER,e),this.current=e,this.dirty=!1}},yd=class extends gd{set(e){if(e===this.current&&!this.dirty)return;this.context.bindFramebuffer.set(this.parent);let t=this.gl;t.framebufferRenderbuffer(t.FRAMEBUFFER,t.DEPTH_STENCIL_ATTACHMENT,t.RENDERBUFFER,e),this.current=e,this.dirty=!1}},bd=class{constructor(e,t,n,r,i){this.context=e,this.width=t,this.height=n;let a=e.gl,o=this.framebuffer=a.createFramebuffer();if(this.colorAttachment=new _d(e,o),r)this.depthAttachment=i?new yd(e,o):new vd(e,o);else if(i)throw Error(`Stencil cannot be set without depth`)}destroy(){let e=this.context.gl,t=this.colorAttachment.get();if(t&&e.deleteTexture(t),this.depthAttachment){let t=this.depthAttachment.get();t&&e.deleteRenderbuffer(t)}e.deleteFramebuffer(this.framebuffer)}},xd=class{constructor(e,t,n){this.blendFunction=e,this.blendColor=t,this.mask=n}};xd.Replace=[1,0],xd.disabled=new xd(xd.Replace,R.transparent,[!1,!1,!1,!1]),xd.unblended=new xd(xd.Replace,R.transparent,[!0,!0,!0,!0]),xd.alphaBlended=new xd([1,771],R.transparent,[!0,!0,!0,!0]);var Sd=class{constructor(e){this.gl=e,this.clearColor=new zu(this),this.clearDepth=new Bu(this),this.clearStencil=new Vu(this),this.colorMask=new Hu(this),this.depthMask=new Uu(this),this.stencilMask=new Wu(this),this.stencilFunc=new Gu(this),this.stencilOp=new Ku(this),this.stencilTest=new qu(this),this.depthRange=new Ju(this),this.depthTest=new Yu(this),this.depthFunc=new Xu(this),this.blend=new Zu(this),this.blendFunc=new Qu(this),this.blendColor=new $u(this),this.blendEquation=new ed(this),this.cullFace=new td(this),this.cullFaceSide=new nd(this),this.frontFace=new rd(this),this.program=new id(this),this.activeTexture=new ad(this),this.viewport=new od(this),this.bindFramebuffer=new sd(this),this.bindRenderbuffer=new cd(this),this.bindTexture=new ld(this),this.bindVertexBuffer=new ud(this),this.bindElementBuffer=new dd(this),this.bindVertexArray=new fd(this),this.pixelStoreUnpack=new pd(this),this.pixelStoreUnpackPremultiplyAlpha=new md(this),this.pixelStoreUnpackFlipY=new hd(this),this.extTextureFilterAnisotropic=e.getExtension(`EXT_texture_filter_anisotropic`),this.extTextureFilterAnisotropic&&(this.extTextureFilterAnisotropicMax=e.getParameter(this.extTextureFilterAnisotropic.MAX_TEXTURE_MAX_ANISOTROPY_EXT)),this.maxTextureSize=e.getParameter(e.MAX_TEXTURE_SIZE),e.getExtension(`EXT_color_buffer_half_float`),e.getExtension(`EXT_color_buffer_float`)}setDefault(){this.unbindVAO(),this.clearColor.setDefault(),this.clearDepth.setDefault(),this.clearStencil.setDefault(),this.colorMask.setDefault(),this.depthMask.setDefault(),this.stencilMask.setDefault(),this.stencilFunc.setDefault(),this.stencilOp.setDefault(),this.stencilTest.setDefault(),this.depthRange.setDefault(),this.depthTest.setDefault(),this.depthFunc.setDefault(),this.blend.setDefault(),this.blendFunc.setDefault(),this.blendColor.setDefault(),this.blendEquation.setDefault(),this.cullFace.setDefault(),this.cullFaceSide.setDefault(),this.frontFace.setDefault(),this.program.setDefault(),this.activeTexture.setDefault(),this.bindFramebuffer.setDefault(),this.pixelStoreUnpack.setDefault(),this.pixelStoreUnpackPremultiplyAlpha.setDefault(),this.pixelStoreUnpackFlipY.setDefault()}setDirty(){this.clearColor.dirty=!0,this.clearDepth.dirty=!0,this.clearStencil.dirty=!0,this.colorMask.dirty=!0,this.depthMask.dirty=!0,this.stencilMask.dirty=!0,this.stencilFunc.dirty=!0,this.stencilOp.dirty=!0,this.stencilTest.dirty=!0,this.depthRange.dirty=!0,this.depthTest.dirty=!0,this.depthFunc.dirty=!0,this.blend.dirty=!0,this.blendFunc.dirty=!0,this.blendColor.dirty=!0,this.blendEquation.dirty=!0,this.cullFace.dirty=!0,this.cullFaceSide.dirty=!0,this.frontFace.dirty=!0,this.program.dirty=!0,this.activeTexture.dirty=!0,this.viewport.dirty=!0,this.bindFramebuffer.dirty=!0,this.bindRenderbuffer.dirty=!0,this.bindTexture.dirty=!0,this.bindVertexBuffer.dirty=!0,this.bindElementBuffer.dirty=!0,this.bindVertexArray.dirty=!0,this.pixelStoreUnpack.dirty=!0,this.pixelStoreUnpackPremultiplyAlpha.dirty=!0,this.pixelStoreUnpackFlipY.dirty=!0}setCustomLayerDefaults(){this.unbindVAO(),this.cullFace.setDefault(),this.activeTexture.setDefault(),this.pixelStoreUnpack.setDefault(),this.pixelStoreUnpackPremultiplyAlpha.setDefault(),this.pixelStoreUnpackFlipY.setDefault()}createIndexBuffer(e,t){return new Iu(this,e,t)}createVertexBuffer(e,t,n){return new Ru(this,e,t,n)}createRenderbuffer(e,t,n){let r=this.gl,i=r.createRenderbuffer();return this.bindRenderbuffer.set(i),r.renderbufferStorage(r.RENDERBUFFER,e,t,n),this.bindRenderbuffer.set(null),i}createFramebuffer(e,t,n,r){return new bd(this,e,t,n,r)}clear({color:e,depth:t,stencil:n}){let r=this.gl,i=0;e&&(i|=r.COLOR_BUFFER_BIT,this.clearColor.set(e),this.colorMask.set([!0,!0,!0,!0])),t!==void 0&&(i|=r.DEPTH_BUFFER_BIT,this.depthRange.set([0,1]),this.clearDepth.set(t),this.depthMask.set(!0)),n!==void 0&&(i|=r.STENCIL_BUFFER_BIT,this.clearStencil.set(n),this.stencilMask.set(255)),r.clear(i)}setCullFace(e){e.enable===!1?this.cullFace.set(!1):(this.cullFace.set(!0),this.cullFaceSide.set(e.mode),this.frontFace.set(e.frontFace))}setDepthMode(e){e.func===this.gl.ALWAYS&&!e.mask?this.depthTest.set(!1):(this.depthTest.set(!0),this.depthFunc.set(e.func),this.depthMask.set(e.mask),this.depthRange.set(e.range))}setStencilMode(e){e.test.func===this.gl.ALWAYS&&!e.mask?this.stencilTest.set(!1):(this.stencilTest.set(!0),this.stencilMask.set(e.mask),this.stencilOp.set([e.fail,e.depthFail,e.pass]),this.stencilFunc.set({func:e.test.func,ref:e.ref,mask:e.test.mask}))}setColorMode(e){Ve(e.blendFunction,xd.Replace)?this.blend.set(!1):(this.blend.set(!0),this.blendFunc.set(e.blendFunction),this.blendColor.set(e.blendColor)),this.colorMask.set(e.mask)}createVertexArray(){return this.gl.createVertexArray()}deleteVertexArray(e){this.gl.deleteVertexArray(e)}unbindVAO(){this.bindVertexArray.set(null)}},Z=class{constructor(e,t,n){this.func=e,this.mask=t,this.range=n}};Z.ReadOnly=!1,Z.ReadWrite=!0,Z.disabled=new Z(519,Z.ReadOnly,[0,1]);const Cd=7680;var Q=class{constructor(e,t,n,r,i,a){this.test=e,this.ref=t,this.mask=n,this.fail=r,this.depthFail=i,this.pass=a}};Q.disabled=new Q({func:519,mask:0},0,0,Cd,Cd,Cd);const wd=1029,Td=2305;var $=class{constructor(e,t,n){this.enable=e,this.mode=t,this.frontFace=n}};$.disabled=new $(!1,wd,Td),$.backCCW=new $(!0,wd,Td),$.frontCCW=new $(!0,1028,Td);let Ed;function Dd(e,t,n,r,i){let a=e.context,o=e.transform,s=a.gl,c=e.useProgram(`collisionBox`),l=[],u=0,d=0;for(let f of r){let r=t.getTile(f).getBucket(n);if(!r)continue;let p=i?r.textCollisionBox:r.iconCollisionBox,m=r.collisionCircleArray;m.length>0&&(l.push({circleArray:m,circleOffset:d,coord:f}),u+=m.length/4,d=u),p&&c.draw(a,s.LINES,Z.disabled,Q.disabled,e.colorModeForRenderPass(),$.disabled,Gl(e.transform),e.style.map.terrain?.getTerrainData(f),o.getProjectionData({overscaledTileID:f,applyGlobeMatrix:!0,applyTerrainMatrix:!0}),n.id,p.layoutVertexBuffer,p.indexBuffer,p.segments,null,e.transform.zoom,null,null,p.collisionVertexBuffer)}if(!i||!l.length)return;let f=e.useProgram(`collisionCircle`),p=new pt;p.resize(u*4),p._trim();let m=0;for(let e of l)for(let t=0;tu.getElevation(i,e,t):void 0;Pd(a,d,f,c,l,g,t,m,_,le(l,e,o,s),i.toUnwrapped(),r,n.layout.get(`symbol-height-anchor`)===`ground`)}}}function Nd(e,t,n,r,i,a){let o=t.tileAnchorPoint.add(new l(t.translation[0],t.translation[1]));if(t.pitchWithMap){let e=r.mult(a);n||(e=e.rotate(-i));let s=o.add(e);return Ko(s.x,s.y,t.pitchedLabelPlaneMatrix,Go(t,s.x,s.y)).point}if(n){let n=ts(t.tileAnchorPoint.x+1,t.tileAnchorPoint.y,t).point.sub(e),i=Math.atan(n.y/n.x)+(n.x<0?Math.PI:0);return e.add(r.rotate(i))}return e.add(r)}function Pd(e,t,n,r,a,o,s,c,u,d,f,p,m){let h=e.text.placedSymbolArray,g=e.text.dynamicLayoutVertexArray,_=e.icon.dynamicLayoutVertexArray,v={};g.clear();for(let _=0;_=0&&(v[y.associatedIconIndex]={shiftedAnchor:k,angle:A})}}if(u){_.clear();let t=e.icon.placedSymbolArray;for(let e=0;ee.style.map.terrain.getElevation(s,t,n):void 0;Yo(c,e,i,ie,t,_,l,n.layout.get(`text-rotation-alignment`)===`map`,s.toUnwrapped(),h.width,h.height,oe,r)}let pe=i&&C||ue,me=_?ie:e.transform.clipSpaceToPixelsMatrix,he=v||pe?kd:me,ge=p&&n.paint.get(i?`text-halo-width`:`icon-halo-width`).constantOr(1)!==0,_e;_e=p?c.iconsInText?Tu(S.kind,ee,y,_,v,pe,e,he,N,oe,k,A,T,de,fe):wu(S.kind,ee,y,_,v,pe,e,he,N,oe,i,k,ge,T,de,fe):Cu(S.kind,ee,y,_,v,pe,e,he,N,oe,i,k,T,de,fe);let ve={program:D,buffers:u,uniformValues:_e,projectionData:se,atlasTexture:j,atlasTextureIcon:te,atlasInterpolation:M,atlasInterpolationIcon:ne,isSDF:p,hasHalo:ge};if(b&&c.canOverlap){x=!0;let e=u.segments.get();for(let t of e)w.push({segments:new ae([t]),sortKey:t.sortKey,state:ve,terrainData:O})}else w.push({segments:u.segments,sortKey:0,state:ve,terrainData:O})}x&&w.sort((e,t)=>e.sortKey-t.sortKey);let E=n.paint.get(i?`text-halo-width`:`icon-halo-width`).constantOr(null)??1/0,D=n.layout.get(`text-letter-spacing`).constantOr(0)*24<0||E>1;for(let t of w){let r=t.state;p.activeTexture.set(m.TEXTURE0),r.atlasTexture.bind(r.atlasInterpolation,m.CLAMP_TO_EDGE),r.atlasTextureIcon&&(p.activeTexture.set(m.TEXTURE1),r.atlasTextureIcon&&r.atlasTextureIcon.bind(r.atlasInterpolationIcon,m.CLAMP_TO_EDGE));let i=r.isSDF&&r.hasHalo;if(i){let i=r.uniformValues;i.u_is_halo=1,D&&(i.u_is_plain=0,Ld(r.buffers,t.segments,n,e,r.program,S,u,d,i,r.projectionData,t.terrainData),i.u_is_halo=0,i.u_is_plain=1)}Ld(r.buffers,t.segments,n,e,r.program,S,u,d,r.uniformValues,r.projectionData,t.terrainData),i&&!D&&(r.uniformValues.u_is_halo=0)}}function Ld(e,t,n,r,i,a,o,s,c,l,u){let d=r.context,f=d.gl;i.draw(d,f.TRIANGLES,a,o,s,$.backCCW,c,u,l,n.id,e.layoutVertexBuffer,e.indexBuffer,t,n.paint,r.transform.zoom,e.programConfigurations.get(n.id),e.dynamicLayoutVertexBuffer,e.opacityVertexBuffer)}function Rd(e,t,n,r,i){if(e.renderPass!==`translucent`)return;let{isRenderingToTexture:a}=i,o=n.paint.get(`circle-opacity`),s=n.paint.get(`circle-stroke-width`),c=n.paint.get(`circle-stroke-opacity`),l=!n.layout.get(`circle-sort-key`).isConstant();if(o.constantOr(1)===0&&(s.constantOr(1)===0||c.constantOr(1)===0))return;let u=e.context,d=u.gl,f=e.transform,p=e.getDepthModeForSublayer(0,Z.ReadOnly),m=Q.disabled,h=e.colorModeForRenderPass(),g=[],_=f.getCircleRadiusCorrection();for(let i of r){let r=t.getTile(i),o=r.getBucket(n);if(!o)continue;let s=n.paint.get(`circle-translate`),c=n.paint.get(`circle-translate-anchor`),u=le(f,r,s,c),d=o.programConfigurations.get(n.id),p=e.useProgram(`circle`,d),m=o.layoutVertexBuffer,h=o.indexBuffer,v=e.style.map.terrain?.getTerrainData(i),y={programConfiguration:d,program:p,layoutVertexBuffer:m,indexBuffer:h,uniformValues:Hl(e,r,n,u,_),terrainData:v,projectionData:f.getProjectionData({overscaledTileID:i,applyGlobeMatrix:!a,applyTerrainMatrix:!0})};if(l){let e=o.segments.get();for(let t of e)g.push({segments:new ae([t]),sortKey:t.sortKey,state:y})}else g.push({segments:o.segments,sortKey:0,state:y})}l&&g.sort((e,t)=>e.sortKey-t.sortKey);for(let t of g){let{programConfiguration:r,program:i,layoutVertexBuffer:a,indexBuffer:o,uniformValues:s,terrainData:c,projectionData:l}=t.state,f=t.segments;i.draw(u,d.TRIANGLES,p,m,h,$.backCCW,s,c,l,n.id,a,o,f,n.paint,e.transform.zoom,r)}}function zd(e,t,n,r,i){if(n.paint.get(`heatmap-opacity`)===0)return;let a=e.context,{isRenderingToTexture:o,isRenderingGlobe:s}=i;if(e.style.map.terrain){for(let i of r){let r=t.getTile(i);t.hasRenderableParent(i)||(e.renderPass===`offscreen`?Hd(e,r,n,i,s):e.renderPass===`translucent`&&Ud(e,n,i,o,s))}a.viewport.set([0,0,e.width,e.height])}else e.renderPass===`offscreen`?Bd(e,t,n,r):e.renderPass===`translucent`&&Vd(e,n)}function Bd(e,t,n,r){let i=e.context,a=i.gl,o=e.transform,s=Q.disabled,c=new xd([a.ONE,a.ONE],R.transparent,[!0,!0,!0,!0]);Wd(i,e,n),i.clear({color:R.transparent});for(let l of r){if(t.hasRenderableParent(l))continue;let r=t.getTile(l),u=r.getBucket(n);if(!u)continue;let d=u.programConfigurations.get(n.id),f=e.useProgram(`heatmap`,d),p=o.getProjectionData({overscaledTileID:l,applyGlobeMatrix:!0,applyTerrainMatrix:!1}),m=o.getCircleRadiusCorrection();f.draw(i,a.TRIANGLES,Z.disabled,s,c,$.backCCW,Zl(r,o.zoom,n.paint.get(`heatmap-intensity`),m),null,p,n.id,u.layoutVertexBuffer,u.indexBuffer,u.segments,n.paint,o.zoom,d)}i.viewport.set([0,0,e.width,e.height])}function Vd(e,t){let n=e.context,r=n.gl;n.setColorMode(e.colorModeForRenderPass());let i=t.heatmapFbos.get(nt);i&&(n.activeTexture.set(r.TEXTURE0),r.bindTexture(r.TEXTURE_2D,i.colorAttachment.get()),n.activeTexture.set(r.TEXTURE1),Kd(n,t).bind(r.LINEAR,r.CLAMP_TO_EDGE),e.useProgram(`heatmapTexture`).draw(n,r.TRIANGLES,Z.disabled,Q.disabled,e.colorModeForRenderPass(),$.disabled,Ql(e,t,0,1),null,null,t.id,e.viewportBuffer,e.quadTriangleIndexBuffer,e.viewportSegments,t.paint,e.transform.zoom))}function Hd(e,t,n,r,i){let a=e.context,o=a.gl,s=Q.disabled,c=new xd([o.ONE,o.ONE],R.transparent,[!0,!0,!0,!0]),l=t.getBucket(n);if(!l)return;let u=r.key,d=n.heatmapFbos.get(u);d||(d=Gd(a,t.tileSize,t.tileSize),n.heatmapFbos.set(u,d)),a.bindFramebuffer.set(d.framebuffer),a.viewport.set([0,0,t.tileSize,t.tileSize]),a.clear({color:R.transparent});let f=l.programConfigurations.get(n.id),p=e.useProgram(`heatmap`,f,!i),m=e.transform.getProjectionData({overscaledTileID:t.tileID,applyGlobeMatrix:!0,applyTerrainMatrix:!0}),h=e.style.map.terrain.getTerrainData(r);p.draw(a,o.TRIANGLES,Z.disabled,s,c,$.disabled,Zl(t,e.transform.zoom,n.paint.get(`heatmap-intensity`),1),h,m,n.id,l.layoutVertexBuffer,l.indexBuffer,l.segments,n.paint,e.transform.zoom,f)}function Ud(e,t,n,r,i){let a=e.context,o=a.gl,s=e.transform;a.setColorMode(e.colorModeForRenderPass());let c=Kd(a,t),l=n.key,u=t.heatmapFbos.get(l);if(!u)return;a.activeTexture.set(o.TEXTURE0),o.bindTexture(o.TEXTURE_2D,u.colorAttachment.get()),a.activeTexture.set(o.TEXTURE1),c.bind(o.LINEAR,o.CLAMP_TO_EDGE);let d=s.getProjectionData({overscaledTileID:n,applyTerrainMatrix:i,applyGlobeMatrix:!r});e.useProgram(`heatmapTexture`).draw(a,o.TRIANGLES,Z.disabled,Q.disabled,e.colorModeForRenderPass(),$.disabled,Ql(e,t,0,1),null,d,t.id,e.rasterBoundsBuffer,e.quadTriangleIndexBuffer,e.rasterBoundsSegments,t.paint,s.zoom),u.destroy(),t.heatmapFbos.delete(l)}function Wd(e,t,n){let r=e.gl;e.activeTexture.set(r.TEXTURE1),e.viewport.set([0,0,t.width/4,t.height/4]);let i=n.heatmapFbos.get(nt);i?(r.bindTexture(r.TEXTURE_2D,i.colorAttachment.get()),e.bindFramebuffer.set(i.framebuffer)):(i=Gd(e,t.width/4,t.height/4),n.heatmapFbos.set(nt,i))}function Gd(e,t,n){let r=e.gl,i=r.createTexture();r.bindTexture(r.TEXTURE_2D,i),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_WRAP_S,r.CLAMP_TO_EDGE),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_WRAP_T,r.CLAMP_TO_EDGE),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_MIN_FILTER,r.LINEAR),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_MAG_FILTER,r.LINEAR),r.texStorage2D(r.TEXTURE_2D,1,r.RGBA16F,t,n);let a=e.createFramebuffer(t,n,!1,!1);return a.colorAttachment.set(i),a}function Kd(e,t){return t.colorRampTexture||=new _(e,t.colorRamp,e.gl.RGBA),t.colorRampTexture}function qd(e,t,n,r){let i=e.context,a=i.bindFramebuffer.get(),o=i.viewport.get(),[,,s,c]=o;return Jd(e,s,c),i.viewport.set([0,0,s,c]),i.clear({color:R.transparent,depth:1,stencil:0}),e.currentStencilSource=void 0,e.renderTileClippingMasks(t,n,r),{compositeTarget:a,compositeViewport:o}}function Jd(e,t,n){let r=e.context.gl;if(!e.layerOpacityFbo){let i=e.context.createFramebuffer(t,n,!0,!0),a=r.createTexture();r.bindTexture(r.TEXTURE_2D,a),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_WRAP_S,r.CLAMP_TO_EDGE),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_WRAP_T,r.CLAMP_TO_EDGE),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_MIN_FILTER,r.LINEAR),r.texParameteri(r.TEXTURE_2D,r.TEXTURE_MAG_FILTER,r.LINEAR),r.texImage2D(r.TEXTURE_2D,0,r.RGBA,t,n,0,r.RGBA,r.UNSIGNED_BYTE,null),i.colorAttachment.set(a),i.depthAttachment.set(e.context.createRenderbuffer(r.DEPTH_STENCIL,t,n)),e.layerOpacityFbo=i,e.context.bindFramebuffer.set(e.layerOpacityFbo.framebuffer);return}if(e.layerOpacityFbo.width===t&&e.layerOpacityFbo.height===n){e.context.bindFramebuffer.set(e.layerOpacityFbo.framebuffer);return}let i=e.layerOpacityFbo;r.bindTexture(r.TEXTURE_2D,i.colorAttachment.get()),r.texImage2D(r.TEXTURE_2D,0,r.RGBA,t,n,0,r.RGBA,r.UNSIGNED_BYTE,null),e.context.bindRenderbuffer.set(i.depthAttachment.get()),r.renderbufferStorage(r.RENDERBUFFER,r.DEPTH_STENCIL,t,n),e.context.bindRenderbuffer.set(null),i.width=t,i.height=n,e.context.bindFramebuffer.set(i.framebuffer)}function Yd(e,t,n,r){let i=e.context,a=i.gl;i.bindFramebuffer.set(n.compositeTarget),i.viewport.set(n.compositeViewport),i.activeTexture.set(a.TEXTURE0),a.bindTexture(a.TEXTURE_2D,e.layerOpacityFbo.colorAttachment.get()),e.useProgram(`layerOpacity`).draw(i,a.TRIANGLES,Z.disabled,Q.disabled,e.colorModeForRenderPass(),$.disabled,yu(t,0),null,null,r.id,e.viewportBuffer,e.quadTriangleIndexBuffer,e.viewportSegments,r.paint,e.transform.zoom),e.currentStencilSource=void 0}function Xd(e,t,n,r,i,a,o,s){let c=256;if(i.stepInterpolant){let r=t.getSource().maxzoom,i=o.canonical.z===r?Math.ceil(1<e.options.anisotropicFilterPitch&&m.texParameterf(m.TEXTURE_2D,p.extTextureFilterAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT,p.extTextureFilterAnisotropicMax);let k=e.getTerrainDataForTile(w,u),A=g.getProjectionData({overscaledTileID:w,aligned:y,applyGlobeMatrix:!u,applyTerrainMatrix:!0}),j=za(ee,D,O.fadeMix,n,s,c),M=d??_.getMeshFromTileID(p,w.canonical,a,o,`raster`),te=i?i[w.overscaledZ]:Q.disabled;h.draw(p,m.TRIANGLES,r,te,v,l?$.frontCCW:$.backCCW,j,k,A,n.id,M.vertexBuffer,M.indexBuffer,M.segments)}}function bf(e,t,n,r){let i={parentTile:null,parentScaleBy:1,parentTopLeft:[0,0],fadeValues:{tileOpacity:1,parentTileOpacity:1,fadeMix:{opacity:1,mix:0}}};if(n===0||r)return i;if(e.fadingParentID){let r=t.getLoadedTile(e.fadingParentID);if(!r)return i;let a=2**(r.tileID.overscaledZ-e.tileID.overscaledZ);return{parentTile:r,parentScaleBy:a,parentTopLeft:[e.tileID.canonical.x*a%1,e.tileID.canonical.y*a%1],fadeValues:xf(e,r,n)}}return e.selfFading?{parentTile:null,parentScaleBy:1,parentTopLeft:[0,0],fadeValues:Sf(e,n)}:i}function xf(e,t,n){let r=U(),i=(r-e.timeAdded)/n,a=(r-t.timeAdded)/n,o=e.fadingDirection===1,s=M(i,0,1),c=M(1-a,0,1),l=o?s:c;return{tileOpacity:l,parentTileOpacity:o?c:s,fadeMix:{opacity:1,mix:1-l}}}function Sf(e,t){let n=(U()-e.timeAdded)/t,r=M(n,0,1);return{tileOpacity:r,fadeMix:{opacity:r,mix:0}}}function Cf(e,t,n,r,i){let a=n.paint.get(`background-color`),o=n.paint.get(`background-opacity`);if(o===0)return;let{isRenderingToTexture:s}=i,c=e.context,l=c.gl,u=e.style.projection,d=e.transform,f=d.tileSize,p=n.paint.get(`background-pattern`);if(e.isPatternMissing(p))return;let m=!p&&a.a===1&&o===1&&e.opaquePassEnabledForLayer()?`opaque`:`translucent`;if(e.renderPass!==m)return;let h=Q.disabled,g=e.getDepthModeForSublayer(0,m===`opaque`?Z.ReadWrite:Z.ReadOnly),_=e.colorModeForRenderPass(),v=e.useProgram(p?`backgroundPattern`:`background`),y=r||So(d,{tileSize:f,terrain:e.style.map.terrain});p&&(c.activeTexture.set(l.TEXTURE0),e.patternAtlas.bind(e.context));let b=n.getCrossfadeParameters();for(let t of y){let r=d.getProjectionData({overscaledTileID:t,applyGlobeMatrix:!s,applyTerrainMatrix:!0}),i=p?ku(o,e,p,{tileID:t,tileSize:f},b):Ou(o,a),m=e.getTerrainDataForTile(t,s),y=u.getMeshFromTileID(c,t.canonical,!1,!0,`raster`);v.draw(c,l.TRIANGLES,g,h,_,$.backCCW,i,m,r,n.id,y.vertexBuffer,y.indexBuffer,y.segments)}}const wf=new R(1,0,0,1),Tf=new R(0,1,0,1),Ef=new R(0,0,1,1),Df=new R(1,0,1,1),Of=new R(0,1,1,1);function kf(e){let t=e.transform.padding;jf(e,e.transform.height-(t.top||0),3,wf),jf(e,t.bottom||0,3,Tf),Mf(e,t.left||0,3,Ef),Mf(e,e.transform.width-(t.right||0),3,Df);let n=e.transform.centerPoint;Af(e,n.x,e.transform.height-n.y,Of)}function Af(e,t,n,r){Nf(e,t-1,n-10,2,20,r),Nf(e,t-10,n-1,20,2,r)}function jf(e,t,n,r){Nf(e,0,t+n/2,e.transform.width,n,r)}function Mf(e,t,n,r){Nf(e,t-n/2,0,n,e.transform.height,r)}function Nf(e,t,n,r,i,a){let o=e.context,s=o.gl;s.enable(s.SCISSOR_TEST),s.scissor(t*e.pixelRatio,n*e.pixelRatio,r*e.pixelRatio,i*e.pixelRatio),o.clear({color:a}),s.disable(s.SCISSOR_TEST)}function Pf(e,t,n){for(let r of n)Ff(e,t,r)}function Ff(e,t,n){let r=e.context,i=r.gl,a=e.useProgram(`debug`),o=Z.disabled,s=Q.disabled,c=e.colorModeForRenderPass(),l=`$debug`,u=e.style.map.terrain?.getTerrainData(n);r.activeTexture.set(i.TEXTURE0);let d=t.getTileByID(n.key).latestRawTileData?.byteLength||0,f=Math.floor(d/1024),p=t.getTile(n).tileSize,m=512/Math.min(p,512)*(n.overscaledZ/e.transform.zoom)*.5,h=n.canonical.toString();n.overscaledZ!==n.canonical.z&&(h+=` => ${n.overscaledZ}`),If(e,`${h} ${f}kB`);let g=e.transform.getProjectionData({overscaledTileID:n,applyGlobeMatrix:!0,applyTerrainMatrix:!0});a.draw(r,i.TRIANGLES,o,s,xd.alphaBlended,$.disabled,Jl(R.transparent,m),null,g,l,e.debugBuffer,e.quadTriangleIndexBuffer,e.debugSegments),a.draw(r,i.LINE_STRIP,o,s,c,$.disabled,Jl(R.red),u,g,l,e.debugBuffer,e.tileBorderIndexBuffer,e.debugSegments)}function If(e,t){e.initDebugOverlayCanvas();let n=e.debugOverlayCanvas,r=e.context.gl,i=e.debugOverlayCanvas.getContext(`2d`);i.clearRect(0,0,n.width,n.height),i.shadowColor=`white`,i.shadowBlur=2,i.lineWidth=1.5,i.strokeStyle=`white`,i.textBaseline=`top`,i.font=`bold 36px Open Sans, sans-serif`,i.fillText(t,5,5),i.strokeText(t,5,5),e.debugOverlayTexture.update(n),e.debugOverlayTexture.bind(r.LINEAR,r.CLAMP_TO_EDGE)}function Lf(e,t){let n=null,r=Object.values(e._layers).flatMap(n=>n.source&&!n.isHidden(t)?[e.tileManagers[n.source]]:[]),i=r.filter(e=>e.getSource().type===`vector`),a=r.filter(e=>e.getSource().type!==`vector`),o=e=>{(!n||n.getSource().maxzoomc.getProjectionData({overscaledTileID:new $t(e.tileID.canonical.z,e.tileID.wrap??0,e.tileID.canonical.z,e.tileID.canonical.x,e.tileID.canonical.y),aligned:e.aligned,applyGlobeMatrix:e.applyGlobeMatrix,applyTerrainMatrix:e.applyTerrainMatrix})},d=o.renderingMode?o.renderingMode:`2d`;if(e.renderPass===`offscreen`){let t=o.prerender;t&&(e.setCustomLayerDefaults(),a.setColorMode(e.colorModeForRenderPass()),t.call(o,a.gl,u),a.setDirty(),e.setBaseState())}else if(e.renderPass===`translucent`){e.setCustomLayerDefaults(),a.setColorMode(e.colorModeForRenderPass()),a.setStencilMode(Q.disabled);let t=d===`3d`?e.getDepthModeFor3D():e.getDepthModeForSublayer(0,Z.ReadOnly);a.setDepthMode(t),o.render(a.gl,u),a.setDirty(),e.setBaseState(),a.bindFramebuffer.set(null)}}function zf(e,t){let n=e.context,r=n.gl,i=e.transform,a=xd.unblended,o=new Z(r.LEQUAL,Z.ReadWrite,[0,1]),s=t.tileManager.getRenderableTiles(),c=e.useProgram(`terrainDepth`);n.bindFramebuffer.set(t.getFramebuffer().framebuffer),n.viewport.set([0,0,e.width/devicePixelRatio,e.height/devicePixelRatio]),n.clear({color:R.white,depth:1});for(let e of s){let s=t.getTerrainMesh(e.tileID),l=t.getTerrainData(e.tileID),u=i.getProjectionData({overscaledTileID:e.tileID,applyTerrainMatrix:!1,applyGlobeMatrix:!0}),d=xl(t.getSkirtLength(i.zoom));c.draw(n,r.TRIANGLES,o,Q.disabled,a,$.backCCW,d,l,u,`terrain`,s.vertexBuffer,s.indexBuffer,s.segments)}n.bindFramebuffer.set(null),n.viewport.set([0,0,e.width,e.height])}function Bf(e,t,n,r){let{isRenderingGlobe:i}=r,a=e.context,o=a.gl,s=e.transform,c=e.colorModeForRenderPass(),l=e.getDepthModeFor3D(),u=e.useProgram(`terrain`);a.bindFramebuffer.set(null),a.viewport.set([0,0,e.width,e.height]);for(let r of n){let n=t.getTerrainMesh(r.tileID),d=e.renderToTexture.getTexture(r),f=t.getTerrainData(r.tileID);a.activeTexture.set(o.TEXTURE0),o.bindTexture(o.TEXTURE_2D,d.texture);let p=t.getSkirtLength(s.zoom),m=s.calculateFogMatrix(r.tileID.toUnwrapped()),h=bl(p,m,e.style.sky,s.pitch,i),g=s.getProjectionData({overscaledTileID:r.tileID,applyTerrainMatrix:!1,applyGlobeMatrix:!0});u.draw(a,o.TRIANGLES,l,Q.disabled,c,$.backCCW,h,f,g,`terrain`,n.vertexBuffer,n.indexBuffer,n.segments)}}function Vf(e,t){if(!t.mesh){let n=new Un;n.emplaceBack(-1,-1),n.emplaceBack(1,-1),n.emplaceBack(1,1),n.emplaceBack(-1,1);let r=new gt;r.emplaceBack(0,1,2),r.emplaceBack(0,2,3),t.mesh=new Ua(e.createVertexBuffer(n,Wa.members),e.createIndexBuffer(r),ae.simpleSegment(0,0,n.length,r.length))}return t.mesh}function Hf(e,t){let n=e.context,r=n.gl,i=Nu(t,e.transform,e.pixelRatio),a=new Z(r.LEQUAL,Z.ReadWrite,[0,1]),o=Q.disabled,s=e.colorModeForRenderPass(),c=e.useProgram(`sky`),l=Vf(n,t);c.draw(n,r.TRIANGLES,a,o,s,$.disabled,i,null,void 0,`sky`,l.vertexBuffer,l.indexBuffer,l.segments)}function Uf(e,t){let n=e.getCartesianPosition();Yn(n,n);let r=$e(new Float64Array(16));return e.properties.get(`anchor`)===`map`&&(we(r,r,t.rollInRadians),a(r,r,-t.pitchInRadians),we(r,r,t.bearingInRadians),a(r,r,t.center.lat*Math.PI/180),pn(r,r,-t.center.lng*Math.PI/180)),en(n,n,r),n}function Wf(e,t,n){let r=e.context,i=r.gl,a=e.useProgram(`atmosphere`),o=new Z(i.LEQUAL,Z.ReadOnly,[0,1]),s=e.transform,c=Uf(n,e.transform),l=s.getProjectionData({overscaledTileID:null,applyGlobeMatrix:!0,applyTerrainMatrix:!0}),u=t.properties.get(`atmosphere-blend`)*l.projectionTransition;if(u===0)return;let d=Lc(s.worldSize,s.center.lat),f=s.inverseProjectionMatrix,p=new Float64Array(4);p[3]=1,Gt(p,p,s.modelViewProjectionMatrix),p[0]/=p[3],p[1]/=p[3],p[2]/=p[3],p[3]=1,Gt(p,p,f),p[0]/=p[3],p[1]/=p[3],p[2]/=p[3],p[3]=1;let m=[p[0],p[1],p[2]],h=ju(c,u,m,d,f),g=Vf(r,t);a.draw(r,i.TRIANGLES,o,Q.disabled,xd.alphaBlended,$.disabled,h,null,null,`atmosphere`,g.vertexBuffer,g.indexBuffer,g.segments)}const Gf={symbol:Ad,circle:Rd,heatmap:zd,line:tf,fill:af,fillExtrusion:lf,hillshade:df,colorRelief:mf,raster:vf,background:Cf,sky:Hf,atmosphere:Wf,custom:Rf,debug:Pf,debugPadding:kf,terrainDepth:zf};var Kf=class e{constructor(e,t){this.drawFunctions=Gf,this.context=new Sd(e),this.transform=t,this.layerOpacityFbo=null,this._tileTextures={},this._rttObjectRecyclePool=[],this._rttSharedFbo=null,this.terrainFacilitator={depthDirty:!0,matrix:$e(new Float64Array(16)),renderTime:0},this.setup(),this.numSublayers=No.maxOverzooming+No.maxUnderzooming+1,this.depthEpsilon=1/2**16,this.crossTileSymbolIndex=new Bs}resize(e,t,n){if(this.width=Math.floor(e*n),this.height=Math.floor(t*n),this.pixelRatio=n,this.context.viewport.set([0,0,this.width,this.height]),this.style)for(let e of this.style._order)this.style._layers[e].resize()}setup(){let e=this.context,t=new Un;t.emplaceBack(0,0),t.emplaceBack(N,0),t.emplaceBack(0,N),t.emplaceBack(N,N),this.tileExtentBuffer=e.createVertexBuffer(t,Wa.members),this.tileExtentSegments=ae.simpleSegment(0,0,4,2);let n=new Un;n.emplaceBack(0,0),n.emplaceBack(N,0),n.emplaceBack(0,N),n.emplaceBack(N,N),this.debugBuffer=e.createVertexBuffer(n,Wa.members),this.debugSegments=ae.simpleSegment(0,0,4,5);let r=new bt;r.emplaceBack(0,0,0,0),r.emplaceBack(N,0,N,0),r.emplaceBack(0,N,0,N),r.emplaceBack(N,N,N,N),this.rasterBoundsBuffer=e.createVertexBuffer(r,hl.members),this.rasterBoundsSegments=ae.simpleSegment(0,0,4,2);let i=new Un;i.emplaceBack(0,0),i.emplaceBack(N,0),i.emplaceBack(0,N),i.emplaceBack(N,N),this.rasterBoundsBufferPosOnly=e.createVertexBuffer(i,Wa.members),this.rasterBoundsSegmentsPosOnly=ae.simpleSegment(0,0,4,5);let a=new Un;a.emplaceBack(0,0),a.emplaceBack(1,0),a.emplaceBack(0,1),a.emplaceBack(1,1),this.viewportBuffer=e.createVertexBuffer(a,Wa.members),this.viewportSegments=ae.simpleSegment(0,0,4,2);let o=new ne;o.emplaceBack(0),o.emplaceBack(1),o.emplaceBack(3),o.emplaceBack(2),o.emplaceBack(0),this.tileBorderIndexBuffer=e.createIndexBuffer(o);let s=new gt;s.emplaceBack(1,0,2),s.emplaceBack(1,2,3),this.quadTriangleIndexBuffer=e.createIndexBuffer(s);let c=this.context.gl;this.stencilClearMode=new Q({func:c.ALWAYS,mask:0},0,255,c.ZERO,c.ZERO,c.ZERO),this.tileExtentMesh=new Ua(this.tileExtentBuffer,this.quadTriangleIndexBuffer,this.tileExtentSegments)}clearStencil(){let e=this.context,t=e.gl;this.nextStencilID=1,this.currentStencilSource=void 0;let n=vr();Ne(n,0,this.width,this.height,0,0,1),ke(n,n,[t.drawingBufferWidth,t.drawingBufferHeight,0]);let r={mainMatrix:n,tileMercatorCoords:[0,0,1,1],clippingPlane:[0,0,0,0],projectionTransition:0,fallbackMatrix:n,clipAntimeridian:!1};this.useProgram(`clippingMask`,null,!0).draw(e,t.TRIANGLES,Z.disabled,this.stencilClearMode,xd.disabled,$.disabled,null,null,r,`$clipping`,this.viewportBuffer,this.quadTriangleIndexBuffer,this.viewportSegments)}renderTileClippingMasks(e,t,n){if(this.currentStencilSource===e.source||!e.isTileClipped()||!t?.length)return;this.currentStencilSource=e.source,this.nextStencilID+t.length>256&&this.clearStencil();let r=this.context;r.setColorMode(xd.disabled),r.setDepthMode(Z.disabled);let i={};for(let e of t)i[e.key]=this.nextStencilID++;this.style.projection.useSubdivision&&this._renderTileMasks(i,t,n,!0),this._renderTileMasks(i,t,n,!1),this._tileClippingMaskIDs=i}_renderTileMasks(e,t,n,r){let i=this.context,a=i.gl,o=this.style.projection,s=this.transform,c=this.useProgram(`clippingMask`);for(let l of t){let t=e[l.key],u=this.getTerrainDataForTile(l,n),d=o.getMeshFromTileID(this.context,l.canonical,r,!0,`stencil`),f=s.getProjectionData({overscaledTileID:l,applyGlobeMatrix:!n,applyTerrainMatrix:!0});c.draw(i,a.TRIANGLES,Z.disabled,new Q({func:a.ALWAYS,mask:0},t,255,a.KEEP,a.KEEP,a.REPLACE),xd.disabled,n?$.disabled:$.backCCW,null,u,f,`$clipping`,d.vertexBuffer,d.indexBuffer,d.segments)}}getTerrainDataForTile(e,t){return t&&this.style.projection?.name===`mercator`?null:this.style.map.terrain?.getTerrainData(e)||null}_renderTilesDepthBuffer(){let e=this.context,t=e.gl,n=this.style.projection,r=this.transform,i=this.useProgram(`depth`),a=this.getDepthModeFor3D(),o=So(r,{tileSize:r.tileSize});for(let s of o){let o=this.style.map.terrain?.getTerrainData(s),c=n.getMeshFromTileID(this.context,s.canonical,!0,!0,`raster`),l=r.getProjectionData({overscaledTileID:s,applyGlobeMatrix:!0,applyTerrainMatrix:!0});i.draw(e,t.TRIANGLES,a,Q.disabled,xd.disabled,$.backCCW,null,o,l,`$clipping`,c.vertexBuffer,c.indexBuffer,c.segments)}}stencilModeFor3D(){this.currentStencilSource=void 0,this.nextStencilID+1>256&&this.clearStencil();let e=this.nextStencilID++,t=this.context.gl;return new Q({func:t.NOTEQUAL,mask:255},e,255,t.KEEP,t.KEEP,t.REPLACE)}stencilModeForClipping(e){let t=this.context.gl;return new Q({func:t.EQUAL,mask:255},this._tileClippingMaskIDs[e.key],0,t.KEEP,t.KEEP,t.REPLACE)}getStencilConfigForOverlapAndUpdateStencilID(e){let t=this.context.gl,n=e.sort((e,t)=>t.overscaledZ-e.overscaledZ),r=n[n.length-1].overscaledZ,i=n[0].overscaledZ-r+1;if(i>1){this.currentStencilSource=void 0,this.nextStencilID+i>256&&this.clearStencil();let e={};for(let n=0;nt.overscaledZ-e.overscaledZ),r=n[n.length-1].overscaledZ,i=n[0].overscaledZ-r+1;if(this.clearStencil(),i>1){let e={},a={};for(let n=0;n0};for(let e in r){let t=r[e];t.used&&t.prepare(this.context),i[e]=t.getVisibleCoordinates(!1),a[e]=i[e].slice().reverse(),o[e]=t.getVisibleCoordinates(!0).reverse()}this.opaquePassCutoff=1/0;for(let e=0;e=0;this.currentLayer--){let e=this.style._layers[n[this.currentLayer]],t=r[e.source],a=i[e.source];this.renderTileClippingMasks(e,a,!1),this.renderLayer(this,t,e,a,s)}this.renderPass=`translucent`;let c=!1;for(this.currentLayer=0;this.currentLayer0?t.pop():null}acquireRTT(e){let t=this.context.gl,n=this._rttObjectRecyclePool.pop();if(n)return n.size!==e&&(t.bindTexture(t.TEXTURE_2D,n.texture.texture),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,e,e,0,t.RGBA,t.UNSIGNED_BYTE,null),n.texture.size=[e,e],n.size=e),n;let r=new _(this.context,{width:e,height:e,data:null},t.RGBA);return r.bind(t.LINEAR,t.CLAMP_TO_EDGE),this.context.extTextureFilterAnisotropic&&t.texParameterf(t.TEXTURE_2D,this.context.extTextureFilterAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT,this.context.extTextureFilterAnisotropicMax),{texture:r,size:e}}bindRTT(e){let t=this.context.gl,n=e.size;if(!this._rttSharedFbo){let e=this.context.createFramebuffer(n,n,!0,!0),r=this.context.createRenderbuffer(t.DEPTH_STENCIL,n,n);e.depthAttachment.set(r),this._rttSharedFbo={fbo:e,depthRenderbuffer:r,size:n}}this._rttSharedFbo.size!==n&&(this.context.bindRenderbuffer.set(this._rttSharedFbo.depthRenderbuffer),t.renderbufferStorage(t.RENDERBUFFER,t.DEPTH_STENCIL,n,n),this.context.bindRenderbuffer.set(null),this._rttSharedFbo.fbo.width=n,this._rttSharedFbo.fbo.height=n,this._rttSharedFbo.size=n),this._rttSharedFbo.fbo.colorAttachment.set(e.texture.texture),this.context.bindFramebuffer.set(this._rttSharedFbo.fbo.framebuffer)}releaseRTT(e){this._rttObjectRecyclePool.push(e)}isPatternMissing(e){if(!e)return!1;if(!e.from||!e.to)return!0;let t=this.patternAtlas.getPattern(e.from.toString()),n=this.patternAtlas.getPattern(e.to.toString());return!t||!n}useProgram(e,t,n=!1,r=[]){this.cache||={};let i=!!this.style.map.terrain,a=this.style.projection,o=n?Xs.projectionMercator:a.shaderPreludeCode,s=n?Zs:a.shaderDefine,c=`/${n?Qs:a.shaderVariantName}`,l=t?t.cacheKey:``,u=this._showOverdrawInspector?`/overdraw`:``,d=i?`/terrain`:``,f=r?`/${r.join(`/`)}`:``,p=e+l+c+u+d+f;return this.cache[p]||=new El(this.context,Xs[e],t,Fu[e],this._showOverdrawInspector,i,o,s,r),this.cache[p]}setCustomLayerDefaults(){this.context.setCustomLayerDefaults()}setBaseState(){let e=this.context.gl;this.context.cullFace.set(!1),this.context.viewport.set([0,0,this.width,this.height]),this.context.blendEquation.set(e.FUNC_ADD)}initDebugOverlayCanvas(){if(this.debugOverlayCanvas==null){this.debugOverlayCanvas=document.createElement(`canvas`),this.debugOverlayCanvas.width=512,this.debugOverlayCanvas.height=512;let e=this.context.gl;this.debugOverlayTexture=new _(this.context,this.debugOverlayCanvas,e.RGBA)}}destroy(){if(this._tileTextures){for(let e in this._tileTextures){let t=this._tileTextures[e];if(t)for(let e of t)e.destroy()}this._tileTextures={}}for(let e of this._rttObjectRecyclePool)e.texture.destroy();if(this._rttObjectRecyclePool=[],this._rttSharedFbo){this._rttSharedFbo.fbo.colorAttachment.set(null),this._rttSharedFbo.fbo.depthAttachment.set(null);let e=this.context.gl;e.deleteRenderbuffer(this._rttSharedFbo.depthRenderbuffer),e.deleteFramebuffer(this._rttSharedFbo.fbo.framebuffer),this._rttSharedFbo=null}if(this.layerOpacityFbo?.destroy(),this.layerOpacityFbo=null,this.tileExtentBuffer&&this.tileExtentBuffer.destroy(),this.debugBuffer&&this.debugBuffer.destroy(),this.rasterBoundsBuffer&&this.rasterBoundsBuffer.destroy(),this.rasterBoundsBufferPosOnly&&this.rasterBoundsBufferPosOnly.destroy(),this.viewportBuffer&&this.viewportBuffer.destroy(),this.tileBorderIndexBuffer&&this.tileBorderIndexBuffer.destroy(),this.quadTriangleIndexBuffer&&this.quadTriangleIndexBuffer.destroy(),this.tileExtentMesh&&this.tileExtentMesh.vertexBuffer?.destroy(),this.tileExtentMesh&&this.tileExtentMesh.indexBuffer?.destroy(),this.debugOverlayTexture&&this.debugOverlayTexture.destroy(),this.cache){for(let e in this.cache){let t=this.cache[e];t?.program&&this.context.gl.deleteProgram(t.program)}this.cache={}}this.context&&this.context.setDefault()}overLimit(){let{drawingBufferWidth:e,drawingBufferHeight:t}=this.context.gl;return this.width!==e||this.height!==t}},qf=class extends Error{constructor(e,t){super(`WebGL2 is required to display this map. We are sorry, but it seems that your browser does not support WebGL2, a technology for rendering 3D graphics on the web. Read more on https://wiki.openstreetmap.org/wiki/This_map_requires_WebGL`),this.name=`GPUInitializationError`,this.requestedAttributes=e,this.statusMessage=t?.statusMessage??null}};function Jf(e,t){let n=!1,r=null,i,a=()=>{r=null,n&&=(e(...i),r=setTimeout(a,t),!1)};return(...e)=>(n=!0,i=e,r||a(),r)}var Yf=class{constructor(e){this._getHashParams=()=>new URLSearchParams(window.location.hash.replace(`#`,``)),this._getCurrentHash=()=>{let e=this._getHashParams();return this._hashName?(e.get(this._hashName)||``).split(`/`):([...e.keys()][0]??``).split(`/`)},this._onHashChange=()=>{let e=this._getCurrentHash();if(!this._isValidHash(e))return!1;let t=this._map.dragRotate.isEnabled()&&this._map.touchZoomRotate.isEnabled()?+(e[3]||0):this._map.getBearing();return this._map.jumpTo({center:[+e[2],+e[1]],zoom:+e[0],bearing:t,pitch:+(e[4]||0)}),!0},this._updateHashUnthrottled=()=>{let e=window.location.href.replace(/(#.*)?$/,this.getHashString());window.history.replaceState(window.history.state,null,e)},this._removeHash=()=>{let e=this._getHashParams();if(this._hashName)e.delete(this._hashName);else{let t=Array.from(e.keys());t.length>0&&e.delete(t[0])}let t=decodeURIComponent(e.toString()).replace(/=&/g,`&`).replace(/=$/g,``),n=t?`#${t}`:``,r=window.location.href.replace(/(#.+)?$/,n);r=r.replace(`&&`,`&`),window.history.replaceState(window.history.state,null,r)},this._updateHash=Jf(this._updateHashUnthrottled,300),this._hashName=e&&encodeURIComponent(e)}addTo(e){return this._map=e,addEventListener(`hashchange`,this._onHashChange,!1),this._map.on(`moveend`,this._updateHash),this}remove(){return removeEventListener(`hashchange`,this._onHashChange,!1),this._map.off(`moveend`,this._updateHash),clearTimeout(this._updateHash()),this._removeHash(),delete this._map,this}getHashString(e){let t=this._map.getCenter(),n=Math.round(this._map.getZoom()*100)/100,r=10**Math.ceil((n*Math.LN2+Math.log(512/360/.5))/Math.LN10),i=Math.round(t.lng*r)/r,a=Math.round(t.lat*r)/r,o=this._map.getBearing(),s=this._map.getPitch(),c=``;if(c+=e?`/${i}/${a}/${n}`:`${n}/${a}/${i}`,(o||s)&&(c+=`/${Math.round(o*10)/10}`),s&&(c+=`/${Math.round(s)}`),this._hashName){let e=this._getHashParams();return e.set(this._hashName,c),`#${decodeURIComponent(e.toString()).replace(/=&/g,`&`).replace(/=$/g,``)}`}return`#${c}`}_isValidHash(e){if(e.length<3||e.some(e=>isNaN(+e)))return!1;try{new V(+e[2],+e[1])}catch{return!1}let t=+e[0],n=+(e[3]||0),r=+(e[4]||0);return t>=this._map.getMinZoom()&&t<=this._map.getMaxZoom()&&n>=-180&&n<=180&&r>=this._map.getMinPitch()&&r<=this._map.getMaxPitch()}};const Xf={linearity:.3,easing:dt(0,0,.3,1)},Zf=z({deceleration:2500,maxSpeed:1400},Xf),Qf=z({deceleration:20,maxSpeed:1400},Xf),$f=z({deceleration:1e3,maxSpeed:360},Xf),ep=z({deceleration:1e3,maxSpeed:90},Xf),tp=z({deceleration:1e3,maxSpeed:360},Xf);var np=class{constructor(e){this._map=e,this.clear()}clear(){this._inertiaBuffer=[]}record(e){this._drainInertiaBuffer(),this._inertiaBuffer.push({time:U(),settings:e})}_drainInertiaBuffer(){let e=this._inertiaBuffer,t=U();for(;e.length>0&&t-e[0].time>160;)e.shift()}_getVelocityEntries(){let e=this._inertiaBuffer,t=U()-60,n=Math.max(0,e.length-2);for(;n>0&&e[n-1].time>=t;)n--;return e.slice(n)}_onMoveEnd(e){this._drainInertiaBuffer();let t=this._getVelocityEntries();if(t.length<2){this.clear();return}let n={zoom:0,bearing:0,pitch:0,roll:0,pan:new l(0,0),pinchAround:void 0,around:void 0};for(let{settings:e}of t)e.around&&(n.around=e.around),e.pinchAround&&(n.pinchAround=e.pinchAround);for(let{settings:e}of t.slice(1))n.zoom+=e.zoomDelta||0,n.bearing+=e.bearingDelta||0,n.pitch+=e.pitchDelta||0,n.roll+=e.rollDelta||0,e.panDelta&&n.pan._add(e.panDelta);if(!n.pan.mag()&&!n.zoom&&!n.bearing&&!n.pitch&&!n.roll){this.clear();return}let r=U()-t[0].time,i={};if(n.pan.mag()){let t=ip(n.pan.mag(),r,z({},Zf,e||{})),a=n.pan.mult(t.amount/n.pan.mag()),o=this._map._camera.cameraHelper.handlePanInertia(a,this._map._camera.transform);i.center=o.easingCenter,i.offset=o.easingOffset,rp(i,t)}if(n.zoom){let e=ip(n.zoom,r,Qf);i.zoom=un(this._map.getZoom()+e.amount,this._map.getZoomSnap(),e.amount),rp(i,e)}if(n.bearing){let e=ip(n.bearing,r,$f);i.bearing=this._map.getBearing()+M(e.amount,-179,179),rp(i,e)}if(n.pitch){let e=ip(n.pitch,r,ep);i.pitch=this._map.getPitch()+e.amount,rp(i,e)}if(n.roll){let e=ip(n.roll,r,tp);i.roll=this._map.getRoll()+M(e.amount,-179,179),rp(i,e)}if(i.zoom||i.bearing){let e=n.pinchAround===void 0?n.around:n.pinchAround;i.around=e?this._map.unproject(e):this._map.getCenter()}return this.clear(),z(i,{noMoveStart:!0})}};function rp(e,t){(!e.duration||e.duration=this._clickTolerance||this._map.fire(new Jr(e.type,this._map,e))}dblclick(e){return this._firePreventable(new Jr(e.type,this._map,e))}mouseover(e){this._map.fire(new Jr(e.type,this._map,e))}mouseout(e){this._map.fire(new Jr(e.type,this._map,e))}touchstart(e){return this._firePreventable(new Yr(e.type,this._map,e))}touchmove(e){this._map.fire(new Yr(e.type,this._map,e))}touchend(e){this._map.fire(new Yr(e.type,this._map,e))}touchcancel(e){this._map.fire(new Yr(e.type,this._map,e))}_firePreventable(e){if(this._map.fire(e),e.defaultPrevented)return{}}isEnabled(){return!0}isActive(){return!1}enable(){}disable(){}},op=class{constructor(e){this._map=e}reset(){this._delayContextMenu=!1,this._ignoreContextMenu=!0,delete this._contextMenuEvent}mousemove(e){this._map.fire(new Jr(e.type,this._map,e))}mousedown(){this._delayContextMenu=!0,this._ignoreContextMenu=!1}mouseup(){this._delayContextMenu=!1,this._contextMenuEvent&&(this._map.fire(new Jr(`contextmenu`,this._map,this._contextMenuEvent)),delete this._contextMenuEvent)}contextmenu(e){this._delayContextMenu?this._contextMenuEvent=e:this._ignoreContextMenu||this._map.fire(new Jr(e.type,this._map,e)),this._map.listens(`contextmenu`)&&e.preventDefault()}isEnabled(){return!0}isActive(){return!1}enable(){}disable(){}},sp=class{constructor(e,t,n){this._map=e,this._tr=n,this._el=e.getCanvasContainer(),this._container=e.getContainer(),this._clickTolerance=t.clickTolerance||1,t.boxZoom&&typeof t.boxZoom==`object`&&(this._boxZoomEnd=t.boxZoom.boxZoomEnd)}isEnabled(){return!!this._enabled}isActive(){return!!this._active}enable(){this.isEnabled()||(this._enabled=!0)}disable(){this.isEnabled()&&(this._enabled=!1)}mousedown(e,t){this.isEnabled()&&e.shiftKey&&e.button===0&&(W.disableDrag(),this._startPos=this._lastPos=t,this._active=!0)}mousemoveWindow(e,t){if(!this._active)return;let n=t;if(this._lastPos.equals(n)||!this._box&&n.dist(this._startPos)e.fitScreenCoordinates(n,r,this._tr.bearing,{linear:!0})}}}keydown(e){this._active&&e.keyCode===27&&(this.reset(),this._fireEvent(`boxzoomcancel`,e))}reset(){this._active=!1,this._container.classList.remove(`maplibregl-crosshair`),this._box&&=(this._box.remove(),null),W.enableDrag(),delete this._startPos,delete this._lastPos}_fireEvent(e,t){return this._map.fire(new Zr(e,{originalEvent:t}))}};function cp(e,t){if(e.length!==t.length)throw Error(`The number of touches and points are not equal - touches ${e.length}, points ${t.length}`);let n={};for(let r=0;rthis.numTouches)&&(this.aborted=!0),!this.aborted&&(this.startTime===void 0&&(this.startTime=e.timeStamp),n.length===this.numTouches&&(this.centroid=lp(t),this.touches=cp(n,t)))}touchmove(e,t,n){if(this.aborted||!this.centroid)return;let r=cp(n,t);for(let e in this.touches){let t=this.touches[e],n=r[e];(!n||n.dist(t)>30)&&(this.aborted=!0)}}touchend(e,t,n){if((!this.centroid||e.timeStamp-this.startTime>500)&&(this.aborted=!0),n.length===0){let e=!this.aborted&&this.centroid;if(this.reset(),e)return e}}},dp=class{constructor(e){this.singleTap=new up(e),this.numTaps=e.numTaps,this.reset()}reset(){this.lastTime=1/0,delete this.lastTap,this.count=0,this.singleTap.reset()}touchstart(e,t,n){this.singleTap.touchstart(e,t,n)}touchmove(e,t,n){this.singleTap.touchmove(e,t,n)}touchend(e,t,n){let r=this.singleTap.touchend(e,t,n);if(r){let t=e.timeStamp-this.lastTime<500,n=!this.lastTap||this.lastTap.dist(r)<30;if((!t||!n)&&this.reset(),this.count++,this.lastTime=e.timeStamp,this.lastTap=r,this.count===this.numTaps)return this.reset(),r}}},fp=class{constructor(e,t){this._tr=t,this._zoomIn=new dp({numTouches:1,numTaps:2}),this._zoomOut=new dp({numTouches:2,numTaps:1}),this.reset()}reset(){this._active=!1,this._zoomIn.reset(),this._zoomOut.reset()}touchstart(e,t,n){this._zoomIn.touchstart(e,t,n),this._zoomOut.touchstart(e,t,n)}touchmove(e,t,n){this._zoomIn.touchmove(e,t,n),this._zoomOut.touchmove(e,t,n)}touchend(e,t,n){let r=this._zoomIn.touchend(e,t,n),i=this._zoomOut.touchend(e,t,n),a=this._tr;if(r)return this._active=!0,e.preventDefault(),setTimeout(()=>this.reset(),0),{cameraAnimation:t=>t.easeTo({duration:300,zoom:un(a.zoom+1,t.getZoomSnap()),around:a.unproject(r)},{originalEvent:e})};if(i)return this._active=!0,e.preventDefault(),setTimeout(()=>this.reset(),0),{cameraAnimation:t=>t.easeTo({duration:300,zoom:un(a.zoom-1,t.getZoomSnap()),around:a.unproject(i)},{originalEvent:e})}}touchcancel(){this.reset()}enable(){this._enabled=!0}disable(){this._enabled=!1,this.reset()}isEnabled(){return this._enabled}isActive(){return this._active}},pp=class{constructor(e){this._enabled=!!e.enable,this._moveStateManager=e.moveStateManager,this._clickTolerance=e.clickTolerance||1,this._moveFunction=e.move,this._activateOnStart=!!e.activateOnStart,e.assignEvents(this),this.reset()}reset(e){this._active=!1,this._moved=!1,delete this._lastPoint,this._moveStateManager.endMove(e)}_move(...e){let t=this._moveFunction(...e);if(t.bearingDelta||t.pitchDelta||t.rollDelta||t.around||t.panDelta)return this._active=!0,t}dragStart(e,t){!this.isEnabled()||this._lastPoint||this._moveStateManager.isValidStartEvent(e)&&(this._moveStateManager.startMove(e),this._lastPoint=Array.isArray(t)?t[0]:t,this._activateOnStart&&this._lastPoint&&(this._active=!0))}dragMove(e,t){if(!this.isEnabled())return;let n=this._lastPoint;if(!n)return;if(e.preventDefault(),!this._moveStateManager.isValidMoveEvent(e)){this.reset(e);return}let r=Array.isArray(t)?t[0]:t;if(!(!this._moved&&r.dist(n)!0}),t=new _p){this.mouseMoveStateManager=e,this.oneFingerTouchMoveStateManager=t}_executeRelevantHandler(e,t,n){if(e instanceof MouseEvent)return t(e);if(typeof TouchEvent<`u`&&e instanceof TouchEvent)return n(e)}startMove(e){this._executeRelevantHandler(e,e=>{this.mouseMoveStateManager.startMove(e)},e=>{this.oneFingerTouchMoveStateManager.startMove(e)})}endMove(e){this._executeRelevantHandler(e,e=>{this.mouseMoveStateManager.endMove(e)},e=>{this.oneFingerTouchMoveStateManager.endMove(e)})}isValidStartEvent(e){return!!this._executeRelevantHandler(e,e=>this.mouseMoveStateManager.isValidStartEvent(e),e=>this.oneFingerTouchMoveStateManager.isValidStartEvent(e))}isValidMoveEvent(e){return!!this._executeRelevantHandler(e,e=>this.mouseMoveStateManager.isValidMoveEvent(e),e=>this.oneFingerTouchMoveStateManager.isValidMoveEvent(e))}isValidEndEvent(e){return!!this._executeRelevantHandler(e,e=>this.mouseMoveStateManager.isValidEndEvent(e),e=>this.oneFingerTouchMoveStateManager.isValidEndEvent(e))}};const yp=e=>{e.mousedown=e.dragStart,e.mousemoveWindow=e.dragMove,e.mouseup=e.dragEnd,e.contextmenu=e=>{e.preventDefault()}};function bp({enable:e,clickTolerance:t}){return new pp({clickTolerance:t,move:(e,t)=>({around:t,panDelta:t.sub(e)}),activateOnStart:!0,moveStateManager:new gp({checkCorrectEvent:e=>e.button===0&&!e.ctrlKey}),enable:e,assignEvents:yp})}function xp({enable:e,clickTolerance:t,aroundCenter:n=!0,minPixelCenterThreshold:r=100,rotateSpeed:i=.8},a){return new pp({clickTolerance:t,move:(e,t)=>{let o=a();if(n&&Math.abs(o.y-e.y)>r)return{bearingDelta:wn(new l(e.x,t.y),t,o)};let s=(t.x-e.x)*i;return n&&t.ye.button===0&&e.ctrlKey||e.button===2&&!e.ctrlKey}),enable:e,assignEvents:yp})}function Sp({enable:e,clickTolerance:t,pitchSpeed:n=-.5}){return new pp({clickTolerance:t,move:(e,t)=>({pitchDelta:(t.y-e.y)*n}),moveStateManager:new gp({checkCorrectEvent:e=>e.button===0&&e.ctrlKey||e.button===2}),enable:e,assignEvents:yp})}function Cp({enable:e,clickTolerance:t,rollDegreesPerPixelMoved:n=.3},r){return new pp({clickTolerance:t,move:(e,t)=>{let i=r(),a=(t.x-e.x)*n;return t.ye.button===2&&e.ctrlKey}),enable:e,assignEvents:yp})}var wp=class{constructor(e,t){this._clickTolerance=e.clickTolerance||1,this._map=t,this.reset()}reset(){this._active=!1,this._touches={},this._sum=new l(0,0)}_shouldBePrevented(e){return e<(this._map.cooperativeGestures.isEnabled()?2:1)}touchstart(e,t,n){return this._calculateTransform(e,t,n)}touchmove(e,t,n){if(this._active){if(this._shouldBePrevented(n.length)){this._map.cooperativeGestures.notifyGestureBlocked(`touch_pan`,e);return}return e.preventDefault(),this._calculateTransform(e,t,n)}}touchend(e,t,n){this._calculateTransform(e,t,n),this._active&&this._shouldBePrevented(n.length)&&this.reset()}touchcancel(){this.reset()}_calculateTransform(e,t,n){n.length>0&&(this._active=!0);let r=cp(n,t),i=new l(0,0),a=new l(0,0),o=0;for(let e in r){let t=r[e],n=this._touches[e];n&&(i._add(t),a._add(t.sub(n)),o++,r[e]=t)}if(this._touches=r,this._shouldBePrevented(o)||!a.mag())return;let s=a.div(o);if(this._sum._add(s),!(this._sum.mag()Math.abs(e.x)}var Np=class extends Tp{constructor(e){super(),this._currentTouchCount=0,this._map=e}reset(){super.reset(),this._valid=void 0,delete this._firstMove,delete this._lastPoints}touchstart(e,t,n){super.touchstart(e,t,n),this._currentTouchCount=n.length}_start(e){this._lastPoints=e,Mp(e[0].sub(e[1]))&&(this._valid=!1)}_move(e,t,n){if(this._map.cooperativeGestures.isEnabled()&&this._currentTouchCount<3)return;let r=e[0].sub(this._lastPoints[0]),i=e[1].sub(this._lastPoints[1]);if(this._valid=this.gestureBeginsVertically(r,i,n.timeStamp),this._valid)return this._lastPoints=e,this._active=!0,{pitchDelta:(r.y+i.y)/2*-.5}}gestureBeginsVertically(e,t,n){if(this._valid!==void 0)return this._valid;let r=e.mag()>=2,i=t.mag()>=2;if(!r&&!i)return;if(!r||!i)return this._firstMove===void 0&&(this._firstMove=n),n-this._firstMove<100&&void 0;let a=e.y>0==t.y>0;return Mp(e)&&Mp(t)&&a}};const Pp={panStep:100,bearingStep:15,pitchStep:10};var Fp=class{constructor(e,t){this._tr=t;let n=Pp;this._panStep=n.panStep,this._bearingStep=n.bearingStep,this._pitchStep=n.pitchStep,this._rotationDisabled=!1}reset(){this._active=!1}keydown(e){if(e.altKey||e.ctrlKey||e.metaKey)return;let t=0,n=0,r=0,i=0,a=0;switch(e.keyCode){case 61:case 107:case 171:case 187:t=1;break;case 189:case 109:case 173:t=-1;break;case 37:e.shiftKey?n=-1:(e.preventDefault(),i=-1);break;case 39:e.shiftKey?n=1:(e.preventDefault(),i=1);break;case 38:e.shiftKey?r=1:(e.preventDefault(),a=-1);break;case 40:e.shiftKey?r=-1:(e.preventDefault(),a=1);break;default:return}return this._rotationDisabled&&(n=0,r=0),{cameraAnimation:o=>{let s=this._tr;o.easeTo({duration:300,easeId:`keyboardHandler`,easing:Ip,zoom:t?un(s.zoom+t*(e.shiftKey?2:1),o.getZoomSnap()):s.zoom,bearing:s.bearing+n*this._bearingStep,pitch:s.pitch+r*this._pitchStep,offset:[-i*this._panStep,-a*this._panStep],center:s.center},{originalEvent:e})}}}enable(){this._enabled=!0}disable(){this._enabled=!1,this.reset()}isEnabled(){return this._enabled}isActive(){return this._active}disableRotation(){this._rotationDisabled=!0}enableRotation(){this._rotationDisabled=!1}};function Ip(e){return e*(2-e)}const Lp=4.000244140625;var Rp=class{constructor(e,t,n){this._onTimeout=e=>{this._type=`wheel`,this._delta-=this._lastValue,this._active||this._start(e)},this._map=e,this._tr=n,this._triggerRenderFrame=t,this._delta=0,this._defaultZoomRate=.01,this._wheelZoomRate=.0022222222222222222}setZoomRate(e){this._defaultZoomRate=e}setWheelZoomRate(e){this._wheelZoomRate=e}isEnabled(){return!!this._enabled}isActive(){return!!this._active||this._finishTimeout!==void 0}isZooming(){return!!this._zooming}enable(e){this.isEnabled()||(this._enabled=!0,this._aroundCenter=!!e&&e.around===`center`)}disable(){this.isEnabled()&&(this._enabled=!1)}_shouldBePrevented(e){return this._map.cooperativeGestures.isEnabled()?!(e.ctrlKey||this._map.cooperativeGestures.isBypassed(e)):!1}wheel(e){if(!this.isEnabled())return;if(this._shouldBePrevented(e)){this._map.cooperativeGestures.notifyGestureBlocked(`wheel_zoom`,e);return}let t=e.deltaMode===WheelEvent.DOM_DELTA_LINE?e.deltaY*40:e.deltaY,n=U(),r=n-(this._lastWheelEventTime||0);this._lastWheelEventTime=n,t!==0&&t%Lp==0?this._type=`wheel`:t!==0&&Math.abs(t)<4?this._type=`trackpad`:r>400?(this._type=null,this._lastValue=t,this._timeout=setTimeout(this._onTimeout,40,e)):this._type||(this._type=Math.abs(r*t)<200?`trackpad`:`wheel`,this._timeout&&(clearTimeout(this._timeout),this._timeout=null,t+=this._lastValue)),e.shiftKey&&t&&(t/=4),this._type&&(this._lastWheelEvent=e,this._delta-=t,this._active||this._start(e)),e.preventDefault()}_start(e){if(!this._delta)return;this._needsRerender=!1,this._active=!0,this.isZooming()||(this._zooming=!0),this._finishTimeout&&(clearTimeout(this._finishTimeout),delete this._finishTimeout);let t=W.mousePos(this._map.getCanvas(),e),n=this._tr;this._aroundPoint=this._aroundCenter?n.transform.locationToScreenPoint(V.convert(n.center)):t,this._needsRerender||(this._needsRerender=!0,this._triggerRenderFrame())}renderFrame(){if(!this._needsRerender||(this._needsRerender=!1,!this.isActive()))return;let e=this._tr.transform;if(typeof this._lastExpectedZoom==`number`){let t=e.zoom-this._lastExpectedZoom;typeof this._startZoom==`number`&&(this._startZoom+=t),typeof this._targetZoom==`number`&&(this._targetZoom+=t)}if(this._delta!==0){let t=this._type===`wheel`&&Math.abs(this._delta)>Lp?this._wheelZoomRate:this._defaultZoomRate,n=2/(1+Math.exp(-Math.abs(this._delta*t)));this._delta<0&&n!==0&&(n=1/n);let r=typeof this._targetZoom==`number`?d(this._targetZoom):e.scale,i=e.applyConstrain(e.getCameraLngLat(),Ee(r*n)).zoom,a=this._map.getZoomSnap();if(this._type===`wheel`&&a>0){let t=un(e.zoom,a);this._targetZoom=un(i,a,i-t)}else this._targetZoom=i;this._type===`wheel`&&(this._startZoom=e.zoom,this._easing=this._smoothOutEasing(200)),this._delta=0}let t=typeof this._targetZoom==`number`?this._targetZoom:e.zoom,n=this._startZoom,r=this._easing,i=!1,a;if(this._type===`wheel`&&n&&r){let e=U()-this._lastWheelEventTime,o=Math.min((e+5)/200,1),s=r(o);a=on.number(n,t,s),o<1?this._needsRerender=!0:i=!0}else a=t,i=!0;return this._active=!0,i&&(this._active=!1,this._finishTimeout=setTimeout(()=>{this._zooming=!1,this._triggerRenderFrame(),delete this._targetZoom,delete this._lastExpectedZoom,delete this._finishTimeout},200)),this._lastExpectedZoom=a,{noInertia:!0,needsRenderFrame:!i,zoomDelta:a-e.zoom,around:this._aroundPoint,originalEvent:this._lastWheelEvent}}_smoothOutEasing(e){let n=t;if(this._prevEase){let e=this._prevEase,t=(U()-e.start)/e.duration,r=e.easing(t+.01)-e.easing(t),i=.27/Math.sqrt(r*r+1e-4)*.01,a=Math.sqrt(.0729-i*i);n=dt(i,a,.25,1)}return this._prevEase={start:U(),duration:e,easing:n},n}reset(){this._active=!1,this._zooming=!1,delete this._targetZoom,delete this._lastExpectedZoom,this._finishTimeout&&(clearTimeout(this._finishTimeout),delete this._finishTimeout)}},zp=class{constructor(e,t){this._clickZoom=e,this._tapZoom=t}enable(){this._clickZoom.enable(),this._tapZoom.enable()}disable(){this._clickZoom.disable(),this._tapZoom.disable()}isEnabled(){return this._clickZoom.isEnabled()&&this._tapZoom.isEnabled()}isActive(){return this._clickZoom.isActive()||this._tapZoom.isActive()}},Bp=class{constructor(e,t){this._tr=t,this.reset()}reset(){this._active=!1}dblclick(e,t){return e.preventDefault(),{cameraAnimation:n=>{n.easeTo({duration:300,zoom:un(this._tr.zoom+(e.shiftKey?-1:1),n.getZoomSnap()),around:this._tr.unproject(t)},{originalEvent:e})}}}enable(){this._enabled=!0}disable(){this._enabled=!1,this.reset()}isEnabled(){return this._enabled}isActive(){return this._active}},Vp=class{constructor(){this._tap=new dp({numTouches:1,numTaps:1}),this._zoomRate=1,this.reset()}setZoomRate(e){this._zoomRate=e??1}reset(){this._active=!1,delete this._swipePoint,delete this._swipeTouch,delete this._tapTime,delete this._tapPoint,this._tap.reset()}touchstart(e,t,n){if(!this._swipePoint){if(!this._tapTime)this._tap.touchstart(e,t,n);else{let r=t[0],i=e.timeStamp-this._tapTime<500,a=this._tapPoint.dist(r)<30;!i||!a?this.reset():n.length>0&&(this._swipePoint=r,this._swipeTouch=n[0].identifier)}}}touchmove(e,t,n){if(!this._tapTime)this._tap.touchmove(e,t,n);else if(this._swipePoint){if(n[0].identifier!==this._swipeTouch)return;let r=t[0],i=r.y-this._swipePoint.y;return this._swipePoint=r,e.preventDefault(),this._active=!0,{zoomDelta:i/128*this._zoomRate}}}touchend(e,t,n){if(this._tapTime)this._swipePoint&&n.length===0&&this.reset();else{let r=this._tap.touchend(e,t,n);r&&(this._tapTime=e.timeStamp,this._tapPoint=r)}}touchcancel(){this.reset()}enable(){this._enabled=!0}disable(){this._enabled=!1,this.reset()}isEnabled(){return this._enabled}isActive(){return this._active}},Hp=class{constructor(e,t,n){this._el=e,this._mousePan=t,this._touchPan=n}enable(e){this._inertiaOptions=e||{},this._mousePan.enable(),this._touchPan.enable(),this._el.classList.add(`maplibregl-touch-drag-pan`)}disable(){this._mousePan.disable(),this._touchPan.disable(),this._el.classList.remove(`maplibregl-touch-drag-pan`)}isEnabled(){return this._mousePan.isEnabled()&&this._touchPan.isEnabled()}isActive(){return this._mousePan.isActive()||this._touchPan.isActive()}},Up=class{constructor(e,t,n,r){this._pitchWithRotate=e.pitchWithRotate,this._rollEnabled=e.rollEnabled,this._mouseRotate=t,this._mousePitch=n,this._mouseRoll=r}enable(){this._mouseRotate.enable(),this._pitchWithRotate&&this._mousePitch.enable(),this._rollEnabled&&this._mouseRoll.enable()}disable(){this._mouseRotate.disable(),this._mousePitch.disable(),this._mouseRoll.disable()}isEnabled(){return this._mouseRotate.isEnabled()&&(!this._pitchWithRotate||this._mousePitch.isEnabled())&&(!this._rollEnabled||this._mouseRoll.isEnabled())}isActive(){return this._mouseRotate.isActive()||this._mousePitch.isActive()||this._mouseRoll.isActive()}},Wp=class{constructor(e,t,n,r){this._el=e,this._touchZoom=t,this._touchRotate=n,this._tapDragZoom=r,this._rotationDisabled=!1,this._enabled=!0}enable(e){this._touchZoom.enable(e),this._rotationDisabled||this._touchRotate.enable(e),this._tapDragZoom.enable(),this._el.classList.add(`maplibregl-touch-zoom-rotate`)}disable(){this._touchZoom.disable(),this._touchRotate.disable(),this._tapDragZoom.disable(),this._el.classList.remove(`maplibregl-touch-zoom-rotate`)}isEnabled(){return this._touchZoom.isEnabled()&&(this._rotationDisabled||this._touchRotate.isEnabled())&&this._tapDragZoom.isEnabled()}isActive(){return this._touchZoom.isActive()||this._touchRotate.isActive()||this._tapDragZoom.isActive()}setZoomRate(e){this._touchZoom.setZoomRate(e),this._tapDragZoom.setZoomRate(e)}setZoomThreshold(e){this._touchZoom.setZoomThreshold(e)}disableRotation(){this._rotationDisabled=!0,this._touchRotate.disable()}enableRotation(){this._rotationDisabled=!1,this._touchZoom.isEnabled()&&this._touchRotate.enable()}},Gp=class{constructor(e,t){this._bypassKey=navigator.userAgent.includes(`Mac`)?`metaKey`:`ctrlKey`,this._map=e,this._options=t,this._enabled=!1}isActive(){return!1}reset(){}_setupUI(){if(this._container)return;let e=this._map.getCanvasContainer();e.classList.add(`maplibregl-cooperative-gestures`),this._container=W.create(`div`,`maplibregl-cooperative-gesture-screen`,e);let t=this._map._getUIString(`CooperativeGesturesHandler.WindowsHelpText`);this._bypassKey===`metaKey`&&(t=this._map._getUIString(`CooperativeGesturesHandler.MacHelpText`));let n=this._map._getUIString(`CooperativeGesturesHandler.MobileHelpText`),r=document.createElement(`div`);r.className=`maplibregl-desktop-message`,r.textContent=t,this._container.appendChild(r);let i=document.createElement(`div`);i.className=`maplibregl-mobile-message`,i.textContent=n,this._container.appendChild(i),this._container.setAttribute(`aria-hidden`,`true`)}_destroyUI(){this._container&&(this._container.remove(),this._map.getCanvasContainer().classList.remove(`maplibregl-cooperative-gestures`)),delete this._container}enable(){this._setupUI(),this._enabled=!0}disable(){this._enabled=!1,this._destroyUI()}isEnabled(){return this._enabled}isBypassed(e){return e[this._bypassKey]}notifyGestureBlocked(e,t){this._enabled&&(this._map.fire(new Gr(`cooperativegestureprevented`,{gestureType:e,originalEvent:t})),this._container.classList.add(`maplibregl-show`),setTimeout(()=>{this._container.classList.remove(`maplibregl-show`)},100))}},Kp=class{constructor(e){this._camera=e}get transform(){return this._camera._requestedCameraState||this._camera.transform}get center(){return{lng:this.transform.center.lng,lat:this.transform.center.lat}}get zoom(){return this.transform.zoom}get pitch(){return this.transform.pitch}get bearing(){return this.transform.bearing}unproject(e){return this.transform.screenPointToLocation(l.convert(e),this._camera.terrain)}};const qp=e=>e.zoom||e.drag||e.roll||e.pitch||e.rotate;var Jp=class extends Xe{};function Yp(e){return e.panDelta?.mag()||e.zoomDelta||e.bearingDelta||e.pitchDelta||e.rollDelta}var Xp=class{get _ownerDocument(){return this._el?.ownerDocument||document}get _ownerWindow(){return this._el?.ownerDocument?.defaultView||window}constructor(e,t,n){this._terrainGestureAnchorElevation=null,this.handleWindowEvent=e=>{this.handleEvent(e,`${e.type}Window`)},this.handleEvent=(e,t)=>{if(e.type===`blur`){this.stop(!0);return}this._updatingCamera=!0;let n=e.type===`renderFrame`?void 0:e,r={needsRenderFrame:!1},i={},a={};for(let{handlerName:o,handler:s,allowed:c}of this._handlers){if(!s.isEnabled())continue;let l;if(this._blockedByActive(a,c,o))s.reset();else if(s[t||e.type]){if(Dn(e,t||e.type)){let n=W.mousePos(this._map.getCanvas(),e);l=s[t||e.type](e,n)}else if(nn(e,t||e.type)){let n=e.touches,r=this._getMapTouches(n),i=W.touchPos(this._map.getCanvas(),r);l=s[t||e.type](e,i,r)}else Dt(t||e.type)||(l=s[t||e.type](e));this.mergeHandlerResult(r,i,l,o,n),l?.needsRenderFrame&&this._triggerRenderFrame()}(l||s.isActive())&&(a[o]=s)}let o={};for(let e in this._previousActiveHandlers)a[e]||(o[e]=n);this._previousActiveHandlers=a,(Object.keys(o).length||Yp(r))&&(this._changes.push([r,i,o]),this._triggerRenderFrame()),(Object.keys(a).length||Yp(r))&&this._camera.stop(!0),this._updatingCamera=!1;let{cameraAnimation:s}=r;s&&(this._inertia.clear(),this._fireEvents({},{},!0),this._changes=[],s(this._map))},this._map=e,this._camera=t,this._transformProvider=new Kp(this._camera),this._el=this._map.getCanvasContainer(),this._handlers=[],this._handlersById={},this._changes=[],this._inertia=new np(e),this._bearingSnap=n.bearingSnap,this._previousActiveHandlers={},this._eventsInProgress={},this._addDefaultHandlers(n);let r=this._el;this._listeners=[[r,`touchstart`,{passive:!0}],[r,`touchmove`,{passive:!1}],[r,`touchend`,void 0],[r,`touchcancel`,void 0],[r,`mousedown`,void 0],[r,`mousemove`,void 0],[r,`mouseup`,void 0],[this._ownerDocument,`mousemove`,{capture:!0}],[this._ownerDocument,`mouseup`,void 0],[r,`mouseover`,void 0],[r,`mouseout`,void 0],[r,`dblclick`,void 0],[r,`click`,void 0],[r,`keydown`,{capture:!1}],[r,`keyup`,void 0],[r,`wheel`,{passive:!1}],[r,`contextmenu`,void 0],[this._ownerWindow,`blur`,void 0]];for(let[e,t,n]of this._listeners)e.addEventListener(t,e===this._ownerDocument?this.handleWindowEvent:this.handleEvent,n)}destroy(){for(let[e,t,n]of this._listeners)e.removeEventListener(t,e===this._ownerDocument?this.handleWindowEvent:this.handleEvent,n)}_addDefaultHandlers(e){let t=this._map,n=t.getCanvasContainer();this._add(`mapEvent`,new ap(t,e));let r=t.boxZoom=new sp(t,e,this._transformProvider);this._add(`boxZoom`,r),e.interactive&&e.boxZoom&&r.enable();let i=t.cooperativeGestures=new Gp(t,e.cooperativeGestures);this._add(`cooperativeGestures`,i),e.cooperativeGestures&&i.enable();let a=new fp(t,this._transformProvider),o=new Bp(t,this._transformProvider);t.doubleClickZoom=new zp(o,a),this._add(`tapZoom`,a),this._add(`clickZoom`,o),e.interactive&&e.doubleClickZoom&&t.doubleClickZoom.enable();let s=new Vp;this._add(`tapDragZoom`,s);let c=t.touchPitch=new Np(t);this._add(`touchPitch`,c),e.interactive&&e.touchPitch&&t.touchPitch.enable(e.touchPitch);let l=()=>t.project(t.getCenter()),u=xp(e,l),d=Sp(e),f=Cp(e,l);t.dragRotate=new Up(e,u,d,f),this._add(`mouseRotate`,u,[`mousePitch`]),this._add(`mousePitch`,d,[`mouseRotate`,`mouseRoll`]),this._add(`mouseRoll`,f,[`mousePitch`]),e.interactive&&e.dragRotate&&t.dragRotate.enable();let p=bp(e),m=new wp(e,t);t.dragPan=new Hp(n,p,m),this._add(`mousePan`,p),this._add(`touchPan`,m,[`touchZoom`,`touchRotate`]),e.interactive&&e.dragPan&&t.dragPan.enable(e.dragPan);let h=new jp,g=new kp;t.touchZoomRotate=new Wp(n,g,h,s),this._add(`touchRotate`,h,[`touchPan`,`touchZoom`]),this._add(`touchZoom`,g,[`touchPan`,`touchRotate`]),e.interactive&&e.touchZoomRotate&&t.touchZoomRotate.enable(e.touchZoomRotate),this._add(`blockableMapEvent`,new op(t));let _=t.scrollZoom=new Rp(t,()=>this._triggerRenderFrame(),this._transformProvider);this._add(`scrollZoom`,_,[`mousePan`]),e.interactive&&e.scrollZoom&&t.scrollZoom.enable(e.scrollZoom);let v=t.keyboard=new Fp(t,this._transformProvider);this._add(`keyboard`,v),e.interactive&&e.keyboard&&t.keyboard.enable()}_add(e,t,n){this._handlers.push({handlerName:e,handler:t,allowed:n}),this._handlersById[e]=t}stop(e){if(!this._updatingCamera){for(let{handler:e}of this._handlers)e.reset();this._inertia.clear(),this._fireEvents({},{},e),this._changes=[]}}isActive(){for(let{handler:e}of this._handlers)if(e.isActive())return!0;return!1}isZooming(){return!!this._eventsInProgress.zoom||this._map.scrollZoom.isZooming()}isRotating(){return!!this._eventsInProgress.rotate}isMoving(){return!!qp(this._eventsInProgress)||this.isZooming()}_blockedByActive(e,t,n){for(let r in e)if(r!==n&&!t?.includes(r))return!0;return!1}_getMapTouches(e){let t=[];for(let n of e){let e=n.target;this._el.contains(e)&&t.push(n)}return t}mergeHandlerResult(e,t,n,r,i){if(!n)return;z(e,n);let a={handlerName:r,originalEvent:n.originalEvent||i};n.zoomDelta!==void 0&&(t.zoom=a),n.panDelta!==void 0&&(t.drag=a),n.rollDelta!==void 0&&(t.roll=a),n.pitchDelta!==void 0&&(t.pitch=a),n.bearingDelta!==void 0&&(t.rotate=a)}_applyChanges(){let e={},t={},n={};for(let[r,i,a]of this._changes)r.panDelta&&(e.panDelta=(e.panDelta||new l(0,0))._add(r.panDelta)),r.zoomDelta&&(e.zoomDelta=(e.zoomDelta||0)+r.zoomDelta),r.bearingDelta&&(e.bearingDelta=(e.bearingDelta||0)+r.bearingDelta),r.pitchDelta&&(e.pitchDelta=(e.pitchDelta||0)+r.pitchDelta),r.rollDelta&&(e.rollDelta=(e.rollDelta||0)+r.rollDelta),r.around!==void 0&&(e.around=r.around),r.pinchAround!==void 0&&(e.pinchAround=r.pinchAround),r.noInertia&&(e.noInertia=r.noInertia),z(t,i),z(n,a);this._updateMapTransform(e,t,n),this._changes=[]}_updateMapTransform(e,t,n){let r=this._map,i=this._camera.getTransformForUpdate(),a=r.terrain;if(!Yp(e)&&!(a&&this._terrainMovement)){this._fireEvents(t,n,!0);return}this._camera.stop(!0);let{panDelta:o,zoomDelta:s,bearingDelta:c,pitchDelta:l,rollDelta:u}=e,{around:d,aroundOnSurface:f}=this._resolveAround(e,a,i),p=a?this._terrainGestureElevation(a,d,f,i,t):void 0,m={panDelta:o,zoomDelta:s,rollDelta:u,pitchDelta:l,bearingDelta:c,around:d,aroundElevation:p};this._camera.cameraHelper.useGlobeControls&&!i.isPointOnMapSurface(d)&&(d=i.centerPoint);let h=this._computePreZoomAroundLoc(i,d,o,p);this._handleMapControls({terrain:a,tr:i,deltasForHelper:m,preZoomAroundLoc:h,combinedEventsInProgress:t,panDelta:o}),this._camera.applyUpdatedTransform(i),this._map._update(),e.noInertia||this._inertia.record(e),this._fireEvents(t,n,!0)}_resolveAround(e,t,n){let r=e.pinchAround===void 0?e.around:e.pinchAround;return r||=this._camera.transform.centerPoint,t&&!n.isPointOnMapSurface(r)?{around:n.centerPoint,aroundOnSurface:!1}:{around:r,aroundOnSurface:!0}}_terrainGestureElevation(e,t,n,r,i){if(!n)return;if(!this._terrainMovement&&(i.drag||i.zoom)){let n=r.screenTerrainPointToMercatorCoordinate(t,e);this._terrainGestureAnchorElevation=n?n.z:null}if(this._terrainGestureAnchorElevation===null)return;let a=this._terrainGestureAnchorElevation;if(!(t.distSqr(r.centerPoint)<.01)&&!(a-r.elevation>=.9*(r.getCameraAltitude()-r.elevation)))return a}_computePreZoomAroundLoc(e,t,n,r){if(t.distSqr(e.centerPoint)<.01)return e.center;let i=n?t.sub(n):t;return r===void 0?e.screenPointToLocation(i):e.screenPointToLocationAtElevation(i,r)}_handleMapControls({terrain:e,tr:t,deltasForHelper:n,preZoomAroundLoc:r,combinedEventsInProgress:i,panDelta:a}){let o=this._camera.cameraHelper;if(o.handleMapControlsRollPitchBearingZoom(n,t),!e){o.handleMapControlsPan(n,t,r);return}if(o.useGlobeControls){!this._terrainMovement&&(i.drag||i.zoom)&&(this._terrainMovement=!0,this._camera.elevationFreeze=!0),o.handleMapControlsPan(n,t,r);return}if(!this._terrainMovement&&(i.drag||i.zoom)){this._terrainMovement=!0,this._camera.elevationFreeze=!0,o.handleMapControlsPan(n,t,r);return}if(n.aroundElevation===void 0&&i.drag&&this._terrainMovement&&a){t.setCenter(t.screenPointToLocation(t.centerPoint.sub(a)));return}o.handleMapControlsPan(n,t,r)}_fireEvents(e,t,n){let r=qp(this._eventsInProgress),i=qp(e),a={};for(let t in e){let{originalEvent:n}=e[t];this._eventsInProgress[t]||(a[`${t}start`]=n),this._eventsInProgress[t]=e[t]}!r&&i&&this._fireEvent(`movestart`,i.originalEvent);for(let e in a)this._fireEvent(e,a[e]);i&&this._fireEvent(`move`,i.originalEvent);for(let t in e){let{originalEvent:n}=e[t];this._fireEvent(t,n)}let o={},s;for(let e in this._eventsInProgress){let{handlerName:n,originalEvent:r}=this._eventsInProgress[e];this._handlersById[n].isActive()||(delete this._eventsInProgress[e],s=t[n]||r,o[`${e}end`]=s)}for(let e in o)this._fireEvent(e,o[e]);let c=qp(this._eventsInProgress),l=(r||i)&&!c;if(l&&this._terrainMovement){this._camera.elevationFreeze=!1,this._terrainMovement=!1,this._terrainGestureAnchorElevation=null;let e=this._camera.getTransformForUpdate();this._map.getCenterClampedToGround()&&e.recalculateZoomAndCenter(this._map.terrain),this._camera.applyUpdatedTransform(e)}if(n&&l){this._updatingCamera=!0;let e=this._inertia._onMoveEnd(this._map.dragPan._inertiaOptions),t=e=>e!==0&&-this._bearingSnap{delete this._frameId,this.handleEvent(new Jp(`renderFrame`,{timeStamp:e})),this._applyChanges()})}_triggerRenderFrame(){this._frameId===void 0&&(this._frameId=this._requestFrame())}},Zp=class extends h{constructor(e){super(),this._renderFrameCallback=()=>{let e=Math.min((U()-this._easeStart)/this._easeOptions.duration,1);this._onEaseFrame(this._easeOptions.easing(e)),e<1&&this._easeFrameId?this._easeFrameId=this._requestRenderFrame(this._renderFrameCallback):this.stop()},this.transform=new yc,this.cameraHelper=new Tc,e.minZoom!==void 0&&this.transform.setMinZoom(e.minZoom),e.maxZoom!==void 0&&this.transform.setMaxZoom(e.maxZoom),e.minPitch!==void 0&&this.transform.setMinPitch(e.minPitch),e.maxPitch!==void 0&&this.transform.setMaxPitch(e.maxPitch),e.renderWorldCopies!==void 0&&this.transform.setRenderWorldCopies(e.renderWorldCopies),e.transformConstrain!==null&&this.transform.setConstrainOverride(e.transformConstrain),this._moving=!1,this._zooming=!1,this._bearingSnap=e.bearingSnap,this._zoomSnap=e.zoomSnap,this._requestRenderFrame=e.requestRenderFrame,this._cancelRenderFrame=e.cancelRenderFrame,this.terrain=e.terrain,this._centerClampedToGround=e.centerClampedToGround??!0,this.transformCameraUpdate=e.transformCameraUpdate??null,this._stopHandlers=e.stopHandlers??(()=>{}),this.on(`moveend`,()=>{delete this._requestedCameraState})}migrateProjection(e,t){e.apply(this.transform,!0),this.transform=e,this.cameraHelper=t}getCenter(){return new V(this.transform.center.lng,this.transform.center.lat)}setCenter(e,t){return this.jumpTo({center:e},t)}getCenterElevation(){return this.transform.elevation}setCenterElevation(e,t){return this.jumpTo({elevation:e},t),this}getCenterClampedToGround(){return this._centerClampedToGround}setCenterClampedToGround(e){this._centerClampedToGround=e}panBy(e,t,n){return e=l.convert(e).mult(-1),this.panTo(this.transform.center,z({offset:e},t),n)}panTo(e,t,n){return this.easeTo(z({center:e},t),n)}getZoom(){return this.transform.zoom}setZoom(e,t){return this.jumpTo({zoom:e},t),this}zoomTo(e,t,n){return this.easeTo(z({zoom:e},t),n)}zoomIn(e,t){return this.zoomTo(un(this.getZoom()+1,this._zoomSnap),e,t),this}zoomOut(e,t){return this.zoomTo(un(this.getZoom()-1,this._zoomSnap),e,t),this}getVerticalFieldOfView(){return this.transform.fov}setVerticalFieldOfView(e,t){return e!=this.transform.fov&&(this.transform.setFov(e),this.fire(new G(`movestart`,t)).fire(new G(`move`,t)).fire(new G(`moveend`,t))),this}getBearing(){return this.transform.bearing}setZoomSnap(e){return this._zoomSnap=e,this}getZoomSnap(){return this._zoomSnap}setBearing(e,t){return this.jumpTo({bearing:e},t),this}getPadding(){return this.transform.padding}setPadding(e,t){return this.jumpTo({padding:e},t),this}rotateTo(e,t,n){return this.easeTo(z({bearing:e},t),n)}resetNorth(e,t){return this.rotateTo(0,z({duration:1e3},e),t),this}resetNorthPitch(e,t){return this.easeTo(z({bearing:0,pitch:0,roll:0,duration:1e3},e),t),this}snapToNorth(e,t){return Math.abs(this.getBearing()){g.easeFunc(t),this.terrain&&!e.freezeElevation&&this._updateElevation(t),this.applyUpdatedTransform(r),this._fireMoveEvents(n)},t=>{this.terrain&&e.freezeElevation&&this._finalizeElevation(),this._afterEase(n,t)},e),this}_prepareEase(e,t,n={}){this._moving=!0,!t&&!n.moving&&this.fire(new G(`movestart`,e)),this._zooming&&!n.zooming&&this.fire(new G(`zoomstart`,e)),this._rotating&&!n.rotating&&this.fire(new G(`rotatestart`,e)),this._pitching&&!n.pitching&&this.fire(new G(`pitchstart`,e)),this._rolling&&!n.rolling&&this.fire(new G(`rollstart`,e))}_prepareElevation(e){this._elevationCenter=e,this._elevationStart=this.transform.elevation,this._elevationTarget=this.terrain.getElevationForLngLat(e,this.transform),this.elevationFreeze=!0}_updateElevation(e){(this._elevationStart===void 0||this._elevationCenter===void 0)&&this._prepareElevation(this.transform.center),this.transform.setMinElevationForCurrentTile(this.terrain.getMinTileElevationForLngLatZoom(this._elevationCenter,this.transform.tileZoom));let t=this.terrain.getElevationForLngLat(this._elevationCenter,this.transform);if(e<1&&t!==this._elevationTarget){let n=this._elevationTarget-this._elevationStart,r=(t-(n*e+this._elevationStart))/(1-e);this._elevationStart+=e*(n-r),this._elevationTarget=t}this.transform.setElevation(on.number(this._elevationStart,this._elevationTarget,e))}_finalizeElevation(){this.elevationFreeze=!1,this.getCenterClampedToGround()&&this.transform.recalculateZoomAndCenter(this.terrain)}getTransformForUpdate(){return!this.transformCameraUpdate&&!this.terrain?this.transform:(this._requestedCameraState||=this.transform.clone(),this._requestedCameraState)}_elevateCameraIfInsideTerrain(e){if(!this.terrain&&e.elevation>=0&&e.pitch<=90)return{};let t=e.getCameraLngLat(),n=e.getCameraAltitude(),r=this.terrain?this.terrain.getElevationForLngLatZoom(t,e.zoom):0;if(nthis._elevateCameraIfInsideTerrain(e)),this.transformCameraUpdate&&t.push(e=>this.transformCameraUpdate(e)),!t.length)return;let n=e.clone();for(let e of t){let t=n.clone(),{center:r,zoom:i,roll:a,pitch:o,bearing:s,elevation:c}=e(t);r&&t.setCenter(r),c!==void 0&&t.setElevation(c),i!==void 0&&t.setZoom(i),a!==void 0&&t.setRoll(a),o!==void 0&&t.setPitch(o),s!==void 0&&t.setBearing(s),n.apply(t,!1)}this.transform.apply(n,!1)}_fireMoveEvents(e){this.fire(new G(`move`,e)),this._zooming&&this.fire(new G(`zoom`,e)),this._rotating&&this.fire(new G(`rotate`,e)),this._pitching&&this.fire(new G(`pitch`,e)),this._rolling&&this.fire(new G(`roll`,e))}_afterEase(e,t){if(this._easeId&&t&&this._easeId===t)return;delete this._easeId;let n=this._zooming,r=this._rotating,i=this._pitching,a=this._rolling;this._moving=!1,this._zooming=!1,this._rotating=!1,this._pitching=!1,this._rolling=!1,this._padding=!1,n&&this.fire(new G(`zoomend`,e)),r&&this.fire(new G(`rotateend`,e)),i&&this.fire(new G(`pitchend`,e)),a&&this.fire(new G(`rollend`,e)),this.fire(new G(`moveend`,e))}flyTo(e,n){if(!e.essential&&Rr.prefersReducedMotion){let t=hr(e,[`center`,`zoom`,`bearing`,`pitch`,`roll`,`elevation`,`padding`]);return this.jumpTo(t,n)}this.stop(),e=z({offset:[0,0],speed:1.2,curve:1.42,easing:t},e),`zoom`in e&&this._zoomSnap&&(e.zoom=un(e.zoom,this._zoomSnap));let r=this.getTransformForUpdate(),i=r.bearing,a=r.pitch,o=r.roll,s=r.padding,c=`bearing`in e?this._normalizeBearing(e.bearing,i):i,u=`pitch`in e?+e.pitch:a,d=`roll`in e?this._normalizeBearing(e.roll,o):o,f=`padding`in e?e.padding:r.padding,p=l.convert(e.offset),m=r.centerPoint.add(p),h=r.screenPointToLocation(m),g=this.cameraHelper.handleFlyTo(r,{bearing:c,pitch:u,roll:d,padding:f,locationAtOffset:h,offsetAsPoint:p,center:e.center,minZoom:e.minZoom,zoom:e.zoom}),_=e.curve,v=Math.max(r.width,r.height),y=v/g.scaleOfZoom,b=g.pixelPathLength,x=v/g.scaleOfMinZoom;_=Math.min(_,Math.sqrt(x/b*2));let S=_*_;function C(e){let t=(y*y-v*v+(e?-1:1)*S*S*b*b)/(2*(e?y:v)*S*b);return Math.log(Math.sqrt(t*t+1)-t)}function w(e){return(Math.exp(e)-Math.exp(-e))/2}function T(e){return(Math.exp(e)+Math.exp(-e))/2}function E(e){return w(e)/T(e)}let D=C(!1),ee=function(e){return T(D)/T(D+_*e)},O=function(e){return v*((T(D)*E(D+_*e)-w(D))/S)/b},k=(C(!0)-D)/_;if(Math.abs(b)<2e-6||!isFinite(k)){if(Math.abs(v-y)<1e-6)return this.easeTo(e,n);let t=y0,ee=e=>Math.exp(t*_*e)}if(`duration`in e)e.duration=+e.duration;else{let t=`screenSpeed`in e?+e.screenSpeed/_:+e.speed;e.duration=1e3*k/t}return e.maxDuration&&e.duration>e.maxDuration&&(e.duration=0),this._zooming=!0,this._rotating=i!==c,this._pitching=u!==a,this._rolling=d!==o,this._padding=!r.isPaddingEqual(f),this._prepareEase(n,!1),this.terrain&&this._prepareElevation(g.targetCenter),this._ease(t=>{let l=t*k,h=1/ee(l),_=O(l);this._rotating&&r.setBearing(on.number(i,c,t)),this._pitching&&r.setPitch(on.number(a,u,t)),this._rolling&&r.setRoll(on.number(o,d,t)),this._padding&&(r.interpolatePadding(s,f,t),m=r.centerPoint.add(p)),g.easeFunc(t,h,_,m),this.terrain&&!e.freezeElevation&&this._updateElevation(t),this.applyUpdatedTransform(r),this._fireMoveEvents(n)},()=>{this.terrain&&e.freezeElevation&&this._finalizeElevation(),this._afterEase(n)},e),this}isEasing(){return!!this._easeFrameId}stop(e){return this._stop(e)}_stop(e,t){if(this._easeFrameId&&(this._cancelRenderFrame(this._easeFrameId),delete this._easeFrameId,delete this._onEaseFrame),this._onEaseEnd){let e=this._onEaseEnd;delete this._onEaseEnd,e.call(this,t)}return e||this._stopHandlers(),this}_ease(e,t,n){n.animate===!1||n.duration===0?(e(1),t()):(this._easeStart=U(),this._easeOptions=n,this._onEaseFrame=e,this._onEaseEnd=t,this._easeFrameId=this._requestRenderFrame(this._renderFrameCallback))}_normalizeBearing(e,t){e=Or(e,-180,180);let n=Math.abs(e-t);return Math.abs(e-360-t)MapLibre `};var $p=class{constructor(e=Qp){this._toggleAttribution=()=>{this._container.classList.contains(`maplibregl-compact`)&&(this._container.classList.contains(`maplibregl-compact-show`)?(this._container.setAttribute(`open`,``),this._container.classList.remove(`maplibregl-compact-show`)):(this._container.classList.add(`maplibregl-compact-show`),this._container.removeAttribute(`open`)))},this._updateData=e=>{e&&(e.type===`terrain`||e.dataType===`style`||e.dataType===`source`&&(e.sourceDataType===`metadata`||e.sourceDataType===`visibility`))&&this._updateAttributions()},this._updateCompact=()=>{this._map.getCanvasContainer().offsetWidth<=640||this._compact?this._compact===!1?this._container.setAttribute(`open`,``):!this._container.classList.contains(`maplibregl-compact`)&&!this._container.classList.contains(`maplibregl-attrib-empty`)&&(this._container.setAttribute(`open`,``),this._container.classList.add(`maplibregl-compact`,`maplibregl-compact-show`)):(this._container.setAttribute(`open`,``),this._container.classList.contains(`maplibregl-compact`)&&this._container.classList.remove(`maplibregl-compact`,`maplibregl-compact-show`))},this._updateCompactMinimize=()=>{this._container.classList.contains(`maplibregl-compact`)&&this._container.classList.contains(`maplibregl-compact-show`)&&this._container.classList.remove(`maplibregl-compact-show`)},this.options=e}getDefaultPosition(){return`bottom-right`}onAdd(e){return this._map=e,this._compact=this.options.compact,this._container=W.create(`details`,`maplibregl-ctrl maplibregl-ctrl-attrib`),this._compactButton=W.create(`summary`,`maplibregl-ctrl-attrib-button`,this._container),this._compactButton.addEventListener(`click`,this._toggleAttribution),this._setElementTitle(this._compactButton,`ToggleAttribution`),this._innerContainer=W.create(`div`,`maplibregl-ctrl-attrib-inner`,this._container),this._updateAttributions(),this._updateCompact(),this._map.on(`styledata`,this._updateData),this._map.on(`sourcedata`,this._updateData),this._map.on(`terrain`,this._updateData),this._map.on(`resize`,this._updateCompact),this._map.on(`drag`,this._updateCompactMinimize),this._container}onRemove(){this._container.remove(),this._map.off(`styledata`,this._updateData),this._map.off(`sourcedata`,this._updateData),this._map.off(`terrain`,this._updateData),this._map.off(`resize`,this._updateCompact),this._map.off(`drag`,this._updateCompactMinimize),this._map=void 0,this._compact=void 0,this._attribHTML=void 0}_setElementTitle(e,t){let n=this._map._getUIString(`AttributionControl.${t}`);e.title=n,e.setAttribute(`aria-label`,n)}_updateAttributions(){if(!this._map.style)return;let e=[];if(this.options.customAttribution&&(Array.isArray(this.options.customAttribution)?e=e.concat(this.options.customAttribution.map(e=>typeof e==`string`?e:``)):typeof this.options.customAttribution==`string`&&e.push(this.options.customAttribution)),this._map.style.stylesheet){let e=this._map.style.stylesheet;this.styleOwner=e.owner,this.styleId=e.id}let t=this._map.style.tileManagers;for(let n in t){let r=t[n];if(r.used||r.usedForTerrain){let t=r.getSource();t.attribution&&!e.includes(t.attribution)&&e.push(t.attribution)}}e=e.filter(e=>String(e).trim()),e.sort((e,t)=>e.length-t.length),e=e.filter((t,n)=>{for(let r=n+1;r{let e=this._container.children;if(e.length){let t=e[0];this._map.getCanvasContainer().offsetWidth<=640||this._compact?this._compact!==!1&&t.classList.add(`maplibregl-compact`):t.classList.remove(`maplibregl-compact`)}},this.options=e}getDefaultPosition(){return`bottom-left`}onAdd(e){this._map=e,this._compact=this.options?.compact,this._container=W.create(`div`,`maplibregl-ctrl`);let t=W.create(`a`,`maplibregl-ctrl-logo`);return t.target=`_blank`,t.rel=`noopener nofollow`,t.href=`https://maplibre.org/`,t.setAttribute(`aria-label`,this._map._getUIString(`LogoControl.Title`)),t.setAttribute(`rel`,`noopener nofollow`),this._container.appendChild(t),this._container.style.display=`block`,this._map.on(`resize`,this._updateCompact),this._updateCompact(),this._container}onRemove(){this._container.remove(),this._map.off(`resize`,this._updateCompact),this._map=void 0,this._compact=void 0}},tm=class{constructor(){this._queue=[],this._id=0,this._cleared=!1,this._currentlyRunning=!1}add(e){let t=++this._id;return this._queue.push({callback:e,id:t,cancelled:!1}),t}remove(e){let t=this._currentlyRunning,n=t?this._queue.concat(t):this._queue;for(let t of n)if(t.id===e){t.cancelled=!0;return}}run(e=0){if(this._currentlyRunning)throw Error(`Attempting to run(), but is already running.`);let t=this._currentlyRunning=this._queue;this._queue=[];for(let n of t)if(!n.cancelled&&(n.callback(e),this._cleared))break;this._cleared=!1,this._currentlyRunning=!1}clear(){this._currentlyRunning&&(this._cleared=!0),this._queue=[]}};const nm={background:!0,fill:!0,line:!0,raster:!0,hillshade:!0,"color-relief":!0};var rm=class{constructor(e,t){this.painter=e,this.terrain=t,this.rttSize=t.tileManager.tileSize*t.qualityFactor}getTexture(e){return e.getRTT(this._stacks.length-1).texture}prepareForRender(e,t){this._stacks=[],this._prevType=null,this._rttTiles=[],this._renderableTiles=this.terrain.tileManager.getRenderableTiles(),this._renderableLayerIds=e._order.filter(n=>!e._layers[n].isHidden(t));let n=new Set;for(let t of this._renderableLayerIds){let r=e._layers[t],i=r.source;i&&nm[r.type]&&n.add(i)}this._coordsAscending={},this._rttFingerprints={};for(let t of n){let n=e.tileManagers[t];if(!n)continue;this._coordsAscending[t]={};let r=this._coordsAscending[t],i=n.getSource(),a=i instanceof Ja?i.terrainTileRanges:null;for(let e of n.getVisibleCoordinates()){let t=this.terrain.tileManager.getTerrainCoords(e,a);for(let e in t)r[e]||=[],r[e].push(t[e])}this._rttFingerprints[t]={};let o=this._rttFingerprints[t],s=n.getState().revision;for(let e in r)o[e]=`${r[e].map(e=>e.key).sort().join()}#${s}`}for(let e of this._renderableTiles)for(let t in this._rttFingerprints){let n=this._rttFingerprints[t][e.tileID.key];n&&n!==e.rttFingerprint[t]&&e.releaseRTT(this.painter)}}renderLayer(e,t){if(e.isHidden(this.painter.transform.zoom))return!1;let n={...t,isRenderingToTexture:!0},r=e.type,i=this.painter,a=this._renderableLayerIds[this._renderableLayerIds.length-1]===e.id;if(nm[r]&&((!this._prevType||!nm[this._prevType])&&this._stacks.push([]),this._prevType=r,this._stacks[this._stacks.length-1].push(e.id),!a))return!0;if(nm[this._prevType]||nm[r]&&a){this._prevType=r;let e=this._stacks.length-1,t=this._stacks[e]||[];for(let r of this._renderableTiles){if(this._rttTiles.push(r),r.getRTT(e))continue;let a=r.acquireRTT(i,e,this.rttSize);i.bindRTT(a),i.context.clear({color:R.transparent,stencil:0}),i.currentStencilSource=void 0;for(let e of t){let t=i.style._layers[e],a=t.source?this._coordsAscending[t.source][r.tileID.key]:[r.tileID];i.context.viewport.set([0,0,this.rttSize,this.rttSize]),i.renderTileClippingMasks(t,a,!0),i.renderLayer(i,i.style.tileManagers[t.source],t,a,n),t.source&&(r.rttFingerprint[t.source]=this._rttFingerprints[t.source][r.tileID.key])}}return Bf(this.painter,this.terrain,this._rttTiles,n),this._rttTiles=[],nm[r]}return!1}};const im={"AttributionControl.ToggleAttribution":`Toggle attribution`,"AttributionControl.MapFeedback":`Map feedback`,"FullscreenControl.Enter":`Enter fullscreen`,"FullscreenControl.Exit":`Exit fullscreen`,"GeolocateControl.FindMyLocation":`Find my location`,"GeolocateControl.LocationNotAvailable":`Location not available`,"LogoControl.Title":`MapLibre logo`,"Map.Title":`Map`,"Marker.Title":`Map marker`,"NavigationControl.ResetBearing":`Drag to rotate map, click to reset north`,"NavigationControl.ZoomIn":`Zoom in`,"NavigationControl.ZoomOut":`Zoom out`,"Popup.Close":`Close popup`,"ScaleControl.Feet":`ft`,"ScaleControl.Meters":`m`,"ScaleControl.Kilometers":`km`,"ScaleControl.Miles":`mi`,"ScaleControl.NauticalMiles":`nm`,"GlobeControl.Enable":`Enable globe`,"GlobeControl.Disable":`Disable globe`,"TerrainControl.Enable":`Enable terrain`,"TerrainControl.Disable":`Disable terrain`,"CooperativeGesturesHandler.WindowsHelpText":`Use Ctrl + scroll to zoom the map`,"CooperativeGesturesHandler.MacHelpText":`Use ⌘ + scroll to zoom the map`,"CooperativeGesturesHandler.MobileHelpText":`Use two fingers to move the map`},am=Ar,om={hash:!1,interactive:!0,bearingSnap:7,zoomSnap:0,attributionControl:Qp,maplibreLogo:!1,refreshExpiredTiles:!0,canvasContextAttributes:{antialias:!1,preserveDrawingBuffer:!1,powerPreference:`high-performance`,failIfMajorPerformanceCaveat:!1,desynchronized:!1,contextType:void 0},scrollZoom:!0,minZoom:-2,maxZoom:22,minPitch:0,maxPitch:60,boxZoom:!0,dragRotate:!0,dragPan:!0,keyboard:!0,doubleClickZoom:!0,touchZoomRotate:!0,touchPitch:!0,cooperativeGestures:!1,trackResize:!0,center:[0,0],elevation:0,zoom:0,bearing:0,pitch:0,roll:0,renderWorldCopies:!0,maxTileCacheSize:null,maxTileCacheZoomLevels:k.MAX_TILE_CACHE_ZOOM_LEVELS,transformRequest:null,transformCameraUpdate:null,transformConstrain:null,fadeDuration:300,crossSourceCollisions:!0,clickTolerance:3,localIdeographFontFamily:`sans-serif`,pitchWithRotate:!0,rollEnabled:!1,rotateSpeed:.8,pitchSpeed:-.5,reduceMotion:void 0,validateStyle:!0,maxCanvasSize:[4096,4096],cancelPendingTileRequestsWhileZooming:!0,centerClampedToGround:!0,terrainSkirtLength:`auto`,zoomLevelsToOverscale:4,anisotropicFilterPitch:20};var sm=class extends h{get _ownerWindow(){return this._container?.ownerDocument?.defaultView||window}constructor(e){super(),this._idleTriggered=!1,this._crossFadingFactor=1,this._renderTaskQueue=new tm,this._controls=[],this._mapId=Se(),this._missingStyleImageResolver=null,this._lostContextStyle={style:null,images:null},this._contextLost=e=>{if(e.preventDefault(),this._frameRequest&&=(this._frameRequest.abort(),null),this.painter.destroy(),this._lostContextStyle=this._getStyleAndImages(),!this.style){this.fire(new ei(`webglcontextlost`,{originalEvent:e}));return}for(let e of Object.values(this.style._layers))if(e.type===`custom`&&console.warn(`Custom layer with id '${e.id}' cannot be restored after WebGL context loss. You will need to re-add it manually after context restoration.`),e._listeners)for(let[t]of Object.entries(e._listeners))console.warn(`Custom layer with id '${e.id}' had event listeners for event '${t}' which cannot be restored after WebGL context loss. You will need to re-add them manually after context restoration.`);this.style.destroy(),this.style=null,this.fire(new ei(`webglcontextlost`,{originalEvent:e}))},this._contextRestored=e=>{if(this._lostContextStyle.style&&this.setStyle(this._lostContextStyle.style,{diff:!1}),this._lostContextStyle.images&&this.style){this.style.imageManager.images=this._lostContextStyle.images;for(let e in this._lostContextStyle.images){let t=this._lostContextStyle.images[e];t.isWebGLImage&&this.style.imageManager.updateImage(e,t,!1)}}this._lostContextStyle={style:null,images:null};try{this._setupPainter()}catch(e){this.fire(new H(e));return}this.resize(),this._update(),this._resizeInternal(),this.fire(new ei(`webglcontextrestored`,{originalEvent:e}))},this._onMapScroll=e=>{if(e.target===this._container)return this._container.scrollTop=0,this._container.scrollLeft=0,!1},this._onWindowOnline=()=>{this._update()};let t={...om,...e,canvasContextAttributes:{...om.canvasContextAttributes,...e.canvasContextAttributes}};if(t.minZoom!=null&&t.maxZoom!=null&&t.minZoom>t.maxZoom)throw Error(`maxZoom must be greater than or equal to minZoom`);if(t.minPitch!=null&&t.maxPitch!=null&&t.minPitch>t.maxPitch)throw Error(`maxPitch must be greater than or equal to minPitch`);if(t.minPitch!=null&&t.minPitch<0)throw Error(`minPitch must be greater than or equal to 0`);if(t.maxPitch!=null&&t.maxPitch>180)throw Error(`maxPitch must be less than or equal to 180`);this._camera=new Zp({minZoom:t.minZoom,maxZoom:t.maxZoom,minPitch:t.minPitch,maxPitch:t.maxPitch,bearingSnap:t.bearingSnap,zoomSnap:t.zoomSnap,renderWorldCopies:t.renderWorldCopies,centerClampedToGround:t.centerClampedToGround,terrain:this.terrain,transformConstrain:t.transformConstrain,requestRenderFrame:e=>this._requestRenderFrame(e),cancelRenderFrame:e=>this._cancelRenderFrame(e),transformCameraUpdate:t.transformCameraUpdate,stopHandlers:()=>this._handlers?.stop(!1)}),this._camera.setEventedParent(this),this._interactive=t.interactive,this._maxTileCacheSize=t.maxTileCacheSize,this._maxTileCacheZoomLevels=t.maxTileCacheZoomLevels,this._canvasContextAttributes={...t.canvasContextAttributes},this._trackResize=t.trackResize===!0,this._terrainSkirtLength=t.terrainSkirtLength,this._refreshExpiredTiles=t.refreshExpiredTiles===!0,this._fadeDuration=t.fadeDuration,this._crossSourceCollisions=t.crossSourceCollisions===!0,this._collectResourceTiming=t.collectResourceTiming===!0,this._locale={...im,...t.locale},this._clickTolerance=t.clickTolerance,this._overridePixelRatio=t.pixelRatio,this._maxCanvasSize=t.maxCanvasSize,this._zoomLevelsToOverscale=t.zoomLevelsToOverscale,this.cancelPendingTileRequestsWhileZooming=t.cancelPendingTileRequestsWhileZooming===!0,this.setAnisotropicFilterPitch(t.anisotropicFilterPitch),t.reduceMotion!==void 0&&(Rr.prefersReducedMotion=t.reduceMotion),this._requestManager=new Wr(t.transformRequest),this._container=this._resolveContainer(t.container),t.maxBounds&&this.setMaxBounds(t.maxBounds),this._setupContainer();try{this._setupPainter()}catch(e){throw this._cleanupContainer(),e}this._imageQueueHandle=Ur.addThrottleControl(()=>this.isMoving()),this.on(`move`,()=>this._update(!1)),this.on(`moveend`,()=>this._update(!1)),this.on(`zoom`,()=>this._update(!0)),this.on(`terrain`,()=>{this.painter.terrainFacilitator.depthDirty=!0,this._update(!0)}),this.once(`idle`,()=>this._idleTriggered=!0),this._handlers=new Xp(this,this._camera,t),typeof window<`u`&&(this._ownerWindow.addEventListener(`online`,this._onWindowOnline,!1),this._setupResizeObserver());let n=typeof t.hash==`string`&&t.hash||void 0;this._hash=t.hash?new Yf(n).addTo(this):void 0,this._hash?._onHashChange()||(this.jumpTo({center:t.center,elevation:t.elevation,zoom:t.zoom,bearing:t.bearing,pitch:t.pitch,roll:t.roll}),t.bounds&&(this.resize(),this.fitBounds(t.bounds,z({},t.fitBoundsOptions,{duration:0}))));let r=typeof t.style==`string`||t.style?.projection?.type!==`globe`;this.resize(null,r),this._localIdeographFontFamily=t.localIdeographFontFamily,this._validateStyle=t.validateStyle,t.style&&this.setStyle(t.style,{localIdeographFontFamily:t.localIdeographFontFamily}),t.attributionControl&&this.addControl(new $p(typeof t.attributionControl==`boolean`?void 0:t.attributionControl)),t.maplibreLogo&&this.addControl(new em,t.logoPosition),this.on(`style.load`,()=>{if(r||this._resizeTransform(),this._camera.transform.unmodified){let e=hr(this.style.stylesheet,[`center`,`zoom`,`bearing`,`pitch`,`roll`]);this.jumpTo(e)}}),this.on(`data`,e=>{this._update(e.dataType===`style`),this.fire(e.dataType===`style`?new qr(`styledata`,e):new K(`sourcedata`,e))}),this.on(`dataloading`,e=>{this.fire(e.dataType===`style`?new qr(`styledataloading`,e):new K(`sourcedataloading`,e))}),this.on(`dataabort`,e=>{this.fire(new K(`sourcedataabort`,e))})}_getMapId(){return this._mapId}setGlobalStateProperty(e,t){return this.style.setGlobalStateProperty(e,t),this._update(!0)}getGlobalState(){return this.style.getGlobalState()}addControl(e,t){if(t===void 0&&(t=e.getDefaultPosition?e.getDefaultPosition():`top-right`),!e?.onAdd)return this.fire(new H(Error(`Invalid argument to map.addControl(). Argument must be a control with onAdd and onRemove methods.`)));let n=e.onAdd(this);this._controls.push(e);let r=this._controlPositions[t];return t.includes(`bottom`)?r.insertBefore(n,r.firstChild):r.appendChild(n),this}removeControl(e){if(!e?.onRemove)return this.fire(new H(Error(`Invalid argument to map.removeControl(). Argument must be a control with onAdd and onRemove methods.`)));let t=this._controls.indexOf(e);return t>-1&&this._controls.splice(t,1),e.onRemove(this),this}hasControl(e){return this._controls.includes(e)}coveringTiles(e){return So(this._camera.transform,e)}setTransformCameraUpdate(e){this._camera.transformCameraUpdate=e}getCenter(){return new V(this._camera.transform.center.lng,this._camera.transform.center.lat)}setCenter(e,t){return this._camera.setCenter(e,t),this}getCenterElevation(){return this._camera.transform.elevation}setCenterElevation(e,t){return this._camera.setCenterElevation(e,t),this}setCenterClampedToGround(e){this._camera.setCenterClampedToGround(e)}panBy(e,t,n){return this._camera.panBy(e,t,n),this}panTo(e,t,n){return this._camera.panTo(e,t,n),this}getZoom(){return this._camera.transform.zoom}setZoom(e,t){return this._camera.setZoom(e,t),this}zoomTo(e,t,n){return this._camera.zoomTo(e,t,n),this}zoomIn(e,t){return this._camera.zoomIn(e,t),this}zoomOut(e,t){return this._camera.zoomOut(e,t),this}getVerticalFieldOfView(){return this._camera.transform.fov}setVerticalFieldOfView(e,t){return this._camera.setVerticalFieldOfView(e,t),this}getBearing(){return this._camera.transform.bearing}setBearing(e,t){return this._camera.setBearing(e,t),this}getZoomSnap(){return this._camera.getZoomSnap()}setZoomSnap(e){return this._camera.setZoomSnap(e),this}getPadding(){return this._camera.transform.padding}setPadding(e,t){return this._camera.setPadding(e,t),this}rotateTo(e,t,n){return this._camera.rotateTo(e,t,n),this}resetNorth(e,t){return this._camera.resetNorth(e,t),this}resetNorthPitch(e,t){return this._camera.resetNorthPitch(e,t),this}snapToNorth(e,t){return this._camera.snapToNorth(e,t),this}getPitch(){return this._camera.transform.pitch}setPitch(e,t){return this._camera.setPitch(e,t),this}getRoll(){return this._camera.transform.roll}setRoll(e,t){return this._camera.setRoll(e,t),this}cameraForBounds(e,t){return this._camera.cameraForBounds(e,t)}fitBounds(e,t,n){return this._camera.fitBounds(e,t,n),this}fitScreenCoordinates(e,t,n,r,i){return this._camera.fitScreenCoordinates(e,t,n,r,i),this}jumpTo(e,t){return this._camera.jumpTo(e,t),this}calculateCameraOptionsFromCameraLngLatAltRotation(e,t,n,r,i){return this._camera.calculateCameraOptionsFromCameraLngLatAltRotation(e,t,n,r,i)}easeTo(e,t){return this._camera.easeTo(e,t),this}flyTo(e,t){return this._camera.flyTo(e,t),this}stop(){return this._camera.stop(),this}queryTerrainElevation(e){return this.terrain?this.terrain.getElevationForLngLat(V.convert(e),this._camera.transform):null}getCenterClampedToGround(){return this._camera.getCenterClampedToGround()}calculateCameraOptionsFromTo(e,t,n,r){return r==null&&this.terrain&&(r=this.terrain.getElevationForLngLat(n,this._camera.transform)),this._camera.calculateCameraOptionsFromTo(e,t,n,r)}resize(e,t=!0){if(this._lostContextStyle.style!==null)return this;this._resizeInternal(t);let n=!this._camera._moving;return n&&(this.stop(),this.fire(new G(`movestart`,e)).fire(new G(`move`,e))),this.fire(new Gr(`resize`,e)),n&&this.fire(new G(`moveend`,e)),this}_resizeInternal(e=!0){let[t,n]=this._containerDimensions(),r=this._getClampedPixelRatio(t,n);if(this._resizeCanvas(t,n,r),this.painter.resize(t,n,r),this.painter.overLimit()){let e=this.painter.context.gl;this._maxCanvasSize=[e.drawingBufferWidth,e.drawingBufferHeight];let r=this._getClampedPixelRatio(t,n);this._resizeCanvas(t,n,r),this.painter.resize(t,n,r)}this._resizeTransform(e)}_resizeTransform(e=!0){let[t,n]=this._containerDimensions();this._camera.transform.resize(t,n,e),this._camera._requestedCameraState?.resize(t,n,e)}_getClampedPixelRatio(e,t){let{0:n,1:r}=this._maxCanvasSize,i=this.getPixelRatio(),a=e*i,o=t*i,s=a>n?n/a:1,c=o>r?r/o:1;return Math.min(s,c)*i}getPixelRatio(){return this._overridePixelRatio??devicePixelRatio}setPixelRatio(e){this._overridePixelRatio=e,this.resize()}getBounds(){return this._camera.transform.getBounds()}getMaxBounds(){return this._camera.transform.getMaxBounds()}setMaxBounds(e){return this._camera.transform.setMaxBounds(_a.convert(e)),this._update()}setMinZoom(e){if(e??=-2,e>=-2&&e<=this._camera.transform.maxZoom){let t=this._camera.transform.zoom,n=this._camera.getTransformForUpdate();return n.setMinZoom(e),this._camera.applyUpdatedTransform(n),this._update(),t!==this._camera.transform.zoom&&this.fire(new G(`zoomstart`)).fire(new G(`zoom`)).fire(new G(`zoomend`)).fire(new G(`movestart`)).fire(new G(`move`)).fire(new G(`moveend`)),this}throw Error(`minZoom must be between -2 and the current maxZoom, inclusive`)}getMinZoom(e=!1){let t=this._camera.transform;return e?t.applyConstrain(t.center,t.minZoom).zoom:t.minZoom}setMaxZoom(e){if(e??=22,e>=this._camera.transform.minZoom){let t=this._camera.transform.zoom,n=this._camera.getTransformForUpdate();return n.setMaxZoom(e),this._camera.applyUpdatedTransform(n),this._update(),t!==this._camera.transform.zoom&&this.fire(new G(`zoomstart`)).fire(new G(`zoom`)).fire(new G(`zoomend`)).fire(new G(`movestart`)).fire(new G(`move`)).fire(new G(`moveend`)),this}throw Error(`maxZoom must be greater than the current minZoom`)}getMaxZoom(){return this._camera.transform.maxZoom}setMinPitch(e){if(e??=0,e<0)throw Error(`minPitch must be greater than or equal to 0`);if(e>=0&&e<=this._camera.transform.maxPitch){let t=this._camera.transform.pitch,n=this._camera.getTransformForUpdate();return n.setMinPitch(e),this._camera.applyUpdatedTransform(n),this._update(),t!==this._camera.transform.pitch&&this.fire(new G(`pitchstart`)).fire(new G(`pitch`)).fire(new G(`pitchend`)).fire(new G(`movestart`)).fire(new G(`move`)).fire(new G(`moveend`)),this}throw Error(`minPitch must be between 0 and the current maxPitch, inclusive`)}getMinPitch(){return this._camera.transform.minPitch}setMaxPitch(e){if(e??=60,e>180)throw Error(`maxPitch must be less than or equal to 180`);if(e>=this._camera.transform.minPitch){let t=this._camera.transform.pitch,n=this._camera.getTransformForUpdate();return n.setMaxPitch(e),this._camera.applyUpdatedTransform(n),this._update(),t!==this._camera.transform.pitch&&this.fire(new G(`pitchstart`)).fire(new G(`pitch`)).fire(new G(`pitchend`)).fire(new G(`movestart`)).fire(new G(`move`)).fire(new G(`moveend`)),this}throw Error(`maxPitch must be greater than the current minPitch`)}getMaxPitch(){return this._camera.transform.maxPitch}getAnisotropicFilterPitch(){return this._anisotropicFilterPitch}setAnisotropicFilterPitch(e){if(e??=20,e>180)throw Error(`anisotropicFilterPitch must be less than or equal to 180`);if(e<0)throw Error(`anisotropicFilterPitch must be greater than or equal to 0`);return this._anisotropicFilterPitch=e,this._update()}getRenderWorldCopies(){return this._camera.transform.renderWorldCopies}setRenderWorldCopies(e){return this._camera.transform.setRenderWorldCopies(e),this._update()}setTransformConstrain(e){return this._camera.transform.setConstrainOverride(e),this._update()}project(e){return this._camera.transform.locationToScreenPoint(V.convert(e),this.style&&this.terrain)}unproject(e){return this._camera.transform.screenPointToLocation(l.convert(e),this.terrain)}isMoving(){return this._camera.isMoving()||this._handlers?.isMoving()||!1}isZooming(){return this._camera.isZooming()||this._handlers?.isZooming()||!1}isRotating(){return this._camera.isRotating()||this._handlers?.isRotating()||!1}_createDelegatedListener(e,t,n){if(e===`mouseenter`||e===`mouseover`){let r=!1;return{layers:t,listener:n,delegates:{mousemove:i=>{let a=t.filter(e=>this.getLayer(e)),o=a.length===0?[]:this.queryRenderedFeatures(i.point,{layers:a});o.length?r||(r=!0,n.call(this,new Jr(e,this,i.originalEvent,{features:o}))):r=!1},mouseout:()=>{r=!1}}}}if(e===`mouseleave`||e===`mouseout`){let r=!1;return{layers:t,listener:n,delegates:{mousemove:i=>{let a=t.filter(e=>this.getLayer(e));(a.length===0?[]:this.queryRenderedFeatures(i.point,{layers:a})).length?r=!0:r&&(r=!1,n.call(this,new Jr(e,this,i.originalEvent)))},mouseout:t=>{r&&(r=!1,n.call(this,new Jr(e,this,t.originalEvent)))}}}}{let r=e=>{let r=t.filter(e=>this.getLayer(e)),i=r.length===0?[]:this.queryRenderedFeatures(e.point,{layers:r});i.length&&(e.features=i,n.call(this,e),delete e.features)};return{layers:t,listener:n,delegates:{[e]:r}}}}_saveDelegatedListener(e,t){this._delegatedListeners||={},this._delegatedListeners[e]||=[],this._delegatedListeners[e].push(t)}_removeDelegatedListener(e,t,n){if(!this._delegatedListeners?.[e])return;let r=this._delegatedListeners[e];for(let e=0;et.includes(e))){for(let e in i.delegates)this.off(e,i.delegates[e]);r.splice(e,1);return}}}on(e,t,n){if(n===void 0)return super.on(e,t);let r=typeof t==`string`?[t]:t,i=this._createDelegatedListener(e,r,n);this._saveDelegatedListener(e,i);for(let e in i.delegates)this.on(e,i.delegates[e]);return{unsubscribe:()=>{this._removeDelegatedListener(e,r,n)}}}once(e,t,n){if(n===void 0)return super.once(e,t);let r=typeof t==`string`?[t]:t,i=this._createDelegatedListener(e,r,n);for(let t in i.delegates){let a=i.delegates[t];i.delegates[t]=(...t)=>{this._removeDelegatedListener(e,r,n),a(...t)}}this._saveDelegatedListener(e,i);for(let e in i.delegates)this.once(e,i.delegates[e]);return this}off(e,t,n){if(n===void 0)return super.off(e,t);let r=typeof t==`string`?[t]:t;return this._removeDelegatedListener(e,r,n),this}queryRenderedFeatures(e,t){if(!this.style)return[];let n,r=e instanceof l||Array.isArray(e),i=r?e:[[0,0],[this._camera.transform.width,this._camera.transform.height]];if(t||=(r?{}:e)||{},i instanceof l||typeof i[0]==`number`)n=[l.convert(i)];else{let e=l.convert(i[0]),t=l.convert(i[1]);n=[e,new l(t.x,e.y),t,new l(e.x,t.y),e]}return this.style.queryRenderedFeatures(n,t,this._camera.transform)}querySourceFeatures(e,t){return this.style.querySourceFeatures(e,t)}setStyle(e,t){return t=z({},{localIdeographFontFamily:this._localIdeographFontFamily,validate:this._validateStyle},t),t.diff!==!1&&t.localIdeographFontFamily===this._localIdeographFontFamily&&this.style&&e?(this._diffStyle(e,t),this):(this._localIdeographFontFamily=t.localIdeographFontFamily,this._updateStyle(e,t))}setTransformRequest(e){return this._requestManager.setTransformRequest(e),this}_getUIString(e){let t=this._locale[e];if(t==null)throw Error(`Missing UI string '${e}'`);return t}_updateStyle(e,t){if(this._diffStyleRequest?.abort(),this._diffStyleRequest=null,t.transformStyle&&this.style&&!this.style._loaded){this.style.once(`style.load`,()=>this._updateStyle(e,t));return}let n=this.style&&t.transformStyle?this.style.serialize():void 0;if(this.style&&(this.style.setEventedParent(null),this.style._remove(!e)),e)this.style=new ml(this,t||{});else return this._frameRequest&&=(this._frameRequest.abort(),null),this.style?.projection?.destroy(),delete this.style,this;return this.style.setEventedParent(this,{style:this.style}),typeof e==`string`?this.style.loadURL(e,t,n):this.style.loadJSON(e,t,n),this}_lazyInitEmptyStyle(){this.style||(this.style=new ml(this,{}),this.style.setEventedParent(this,{style:this.style}),this.style.loadEmpty())}async _diffStyle(e,t){if(this._diffStyleRequest?.abort(),typeof e==`string`){let n=e;this._diffStyleRequest=new AbortController;let r=this._diffStyleRequest;try{let e=await this._requestManager.transformRequest(n,`Style`);if(r.signal.aborted){this._diffStyleRequest=null;return}let i=await b(e,r);this._diffStyleRequest=null,this._updateDiff(i.data,t)}catch(e){this._diffStyleRequest=null,xe(e)||this.fire(new H(qn(e)))}}else typeof e==`object`&&(this._diffStyleRequest=null,this._updateDiff(e,t))}_updateDiff(e,t){try{this.style.setState(e,t)&&this._update(!0)}catch(n){I(`Unable to perform style diff: ${qn(n).message}. Rebuilding the style from scratch.`),this._updateStyle(e,t)}}getStyle(){if(this.style)return this.style.serialize()}_getStyleAndImages(){return this.style?{style:this.style.serialize(),images:this.style.imageManager.cloneImages()}:{style:null,images:{}}}isStyleLoaded(){if(!this.style){I(`There is no style added to the map.`);return}return this.style.loaded()}addSource(e,t){return this._lazyInitEmptyStyle(),this.style.addSource(e,t),this._update(!0)}isSourceLoaded(e){let t=this.style?.tileManagers[e];if(t===void 0){this.fire(new H(Error(`There is no tile manager with ID '${e}'`)));return}return t.loaded()}setTerrain(e,t={}){if(this.style._checkLoaded(),e&&ar(this,Ut.terrain,{value:e},t))return this;if(this._terrainDataCallback&&this.style.off(`data`,this._terrainDataCallback),!e)this.terrain&&this.terrain.destroy(),this.terrain=null,this.painter.renderToTexture=null,this._camera.terrain=null,this._camera.transform.setMinElevationForCurrentTile(0),this.getCenterClampedToGround()&&this._camera.transform.setElevation(0);else{let t=this.style.tileManagers[e.source];if(!t)throw Error(`cannot load terrain, because there exists no source with ID: ${e.source}`);this.terrain===null&&t.reload();for(let t in this.style._layers){let n=this.style._layers[t];n.type===`hillshade`&&n.source===e.source&&I(`You are using the same source for a hillshade layer and for 3D terrain. Please consider using two separate sources to improve rendering quality.`),n.type===`color-relief`&&n.source===e.source&&I(`You are using the same source for a color-relief layer and for 3D terrain. Please consider using two separate sources to improve rendering quality.`)}this.terrain&&this.terrain.destroy(),this.terrain=new mc(this.painter,t,e,this._terrainSkirtLength),this.painter.renderToTexture=new rm(this.painter,this.terrain),this._camera.terrain=this.terrain,this._camera.transform.setMinElevationForCurrentTile(this.terrain.getMinTileElevationForLngLatZoom(this._camera.transform.center,this._camera.transform.tileZoom)),this._camera.transform.setElevation(this.terrain.getElevationForLngLat(this._camera.transform.center,this._camera.transform)),this._terrainDataCallback=t=>this._handleTerrainDataEvent(t,e.source),this.style.on(`data`,this._terrainDataCallback)}return this.style.triggerSymbolPlacement(),this.fire(new Qr({terrain:e})),this}_handleTerrainDataEvent(e,t){if(e.dataType===`style`){this.terrain.tileManager.releaseAllRTT();return}let n=e.sourceId===t;if(n&&(this.terrain.resetElevationCache(),this.style.triggerSymbolPlacement()),n&&e.tile&&!this._camera.elevationFreeze&&(this._camera.transform.setMinElevationForCurrentTile(this.terrain.getMinTileElevationForLngLatZoom(this._camera.transform.center,this._camera.transform.tileZoom)),this.getCenterClampedToGround()&&this._camera.transform.setElevation(this.terrain.getElevationForLngLat(this._camera.transform.center,this._camera.transform))),e.tile){if(e.source?.type===`image`){this.terrain.tileManager.releaseAllRTT();return}this.terrain.tileManager.releaseRTT(e.tile.tileID)}}getTerrain(){return this.terrain?.options??null}areTilesLoaded(){let e=this.style?.tileManagers;for(let t of Object.values(e))if(!t.areTilesLoaded())return!1;return!0}removeSource(e){return this.style.removeSource(e),this._update(!0)}getSource(e){return this.style?.getSource(e)}setSourceTileLodParams(e,t,n){if(n){let r=this.getSource(n);if(!r)throw Error(`There is no source with ID "${n}", cannot set LOD parameters`);r.calculateTileZoom=vo(Math.max(1,e),Math.max(1,t))}else for(let n in this.style.tileManagers)this.style.tileManagers[n].getSource().calculateTileZoom=vo(Math.max(1,e),Math.max(1,t));return this._update(!0),this}refreshTiles(e,t){let n=this.style.tileManagers[e];if(!n)throw Error(`There is no tile manager with ID "${e}", cannot refresh tile`);t===void 0?n.reload(!0):n.refreshTiles(t.map(e=>new rn(e.z,e.x,e.y)))}addImage(e,t,n={}){this._lazyInitEmptyStyle();let r=this._createStyleImage(t,n);return r?(this.style.addImage(e,r),r.userImage?.onAdd&&r.userImage.onAdd(this,e),this):this}setMissingStyleImageResolver(e){return this._missingStyleImageResolver=e,this.style?.setMissingImageResolver(e),this}_createStyleImage(e,t={}){let{pixelRatio:n=1,sdf:r=!1,stretchX:i,stretchY:a,content:o,textFitWidth:s,textFitHeight:c}=t;if(e instanceof HTMLImageElement||zn(e)){let{width:t,height:l,data:u}=Rr.getImageData(e);return{data:new xn({width:t,height:l},u),pixelRatio:n,stretchX:i,stretchY:a,content:o,textFitWidth:s,textFitHeight:c,sdf:r,version:0}}if(e.width===void 0||e.height===void 0)return this.fire(new H(Error("Invalid arguments to map.addImage(). The second argument must be an `HTMLImageElement`, `ImageData`, `ImageBitmap`, or object with `width`, `height`, and `data` properties with the same format as `ImageData`"))),null;{let{width:t,height:l,data:u}=e,d=e,f=ye(d.data);return{data:f?new xn({width:t,height:l}):new xn({width:t,height:l},new Uint8Array(u)),pixelRatio:n,stretchX:i,stretchY:a,content:o,textFitWidth:s,textFitHeight:c,sdf:r,version:0,isWebGLImage:f,userImage:d}}}updateImage(e,t){let n=this.style.getImage(e);if(!n)return this.fire(new H(Error("The map has no image with that id. If you are adding a new image use `map.addImage(...)` instead.")));let{width:r,height:i,data:a}=t instanceof HTMLImageElement||zn(t)?Rr.getImageData(t):t;if(r===void 0||i===void 0)return this.fire(new H(Error("Invalid arguments to map.updateImage(). The second argument must be an `HTMLImageElement`, `ImageData`, `ImageBitmap`, or object with `width`, `height`, and `data` properties with the same format as `ImageData`")));if(r!==n.data.width||i!==n.data.height)return this.fire(new H(Error(`The width and height of the updated image must be that same as the previous version of the image`)));if(n.isWebGLImage=ye(a),n.isWebGLImage)n.userImage=t;else{let e=!(t instanceof HTMLImageElement||zn(t));n.data.replace(a,e)}return this.style.updateImage(e,n),this}getImage(e){return this.style.getImage(e)}hasImage(e){return e?!!this.style.getImage(e):(this.fire(new H(Error(`Missing required image id`))),!1)}removeImage(e){this.style.removeImage(e)}async loadImage(e){return Ur.getImage(await this._requestManager.transformRequest(e,`Image`),new AbortController)}listImages(){return this.style?.listImages()??[]}addLayer(e,t){return this._lazyInitEmptyStyle(),this.style.addLayer(e,t),this._update(!0)}moveLayer(e,t){return this.style.moveLayer(e,t),this._update(!0)}removeLayer(e){return this.style.removeLayer(e),this._update(!0)}getLayer(e){return this.style?.getLayer(e)}getLayersOrder(){return this.style?.getLayersOrder()??[]}setLayerZoomRange(e,t,n){return this.style.setLayerZoomRange(e,t,n),this._update(!0)}setFilter(e,t,n={}){return this.style?.setFilter(e,t,n),this._update(!0)}getFilter(e){return this.style.getFilter(e)}setPaintProperty(e,t,n,r={}){return this.style?.setPaintProperty(e,t,n,r),this._update(!0)}getPaintProperty(e,t){return this.style.getPaintProperty(e,t)}setLayoutProperty(e,t,n,r={}){return this.style.setLayoutProperty(e,t,n,r),this._update(!0)}getLayoutProperty(e,t){return this.style.getLayoutProperty(e,t)}setGlyphs(e,t={}){return this._lazyInitEmptyStyle(),this.style.setGlyphs(e,t),this._update(!0)}getGlyphs(){return this.style.getGlyphsUrl()}setFontFaces(e){return this._lazyInitEmptyStyle(),this.style.setFontFaces(e),this._update(!0)}getFontFaces(){return this.style.getFontFaces()}addSprite(e,t,n={}){return this._lazyInitEmptyStyle(),this.style.addSprite(e,t,n,e=>{e||this._update(!0)}),this}removeSprite(e){return this._lazyInitEmptyStyle(),this.style.removeSprite(e),this._update(!0)}getSprite(){return this.style.getSprite()}setSprite(e,t={}){return this._lazyInitEmptyStyle(),this.style.setSprite(e,t,e=>{e||this._update(!0)}),this}setLight(e,t={}){return this._lazyInitEmptyStyle(),this.style.setLight(e,t),this._update(!0)}getLight(){return this.style.getLight()}setSky(e,t={}){return this._lazyInitEmptyStyle(),this.style.setSky(e,t),this._update(!0)}getSky(){return this.style.getSky()}setFeatureState(e,t){return this.style.setFeatureState(e,t),this._update()}removeFeatureState(e,t){return this.style.removeFeatureState(e,t),this._update()}getFeatureState(e){return this.style.getFeatureState(e)}getContainer(){return this._container}getCanvasContainer(){return this._canvasContainer}getCanvas(){return this._canvas}_containerDimensions(){let e=0,t=0;return this._container&&(e=this._container.clientWidth||400,t=this._container.clientHeight||300),[e,t]}_setupResizeObserver(){let e=!1,t=Jf(e=>{this._trackResize&&!this._removed&&(this.resize(e),this.redraw())},50),n=this._ownerWindow.ResizeObserver??ResizeObserver;this._resizeObserver=new n(n=>{if(!e){e=!0;return}t(n)}),this._resizeObserver.observe(this._container)}_resolveContainer(e){if(typeof e==`string`){let t=document.getElementById(e);if(!t)throw Error(`Container '${e}' not found.`);return t}if(e instanceof HTMLElement||e&&typeof e==`object`&&e.nodeType===1)return e;throw Error(`Invalid type: 'container' must be a String or HTMLElement.`)}_setupContainer(){let e=this._container;e.classList.add(`maplibregl-map`);let t=this._canvasContainer=W.create(`div`,`maplibregl-canvas-container`,e);this._interactive&&t.classList.add(`maplibregl-interactive`),this._canvas=W.create(`canvas`,`maplibregl-canvas`,t),this._canvas.addEventListener(`webglcontextlost`,this._contextLost,!1),this._canvas.addEventListener(`webglcontextrestored`,this._contextRestored,!1),this._canvas.setAttribute(`tabindex`,this._interactive?`0`:`-1`),this._canvas.setAttribute(`aria-label`,this._getUIString(`Map.Title`)),this._canvas.setAttribute(`role`,`region`);let n=this._containerDimensions(),r=this._getClampedPixelRatio(n[0],n[1]);this._resizeCanvas(n[0],n[1],r);let i=this._controlContainer=W.create(`div`,`maplibregl-control-container`,e),a=this._controlPositions={};for(let e of[`top-left`,`top-right`,`bottom-left`,`bottom-right`])a[e]=W.create(`div`,`maplibregl-ctrl-${e} `,i);this._container.addEventListener(`scroll`,this._onMapScroll,!1)}_cleanupContainer(){this._canvas.removeEventListener(`webglcontextrestored`,this._contextRestored,!1),this._canvas.removeEventListener(`webglcontextlost`,this._contextLost,!1),this._canvasContainer.remove(),this._controlContainer.remove(),this._container.removeEventListener(`scroll`,this._onMapScroll,!1),this._container.classList.remove(`maplibregl-map`)}_resizeCanvas(e,t,n){this._canvas.width=Math.floor(n*e),this._canvas.height=Math.floor(n*t),this._canvas.style.width=`${e}px`,this._canvas.style.height=`${t}px`}_setupPainter(){let e={...this._canvasContextAttributes,alpha:!0,depth:!0,stencil:!0,premultipliedAlpha:!0},t=null;this._canvas.addEventListener(`webglcontextcreationerror`,e=>{t=e},{once:!0});let n=this._canvas.getContext(`webgl2`,e);if(!n)throw new qf(e,t);this.painter=new Kf(n,this._camera.transform)}migrateProjection(e,t){this._camera.migrateProjection(e,t),this.painter.transform=e,this.fire(new $r({newProjection:this.style.projection.name}))}loaded(){return!this._styleDirty&&!this._sourcesDirty&&!!this.style&&this.style.loaded()}_update(e){return this.style?._loaded?(this._styleDirty||=e,this._sourcesDirty=!0,this.triggerRepaint(),this):this}_requestRenderFrame(e){return this._update(),this._renderTaskQueue.add(e)}_cancelRenderFrame(e){this._renderTaskQueue.remove(e)}_render(e){let t=this._idleTriggered?this._fadeDuration:0,n=this.style.projection?.transitionState>0;if(this.painter.context.setDirty(),this.painter.setBaseState(),this._renderTaskQueue.run(e),this._removed)return;let r=!1;if(this.style&&this._styleDirty){this._styleDirty=!1;let e=this._camera.transform.zoom,n=U();this.style.zoomHistory.update(e,n);let i=new Kn(e,{now:n,fadeDuration:t,zoomHistory:this.style.zoomHistory,transition:this.style.getTransition()}),a=i.crossFadingFactor();(a!==1||a!==this._crossFadingFactor)&&(r=!0,this._crossFadingFactor=a),this.style.update(i)}let i=this.style.projection?.transitionState>0!==n;this._camera.transform.setTransitionState(this.style.projection?.transitionState),this.style&&(this._sourcesDirty||i)&&(this._sourcesDirty=!1,this.style._updateSources(this._camera.transform)),this.terrain?(this.terrain.tileManager.update(this._camera.transform,this.terrain)&&this.terrain.resetElevationCache(),this._camera.transform.setMinElevationForCurrentTile(this.terrain.getMinTileElevationForLngLatZoom(this._camera.transform.center,this._camera.transform.tileZoom)),!this._camera.elevationFreeze&&this.getCenterClampedToGround()&&this._camera.transform.setElevation(this.terrain.getElevationForLngLat(this._camera.transform.center,this._camera.transform))):(this._camera.transform.setMinElevationForCurrentTile(0),this.getCenterClampedToGround()&&this._camera.transform.setElevation(0)),this._placementDirty=this.style?._updatePlacement(this._camera.transform,this.showCollisionBoxes,t,this._crossSourceCollisions,i),this.painter.render(this.style,{showTileBoundaries:this.showTileBoundaries,showOverdrawInspector:this._showOverdrawInspector,rotating:this.isRotating(),zooming:this.isZooming(),moving:this.isMoving(),fadeDuration:t,showPadding:this.showPadding,anisotropicFilterPitch:this.getAnisotropicFilterPitch()}),this.fire(new Gr(`render`)),this.loaded()&&!this._loaded&&(this._loaded=!0,this.fire(new Gr(`load`))),this.style&&(this.style.hasTransitions()||r)&&(this._styleDirty=!0),this.style&&!this._placementDirty&&this.style._releaseSymbolFadeTiles();let a=this._sourcesDirty||this._styleDirty||this._placementDirty;return a||this._repaint?this.triggerRepaint():!this.isMoving()&&this.loaded()&&this.fire(new Gr(`idle`)),this._loaded&&!this._fullyLoaded&&!a&&(this._fullyLoaded=!0),this}redraw(){return this.style&&(this._frameRequest&&=(this._frameRequest.abort(),null),this._render(0)),this}remove(){this._hash&&this._hash.remove();for(let e of this._controls)e.onRemove(this);this._controls=[],this._frameRequest&&=(this._frameRequest.abort(),null),this._renderTaskQueue.clear(),this._diffStyleRequest?.abort(),this.painter.destroy(),this._handlers.destroy(),this.setStyle(null),typeof window<`u`&&this._ownerWindow.removeEventListener(`online`,this._onWindowOnline,!1),Ur.removeThrottleControl(this._imageQueueHandle),this._resizeObserver?.disconnect();let e=this.painter.context.gl.getExtension(`WEBGL_lose_context`);e?.loseContext&&e.loseContext(),this._cleanupContainer(),this._removed=!0,this.fire(new Gr(`remove`))}triggerRepaint(){this.style&&!this._frameRequest&&(this._frameRequest=new AbortController,Rr.frame(this._frameRequest,e=>{this._frameRequest=null;try{this._render(e)}catch(e){if(!xe(e))throw e}},()=>{},this._ownerWindow))}get showTileBoundaries(){return!!this._showTileBoundaries}set showTileBoundaries(e){this._showTileBoundaries!==e&&(this._showTileBoundaries=e,this._update())}get showPadding(){return!!this._showPadding}set showPadding(e){this._showPadding!==e&&(this._showPadding=e,this._update())}get showCollisionBoxes(){return!!this._showCollisionBoxes}set showCollisionBoxes(e){this._showCollisionBoxes!==e&&(this._showCollisionBoxes=e,e?this.style._generateCollisionBoxes():this._update())}get showOverdrawInspector(){return!!this._showOverdrawInspector}set showOverdrawInspector(e){this._showOverdrawInspector!==e&&(this._showOverdrawInspector=e,this._update())}get repaint(){return!!this._repaint}set repaint(e){this._repaint!==e&&(this._repaint=e,this.triggerRepaint())}get vertices(){return!!this._vertices}set vertices(e){this._vertices=e,this._update()}get version(){return am}getCameraTargetElevation(){return this._camera.transform.elevation}getProjection(){return this.style.getProjection()}setProjection(e){return this._lazyInitEmptyStyle(),this.style.setProjection(e),this._update(!0)}};const cm={showCompass:!0,showZoom:!0,visualizePitch:!1,visualizeRoll:!0};var lm=class{constructor(e){this._updateZoomButtons=()=>{let e=this._map.getZoom(),t=e===this._map.getMaxZoom(),n=e===this._map.getMinZoom(!0);this._zoomInButton.disabled=t,this._zoomOutButton.disabled=n,this._zoomInButton.setAttribute(`aria-disabled`,t.toString()),this._zoomOutButton.setAttribute(`aria-disabled`,n.toString())},this._rotateCompassArrow=()=>{let e=this._map.getPitch(),t=this._map.getRoll(),n=this._map.getBearing(),r=1/Math.cos(qt(e))**.5;if(this.options.visualizePitch&&this.options.visualizeRoll){this._compassIcon.style.transform=`scale(${r}) rotateZ(${-t}deg) rotateX(${e}deg) rotateZ(${-n}deg)`;return}if(this.options.visualizePitch){this._compassIcon.style.transform=`scale(${r}) rotateX(${e}deg) rotateZ(${-n}deg)`;return}if(this.options.visualizeRoll){this._compassIcon.style.transform=`rotate(${-n-t}deg)`;return}this._compassIcon.style.transform=`rotate(${-n}deg)`},this._setButtonTitle=(e,t)=>{let n=this._map._getUIString(`NavigationControl.${t}`);e.title=n,e.setAttribute(`aria-label`,n)},this.options=z({},cm,e),this._container=W.create(`div`,`maplibregl-ctrl maplibregl-ctrl-group`),this._container.addEventListener(`contextmenu`,e=>e.preventDefault()),this.options.showZoom&&(this._zoomInButton=this._createButton(`maplibregl-ctrl-zoom-in`,e=>this._map.zoomIn({},{originalEvent:e})),W.create(`span`,`maplibregl-ctrl-icon`,this._zoomInButton).setAttribute(`aria-hidden`,`true`),this._zoomOutButton=this._createButton(`maplibregl-ctrl-zoom-out`,e=>this._map.zoomOut({},{originalEvent:e})),W.create(`span`,`maplibregl-ctrl-icon`,this._zoomOutButton).setAttribute(`aria-hidden`,`true`)),this.options.showCompass&&(this._compass=this._createButton(`maplibregl-ctrl-compass`,e=>{this.options.visualizePitch?this._map.resetNorthPitch({},{originalEvent:e}):this._map.resetNorth({},{originalEvent:e})}),this._compassIcon=W.create(`span`,`maplibregl-ctrl-icon`,this._compass),this._compassIcon.setAttribute(`aria-hidden`,`true`))}onAdd(e){return this._map=e,this.options.showZoom&&(this._setButtonTitle(this._zoomInButton,`ZoomIn`),this._setButtonTitle(this._zoomOutButton,`ZoomOut`),this._map.on(`move`,this._updateZoomButtons),this._updateZoomButtons()),this.options.showCompass&&(this._setButtonTitle(this._compass,`ResetBearing`),this.options.visualizePitch&&this._map.on(`pitch`,this._rotateCompassArrow),this.options.visualizeRoll&&this._map.on(`roll`,this._rotateCompassArrow),this._map.on(`rotate`,this._rotateCompassArrow),this._rotateCompassArrow(),this._handler=new um(this._map,this._compass,this.options.visualizePitch)),this._container}onRemove(){this._container.remove(),this.options.showZoom&&this._map.off(`move`,this._updateZoomButtons),this.options.showCompass&&(this.options.visualizePitch&&this._map.off(`pitch`,this._rotateCompassArrow),this.options.visualizeRoll&&this._map.off(`roll`,this._rotateCompassArrow),this._map.off(`rotate`,this._rotateCompassArrow),this._handler.off(),delete this._handler),delete this._map}_createButton(e,t){let n=W.create(`button`,e,this._container);return n.type=`button`,n.addEventListener(`click`,t),n}},um=class{constructor(e,t,n=!1){this.mousedown=e=>{this.startMove(e,W.mousePos(this.element,e)),window.addEventListener(`mousemove`,this.mousemove),window.addEventListener(`mouseup`,this.mouseup)},this.mousemove=e=>{this.move(e,W.mousePos(this.element,e))},this.mouseup=e=>{this._rotatePitchHandler.dragEnd(e),this.offTemp()},this.touchstart=e=>{e.targetTouches.length===1?(this._startPos=this._lastPos=W.touchPos(this.element,e.targetTouches)[0],this.startMove(e,this._startPos),window.addEventListener(`touchmove`,this.touchmove,{passive:!1}),window.addEventListener(`touchend`,this.touchend)):this.reset()},this.touchmove=e=>{e.targetTouches.length===1?(this._lastPos=W.touchPos(this.element,e.targetTouches)[0],this.move(e,this._lastPos)):this.reset()},this.touchend=e=>{e.targetTouches.length===0&&this._startPos&&this._lastPos&&this._startPos.dist(this._lastPos){this._rotatePitchHandler.reset(),delete this._startPos,delete this._lastPos,this.offTemp()},this._clickTolerance=10,this.element=t;let r=new vp;this._rotatePitchHandler=new pp({clickTolerance:3,move:(e,r)=>{let i=t.getBoundingClientRect(),a=new l((i.bottom-i.top)/2,(i.right-i.left)/2);return{bearingDelta:wn(new l(e.x,r.y),r,a),pitchDelta:n?(r.y-e.y)*-.5:void 0}},moveStateManager:r,enable:!0,assignEvents:()=>{}}),this.map=e,t.addEventListener(`mousedown`,this.mousedown),t.addEventListener(`touchstart`,this.touchstart,{passive:!1}),t.addEventListener(`touchcancel`,this.reset)}startMove(e,t){this._rotatePitchHandler.dragStart(e,t),W.disableDrag()}move(e,t){let n=this.map,{bearingDelta:r,pitchDelta:i}=this._rotatePitchHandler.dragMove(e,t)||{};r&&n.setBearing(n.getBearing()+r),i&&n.setPitch(n.getPitch()+i)}off(){let e=this.element;e.removeEventListener(`mousedown`,this.mousedown),e.removeEventListener(`touchstart`,this.touchstart),window.removeEventListener(`touchmove`,this.touchmove),window.removeEventListener(`touchend`,this.touchend),e.removeEventListener(`touchcancel`,this.reset),this.offTemp()}offTemp(){W.enableDrag(),window.removeEventListener(`mousemove`,this.mousemove),window.removeEventListener(`mouseup`,this.mouseup),window.removeEventListener(`touchmove`,this.touchmove),window.removeEventListener(`touchend`,this.touchend)}};let dm;async function fm(e=!1){if(dm!==void 0&&!e)return dm;if(window.navigator.permissions===void 0)return dm=!!window.navigator.geolocation,dm;try{dm=(await window.navigator.permissions.query({name:`geolocation`})).state!==`denied`}catch{dm=!!window.navigator.geolocation}return dm}function pm(e,t,n,r=!1){if(r||!n.getCoveringTilesDetailsProvider().allowWorldCopies())return e?.wrap();let i=new V(e.lng,e.lat);if(e=new V(e.lng,e.lat),t){let r=new V(e.lng-360,e.lat),i=new V(e.lng+360,e.lat),a=n.locationToScreenPoint(e).distSqr(t);n.locationToScreenPoint(r).distSqr(t)180;){let t=n.locationToScreenPoint(e);if(t.x>=0&&t.y>=0&&t.x<=n.width&&t.y<=n.height)break;e.lng>n.center.lng?e.lng-=360:e.lng+=360}return e.lng!==i.lng&&n.isPointOnMapSurface(n.locationToScreenPoint(e))?e:i}const mm={center:`translate(-50%,-50%)`,top:`translate(-50%,0)`,"top-left":`translate(0,0)`,"top-right":`translate(-100%,0)`,bottom:`translate(-50%,-100%)`,"bottom-left":`translate(0,-100%)`,"bottom-right":`translate(-100%,-100%)`,left:`translate(0,-50%)`,right:`translate(-100%,-50%)`};function hm(e,t,n){let r=e.classList;for(let e in mm)r.remove(`maplibregl-${n}-anchor-${e}`);r.add(`maplibregl-${n}-anchor-${t}`)}const gm={ArrowLeft:[-1,0],ArrowRight:[1,0],ArrowUp:[0,-1],ArrowDown:[0,1]};var _m=class extends Xe{},vm=class extends Xe{},ym=class extends h{constructor(e){if(super(),this._onClick=e=>{this.fire(new vm(`click`,{originalEvent:e}))},this._onKeyPress=e=>{(e.code===`Space`||e.code===`Enter`)&&this.togglePopup()},this._onKeyDown=e=>{if(!this._defaultMarker||!this._draggable||!this._map||!this._lngLat||e.composedPath()[0]!==this._element||e.altKey||e.ctrlKey||e.metaKey)return;let t=gm[e.key];if(!t)return;e.preventDefault(),e.stopPropagation();let n=e.shiftKey?10:1,r=this._map.project(this._lngLat);this.setLngLat(this._map.unproject(new l(r.x+t[0]*n,r.y+t[1]*n))),this._keyboardDragActive||(this._keyboardDragActive=!0,this.fire(new _m(`dragstart`))),this.fire(new _m(`drag`))},this._onKeyUp=e=>{gm[e.key]&&this._endKeyboardDrag()},this._onBlur=()=>{this._endKeyboardDrag()},this._onMapClick=e=>{let t=e.originalEvent.target,n=this._element;this._popup&&(t===n||n.contains(t))&&this.togglePopup()},this._update=e=>{if(!this._map)return;let t=this._map.loaded()&&!this._map.isMoving();(e?.type===`terrain`||e?.type===`render`&&!t)&&this._map.once(`render`,this._update),this._lngLat=pm(this._lngLat,this._flatPos,this._map._camera.transform),this._flatPos=this._pos=this._map.project(this._lngLat)._add(this._offset),this._map.terrain&&(this._flatPos=this._map._camera.transform.locationToScreenPoint(this._lngLat)._add(this._offset));let n=``;this._rotationAlignment===`viewport`||this._rotationAlignment===`auto`?n=`rotateZ(${this._rotation}deg)`:this._rotationAlignment===`map`&&(n=`rotateZ(${this._rotation-this._map.getBearing()}deg)`);let r=``;this._pitchAlignment===`viewport`||this._pitchAlignment===`auto`?r=`rotateX(0deg)`:this._pitchAlignment===`map`&&(r=`rotateX(${this._map.getPitch()}deg)`),!this._subpixelPositioning&&(!e||e.type===`moveend`)&&(this._pos=this._pos.round()),this._element.style.transform=`${mm[this._anchor]} translate(${this._pos.x}px, ${this._pos.y}px) ${r} ${n}`,Rr.frameAsync(new AbortController,this._map._ownerWindow).then(()=>{this._updateOpacity(e?.type===`moveend`)}).catch(()=>{})},this._onMove=e=>{if(!this._isDragging){let t=this._clickTolerance||this._map._clickTolerance;this._isDragging=e.point.dist(this._pointerdownPos)>=t}this._isDragging&&(this._pos=e.point.sub(this._positionDelta),this._lngLat=this._map.unproject(this._pos),this.setLngLat(this._lngLat),this._element.style.pointerEvents=`none`,this._state===`pending`&&(this._state=`active`,this.fire(new _m(`dragstart`))),this.fire(new _m(`drag`)))},this._onUp=()=>{this._element.style.pointerEvents=`auto`,this._positionDelta=null,this._pointerdownPos=null,this._isDragging=!1,this._map.off(`mousemove`,this._onMove),this._map.off(`touchmove`,this._onMove),this._state===`active`&&this.fire(new _m(`dragend`)),this._state=`inactive`},this._addDragHandler=e=>{this._element.contains(e.originalEvent.target)&&(e.preventDefault(),this._positionDelta=e.point.sub(this._pos).add(this._offset),this._pointerdownPos=e.point,this._state=`pending`,this._map.on(`mousemove`,this._onMove),this._map.on(`touchmove`,this._onMove),this._map.once(`mouseup`,this._onUp),this._map.once(`touchend`,this._onUp))},this._anchor=e?.anchor||`center`,this._color=e?.color||`#3FB1CE`,this._scale=e?.scale||1,this._draggable=e?.draggable||!1,this._clickTolerance=e?.clickTolerance||0,this._subpixelPositioning=e?.subpixelPositioning||!1,this._isDragging=!1,this._roleManaged=!1,this._tabIndexManaged=!1,this._keyboardDragActive=!1,this._state=`inactive`,this._rotation=e?.rotation||0,this._rotationAlignment=e?.rotationAlignment||`auto`,this._pitchAlignment=e?.pitchAlignment&&e.pitchAlignment!==`auto`?e.pitchAlignment:this._rotationAlignment,this.setOpacity(e?.opacity,e?.opacityWhenCovered),e?.element)this._element=e.element,this._offset=l.convert(e?.offset||[0,0]);else{this._defaultMarker=!0,this._element=W.create(`div`);let t=W.createNS(`http://www.w3.org/2000/svg`,`svg`);t.setAttributeNS(null,`display`,`block`),t.setAttributeNS(null,`height`,`41px`),t.setAttributeNS(null,`width`,`27px`),t.setAttributeNS(null,`viewBox`,`0 0 27 41`);let n=W.createNS(`http://www.w3.org/2000/svg`,`g`);n.setAttributeNS(null,`stroke`,`none`),n.setAttributeNS(null,`stroke-width`,`1`),n.setAttributeNS(null,`fill`,`none`),n.setAttributeNS(null,`fill-rule`,`evenodd`);let r=W.createNS(`http://www.w3.org/2000/svg`,`g`);r.setAttributeNS(null,`fill-rule`,`nonzero`);let i=W.createNS(`http://www.w3.org/2000/svg`,`g`);i.setAttributeNS(null,`transform`,`translate(3.0, 29.0)`),i.setAttributeNS(null,`fill`,`#000000`);for(let e of[{rx:`10.5`,ry:`5.25002273`},{rx:`10.5`,ry:`5.25002273`},{rx:`9.5`,ry:`4.77275007`},{rx:`8.5`,ry:`4.29549936`},{rx:`7.5`,ry:`3.81822308`},{rx:`6.5`,ry:`3.34094679`},{rx:`5.5`,ry:`2.86367051`},{rx:`4.5`,ry:`2.38636864`}]){let t=W.createNS(`http://www.w3.org/2000/svg`,`ellipse`);t.setAttributeNS(null,`opacity`,`0.04`),t.setAttributeNS(null,`cx`,`10.5`),t.setAttributeNS(null,`cy`,`5.80029008`),t.setAttributeNS(null,`rx`,e.rx),t.setAttributeNS(null,`ry`,e.ry),i.appendChild(t)}let a=W.createNS(`http://www.w3.org/2000/svg`,`g`);a.setAttributeNS(null,`fill`,this._color);let o=W.createNS(`http://www.w3.org/2000/svg`,`path`);o.setAttributeNS(null,`d`,`M27,13.5 C27,19.074644 20.250001,27.000002 14.75,34.500002 C14.016665,35.500004 12.983335,35.500004 12.25,34.500002 C6.7499993,27.000002 0,19.222562 0,13.5 C0,6.0441559 6.0441559,0 13.5,0 C20.955844,0 27,6.0441559 27,13.5 Z`),a.appendChild(o);let s=W.createNS(`http://www.w3.org/2000/svg`,`g`);s.setAttributeNS(null,`opacity`,`0.25`),s.setAttributeNS(null,`fill`,`#000000`);let c=W.createNS(`http://www.w3.org/2000/svg`,`path`);c.setAttributeNS(null,`d`,`M13.5,0 C6.0441559,0 0,6.0441559 0,13.5 C0,19.222562 6.7499993,27 12.25,34.5 C13,35.522727 14.016664,35.500004 14.75,34.5 C20.250001,27 27,19.074644 27,13.5 C27,6.0441559 20.955844,0 13.5,0 Z M13.5,1 C20.415404,1 26,6.584596 26,13.5 C26,15.898657 24.495584,19.181431 22.220703,22.738281 C19.945823,26.295132 16.705119,30.142167 13.943359,33.908203 C13.743445,34.180814 13.612715,34.322738 13.5,34.441406 C13.387285,34.322738 13.256555,34.180814 13.056641,33.908203 C10.284481,30.127985 7.4148684,26.314159 5.015625,22.773438 C2.6163816,19.232715 1,15.953538 1,13.5 C1,6.584596 6.584596,1 13.5,1 Z`),s.appendChild(c);let u=W.createNS(`http://www.w3.org/2000/svg`,`g`);u.setAttributeNS(null,`transform`,`translate(6.0, 7.0)`),u.setAttributeNS(null,`fill`,`#FFFFFF`);let d=W.createNS(`http://www.w3.org/2000/svg`,`g`);d.setAttributeNS(null,`transform`,`translate(8.0, 8.0)`);let f=W.createNS(`http://www.w3.org/2000/svg`,`circle`);f.setAttributeNS(null,`fill`,`#000000`),f.setAttributeNS(null,`opacity`,`0.25`),f.setAttributeNS(null,`cx`,`5.5`),f.setAttributeNS(null,`cy`,`5.5`),f.setAttributeNS(null,`r`,`5.4999962`);let p=W.createNS(`http://www.w3.org/2000/svg`,`circle`);p.setAttributeNS(null,`fill`,`#FFFFFF`),p.setAttributeNS(null,`cx`,`5.5`),p.setAttributeNS(null,`cy`,`5.5`),p.setAttributeNS(null,`r`,`5.4999962`),d.appendChild(f),d.appendChild(p),r.appendChild(i),r.appendChild(a),r.appendChild(s),r.appendChild(u),r.appendChild(d),t.appendChild(r),t.setAttributeNS(null,`height`,`${41*this._scale}px`),t.setAttributeNS(null,`width`,`${27*this._scale}px`),this._element.appendChild(t),this._offset=l.convert(e?.offset||[0,-14])}if(this._element.classList.add(`maplibregl-marker`),this._element.addEventListener(`dragstart`,e=>{e.preventDefault()}),this._element.addEventListener(`mousedown`,e=>{e.preventDefault()}),hm(this._element,this._anchor,`marker`),e?.className)for(let t of e.className.split(` `))this._element.classList.add(t);this._popup=null}addTo(e){return this.remove(),this._map=e,this._defaultMarker&&!this._element.hasAttribute(`aria-label`)&&this._element.setAttribute(`aria-label`,e._getUIString(`Marker.Title`)),this._updateAccessibilityRole(),e.getCanvasContainer().appendChild(this._element),e.on(`move`,this._update),e.on(`moveend`,this._update),e.on(`terrain`,this._update),e.on(`projectiontransition`,this._update),this._element.addEventListener(`click`,this._onClick),this.setDraggable(this._draggable),this._update(),this._map.on(`click`,this._onMapClick),this}remove(){return this._opacityTimeout&&(clearTimeout(this._opacityTimeout),delete this._opacityTimeout),this._map&&(this._map.off(`click`,this._onMapClick),this._map.off(`move`,this._update),this._map.off(`moveend`,this._update),this._map.off(`terrain`,this._update),this._map.off(`projectiontransition`,this._update),this._map.off(`mousedown`,this._addDragHandler),this._map.off(`touchstart`,this._addDragHandler),this._map.off(`mouseup`,this._onUp),this._map.off(`touchend`,this._onUp),this._map.off(`mousemove`,this._onMove),this._map.off(`touchmove`,this._onMove),delete this._map),this._element.removeEventListener(`click`,this._onClick),this._element.removeEventListener(`keydown`,this._onKeyDown),this._element.removeEventListener(`keyup`,this._onKeyUp),this._element.removeEventListener(`blur`,this._onBlur),this._element.removeEventListener(`keypress`,this._onKeyPress),this._keyboardDragActive=!1,this._element.remove(),this._popup&&this._popup.remove(),this}getLngLat(){return this._lngLat}setLngLat(e){return this._lngLat=V.convert(e),this._pos=null,this._popup&&this._popup.setLngLat(this._lngLat),this._update(),this}getElement(){return this._element}setPopup(e){if(this._popup&&(this._popup.remove(),this._popup=null,this._element.removeEventListener(`keypress`,this._onKeyPress)),e){if(!(`offset`in e.options)){let t=13.5/Math.SQRT2;e.options.offset=this._defaultMarker?{top:[0,0],"top-left":[0,0],"top-right":[0,0],bottom:[0,-38.1],"bottom-left":[t,(24.6+t)*-1],"bottom-right":[-t,(24.6+t)*-1],left:[13.5,-24.6],right:[-13.5,-24.6]}:this._offset}this._popup=e,this._element.addEventListener(`keypress`,this._onKeyPress)}return this._updateTabIndex(),this._updateAccessibilityRole(),this}setSubpixelPositioning(e){return this._subpixelPositioning=e,this}_endKeyboardDrag(){this._keyboardDragActive&&(this._keyboardDragActive=!1,this.fire(new _m(`dragend`)))}getPopup(){return this._popup}togglePopup(){let e=this._popup;if(this._element.style.opacity===this._opacityWhenCovered)return this;if(e)e.isOpen()?e.remove():(e.setLngLat(this._lngLat),e.addTo(this._map));else return this;return this}_updateOpacity(e=!1){let t=this._map?.terrain,n=this._map._camera.transform.isLocationOccluded(this._lngLat);if(!t||n){let e=n?this._opacityWhenCovered:this._opacity;this._element.style.opacity!==e&&(this._element.style.opacity=e,this._element.classList.toggle(`maplibregl-marker-covered`,n));return}if(e)this._opacityTimeout=null;else{if(this._opacityTimeout)return;this._opacityTimeout=setTimeout(()=>{this._opacityTimeout=null},100)}let r=this._map,i=r.terrain.depthAtPoint(this._pos),a=r.terrain.getElevationForLngLat(this._lngLat,r._camera.transform),o=r._camera.transform.lngLatToCameraDepth(this._lngLat,a),s=.006;if(o-is;this._popup?.isOpen()&&f&&this._popup.remove(),this._element.style.opacity=f?this._opacityWhenCovered:this._opacity,this._element.classList.toggle(`maplibregl-marker-covered`,f)}getOffset(){return this._offset}setOffset(e){return this._offset=l.convert(e),this._update(),this}addClassName(e){this._element.classList.add(e)}removeClassName(e){this._element.classList.remove(e)}toggleClassName(e){return this._element.classList.toggle(e)}setDraggable(e){return this._draggable=!!e,this._element.classList.toggle(`maplibregl-marker-draggable`,this._draggable),this._map&&(e?(this._map.on(`mousedown`,this._addDragHandler),this._map.on(`touchstart`,this._addDragHandler)):(this._map.off(`mousedown`,this._addDragHandler),this._map.off(`touchstart`,this._addDragHandler))),this._defaultMarker&&(this._draggable?(this._element.addEventListener(`keydown`,this._onKeyDown),this._element.addEventListener(`keyup`,this._onKeyUp),this._element.addEventListener(`blur`,this._onBlur)):(this._element.removeEventListener(`keydown`,this._onKeyDown),this._element.removeEventListener(`keyup`,this._onKeyUp),this._element.removeEventListener(`blur`,this._onBlur),this._endKeyboardDrag())),this._updateTabIndex(),this._updateAccessibilityRole(),this}isDraggable(){return this._draggable}_updateTabIndex(){this._popup||this._defaultMarker&&this._draggable?this._element.hasAttribute(`tabindex`)||(this._element.setAttribute(`tabindex`,`0`),this._tabIndexManaged=!0):this._tabIndexManaged&&=(this._element.getAttribute(`tabindex`)===`0`&&this._element.removeAttribute(`tabindex`),!1)}_updateAccessibilityRole(){if(!this._defaultMarker||this._element.hasAttribute(`role`)&&!this._roleManaged)return;let e=this._draggable||this._popup?`button`:`img`;this._element.setAttribute(`role`,e),this._roleManaged=!0}setRotation(e){return this._rotation=e||0,this._update(),this}getRotation(){return this._rotation}setRotationAlignment(e){return this._rotationAlignment=e||`auto`,this._update(),this}getRotationAlignment(){return this._rotationAlignment}setPitchAlignment(e){return this._pitchAlignment=e&&e!==`auto`?e:this._rotationAlignment,this._update(),this}getPitchAlignment(){return this._pitchAlignment}setOpacity(e,t){return(this._opacity===void 0||e===void 0&&t===void 0)&&(this._opacity=`1`,this._opacityWhenCovered=`0.2`),e!==void 0&&(this._opacity=String(e)),t!==void 0&&(this._opacityWhenCovered=String(t)),this._map&&this._updateOpacity(!0),this}};const bm={positionOptions:{enableHighAccuracy:!1,maximumAge:0,timeout:6e3},fitBoundsOptions:{maxZoom:15},trackUserLocation:!1,showAccuracyCircle:!0,showUserLocation:!0};let xm=0,Sm=!1;var Cm=class extends Xe{},wm=class extends Xe{},Tm=class extends Xe{},Em=class extends h{constructor(e){super(),this._onSuccess=e=>{if(this._map){if(this._isOutOfMapMaxBounds(e)){this._setErrorState(),this.fire(new wm(`outofmaxbounds`,e)),this._updateMarker(),this._finish();return}if(this.options.trackUserLocation)switch(this._lastKnownPosition=e,this._watchState){case`WAITING_ACTIVE`:case`ACTIVE_LOCK`:case`ACTIVE_ERROR`:this._watchState=`ACTIVE_LOCK`,this._geolocateButton.classList.remove(`maplibregl-ctrl-geolocate-waiting`),this._geolocateButton.classList.remove(`maplibregl-ctrl-geolocate-active-error`),this._geolocateButton.classList.add(`maplibregl-ctrl-geolocate-active`);break;case`BACKGROUND`:case`BACKGROUND_ERROR`:this._watchState=`BACKGROUND`,this._geolocateButton.classList.remove(`maplibregl-ctrl-geolocate-waiting`),this._geolocateButton.classList.remove(`maplibregl-ctrl-geolocate-background-error`),this._geolocateButton.classList.add(`maplibregl-ctrl-geolocate-background`);break;default:throw Error(`Unexpected watchState ${this._watchState}`)}this.options.showUserLocation&&this._watchState!==`OFF`&&this._updateMarker(e),(!this.options.trackUserLocation||this._watchState===`ACTIVE_LOCK`)&&this._updateCamera(e),this.options.showUserLocation&&this._dotElement.classList.remove(`maplibregl-user-location-dot-stale`),this.fire(new wm(`geolocate`,e)),this._finish()}},this._updateCamera=e=>{let t=new V(e.coords.longitude,e.coords.latitude),n=e.coords.accuracy,r=this._map.getBearing(),i=z({bearing:r},this.options.fitBoundsOptions),a=_a.fromLngLat(t,n);this._map.fitBounds(a,i,{geolocateSource:!0})},this._updateMarker=e=>{if(e){let t=new V(e.coords.longitude,e.coords.latitude);this._accuracyCircleMarker.setLngLat(t).addTo(this._map),this._userLocationDotMarker.setLngLat(t).addTo(this._map),this._accuracy=e.coords.accuracy,this._updateCircleRadiusIfNeeded()}else this._userLocationDotMarker.remove(),this._accuracyCircleMarker.remove()},this._onUpdate=()=>{this._updateCircleRadiusIfNeeded()},this._onError=e=>{if(this._map){if(e.code===1){this._watchState=`OFF`,this._geolocateButton.classList.remove(`maplibregl-ctrl-geolocate-waiting`),this._geolocateButton.classList.remove(`maplibregl-ctrl-geolocate-active`),this._geolocateButton.classList.remove(`maplibregl-ctrl-geolocate-active-error`),this._geolocateButton.classList.remove(`maplibregl-ctrl-geolocate-background`),this._geolocateButton.classList.remove(`maplibregl-ctrl-geolocate-background-error`),this._geolocateButton.disabled=!0;let e=this._map._getUIString(`GeolocateControl.LocationNotAvailable`);this._geolocateButton.title=e,this._geolocateButton.setAttribute(`aria-label`,e),this._geolocationWatchID!==void 0&&this._clearWatch()}else if(e.code===3&&Sm)return;else this._setErrorState();this._watchState!==`OFF`&&this.options.showUserLocation&&this._dotElement.classList.add(`maplibregl-user-location-dot-stale`),this.fire(new Tm(`error`,e)),this._finish()}},this._finish=()=>{this._timeoutId&&clearTimeout(this._timeoutId),this._timeoutId=void 0},this._onMoveStart=e=>{if(!this._map)return;let t=e?.[0]instanceof ResizeObserverEntry;!e.geolocateSource&&this._watchState===`ACTIVE_LOCK`&&!t&&!this._map.isZooming()&&(this._watchState=`BACKGROUND`,this._geolocateButton.classList.add(`maplibregl-ctrl-geolocate-background`),this._geolocateButton.classList.remove(`maplibregl-ctrl-geolocate-active`),this.fire(new Cm(`trackuserlocationend`)),this.fire(new Cm(`userlocationlostfocus`)))},this._setupUI=()=>{this._map&&(this._container.addEventListener(`contextmenu`,e=>{e.preventDefault()}),this._geolocateButton=W.create(`button`,`maplibregl-ctrl-geolocate`,this._container),W.create(`span`,`maplibregl-ctrl-icon`,this._geolocateButton).setAttribute(`aria-hidden`,`true`),this._geolocateButton.type=`button`,this._geolocateButton.disabled=!0)},this._finishSetupUI=e=>{if(this._map){if(e===!1){I(`Geolocation support is not available so the GeolocateControl will be disabled.`);let e=this._map._getUIString(`GeolocateControl.LocationNotAvailable`);this._geolocateButton.disabled=!0,this._geolocateButton.title=e,this._geolocateButton.setAttribute(`aria-label`,e)}else{let e=this._map._getUIString(`GeolocateControl.FindMyLocation`);this._geolocateButton.disabled=!1,this._geolocateButton.title=e,this._geolocateButton.setAttribute(`aria-label`,e)}this.options.trackUserLocation&&(this._geolocateButton.setAttribute(`aria-pressed`,`false`),this._watchState=`OFF`),this.options.showUserLocation&&(this._dotElement=W.create(`div`,`maplibregl-user-location-dot`),this._userLocationDotMarker=new ym({element:this._dotElement}),this._circleElement=W.create(`div`,`maplibregl-user-location-accuracy-circle`),this._accuracyCircleMarker=new ym({element:this._circleElement,pitchAlignment:`map`}),this.options.trackUserLocation&&(this._watchState=`OFF`),this._map.on(`zoom`,this._onUpdate),this._map.on(`move`,this._onUpdate),this._map.on(`rotate`,this._onUpdate),this._map.on(`pitch`,this._onUpdate)),this._geolocateButton.addEventListener(`click`,()=>this.trigger()),this._setup=!0,this.options.trackUserLocation&&this._map.on(`movestart`,this._onMoveStart)}},this.options=z({},bm,e)}onAdd(e){return this._map=e,this._container=W.create(`div`,`maplibregl-ctrl maplibregl-ctrl-group`),this._setupUI(),fm().then(e=>this._finishSetupUI(e)),this._container}onRemove(){this._geolocationWatchID!==void 0&&(window.navigator.geolocation.clearWatch(this._geolocationWatchID),this._geolocationWatchID=void 0),this.options.showUserLocation&&this._userLocationDotMarker&&this._userLocationDotMarker.remove(),this.options.showAccuracyCircle&&this._accuracyCircleMarker&&this._accuracyCircleMarker.remove(),this._container.remove(),this._map.off(`movestart`,this._onMoveStart),this._map.off(`zoom`,this._onUpdate),this._map.off(`move`,this._onUpdate),this._map.off(`rotate`,this._onUpdate),this._map.off(`pitch`,this._onUpdate),this._map=void 0,xm=0,Sm=!1}_isOutOfMapMaxBounds(e){let t=this._map.getMaxBounds(),n=e.coords;return t&&(n.longitudet.getEast()||n.latitudet.getNorth())}_setErrorState(){switch(this._watchState){case`WAITING_ACTIVE`:this._watchState=`ACTIVE_ERROR`,this._geolocateButton.classList.remove(`maplibregl-ctrl-geolocate-active`),this._geolocateButton.classList.add(`maplibregl-ctrl-geolocate-active-error`);break;case`ACTIVE_LOCK`:this._watchState=`ACTIVE_ERROR`,this._geolocateButton.classList.remove(`maplibregl-ctrl-geolocate-active`),this._geolocateButton.classList.add(`maplibregl-ctrl-geolocate-active-error`),this._geolocateButton.classList.add(`maplibregl-ctrl-geolocate-waiting`);break;case`BACKGROUND`:this._watchState=`BACKGROUND_ERROR`,this._geolocateButton.classList.remove(`maplibregl-ctrl-geolocate-background`),this._geolocateButton.classList.add(`maplibregl-ctrl-geolocate-background-error`),this._geolocateButton.classList.add(`maplibregl-ctrl-geolocate-waiting`);break;case`ACTIVE_ERROR`:case`BACKGROUND_ERROR`:break;case`OFF`:case void 0:break;default:throw Error(`Unexpected watchState ${this._watchState}`)}}_updateCircleRadiusIfNeeded(){let e=this._userLocationDotMarker.getLngLat();if(!this.options.showUserLocation||!this.options.showAccuracyCircle||!this._accuracy||!e)return;let t=this._map.project(e),n=this._map.unproject([t.x+100,t.y]),r=e.distanceTo(n)/100,i=2*this._accuracy/r;this._circleElement.style.width=`${i.toFixed(2)}px`,this._circleElement.style.height=`${i.toFixed(2)}px`}trigger(){if(!this._setup)return I(`Geolocate control triggered before added to a map`),!1;if(this.options.trackUserLocation){switch(this._watchState){case`OFF`:this._watchState=`WAITING_ACTIVE`,this.fire(new Cm(`trackuserlocationstart`));break;case`WAITING_ACTIVE`:case`ACTIVE_LOCK`:case`ACTIVE_ERROR`:case`BACKGROUND_ERROR`:xm--,Sm=!1,this._watchState=`OFF`,this._geolocateButton.classList.remove(`maplibregl-ctrl-geolocate-waiting`),this._geolocateButton.classList.remove(`maplibregl-ctrl-geolocate-active`),this._geolocateButton.classList.remove(`maplibregl-ctrl-geolocate-active-error`),this._geolocateButton.classList.remove(`maplibregl-ctrl-geolocate-background`),this._geolocateButton.classList.remove(`maplibregl-ctrl-geolocate-background-error`),this.fire(new Cm(`trackuserlocationend`));break;case`BACKGROUND`:this._watchState=`ACTIVE_LOCK`,this._geolocateButton.classList.remove(`maplibregl-ctrl-geolocate-background`),this._lastKnownPosition&&this._updateCamera(this._lastKnownPosition),this.fire(new Cm(`trackuserlocationstart`)),this.fire(new Cm(`userlocationfocus`));break;default:throw Error(`Unexpected watchState ${this._watchState}`)}switch(this._watchState){case`WAITING_ACTIVE`:this._geolocateButton.classList.add(`maplibregl-ctrl-geolocate-waiting`),this._geolocateButton.classList.add(`maplibregl-ctrl-geolocate-active`);break;case`ACTIVE_LOCK`:this._geolocateButton.classList.add(`maplibregl-ctrl-geolocate-active`);break;case`OFF`:break;default:throw Error(`Unexpected watchState ${this._watchState}`)}if(this._watchState===`OFF`&&this._geolocationWatchID!==void 0)this._clearWatch();else if(this._geolocationWatchID===void 0){this._geolocateButton.classList.add(`maplibregl-ctrl-geolocate-waiting`),this._geolocateButton.setAttribute(`aria-pressed`,`true`),xm++;let e;xm>1?(e={maximumAge:6e5,timeout:0},Sm=!0):(e=this.options.positionOptions,Sm=!1),this._geolocationWatchID=window.navigator.geolocation.watchPosition(this._onSuccess,this._onError,e)}}else window.navigator.geolocation.getCurrentPosition(this._onSuccess,this._onError,this.options.positionOptions),this._timeoutId=setTimeout(this._finish,1e4);return!0}_clearWatch(){window.navigator.geolocation.clearWatch(this._geolocationWatchID),this._geolocationWatchID=void 0,this._geolocateButton.classList.remove(`maplibregl-ctrl-geolocate-waiting`),this._geolocateButton.setAttribute(`aria-pressed`,`false`),this.options.showUserLocation&&this._updateMarker(null)}};const Dm={maxWidth:100,unit:`metric`};var Om=class{constructor(e){this._onMove=()=>{km(this._map,this._container,this.options)},this.setUnit=e=>{this.options.unit=e,km(this._map,this._container,this.options)},this.options={...Dm,...e}}getDefaultPosition(){return`bottom-left`}onAdd(e){return this._map=e,this._container=W.create(`div`,`maplibregl-ctrl maplibregl-ctrl-scale`,e.getContainer()),this._map.on(`move`,this._onMove),this._onMove(),this._container}onRemove(){this._container.remove(),this._map.off(`move`,this._onMove),this._map=void 0}};function km(e,t,n){let r=n?.maxWidth||100,i=e._container.clientHeight/2,a=e._container.clientWidth/2,o=e.unproject([a-r/2,i]),s=e.unproject([a+r/2,i]),c=Math.round(e.project(s).x-e.project(o).x),l=Math.min(r,c,e._container.clientWidth),u=o.distanceTo(s);if(n?.unit===`imperial`){let n=3.2808*u;n>5280?Am(t,l,n/5280,e._getUIString(`ScaleControl.Miles`)):Am(t,l,n,e._getUIString(`ScaleControl.Feet`))}else n?.unit===`nautical`?Am(t,l,u/1852,e._getUIString(`ScaleControl.NauticalMiles`)):u>=1e3?Am(t,l,u/1e3,e._getUIString(`ScaleControl.Kilometers`)):Am(t,l,u,e._getUIString(`ScaleControl.Meters`))}function Am(e,t,n,r){let i=Mm(n),a=i/n;e.style.width=`${t*a}px`,e.innerHTML=`${i} ${r}`}function jm(e){let t=10**Math.ceil(-Math.log(e)/Math.LN10);return Math.round(e*t)/t}function Mm(e){let t=10**(`${Math.floor(e)}`.length-1),n=e/t;return n=n>=10?10:n>=5?5:n>=3?3:n>=2?2:n>=1?1:jm(n),t*n}var Nm=class extends Xe{},Pm=class extends h{constructor(e={}){super(),this._onFullscreenChange=()=>{let e=window.document.fullscreenElement||window.document.webkitFullscreenElement;for(;e?.shadowRoot?.fullscreenElement;)e=e.shadowRoot.fullscreenElement;e===this._container!==this._fullscreen&&this._handleFullscreenChange()},this._onClickFullscreen=()=>{this._isFullscreen()?this._exitFullscreen():this._requestFullscreen()},this._fullscreen=!1,this._pseudo=e.pseudo??!1,e?.container&&(e.container instanceof HTMLElement?this._container=e.container:I(`Full screen control 'container' must be a DOM element.`)),`onfullscreenchange`in document?this._fullscreenchange=`fullscreenchange`:`onmozfullscreenchange`in document?this._fullscreenchange=`mozfullscreenchange`:`onwebkitfullscreenchange`in document?this._fullscreenchange=`webkitfullscreenchange`:`onmsfullscreenchange`in document&&(this._fullscreenchange=`MSFullscreenChange`)}onAdd(e){return this._map=e,this._container||=this._map.getContainer(),this._controlContainer=W.create(`div`,`maplibregl-ctrl maplibregl-ctrl-group`),this._setupUI(),this._controlContainer}onRemove(){this._controlContainer.remove(),this._map=null,window.document.removeEventListener(this._fullscreenchange,this._onFullscreenChange)}_setupUI(){let e=this._fullscreenButton=W.create(`button`,`maplibregl-ctrl-fullscreen`,this._controlContainer);W.create(`span`,`maplibregl-ctrl-icon`,e).setAttribute(`aria-hidden`,`true`),e.type=`button`,this._updateTitle(),this._fullscreenButton.addEventListener(`click`,this._onClickFullscreen),window.document.addEventListener(this._fullscreenchange,this._onFullscreenChange)}_updateTitle(){let e=this._getTitle();this._fullscreenButton.setAttribute(`aria-label`,e),this._fullscreenButton.title=e}_getTitle(){return this._map._getUIString(this._isFullscreen()?`FullscreenControl.Exit`:`FullscreenControl.Enter`)}_isFullscreen(){return this._fullscreen}_handleFullscreenChange(){this._fullscreen=!this._fullscreen,this._fullscreenButton.classList.toggle(`maplibregl-ctrl-shrink`),this._fullscreenButton.classList.toggle(`maplibregl-ctrl-fullscreen`),this._updateTitle(),this._fullscreen?(this.fire(new Nm(`fullscreenstart`)),this._prevCooperativeGesturesEnabled=this._map.cooperativeGestures.isEnabled(),this._map.cooperativeGestures.disable()):(this.fire(new Nm(`fullscreenend`)),this._prevCooperativeGesturesEnabled&&this._map.cooperativeGestures.enable())}_exitFullscreen(){this._pseudo?this._togglePseudoFullScreen():window.document.exitFullscreen?window.document.exitFullscreen():window.document.webkitCancelFullScreen?window.document.webkitCancelFullScreen():this._togglePseudoFullScreen()}_requestFullscreen(){this._pseudo?this._togglePseudoFullScreen():this._container.requestFullscreen?this._container.requestFullscreen():this._container.webkitRequestFullscreen?this._container.webkitRequestFullscreen():this._togglePseudoFullScreen()}_togglePseudoFullScreen(){this._container.classList.toggle(`maplibregl-pseudo-fullscreen`),this._handleFullscreenChange(),this._map.resize()}},Fm=class{constructor(e){this._toggleTerrain=()=>{this._map.getTerrain()?this._map.setTerrain(null):this._map.setTerrain(this.options),this._updateTerrainIcon()},this._updateTerrainIcon=()=>{this._terrainButton.classList.remove(`maplibregl-ctrl-terrain`),this._terrainButton.classList.remove(`maplibregl-ctrl-terrain-enabled`),this._map.terrain?(this._terrainButton.classList.add(`maplibregl-ctrl-terrain-enabled`),this._terrainButton.title=this._map._getUIString(`TerrainControl.Disable`)):(this._terrainButton.classList.add(`maplibregl-ctrl-terrain`),this._terrainButton.title=this._map._getUIString(`TerrainControl.Enable`))},this.options=e}onAdd(e){return this._map=e,this._container=W.create(`div`,`maplibregl-ctrl maplibregl-ctrl-group`),this._terrainButton=W.create(`button`,`maplibregl-ctrl-terrain`,this._container),W.create(`span`,`maplibregl-ctrl-icon`,this._terrainButton).setAttribute(`aria-hidden`,`true`),this._terrainButton.type=`button`,this._terrainButton.addEventListener(`click`,this._toggleTerrain),this._updateTerrainIcon(),this._map.on(`terrain`,this._updateTerrainIcon),this._container}onRemove(){this._container.remove(),this._map.off(`terrain`,this._updateTerrainIcon),this._map=void 0}},Im=class{constructor(){this._toggleProjection=()=>{let e=this._map.getProjection()?.type;e===`mercator`||!e?this._map.setProjection({type:`globe`}):this._map.setProjection({type:`mercator`}),this._updateGlobeIcon()},this._updateGlobeIcon=()=>{this._globeButton.classList.remove(`maplibregl-ctrl-globe`),this._globeButton.classList.remove(`maplibregl-ctrl-globe-enabled`),this._map.getProjection()?.type===`globe`?(this._globeButton.classList.add(`maplibregl-ctrl-globe-enabled`),this._globeButton.title=this._map._getUIString(`GlobeControl.Disable`)):(this._globeButton.classList.add(`maplibregl-ctrl-globe`),this._globeButton.title=this._map._getUIString(`GlobeControl.Enable`))}}onAdd(e){return this._map=e,this._container=W.create(`div`,`maplibregl-ctrl maplibregl-ctrl-group`),this._globeButton=W.create(`button`,`maplibregl-ctrl-globe`,this._container),W.create(`span`,`maplibregl-ctrl-icon`,this._globeButton).setAttribute(`aria-hidden`,`true`),this._globeButton.type=`button`,this._globeButton.addEventListener(`click`,this._toggleProjection),this._updateGlobeIcon(),this._map.on(`styledata`,this._updateGlobeIcon),this._map.on(`projectiontransition`,this._updateGlobeIcon),this._container}onRemove(){this._container.remove(),this._map.off(`styledata`,this._updateGlobeIcon),this._map.off(`projectiontransition`,this._updateGlobeIcon),this._globeButton.removeEventListener(`click`,this._toggleProjection),this._map=void 0}};const Lm={closeButton:!0,closeOnClick:!0,focusAfterOpen:!0,className:``,maxWidth:`240px`,subpixelPositioning:!1,locationOccludedOpacity:void 0,padding:void 0},Rm=[`a[href]`,`[tabindex]:not([tabindex='-1'])`,`[contenteditable]:not([contenteditable='false'])`,`button:not([disabled])`,`input:not([disabled])`,`select:not([disabled])`,`textarea:not([disabled])`].join(`, `);var zm=class extends Xe{},Bm=class extends h{constructor(e){super(),this._updateOpacity=()=>{this.options.locationOccludedOpacity!==void 0&&(this._map._camera.transform.isLocationOccluded(this.getLngLat())?this._container.style.opacity=`${this.options.locationOccludedOpacity}`:this._container.style.opacity=``)},this.remove=()=>(this._content&&this._content.remove(),this._container&&(this._container.remove(),delete this._container),this._map&&(this._map.off(`move`,this._update),this._map.off(`move`,this._onClose),this._map.off(`click`,this._onClose),this._map.off(`remove`,this.remove),this._map.off(`terrain`,this._update),this._map.off(`projectiontransition`,this._update),this._map.off(`mousemove`,this._update),this._map.off(`mouseup`,this._update),this._map.off(`drag`,this._update),this._map._canvasContainer.classList.remove(`maplibregl-track-pointer`),delete this._map,this.fire(new zm(`close`))),this),this._update=e=>{let t=this._lngLat||this._trackPointer;if(!this._map||!t||!this._content)return;if(!this._container){if(this._container=W.create(`div`,`maplibregl-popup`,this._map.getContainer()),this._tip=W.create(`div`,`maplibregl-popup-tip`,this._container),this._container.appendChild(this._content),this.options.className)for(let e of this.options.className.split(` `))this._container.classList.add(e);this._closeButton&&this._closeButton.setAttribute(`aria-label`,this._map._getUIString(`Popup.Close`)),this._trackPointer&&this._container.classList.add(`maplibregl-popup-track-pointer`)}this.options.maxWidth&&this._container.style.maxWidth!==this.options.maxWidth&&(this._container.style.maxWidth=this.options.maxWidth),this._lngLat=pm(this._lngLat,this._flatPos,this._map._camera.transform,this._trackPointer);let n;if(e&&`point`in e&&e.point&&(n=e.point),this._trackPointer&&!n)return;let r=this._flatPos=this._pos=this._trackPointer&&n?n:this._map.project(this._lngLat);this._map.terrain&&(this._flatPos=this._trackPointer&&n?n:this._map._camera.transform.locationToScreenPoint(this._lngLat));let i=this.options.anchor,a=Vm(this.options.offset);if(!i){let e=this._container.offsetWidth,t=this._container.offsetHeight,n=Hm(this.options.padding),o;o=r.y+a.bottom.ythis._map._camera.transform.height-t-n.bottom?[`bottom`]:[],r.xthis._map._camera.transform.width-e/2-n.right&&o.push(`right`),i=o.length===0?`bottom`:o.join(`-`)}let o=r.add(a[i]);this.options.subpixelPositioning||(o=o.round()),this._container.style.transform=`${mm[i]} translate(${o.x}px,${o.y}px)`,hm(this._container,i,`popup`),this._updateOpacity()},this._onClose=()=>{this.remove()},this.options=z(Object.create(Lm),e)}addTo(e){return this._map&&this.remove(),this._map=e,this.options.closeOnClick&&this._map.on(`click`,this._onClose),this.options.closeOnMove&&this._map.on(`move`,this._onClose),this._map.on(`remove`,this.remove),this._map.on(`terrain`,this._update),this._map.on(`projectiontransition`,this._update),this._update(),this._focusFirstElement(),this._trackPointer?(this._map.on(`mousemove`,this._update),this._map.on(`mouseup`,this._update),this._container&&this._container.classList.add(`maplibregl-popup-track-pointer`),this._map._canvasContainer.classList.add(`maplibregl-track-pointer`)):this._map.on(`move`,this._update),this.fire(new zm(`open`)),this}isOpen(){return!!this._map}getLngLat(){return this._lngLat}setLngLat(e){return this._lngLat=V.convert(e),this._pos=null,this._flatPos=null,this._trackPointer=!1,this._update(),this._map&&(this._map.on(`move`,this._update),this._map.off(`mousemove`,this._update),this._container&&this._container.classList.remove(`maplibregl-popup-track-pointer`),this._map._canvasContainer.classList.remove(`maplibregl-track-pointer`)),this}trackPointer(){return this._trackPointer=!0,this._pos=null,this._flatPos=null,this._update(),this._map&&(this._map.off(`move`,this._update),this._map.on(`mousemove`,this._update),this._map.on(`drag`,this._update),this._container&&this._container.classList.add(`maplibregl-popup-track-pointer`),this._map._canvasContainer.classList.add(`maplibregl-track-pointer`)),this}getElement(){return this._container}setText(e){return this.setDOMContent(document.createTextNode(e))}setHTML(e){let t=document.createDocumentFragment(),n=document.createElement(`body`),r;for(n.innerHTML=e;r=n.firstChild,r;)t.appendChild(r);return this.setDOMContent(t)}getMaxWidth(){return this._container?.style.maxWidth}setMaxWidth(e){return this.options.maxWidth=e,this._update(),this}setDOMContent(e){if(this._content)for(;this._content.hasChildNodes();)this._content.firstChild&&this._content.removeChild(this._content.firstChild);else this._content=W.create(`div`,`maplibregl-popup-content`,this._container);return this._content.appendChild(e),this._createCloseButton(),this._update(),this._focusFirstElement(),this}addClassName(e){return this._container&&this._container.classList.add(e),this}removeClassName(e){return this._container&&this._container.classList.remove(e),this}setOffset(e){return this.options.offset=e,this._update(),this}toggleClassName(e){if(this._container)return this._container.classList.toggle(e)}setSubpixelPositioning(e){this.options.subpixelPositioning=e}setPadding(e){this.options.padding=e,this._update()}_createCloseButton(){this.options.closeButton&&(this._closeButton=W.create(`button`,`maplibregl-popup-close-button`,this._content),this._closeButton.type=`button`,this._closeButton.innerHTML=`×`,this._closeButton.addEventListener(`click`,this._onClose))}_focusFirstElement(){if(!this.options.focusAfterOpen||!this._container)return;let e=this._container.querySelector(Rm);e&&e.focus()}};function Vm(e){if(!e)return Vm(new l(0,0));if(typeof e==`number`){let t=Math.round(Math.abs(e)/Math.SQRT2);return{center:new l(0,0),top:new l(0,e),"top-left":new l(t,t),"top-right":new l(-t,t),bottom:new l(0,-e),"bottom-left":new l(t,-t),"bottom-right":new l(-t,-t),left:new l(e,0),right:new l(-e,0)}}if(e instanceof l||Array.isArray(e)){let t=l.convert(e);return{center:t,top:t,"top-left":t,"top-right":t,bottom:t,"bottom-left":t,"bottom-right":t,left:t,right:t}}return{center:l.convert(e.center||[0,0]),top:l.convert(e.top||[0,0]),"top-left":l.convert(e[`top-left`]||[0,0]),"top-right":l.convert(e[`top-right`]||[0,0]),bottom:l.convert(e.bottom||[0,0]),"bottom-left":l.convert(e[`bottom-left`]||[0,0]),"bottom-right":l.convert(e[`bottom-right`]||[0,0]),left:l.convert(e.left||[0,0]),right:l.convert(e.right||[0,0])}}function Hm(e){return e?{top:e.top??0,right:e.right??0,bottom:e.bottom??0,left:e.left??0}:{top:0,right:0,bottom:0,left:0}}const Um=Ar;function Wm(e,t){return fo().setRTLTextPlugin(e,t)}function Gm(){return fo().getRTLTextPluginStatus()}function Km(){return Um}function qm(){return Zi.workerCount}function Jm(e){Zi.workerCount=e}function Ym(){return k.MAX_PARALLEL_IMAGE_REQUESTS}function Xm(e){k.MAX_PARALLEL_IMAGE_REQUESTS=e}function Zm(){return k.WORKER_URL}function Qm(e){k.WORKER_URL=e}async function $m(e){await aa().broadcast(`IS`,e)}export{mr as AJAXError,$p as AttributionControl,sp as BoxZoomHandler,to as CanvasSource,Gp as CooperativeGesturesHandler,zp as DoubleClickZoomHandler,Hp as DragPanHandler,Up as DragRotateHandler,N as EXTENT,ec as EdgeInsets,H as ErrorEvent,Xe as Event,h as Evented,Pm as FullscreenControl,Nm as FullscreenEvent,qf as GPUInitializationError,Ia as GeoJSONSource,Em as GeolocateControl,Tm as GeolocateErrorEvent,Cm as GeolocateEvent,wm as GeolocatePositionEvent,Im as GlobeControl,Yf as Hash,Ja as ImageSource,Fp as KeyboardHandler,V as LngLat,_a as LngLatBounds,em as LogoControl,sm as Map,sm as MapLibreMap,Zr as MapBoxZoomEvent,ei as MapContextEvent,Gr as MapLibreEvent,Jr as MapMouseEvent,G as MapMovementEvent,$r as MapProjectionEvent,K as MapSourceDataEvent,qr as MapStyleDataEvent,ti as MapStyleImageMissingEvent,Kr as MapStyleLoadEvent,Qr as MapTerrainEvent,Yr as MapTouchEvent,Xr as MapWheelEvent,ym as Marker,vm as MarkerClickEvent,_m as MarkerDragEvent,B as MercatorCoordinate,lm as NavigationControl,l as Point,Bm as Popup,zm as PopupEvent,xa as RasterDEMTileSource,ba as RasterTileSource,Om as ScaleControl,Rp as ScrollZoomHandler,ml as Style,Fm as TerrainControl,Np as TwoFingersTouchPitchHandler,jp as TwoFingersTouchRotateHandler,kp as TwoFingersTouchZoomHandler,Wp as TwoFingersTouchZoomRotateHandler,ya as VectorTileSource,eo as VideoSource,Te as addProtocol,oo as addSourceType,na as clearPrewarmedResources,k as config,qa as createTileMesh,aa as getGlobalDispatcher,Ym as getMaxParallelImageRequests,Gm as getRTLTextPluginStatus,Km as getVersion,qm as getWorkerCount,Zm as getWorkerUrl,$m as importScriptInWorkers,Hr as isTimeFrozen,U as now,ta as prewarm,Re as removeProtocol,Vr as restoreNow,Xm as setMaxParallelImageRequests,Br as setNow,Wm as setRTLTextPlugin,Jm as setWorkerCount,Qm as setWorkerUrl};
+//# sourceMappingURL=maplibre-gl.mjs.map
\ No newline at end of file
diff --git a/web/vendor/terra-draw/LICENSE b/web/vendor/terra-draw/LICENSE
new file mode 100644
index 000000000..407a4b959
--- /dev/null
+++ b/web/vendor/terra-draw/LICENSE
@@ -0,0 +1,8 @@
+Copyright 2022 James Milner
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
diff --git a/web/vendor/terra-draw/README.md b/web/vendor/terra-draw/README.md
new file mode 100644
index 000000000..1817aa3ae
--- /dev/null
+++ b/web/vendor/terra-draw/README.md
@@ -0,0 +1,19 @@
+# Terra Draw, vendored
+
+Terra Draw 1.32.2 and terra-draw-maplibre-gl-adapter 1.4.1, MIT. See
+`LICENSE` (the npm packages ship no license file; the text comes from the
+project repository, which covers both packages).
+
+Vendored rather than pulled from a CDN, for the same reason as
+`/vendor/maplibre/` next door: the box UI must not execute third-party JS
+from a CDN, and the PV-array drawing tools have to load even when the
+gateway cannot reach the internet.
+
+| File | Why |
+|---|---|
+| `terra-draw.umd.js` | the drawing engine (self-contained UMD build) |
+| `terra-draw-maplibre-gl-adapter.umd.js` | binds Terra Draw to a MapLibre map |
+
+To upgrade: bump the versions in this file, replace the two files from the
+packages' `dist/`, and update `web/settings/tabs/weather.js` if the layout
+changed. `web/terra-draw-vendor.test.mjs` pins the contract.
diff --git a/web/vendor/terra-draw/terra-draw-maplibre-gl-adapter.umd.js b/web/vendor/terra-draw/terra-draw-maplibre-gl-adapter.umd.js
new file mode 100644
index 000000000..29409f27b
--- /dev/null
+++ b/web/vendor/terra-draw/terra-draw-maplibre-gl-adapter.umd.js
@@ -0,0 +1,2 @@
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("terra-draw")):"function"==typeof define&&define.amd?define(["exports","terra-draw"],t):t((e||self).terraDrawMaplibreGlAdapter={},e.terraDraw)}(this,function(e,t){function i(){return i=Object.assign?Object.assign.bind():function(e){for(var t=1;tl:o!==d?o>d:n[2]>=r[2]},o._addGeoJSONSource=function(e,t){this._map.addSource(e,{type:"geojson",data:{type:"FeatureCollection",features:t},tolerance:0})},o._addFillLayer=function(e){return this._map.addLayer({id:e,source:e,type:"fill",layout:{"fill-sort-key":["get","zIndex"]},paint:{"fill-color":["get","polygonFillColor"],"fill-opacity":["get","polygonFillOpacity"]}})},o._addFillOutlineLayer=function(e){return this._map.addLayer({id:e+"-outline",source:e,type:"line",layout:{"line-sort-key":["get","zIndex"]},paint:{"line-width":["get","polygonOutlineWidth"],"line-color":["get","polygonOutlineColor"],"line-opacity":["get","polygonOutlineOpacity"]}})},o._addLineLayer=function(e){var t={};return this.isMapLibreAtLeast("5.8.0")&&(t["line-dasharray"]=["coalesce",["get","lineStringDash"],["literal",[1,0]]]),this._map.addLayer({id:e,source:e,type:"line",layout:{"line-sort-key":["get","zIndex"]},paint:i({},t,{"line-width":["get","lineStringWidth"],"line-color":["get","lineStringColor"],"line-opacity":["get","lineStringOpacity"]})})},o._addPointLayer=function(e){return this._map.addLayer({id:e,source:e,type:"circle",layout:{"circle-sort-key":["get","zIndex"]},paint:{"circle-stroke-color":["get","pointOutlineColor"],"circle-stroke-width":["get","pointOutlineWidth"],"circle-stroke-opacity":["get","pointOutlineOpacity"],"circle-radius":["get","pointWidth"],"circle-color":["get","pointColor"],"circle-opacity":["get","pointOpacity"]}})},o._addMarkerLayer=function(e){return this._map.addLayer({id:e+"-marker",source:e,type:"symbol",filter:["has","markerId"],layout:{"icon-image":["image",["get","markerId"]],"icon-anchor":"bottom","icon-allow-overlap":!0}})},o._addLayer=function(e,t){"Point"===t&&(this._addPointLayer(e),this._addMarkerLayer(e)),"LineString"===t&&this._addLineLayer(e),"Polygon"===t&&(this._addFillLayer(e),this._addFillOutlineLayer(e))},o._addGeoJSONLayer=function(e,t){var i=this._prefixId+"-"+e.toLowerCase();return this._addGeoJSONSource(i,t),this._addLayer(i,e),i},o._setGeoJSONLayerData=function(e,t){var i=this._prefixId+"-"+e.toLowerCase();return this._map.getSource(i).setData({type:"FeatureCollection",features:t}),i},o.updateChangedIds=function(e){var t=this;[].concat(e.updated,e.created).forEach(function(e){"Point"===e.geometry.type?t.changedIds.points=!0:"LineString"===e.geometry.type?t.changedIds.linestrings=!0:"Polygon"===e.geometry.type&&(t.changedIds.polygons=!0)}),e.deletedIds.length>0&&(this.changedIds.deletion=!0),0===e.created.length&&0===e.updated.length&&0===e.deletedIds.length&&(this.changedIds.styling=!0)},o.getLngLatFromEvent=function(e){var t=this._container.getBoundingClientRect();return this.unproject(e.clientX-t.left,e.clientY-t.top)},o.getMapEventElement=function(){return this._map.getCanvas()},o.setDraggability=function(e){e?(this._initialDragRotate&&this._map.dragRotate.enable(),this._initialDragPan&&this._map.dragPan.enable()):(this._initialDragRotate&&this._map.dragRotate.disable(),this._initialDragPan&&this._map.dragPan.disable())},o.project=function(e,t){var i=this._map.project({lng:e,lat:t});return{x:i.x,y:i.y}},o.unproject=function(e,t){var i=this._map.unproject({x:e,y:t});return{lng:i.lng,lat:i.lat}},o.setCursor=function(e){var t=this._map.getCanvas();"unset"===e?t.style.removeProperty("cursor"):t.style.cursor=e},o.setDoubleClickToZoom=function(e){e?this._map.doubleClickZoom.enable():this._map.doubleClickZoom.disable()},o.render=function(e,t){var i=this;this.updateChangedIds(e),this._nextRender&&cancelAnimationFrame(this._nextRender),this._nextRender=requestAnimationFrame(function(){if(i._currentModeCallbacks){for(var n=[].concat(e.created,e.updated,e.unchanged),r=[],a=[],o=[],l=function(){var e=n[d],l=e.properties,s=t[l.mode](e);if(l.zIndex=s.zIndex,l.zIndex=s.zIndex,"Point"===e.geometry.type){l.pointColor=s.pointColor,l.pointOutlineColor=s.pointOutlineColor,l.pointOutlineWidth=s.pointOutlineWidth;var p=s.pointOutlineOpacity;l.pointOutlineOpacity=void 0===p?1:p,l.pointWidth=s.pointWidth;var c=s.pointOpacity;if(l.pointOpacity=void 0===c?1:c,s.markerUrl&&s.markerWidth&&s.markerHeight){var g="marker-"+i.hashCode(s.markerUrl);i._map.hasImage(g)||i.resizeImage(s.markerUrl,s.markerWidth,s.markerHeight,function(e){i._map.loadImage(e).then(function(e){i._map.hasImage(g)||i._map.addImage(g,e.data)})}),l.markerId=g,l.pointWidth=0}r.push(e)}else if("LineString"===e.geometry.type){l.lineStringDash=i.toGlDashArrayFromPixels(s.lineStringDash,s.lineStringWidth),l.lineStringColor=s.lineStringColor,l.lineStringWidth=s.lineStringWidth;var h=s.lineStringOpacity;l.lineStringOpacity=void 0===h?1:h,a.push(e)}else if("Polygon"===e.geometry.type){var u=s.polygonOutlineOpacity;l.polygonFillColor=s.polygonFillColor,l.polygonFillOpacity=s.polygonFillOpacity,l.polygonOutlineOpacity=void 0===u?1:u,l.polygonOutlineColor=s.polygonOutlineColor,l.polygonOutlineWidth=s.polygonOutlineWidth,o.push(e)}},d=0;dt.length)&&(e=t.length);for(var i=0,n=Array(e);i=t.length?{done:!0}:{done:!1,value:t[o++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function r(){return r=Object.assign?Object.assign.bind():function(t){for(var e=1;e0;function a(t){return t<0||t>1}function d(t,n,o,r){var s,d=e[t][n],u=e[t][n+1],h=e[o][r],l=e[o][r+1],c=function(t,e,i,n){if(z(t,i)||z(t,n)||z(e,i)||z(n,i))return null;var o=t[0],r=t[1],s=e[0],a=e[1],d=i[0],u=i[1],h=n[0],l=n[1],c=(o-s)*(u-l)-(r-a)*(d-h);return 0===c?null:[((o*a-r*s)*(d-h)-(o-s)*(d*l-u*h))/c,((o*a-r*s)*(u-l)-(r-a)*(d*l-u*h))/c]}(d,u,h,l);null!==c&&(s=l[0]!==h[0]?(c[0]-h[0])/(l[0]-h[0]):(c[1]-h[1])/(l[1]-h[1]),a(u[0]!==d[0]?(c[0]-d[0])/(u[0]-d[0]):(c[1]-d[1])/(u[1]-d[1]))||a(s)||(c.toString(),i.push(c)))}}function z(t,e){return t[0]===e[0]&&t[1]===e[1]}function H(t,e){return G(t[0])<=e&&G(t[1])<=e}function V(t){return 2===t.length&&"number"==typeof t[0]&&"number"==typeof t[1]&&Infinity!==t[0]&&Infinity!==t[1]&&(i=t[0])>=-180&&i<=180&&(e=t[1])>=-90&&e<=90;var e,i}function G(t){for(var e=1,i=0;Math.round(t*e)/e!==t;)e*=10,i++;return i}var j="Feature has holes",K="Feature has less than 4 coordinates",Y="Feature has invalid coordinates",X="Feature coordinates are not closed";function q(t,e){if("Polygon"!==t.geometry.type)return{valid:!1,reason:"Feature is not a Polygon"};if(1!==t.geometry.coordinates.length)return{valid:!1,reason:j};if(t.geometry.coordinates[0].length<4)return{valid:!1,reason:K};for(var i=0;i=a)throw new RangeError("Index "+t+" (normalized to "+e+") is out of bounds");return e},u=new Array(a).fill(void 0),h=Array.from({length:a},function(){return[]}),l=Array.from({length:a},function(){return[]}),c=[],p=o(e);!(i=p()).done;){var g=i.value;if(g.type!==Q&&g.type!==tt){var f=d(g.index);u[f]=r({},g,{index:f})}else{var y=g.index,v=y<0?a+y:y;if(v<0||v>a)throw new RangeError("Index "+g.index+" (normalized to "+v+") is out of bounds");if(g.type===Q){if(v>=a)throw new RangeError("INSERT_BEFORE index "+g.index+" (normalized to "+v+") is out of bounds for length "+a);h[v].push(g)}else v===a?c.push(g):l[v].push(g)}}for(var m=[],C=0;C=i.length)throw new RangeError("Index "+e+" (normalized to "+n+") is out of bounds");return i[n]},i.getProperties=function(t){return this.store.getPropertiesCopy(t)},i.hasFeature=function(t){return this.store.has(t)},i.getAllFeatureIdsWhere=function(t){return this.store.copyAllWhere(t).map(function(t){return t.id})},e}(J),lt={cancel:"Escape",finish:"Enter"},ct={start:"crosshair",close:"pointer"},pt=/*#__PURE__*/function(t){function e(e){var i;return(i=t.call(this,e,!0)||this).mode="freehand",i.canClose=!1,i.currentId=void 0,i.closingPointId=void 0,i.minDistance=20,i.keyEvents=lt,i.cursors=ct,i.preventPointsNearClose=!0,i.autoClose=!1,i.autoCloseTimeout=500,i.hasLeftStartingPoint=!1,i.preventNewFeature=!1,i.drawInteraction="click-move",i.drawType=void 0,i.smoothing=0,i.mutateFeature=void 0,i.readFeature=void 0,i.updateOptions(e),i}s(e,t);var i=e.prototype;return i.updateOptions=function(e){t.prototype.updateOptions.call(this,e),null!=e&&e.minDistance&&(this.minDistance=e.minDistance),void 0!==(null==e?void 0:e.smoothing)&&(this.smoothing=Math.min(Math.max(e.smoothing,0),.999)),void 0!==(null==e?void 0:e.preventPointsNearClose)&&(this.preventPointsNearClose=e.preventPointsNearClose),void 0!==(null==e?void 0:e.autoClose)&&(this.autoClose=e.autoClose),null!=e&&e.autoCloseTimeout&&(this.autoCloseTimeout=e.autoCloseTimeout),null===(null==e?void 0:e.keyEvents)?this.keyEvents={cancel:null,finish:null}:null!=e&&e.keyEvents&&(this.keyEvents=r({},this.keyEvents,e.keyEvents)),null!=e&&e.cursors&&(this.cursors=r({},this.cursors,e.cursors)),null!=e&&e.drawInteraction&&(this.drawInteraction=e.drawInteraction)},i.moveDrawAllowed=function(){return"click-move"===this.drawInteraction||"click-move-or-drag"===this.drawInteraction},i.dragDrawAllowed=function(){return"click-drag"===this.drawInteraction||"click-move-or-drag"===this.drawInteraction},i.beginDrawing=function(t,e){var i;void 0===e&&(e="click");var n=this.mutateFeature.createPolygon({coordinates:[[t.lng,t.lat],[t.lng,t.lat],[t.lng,t.lat],[t.lng,t.lat]],properties:(i={mode:this.mode},i[y.CURRENTLY_DRAWING]=!0,i)});this.currentId=n.id,this.drawType=e,this.closingPointId=this.mutateFeature.createGuidancePoint({coordinate:[t.lng,t.lat],type:y.CLOSING_POINT}),this.canClose=!0,"drawing"!==this.state&&this.setDrawing()},i.addCoordinate=function(t){var e=this;if(void 0!==this.currentId&&!1!==this.canClose){var i=this.readFeature.getCoordinate(this.currentId,-2),n=i[0],o=i[1],r=this.project(n,o),s=dt({x:r.x,y:r.y},{x:t.containerX,y:t.containerY}),a=this.readFeature.getCoordinate(this.currentId,0),d=this.project(a[0],a[1]);if(dt({x:d.x,y:d.y},{x:t.containerX,y:t.containerY})180?o-=360:o<-180&&(o+=360),o}function St(t){return(t+360)%360}function Ft(t,e,i){for(var n,o,r,s=[],a=t.length,d=0,u=0;u=d&&u===t.length-1);u++){if(d>e&&0===s.length){if(!(n=e-d))return s.push(t[u]),s;o=Pt(t[u],t[u-1])-180,r=mt(t[u],n,o),s.push(r)}if(d>=i)return(n=i-d)?(o=Pt(t[u],t[u-1])-180,r=mt(t[u],n,o),s.push(r),s):(s.push(t[u]),s);if(d>=e&&s.push(t[u]),u===t.length-1)return s;d+=w(t[u],t[u+1])}if(dj||Dt(M,x)>j?w(bt(x),bt(O))<=w(bt(x),bt(M))?[bt(O),!0,!1]:[bt(M),!1,!0]:[bt(x),!1,!1])[0])&&(c=w(t,d))0&&Array.isArray(t[0])&&Array.isArray(t[0][0])}var Rt=function(t){return Nt(t)?t[0].slice(0,-1):t},Lt=function(t){return Nt(t)?t[0]:t},Wt=/*#__PURE__*/function(t){function e(e,i,n,o){var r;return(r=t.call(this,e)||this).config=void 0,r.pixelDistance=void 0,r.mutateFeatureBehavior=void 0,r.readFeatureBehavior=void 0,r._startEndPoints=[],r.config=e,r.pixelDistance=i,r.mutateFeatureBehavior=n,r.readFeatureBehavior=o,r}s(e,t);var i=e.prototype;return i.create=function(t){if(this.ids.length)throw new Error("Opening and closing points already created");var e=Nt(t),i=Lt(t);if(e){if(i.length<=3)throw new Error("Requires at least 4 coordinates");this._startEndPoints=this.mutateFeatureBehavior.createGuidancePoints({coordinates:[i[0],i[i.length-2]],type:y.CLOSING_POINT})}else this._startEndPoints=[this.mutateFeatureBehavior.createGuidancePoint({coordinate:i[i.length-2],type:y.CLOSING_POINT})]},i.delete=function(){this.ids.length&&(this.mutateFeatureBehavior.deleteFeaturesIfPresent(this.ids),this._startEndPoints=[])},i.updateOne=function(t,e){this.mutateFeatureBehavior.updateGuidancePoints([{featureId:this.ids[t],coordinate:e}])},i.update=function(t){var e=Lt(t);1!==this.ids.length?2===this.ids.length&&this.mutateFeatureBehavior.updateGuidancePoints([{featureId:this.ids[0],coordinate:e[0]},{featureId:this.ids[1],coordinate:e[e.length-3]}]):this.mutateFeatureBehavior.updateGuidancePoints([{featureId:this.ids[0],coordinate:e[e.length-2]}])},i.isLineStringClosingPoint=function(t){if(1!==this.ids.length)return{isClosing:!1};var e=this.readFeatureBehavior.getGeometry(this.ids[0]);return{isClosing:this.pixelDistance.measure(t,e.coordinates)this.maxStackSize;)t.shift()},e.pushUndoEntry=function(t){0!==this.maxStackSize&&(this.undoHistory.push(t),this.trimHistoryToMax(this.undoHistory))},e.pushRedoEntry=function(t){0!==this.maxStackSize&&(this.redoHistory.push(t),this.trimHistoryToMax(this.redoHistory))},e.cloneRecursively=function(t){var e=this;return Array.isArray(t)?t.map(function(t){return e.cloneRecursively(t)}):null!==t&&"object"==typeof t?r({},t):t},e.cloneCoordinates=function(t){return this.cloneCoordinatesFunction(t)},e.cloneEntry=function(t){return{featureCoordinates:this.cloneCoordinates(t.featureCoordinates),currentCoordinate:t.currentCoordinate}},e.clear=function(){this.undoHistory=[],this.redoHistory=[]},e.undoSize=function(){return this.undoHistory.length},e.redoSize=function(){return this.redoHistory.length},e.recordSnapshot=function(t){this.pushUndoEntry(this.cloneEntry(t)),this.redoHistory=[]},e.beginUndo=function(){var t=this.undoHistory.pop();if(t){var e=this.cloneEntry(t);this.pushRedoEntry(e);var i=this.undoHistory[this.undoHistory.length-1];return{undoneEntry:e,previousEntry:i?this.cloneEntry(i):void 0}}},e.takeRedo=function(){var t=this.redoHistory.pop();if(t)return this.cloneEntry(t)},e.commitRedo=function(t){this.pushUndoEntry(this.cloneEntry(t))},t}(),Bt={cancel:"Escape",finish:"Enter"},zt={start:"crosshair",close:"pointer",dragStart:"grabbing",dragEnd:"crosshair"},Ht=/*#__PURE__*/function(t){function e(e){var i;return(i=t.call(this,e,!0)||this).mode="linestring",i.currentCoordinate=0,i.currentId=void 0,i.keyEvents=Bt,i.snapping=void 0,i.cursors=zt,i.mouseMove=!1,i.insertCoordinates=void 0,i.lastCommittedCoordinates=void 0,i.snappedPointId=void 0,i.lastMouseMoveEvent=void 0,i.showCoordinatePoints=!1,i.finishOnNthCoordinate=void 0,i.editable=!1,i.editedFeatureId=void 0,i.editedFeatureCoordinateIndex=void 0,i.editedSnapType=void 0,i.editedInsertIndex=void 0,i.editedPointId=void 0,i.coordinateSnapping=void 0,i.insertPoint=void 0,i.lineSnapping=void 0,i.featureSnapping=void 0,i.pixelDistance=void 0,i.clickBoundingBox=void 0,i.mutateFeature=void 0,i.readFeature=void 0,i.closingPoints=void 0,i.coordinatePoints=void 0,i.undoRedo=void 0,i.updateOptions(e),i}s(e,t);var i=e.prototype;return i.updateOptions=function(e){var i=this;if(t.prototype.updateOptions.call(this,e),void 0!==(null==e?void 0:e.finishOnNthCoordinate)&&Number.isInteger(e.finishOnNthCoordinate)&&e.finishOnNthCoordinate>1&&(this.finishOnNthCoordinate=Math.floor(e.finishOnNthCoordinate)),null!=e&&e.cursors&&(this.cursors=r({},this.cursors,e.cursors)),null!=e&&e.snapping&&(this.snapping=e.snapping),null===(null==e?void 0:e.keyEvents)?this.keyEvents={cancel:null,finish:null}:null!=e&&e.keyEvents&&(this.keyEvents=r({},this.keyEvents,e.keyEvents)),null!=e&&e.insertCoordinates&&(this.insertCoordinates=e.insertCoordinates),e&&e.editable&&(this.editable=e.editable),void 0!==(null==e?void 0:e.showCoordinatePoints))if(this.showCoordinatePoints=e.showCoordinatePoints,this.coordinatePoints&&!0===e.showCoordinatePoints)this.store.copyAllWhere(function(t){return t.mode===i.mode}).forEach(function(t){i.coordinatePoints.createOrUpdate({featureId:t.id,featureCoordinates:t.geometry.coordinates})});else if(this.coordinatePoints&&!1===this.showCoordinatePoints){var n=this.store.copyAllWhere(function(t){var e;return t.mode===i.mode&&Boolean(null==(e=t[y.COORDINATE_POINT_IDS])?void 0:e.length)});this.coordinatePoints.deletePointsByFeatureIds(n.map(function(t){return t.id}))}},i.shouldFinishOnCommit=function(t){return!!this.finishOnNthCoordinate&&Math.max(0,t.coordinates.length-1)>=this.finishOnNthCoordinate},i.updateSnappedCoordinate=function(t){var e=this.snapCoordinate(t);return e?(this.snappedPointId?this.mutateFeature.updateGuidancePoints([{featureId:this.snappedPointId,coordinate:e}]):this.snappedPointId=this.mutateFeature.createGuidancePoint({coordinate:e,type:y.SNAPPING_POINT}),t.lng=e[0],t.lat=e[1]):this.snappedPointId&&(this.mutateFeature.deleteFeatureIfPresent(this.snappedPointId),this.snappedPointId=void 0),e},i.close=function(){var t;if(void 0!==this.currentId){var e=this.mutateFeature.updateLineString({featureId:this.currentId,context:{updateType:u.Finish,action:h},coordinateMutations:[{type:it,index:-1}],propertyMutations:(t={},t[y.CURRENTLY_DRAWING]=void 0,t)});if(e){this.showCoordinatePoints&&this.coordinatePoints.createOrUpdate({featureId:this.currentId,featureCoordinates:e.geometry.coordinates});var i=this.currentId;this.currentCoordinate=0,this.currentId=void 0,this.lastCommittedCoordinates=void 0,this.undoRedo.clear(),"drawing"===this.state&&this.setStarted(),this.closingPoints.delete(),this.snappedPointId&&(this.mutateFeature.deleteFeatureIfPresent(this.snappedPointId),this.snappedPointId=void 0),this.editedPointId&&(this.mutateFeature.deleteFeatureIfPresent(this.editedPointId),this.editedPointId=void 0,this.editedFeatureId=void 0,this.editedFeatureCoordinateIndex=void 0,this.editedInsertIndex=void 0,this.editedSnapType=void 0),this.onFinish(i,{mode:this.mode,action:h})}}},i.generateInsertCoordinates=function(t,e){if(!this.insertCoordinates||!this.lastCommittedCoordinates)throw new Error("Not able to insert coordinates");if("amount"!==this.insertCoordinates.strategy)throw new Error("Strategy does not exist");var i=w(t,e)/(this.insertCoordinates.value+1),n=[];return"globe"===this.projection?n=this.insertPoint.generateInsertionGeodesicCoordinates(t,e,i):"web-mercator"===this.projection&&(n=this.insertPoint.generateInsertionCoordinates(t,e,i)),n},i.createLine=function(t){var e,i=this.mutateFeature.createLineString({coordinates:[t,t],properties:(e={mode:this.mode},e[y.CURRENTLY_DRAWING]=!0,e)});this.lastCommittedCoordinates=i.geometry.coordinates,this.currentId=i.id,this.currentCoordinate++,this.pushHistorySnapshot(this.currentId,this.currentCoordinate),this.setDrawing(),this.showCoordinatePoints&&this.coordinatePoints.createOrUpdate({featureId:this.currentId,featureCoordinates:i.geometry.coordinates})},i.firstUpdateToLine=function(t){if(this.currentId){this.setCursor(this.cursors.close);var e=this.mutateFeature.updateLineString({featureId:this.currentId,context:{updateType:u.Commit},coordinateMutations:[{type:tt,index:-1,coordinate:t}]});e&&(this.closingPoints.create(e.geometry.coordinates),this.showCoordinatePoints&&this.coordinatePoints.createOrUpdate({featureId:this.currentId,featureCoordinates:e.geometry.coordinates}),this.lastCommittedCoordinates=e.geometry.coordinates,this.currentCoordinate++,this.pushHistorySnapshot(this.currentId,this.currentCoordinate),this.shouldFinishOnCommit(e.geometry)&&this.close())}},i.updateToLine=function(t,e){if(this.currentId)if(this.closingPoints.isLineStringClosingPoint(t).isClosing)this.close();else{this.setCursor(this.cursors.close);var i=this.mutateFeature.updateLineString({featureId:this.currentId,context:{updateType:u.Commit},coordinateMutations:[{type:tt,index:-1,coordinate:e}]});i&&(this.closingPoints.update(i.geometry.coordinates),this.showCoordinatePoints&&this.coordinatePoints.createOrUpdate({featureId:this.currentId,featureCoordinates:i.geometry.coordinates}),this.lastCommittedCoordinates=i.geometry.coordinates,this.currentCoordinate++,this.pushHistorySnapshot(this.currentId,this.currentCoordinate),this.shouldFinishOnCommit(i.geometry)&&this.close())}},i.undoSize=function(){return this.undoRedo.undoSize()},i.clearHistory=function(){this.undoRedo.clear()},i.pushHistorySnapshot=function(t,e){var i=this.readFeature.getGeometry(t);this.undoRedo.recordSnapshot({featureCoordinates:i.coordinates,currentCoordinate:e})},i.updateSnappedGuidancePointFromLastMouseMove=function(){this.snapping&&this.lastMouseMoveEvent?this.updateSnappedCoordinate(this.lastMouseMoveEvent):this.snappedPointId&&(this.mutateFeature.deleteFeatureIfPresent(this.snappedPointId),this.snappedPointId=void 0)},i.syncClosingPoints=function(t){this.currentCoordinate>=2?this.closingPoints.ids.length?this.closingPoints.update(t):this.closingPoints.create(t):this.closingPoints.delete()},i.undo=function(){var t;if("drawing"===this.state&&this.currentId){var e=this.undoRedo.beginUndo();if(e){var i=e.previousEntry;if(!i){var n=this.currentId;return this.currentId=void 0,this.currentCoordinate=0,this.lastCommittedCoordinates=void 0,this.closingPoints.delete(),"drawing"===this.state&&this.setStarted(),this.showCoordinatePoints&&this.coordinatePoints.deletePointsByFeatureIds([n]),this.mutateFeature.deleteFeatureIfPresent(n),void this.updateSnappedGuidancePointFromLastMouseMove()}var o=this.mutateFeature.updateLineString({featureId:this.currentId,coordinateMutations:{type:nt,coordinates:i.featureCoordinates},propertyMutations:(t={},t[y.CURRENTLY_DRAWING]=!0,t),context:{updateType:u.Commit}});o&&(this.currentCoordinate=i.currentCoordinate,this.lastCommittedCoordinates=o.geometry.coordinates,this.syncClosingPoints(o.geometry.coordinates),this.showCoordinatePoints&&this.coordinatePoints.createOrUpdate({featureId:this.currentId,featureCoordinates:o.geometry.coordinates}),this.updateSnappedGuidancePointFromLastMouseMove())}}},i.redoSize=function(){return this.undoRedo.redoSize()},i.redo=function(){var t=this.undoRedo.takeRedo();if(t){if(this.currentId){var e,i=this.mutateFeature.updateLineString({featureId:this.currentId,coordinateMutations:{type:nt,coordinates:t.featureCoordinates},propertyMutations:(e={},e[y.CURRENTLY_DRAWING]=!0,e),context:{updateType:u.Commit}});if(!i)return;this.currentCoordinate=t.currentCoordinate,this.lastCommittedCoordinates=i.geometry.coordinates,this.syncClosingPoints(i.geometry.coordinates),this.showCoordinatePoints&&this.coordinatePoints.createOrUpdate({featureId:this.currentId,featureCoordinates:i.geometry.coordinates})}else{var n,o=this.mutateFeature.createLineString({coordinates:t.featureCoordinates,properties:(n={mode:this.mode},n[y.CURRENTLY_DRAWING]=!0,n)}),r=o.id,s=o.geometry;this.currentId=r,this.currentCoordinate=t.currentCoordinate,this.lastCommittedCoordinates=s.coordinates,"started"===this.state&&this.setDrawing(),this.syncClosingPoints(s.coordinates),this.showCoordinatePoints&&this.coordinatePoints.createOrUpdate({featureId:r,featureCoordinates:s.coordinates})}this.undoRedo.commitRedo(t),this.updateSnappedGuidancePointFromLastMouseMove()}},i.registerBehaviors=function(t){this.insertPoint=new Mt(t),this.clickBoundingBox=new ft(t),this.pixelDistance=new yt(t),this.lineSnapping=new _t(t,this.pixelDistance,this.clickBoundingBox),this.coordinateSnapping=new vt(t,this.pixelDistance,this.clickBoundingBox),this.featureSnapping=new Tt(this.coordinateSnapping,this.lineSnapping),this.readFeature=new ht(t),this.mutateFeature=new ot(t,{validate:this.validate}),this.closingPoints=new Wt(t,this.pixelDistance,this.mutateFeature,this.readFeature),this.coordinatePoints=new Ut(t,this.readFeature,this.mutateFeature),this.undoRedo=new At({maxStackSize:t.undoRedoMaxStackSize})},i.start=function(){this.setStarted(),this.setCursor(this.cursors.start)},i.stop=function(){this.cleanUp(),this.setStopped(),this.setCursor("unset")},i.onMouseMove=function(t){this.mouseMove=!0,this.setCursor(this.cursors.start),this.lastMouseMoveEvent=t;var e=this.updateSnappedCoordinate(t)||[t.lng,t.lat];if(void 0!==this.currentId&&0!==this.currentCoordinate){this.closingPoints.isLineStringClosingPoint(t).isClosing&&this.setCursor(this.cursors.close);var i=[{type:et,index:-1,coordinate:e}];if(this.insertCoordinates){var n=this.getInsertCoordinates(e);n&&(i={type:nt,coordinates:n})}var o=this.mutateFeature.updateLineString({coordinateMutations:i,featureId:this.currentId,context:{updateType:u.Provisional}});o&&this.showCoordinatePoints&&this.coordinatePoints.createOrUpdate({featureId:this.currentId,featureCoordinates:o.geometry.coordinates})}},i.getInsertCoordinates=function(t){if(this.lastCommittedCoordinates){var e=this.lastCommittedCoordinates[this.lastCommittedCoordinates.length-1];if(!ut(e,t)){var i=this.generateInsertCoordinates(e,t),n=this.lastCommittedCoordinates.slice(0,-1);return[].concat(n,i,[t])}}},i.onRightClick=function(t){var e=this;if(this.editable&&"started"===this.state){var i=this.coordinateSnapping.getSnappable(t,function(t){return e.lineStringFilter(t)}),n=i.featureId,o=i.featureCoordinateIndex;if(n&&void 0!==o){var r=this.readFeature.getGeometry(n);if("LineString"===r.type&&!(r.coordinates.length<=2)){var s=this.mutateFeature.updateLineString({featureId:n,coordinateMutations:[{type:it,index:o}],context:{updateType:u.Finish,action:l}});s&&this.showCoordinatePoints&&this.coordinatePoints.createOrUpdate({featureId:n,featureCoordinates:s.geometry.coordinates}),this.snappedPointId&&(this.mutateFeature.deleteFeatureIfPresent(this.snappedPointId),this.snappedPointId=void 0),this.editedPointId&&(this.mutateFeature.deleteFeatureIfPresent(this.editedPointId),this.editedPointId=void 0,this.editedFeatureId=void 0,this.editedFeatureCoordinateIndex=void 0,this.editedInsertIndex=void 0,this.editedSnapType=void 0),this.closingPoints.delete(),this.onFinish(n,{mode:this.mode,action:c})}}}},i.onLeftClick=function(t){this.snappedPointId&&(this.mutateFeature.deleteFeatureIfPresent(this.snappedPointId),this.snappedPointId=void 0);var e=this.snapCoordinate(t)||[t.lng,t.lat];0===this.currentCoordinate?this.createLine(e):1===this.currentCoordinate&&this.currentId?this.firstUpdateToLine(e):this.currentId&&this.updateToLine(t,e)},i.onClick=function(t){void 0===this.currentId||this.readFeature.hasFeature(this.currentId)||this.cleanUp(),("right"===t.button&&this.allowPointerEvent(this.pointerEvents.rightClick,t)||"left"===t.button&&this.allowPointerEvent(this.pointerEvents.leftClick,t)||t.isContextMenu&&this.allowPointerEvent(this.pointerEvents.contextMenu,t))&&(this.currentCoordinate>0&&!this.mouseMove&&this.onMouseMove(t),this.mouseMove=!1,"right"===t.button?this.onRightClick(t):"left"===t.button&&this.onLeftClick(t))},i.onKeyDown=function(){},i.onKeyUp=function(t){t.key===this.keyEvents.cancel&&this.cleanUp(),t.key===this.keyEvents.finish&&this.close()},i.onDragStart=function(t,e){var i=this;if(this.allowPointerEvent(this.pointerEvents.onDragStart,t)&&this.editable){var n=void 0;if("started"===this.state){var o=this.lineSnapping.getSnappable(t,function(t){return i.lineStringFilter(t)});o.coordinate&&(this.editedSnapType="line",this.editedFeatureCoordinateIndex=o.featureCoordinateIndex,this.editedFeatureId=o.featureId,n=o.coordinate);var r=this.coordinateSnapping.getSnappable(t,function(t){return i.lineStringFilter(t)});r.coordinate&&(this.editedSnapType="coordinate",this.editedFeatureCoordinateIndex=r.featureCoordinateIndex,this.editedFeatureId=r.featureId,n=r.coordinate)}this.editedFeatureId&&n&&(this.editedPointId||(this.editedPointId=this.mutateFeature.createGuidancePoint({coordinate:n,type:y.EDITED})),this.setCursor(this.cursors.dragStart),e(!1))}},i.onDrag=function(t,e){var i;if(this.allowPointerEvent(this.pointerEvents.onDrag,t)&&void 0!==this.editedFeatureId&&void 0!==this.editedFeatureCoordinateIndex){if("coordinate"===this.editedSnapType||"line"===this.editedSnapType&&void 0!==this.editedInsertIndex){var n=this.mutateFeature.updateLineString({featureId:this.editedFeatureId,context:{updateType:u.Provisional},coordinateMutations:[{type:et,index:this.editedFeatureCoordinateIndex,coordinate:[t.lng,t.lat]}]});if(!n)return;this.showCoordinatePoints&&(void 0!==this.editedInsertIndex?this.coordinatePoints.createOrUpdate({featureId:this.editedFeatureId,featureCoordinates:n.geometry.coordinates}):this.coordinatePoints.updateOneAtIndex(this.editedFeatureId,this.editedFeatureCoordinateIndex,[t.lng,t.lat]))}else if("line"===this.editedSnapType&&void 0===this.editedInsertIndex){this.editedInsertIndex=this.editedFeatureCoordinateIndex+1;var o=this.mutateFeature.updateLineString({featureId:this.editedFeatureId,context:{updateType:u.Provisional}});if(!o)return;this.showCoordinatePoints&&this.coordinatePoints.createOrUpdate({featureId:this.editedFeatureId,featureCoordinates:o.geometry.coordinates}),this.editedFeatureCoordinateIndex++}this.snapping&&this.snappedPointId&&(this.mutateFeature.deleteFeatureIfPresent(this.snappedPointId),this.snappedPointId=void 0),this.editedPointId&&this.mutateFeature.updateGuidancePoints([{featureId:this.editedPointId,coordinate:[t.lng,t.lat]}]),this.mutateFeature.updateLineString({featureId:this.editedFeatureId,context:{updateType:u.Provisional},propertyMutations:(i={},i[y.EDITED]=!0,i)})}},i.onDragEnd=function(t,e){var i;if(this.allowPointerEvent(this.pointerEvents.onDragEnd,t)&&void 0!==this.editedFeatureId&&(this.setCursor(this.cursors.dragEnd),this.mutateFeature.updateLineString({featureId:this.editedFeatureId,propertyMutations:(i={},i[y.EDITED]=!1,i),context:{updateType:u.Finish,action:l}}))){var n=this.editedFeatureId;e(!0),this.snappedPointId&&(this.mutateFeature.deleteFeatureIfPresent(this.snappedPointId),this.snappedPointId=void 0),this.editedPointId&&(this.mutateFeature.deleteFeatureIfPresent(this.editedPointId),this.editedPointId=void 0,this.editedFeatureId=void 0,this.editedFeatureCoordinateIndex=void 0,this.editedInsertIndex=void 0,this.editedSnapType=void 0),this.closingPoints.delete(),this.onFinish(n,{mode:this.mode,action:l})}},i.cleanUp=function(){var t=this.currentId,e=this.snappedPointId;this.snappedPointId=void 0,this.currentId=void 0,this.currentCoordinate=0,this.lastCommittedCoordinates=void 0,this.undoRedo.clear(),"drawing"===this.state&&this.setStarted(),t&&this.showCoordinatePoints&&this.coordinatePoints.deletePointsByFeatureIds([t]),this.mutateFeature.deleteFeatureIfPresent(t),this.mutateFeature.deleteFeatureIfPresent(e),this.closingPoints.delete()},i.styleFeature=function(t){var e=r({},{polygonFillColor:"#3f97e0",polygonOutlineColor:"#3f97e0",polygonOutlineWidth:4,polygonOutlineOpacity:1,polygonFillOpacity:.3,pointColor:"#3f97e0",pointOpacity:1,pointOutlineColor:"#ffffff",pointOutlineOpacity:1,pointOutlineWidth:0,pointWidth:6,lineStringColor:"#3f97e0",lineStringWidth:4,lineStringOpacity:1,zIndex:0,markerUrl:void 0,markerHeight:void 0,markerWidth:void 0,lineStringDash:void 0});if("Feature"===t.type&&"LineString"===t.geometry.type&&t.properties.mode===this.mode)return e.lineStringDash=this.getDashArrayStylingValue(this.styles.lineStringDash,void 0,t),e.lineStringColor=this.getHexColorStylingValue(this.styles.lineStringColor,e.lineStringColor,t),e.lineStringOpacity=this.getNumericStylingValue(this.styles.lineStringOpacity,void 0===e.lineStringOpacity?1:e.lineStringOpacity,t),e.lineStringWidth=this.getNumericStylingValue(this.styles.lineStringWidth,e.lineStringWidth,t),e.zIndex=v,e;if("Feature"===t.type&&"Point"===t.geometry.type&&t.properties.mode===this.mode){var i=t.properties[y.COORDINATE_POINT],n=t.properties[y.CLOSING_POINT]?"closingPoint":t.properties[y.SNAPPING_POINT]?"snappingPoint":i?"coordinatePoint":void 0;if(!n)return e;var o={closingPoint:{width:this.styles.closingPointWidth,color:this.styles.closingPointColor,opacity:this.styles.closingPointOpacity,outlineColor:this.styles.closingPointOutlineColor,outlineWidth:this.styles.closingPointOutlineWidth,outlineOpacity:this.styles.closingPointOutlineOpacity},snappingPoint:{width:this.styles.snappingPointWidth,color:this.styles.snappingPointColor,opacity:this.styles.snappingPointOpacity,outlineColor:this.styles.snappingPointOutlineColor,outlineWidth:this.styles.snappingPointOutlineWidth,outlineOpacity:this.styles.snappingPointOutlineOpacity},coordinatePoint:{width:this.styles.coordinatePointWidth,color:this.styles.coordinatePointColor,opacity:this.styles.coordinatePointOpacity,outlineColor:this.styles.coordinatePointOutlineColor,outlineWidth:this.styles.coordinatePointOutlineWidth,outlineOpacity:this.styles.coordinatePointOutlineOpacity}};return e.pointWidth=this.getNumericStylingValue(o[n].width,e.pointWidth,t),e.pointOpacity=this.getNumericStylingValue(o[n].opacity,1,t),e.pointColor=this.getHexColorStylingValue(o[n].color,e.pointColor,t),e.pointOutlineColor=this.getHexColorStylingValue(o[n].outlineColor,"#ffffff",t),e.pointOutlineWidth=this.getNumericStylingValue(o[n].outlineWidth,2,t),e.pointOutlineOpacity=this.getNumericStylingValue(o[n].outlineOpacity,1,t),e.zIndex=i?20:50,e}return e},i.validateFeature=function(t){var e=this;return this.validateModeFeature(t,function(t){return wt(t,e.coordinatePrecision)})},i.lineStringFilter=function(t){return Boolean("LineString"===t.geometry.type&&t.properties&&t.properties.mode===this.mode)},i.snapCoordinate=function(t){var e,i,n,o,r,s,a,d=this;if(null!=(e=this.snapping)&&e.toLine&&(s=this.currentId?this.lineSnapping.getSnappableCoordinate(t,this.currentId):this.lineSnapping.getSnappableCoordinateFirstClick(t))&&(r=s),null!=(i=this.snapping)&&i.toCoordinate&&(a=this.currentId?this.coordinateSnapping.getSnappableCoordinate(t,this.currentId):this.coordinateSnapping.getSnappableCoordinateFirstClick(t))&&(r=a),null!=(n=this.snapping)&&n.toCustom){var u=this.snapping.toCustom(t,{currentCoordinate:this.currentCoordinate,currentId:this.currentId,getCurrentGeometrySnapshot:this.currentId?function(){return d.readFeature.getGeometry(d.currentId)}:function(){return null},project:this.project,unproject:this.unproject});u&&(r=u)}if(null!=(o=this.snapping)&&o.toFeature){var h=this.featureSnapping.getSnappable(t,this.currentId,this.snapping.toFeature.filter,{toLine:this.snapping.toFeature.toLine,toCoordinate:this.snapping.toFeature.toCoordinate});h.coordinate&&(r=h.coordinate)}return r},i.afterFeatureUpdated=function(t){this.showCoordinatePoints&&this.coordinatePoints.createOrUpdate({featureId:t.id,featureCoordinates:t.geometry.coordinates}),this.editedFeatureId===t.id&&this.editedPointId&&(this.mutateFeature.deleteFeatureIfPresent(this.editedPointId),this.editedPointId=void 0,this.editedFeatureId=void 0,this.editedFeatureCoordinateIndex=void 0,this.editedSnapType=void 0),this.snappedPointId&&this.lastMouseMoveEvent&&this.updateSnappedCoordinate(this.lastMouseMoveEvent),this.currentId===t.id&&(this.closingPoints.delete(),this.currentCoordinate=0,this.currentId=void 0,this.lastCommittedCoordinates=void 0,this.undoRedo.clear(),"drawing"===this.state&&this.setStarted())},i.afterFeatureAdded=function(t){this.showCoordinatePoints&&this.coordinatePoints.createOrUpdate({featureId:t.id,featureCoordinates:t.geometry.coordinates})},e}(O),Vt={cancel:"Escape",finish:"Enter"},Gt={start:"crosshair",close:"pointer"},jt=/*#__PURE__*/function(t){function e(e){var i;return(i=t.call(this,e,!0)||this).mode="polyline",i.currentCoordinate=0,i.currentId=void 0,i.keyEvents=Vt,i.cursors=Gt,i.mouseMove=!1,i.snapping=void 0,i.snappedPointId=void 0,i.mutateFeature=void 0,i.readFeature=void 0,i.pixelDistance=void 0,i.closingPoints=void 0,i.clickBoundingBox=void 0,i.lineSnapping=void 0,i.coordinateSnapping=void 0,i.featureSnapping=void 0,i.updateOptions(e),i}s(e,t);var i=e.prototype;return i.updateOptions=function(e){t.prototype.updateOptions.call(this,e),null!=e&&e.cursors&&(this.cursors=r({},this.cursors,e.cursors)),null!=e&&e.snapping&&(this.snapping=e.snapping),null===(null==e?void 0:e.keyEvents)?this.keyEvents={cancel:null,finish:null}:null!=e&&e.keyEvents&&(this.keyEvents=r({},this.keyEvents,e.keyEvents))},i.registerBehaviors=function(t){this.clickBoundingBox=new ft(t),this.pixelDistance=new yt(t),this.lineSnapping=new _t(t,this.pixelDistance,this.clickBoundingBox),this.coordinateSnapping=new vt(t,this.pixelDistance,this.clickBoundingBox),this.featureSnapping=new Tt(this.coordinateSnapping,this.lineSnapping),this.readFeature=new ht(t),this.mutateFeature=new ot(t,{validate:this.validate}),this.closingPoints=new Wt(t,this.pixelDistance,this.mutateFeature,this.readFeature)},i.start=function(){this.setStarted(),this.setCursor(this.cursors.start)},i.stop=function(){this.cleanUp(),this.setStopped(),this.setCursor("unset")},i.finishLine=function(){var t;if(this.currentId&&this.mutateFeature.updateLineString({featureId:this.currentId,context:{updateType:u.Finish,action:h},coordinateMutations:[{type:it,index:-1}],propertyMutations:(t={},t[y.CURRENTLY_DRAWING]=void 0,t)})){var e=this.currentId;this.currentCoordinate=0,this.currentId=void 0,this.closingPoints.delete(),this.mutateFeature.deleteFeatureIfPresent(this.snappedPointId),this.snappedPointId=void 0,"drawing"===this.state&&this.setStarted(),this.onFinish(e,{mode:this.mode,action:h})}},i.toPolygonLikeCoordinates=function(t){return 0===t.length?[t]:[[].concat(t,[t[0]])]},i.closeAsPolygon=function(){if(this.currentId){var t=this.readFeature.getGeometry(this.currentId).coordinates.slice(0,-1);if(!(t.length<3)){var e=this.currentId,i=[].concat(t,[t[0]]),n=this.mutateFeature.createPolygon({coordinates:i,properties:{mode:this.mode},context:{updateType:u.Finish,action:h}});n&&(this.mutateFeature.deleteFeatureIfPresent(e),this.currentCoordinate=0,this.currentId=void 0,this.closingPoints.delete(),this.mutateFeature.deleteFeatureIfPresent(this.snappedPointId),this.snappedPointId=void 0,"drawing"===this.state&&this.setStarted(),this.onFinish(n.id,{mode:this.mode,action:h}))}}},i.onMouseMove=function(t){if(this.mouseMove=!0,this.setCursor(this.cursors.start),this.updateSnappedCoordinate(t),this.currentId&&0!==this.currentCoordinate&&this.mutateFeature.updateLineString({featureId:this.currentId,coordinateMutations:[{type:et,index:-1,coordinate:[t.lng,t.lat]}],context:{updateType:u.Provisional}})){var e=this.closingPoints.isPolygonClosingPoints(t);(e.isClosing&&this.currentCoordinate>=3||e.isPreviousClosing&&this.currentCoordinate>=2)&&this.setCursor(this.cursors.close)}},i.onLeftClick=function(t){this.updateSnappedCoordinate(t);var e=[t.lng,t.lat];if(0===this.currentCoordinate){var i,n=this.mutateFeature.createLineString({coordinates:[e,e],properties:(i={mode:this.mode},i[y.CURRENTLY_DRAWING]=!0,i)});return this.currentId=n.id,this.currentCoordinate=1,void this.setDrawing()}if(this.currentId){var o=this.closingPoints.isPolygonClosingPoints(t),r=o.isPreviousClosing;if(o.isClosing&&this.currentCoordinate>=3)this.closeAsPolygon();else if(r&&this.currentCoordinate>=2)this.finishLine();else{var s=this.mutateFeature.updateLineString({featureId:this.currentId,context:{updateType:u.Commit},coordinateMutations:[{type:tt,index:-1,coordinate:e}]});if(s&&(this.currentCoordinate++,this.currentCoordinate>=2)){var a=this.toPolygonLikeCoordinates(s.geometry.coordinates);0===this.closingPoints.ids.length?this.closingPoints.create(a):this.closingPoints.update(a)}}}},i.onClick=function(t){"left"===t.button&&this.allowPointerEvent(this.pointerEvents.leftClick,t)&&(this.currentCoordinate>0&&!this.mouseMove&&this.onMouseMove(t),this.mouseMove=!1,this.onLeftClick(t))},i.onKeyUp=function(t){t.key===this.keyEvents.cancel?this.cleanUp():t.key===this.keyEvents.finish&&this.finishLine()},i.onKeyDown=function(){},i.onDragStart=function(){},i.onDrag=function(){},i.onDragEnd=function(){},i.cleanUp=function(){var t=this.currentId;this.currentId=void 0,this.currentCoordinate=0,"drawing"===this.state&&this.setStarted(),this.mutateFeature.deleteFeatureIfPresent(t),this.mutateFeature.deleteFeatureIfPresent(this.snappedPointId),this.snappedPointId=void 0,this.closingPoints.delete()},i.updateSnappedCoordinate=function(t){var e=this.snapCoordinate(t);e?(this.snappedPointId?this.mutateFeature.updateGuidancePoints([{featureId:this.snappedPointId,coordinate:e}]):this.snappedPointId=this.mutateFeature.createGuidancePoint({coordinate:e,type:y.SNAPPING_POINT}),t.lng=e[0],t.lat=e[1]):this.snappedPointId&&(this.mutateFeature.deleteFeatureIfPresent(this.snappedPointId),this.snappedPointId=void 0)},i.snapCoordinate=function(t){var e,i,n,o,r,s,a,d=this;if(null!=(e=this.snapping)&&e.toLine&&(s=this.currentId?this.lineSnapping.getSnappableCoordinate(t,this.currentId):this.lineSnapping.getSnappableCoordinateFirstClick(t))&&(r=s),null!=(i=this.snapping)&&i.toCoordinate&&(a=this.currentId?this.coordinateSnapping.getSnappableCoordinate(t,this.currentId):this.coordinateSnapping.getSnappableCoordinateFirstClick(t))&&(r=a),null!=(n=this.snapping)&&n.toFeature){var u=this.featureSnapping.getSnappable(t,this.currentId,this.snapping.toFeature.filter,{toLine:this.snapping.toFeature.toLine,toCoordinate:this.snapping.toFeature.toCoordinate});u.coordinate&&(r=u.coordinate)}if(null!=(o=this.snapping)&&o.toCustom){var h=this.snapping.toCustom(t,{currentCoordinate:this.currentCoordinate,currentId:this.currentId,getCurrentGeometrySnapshot:this.currentId?function(){return d.readFeature.getGeometry(d.currentId)}:function(){return null},project:this.project,unproject:this.unproject});h&&(r=h)}return r},i.styleFeature=function(t){var e=r({},{polygonFillColor:"#3f97e0",polygonOutlineColor:"#3f97e0",polygonOutlineWidth:4,polygonOutlineOpacity:1,polygonFillOpacity:.3,pointColor:"#3f97e0",pointOpacity:1,pointOutlineColor:"#ffffff",pointOutlineOpacity:1,pointOutlineWidth:0,pointWidth:6,lineStringColor:"#3f97e0",lineStringWidth:4,lineStringOpacity:1,zIndex:0,markerUrl:void 0,markerHeight:void 0,markerWidth:void 0,lineStringDash:void 0});if(t.properties.mode!==this.mode)return e;if("LineString"===t.geometry.type)return e.lineStringColor=this.getHexColorStylingValue(this.styles.lineStringColor,e.lineStringColor,t),e.lineStringWidth=this.getNumericStylingValue(this.styles.lineStringWidth,e.lineStringWidth,t),e.lineStringOpacity=this.getNumericStylingValue(this.styles.lineStringOpacity,1,t),e.lineStringDash=this.getDashArrayStylingValue(this.styles.lineStringDash,void 0,t),e.zIndex=v,e;if("Polygon"===t.geometry.type)return e.polygonFillColor=this.getHexColorStylingValue(this.styles.polygonFillColor,e.polygonFillColor,t),e.polygonFillOpacity=this.getNumericStylingValue(this.styles.polygonFillOpacity,e.polygonFillOpacity,t),e.polygonOutlineColor=this.getHexColorStylingValue(this.styles.polygonOutlineColor,e.polygonOutlineColor,t),e.polygonOutlineWidth=this.getNumericStylingValue(this.styles.polygonOutlineWidth,e.polygonOutlineWidth,t),e.polygonOutlineOpacity=this.getNumericStylingValue(this.styles.polygonOutlineOpacity,1,t),e.zIndex=v,e;if("Point"===t.geometry.type){var i=!0===t.properties[y.CLOSING_POINT];if(!i&&!0!==t.properties[y.SNAPPING_POINT])return e;e.pointColor=this.getHexColorStylingValue(i?this.styles.closingPointColor:this.styles.snappingPointColor,e.pointColor,t),e.pointWidth=this.getNumericStylingValue(i?this.styles.closingPointWidth:this.styles.snappingPointWidth,e.pointWidth,t),e.pointOpacity=this.getNumericStylingValue(i?this.styles.closingPointOpacity:this.styles.snappingPointOpacity,1,t),e.pointOutlineColor=this.getHexColorStylingValue(i?this.styles.closingPointOutlineColor:this.styles.snappingPointOutlineColor,e.pointOutlineColor,t),e.pointOutlineWidth=this.getNumericStylingValue(i?this.styles.closingPointOutlineWidth:this.styles.snappingPointOutlineWidth,2,t),e.pointOutlineOpacity=this.getNumericStylingValue(i?this.styles.closingPointOutlineOpacity:this.styles.snappingPointOutlineOpacity,1,t),e.zIndex=30}return e},i.afterFeatureAdded=function(t){},i.afterFeatureUpdated=function(t){this.snappedPointId&&(this.mutateFeature.deleteFeatureIfPresent(this.snappedPointId),this.snappedPointId=void 0),this.currentId===t.id&&(this.currentCoordinate=0,this.currentId=void 0,this.closingPoints.delete(),"drawing"===this.state&&this.setStarted())},i.validateFeature=function(t){var e=this;return this.validateModeFeature(t,function(t){return"LineString"===t.geometry.type?wt(t,e.coordinatePrecision):"Polygon"===t.geometry.type?q(t,e.coordinatePrecision):{valid:!1,reason:"Only LineString or Polygon features are valid"}})},e}(O),Kt="Feature is not a Point",Yt="Feature has invalid coordinates",Xt="Feature has coordinates with excessive precision";function qt(t,e){return"Point"!==t.geometry.type?{valid:!1,reason:Kt}:V(t.geometry.coordinates)?H(t.geometry.coordinates,e)?{valid:!0}:{valid:!1,reason:Xt}:{valid:!1,reason:Yt}}var Zt=/*#__PURE__*/function(t){function e(e,i,n){var o;return(o=t.call(this,e)||this).pixelDistance=void 0,o.clickBoundingBox=void 0,o.pixelDistance=i,o.clickBoundingBox=n,o}return s(e,t),e.prototype.getNearestPointFeature=function(t){for(var e=this.clickBoundingBox.create(t),i=this.store.search(e),n=Infinity,o=void 0,r=0;rn||a>this.pointerDistance||(n=a,o=s)}}return o},e}(J),Jt={create:"crosshair",dragStart:"grabbing",dragEnd:"crosshair"},$t=/*#__PURE__*/function(t){function e(e){var i;return(i=t.call(this,e,!0)||this).mode="point",i.cursors=Jt,i.editable=!1,i.editedFeatureId=void 0,i.pixelDistance=void 0,i.clickBoundingBox=void 0,i.pointSearch=void 0,i.mutateFeature=void 0,i.updateOptions(e),i}s(e,t);var i=e.prototype;return i.updateOptions=function(e){t.prototype.updateOptions.call(this,e),null!=e&&e.cursors&&(this.cursors=r({},this.cursors,e.cursors)),null!=e&&e.editable&&(this.editable=e.editable)},i.start=function(){this.setStarted(),this.setCursor(this.cursors.create)},i.stop=function(){this.cleanUp(),this.setStopped(),this.setCursor("unset")},i.onClick=function(t){"right"===t.button&&this.allowPointerEvent(this.pointerEvents.rightClick,t)||t.isContextMenu&&this.allowPointerEvent(this.pointerEvents.contextMenu,t)?this.onRightClick(t):"left"===t.button&&this.allowPointerEvent(this.pointerEvents.leftClick,t)&&this.onLeftClick(t)},i.onMouseMove=function(){},i.onKeyDown=function(){},i.onKeyUp=function(){},i.cleanUp=function(){this.editedFeatureId=void 0},i.onDragStart=function(t,e){if(this.allowPointerEvent(this.pointerEvents.onDragStart,t)){if(this.editable){var i=this.pointSearch.getNearestPointFeature(t);this.editedFeatureId=null==i?void 0:i.id}this.editedFeatureId&&(this.setCursor(this.cursors.dragStart),e(!1))}},i.onDrag=function(t,e){var i;this.allowPointerEvent(this.pointerEvents.onDrag,t)&&void 0!==this.editedFeatureId&&this.mutateFeature.updatePoint({featureId:this.editedFeatureId,coordinateMutations:{type:nt,coordinates:[t.lng,t.lat]},propertyMutations:(i={},i[y.EDITED]=!0,i),context:{updateType:u.Provisional}})},i.onDragEnd=function(t,e){var i;if(this.allowPointerEvent(this.pointerEvents.onDragEnd,t)&&void 0!==this.editedFeatureId&&this.mutateFeature.updatePoint({featureId:this.editedFeatureId,propertyMutations:(i={mode:this.mode},i[y.EDITED]=!1,i),context:{updateType:u.Finish,action:"edit"}})){var n=this.editedFeatureId;this.setCursor(this.cursors.dragEnd),this.editedFeatureId=void 0,e(!0),this.onFinish(n,{mode:this.mode,action:h})}},i.registerBehaviors=function(t){this.pixelDistance=new yt(t),this.clickBoundingBox=new ft(t),this.pointSearch=new Zt(t,this.pixelDistance,this.clickBoundingBox),this.mutateFeature=new ot(t,{validate:this.validate})},i.styleFeature=function(t){var e=r({},{polygonFillColor:"#3f97e0",polygonOutlineColor:"#3f97e0",polygonOutlineWidth:4,polygonOutlineOpacity:1,polygonFillOpacity:.3,pointColor:"#3f97e0",pointOpacity:1,pointOutlineColor:"#ffffff",pointOutlineOpacity:1,pointOutlineWidth:0,pointWidth:6,lineStringColor:"#3f97e0",lineStringWidth:4,lineStringOpacity:1,zIndex:0,markerUrl:void 0,markerHeight:void 0,markerWidth:void 0,lineStringDash:void 0});if("Feature"===t.type&&"Point"===t.geometry.type&&t.properties.mode===this.mode){var i=Boolean(t.id&&this.editedFeatureId===t.id);e.pointWidth=this.getNumericStylingValue(i?this.styles.editedPointWidth:this.styles.pointWidth,e.pointWidth,t),e.pointOpacity=this.getNumericStylingValue(this.styles.pointOpacity,void 0===e.pointOpacity?1:e.pointOpacity,t),e.pointColor=this.getHexColorStylingValue(i?this.styles.editedPointColor:this.styles.pointColor,e.pointColor,t),e.pointOutlineColor=this.getHexColorStylingValue(i?this.styles.editedPointOutlineColor:this.styles.pointOutlineColor,e.pointOutlineColor,t),e.pointOutlineOpacity=this.getNumericStylingValue(this.styles.pointOutlineOpacity,void 0===e.pointOutlineOpacity?1:e.pointOutlineOpacity,t),e.pointOutlineWidth=this.getNumericStylingValue(i?this.styles.editedPointOutlineWidth:this.styles.pointOutlineWidth,2,t),e.zIndex=30}return e},i.validateFeature=function(t){var e=this;return this.validateModeFeature(t,function(t){return qt(t,e.coordinatePrecision)})},i.onLeftClick=function(t){var e=this.mutateFeature.createPoint({coordinates:[t.lng,t.lat],properties:{mode:this.mode},context:{updateType:u.Finish,action:h}});e&&this.onFinish(e.id,{mode:this.mode,action:h})},i.onRightClick=function(t){if(this.editable){var e=this.pointSearch.getNearestPointFeature(t);e&&this.mutateFeature.deleteFeatureIfPresent(e.id)}},i.afterFeatureUpdated=function(t){this.editedFeatureId===t.id&&(this.editedFeatureId=void 0,this.setCursor(this.cursors.create))},e}(O),Qt={cancel:"Escape",finish:"Enter"},te={start:"crosshair",close:"pointer",dragStart:"grabbing",dragEnd:"crosshair"},ee=/*#__PURE__*/function(t){function e(e){var i;return(i=t.call(this,e,!0)||this).mode="polygon",i.currentCoordinate=0,i.currentId=void 0,i.keyEvents=Qt,i.cursors=te,i.mouseMove=!1,i.showCoordinatePoints=!1,i.lastMouseMoveEvent=void 0,i.snapping=void 0,i.snappedPointId=void 0,i.editable=!1,i.editedFeatureId=void 0,i.editedFeatureCoordinateIndex=void 0,i.editedSnapType=void 0,i.editedInsertIndex=void 0,i.editedPointId=void 0,i.coordinatePoints=void 0,i.lineSnapping=void 0,i.coordinateSnapping=void 0,i.featureSnapping=void 0,i.pixelDistance=void 0,i.closingPoints=void 0,i.clickBoundingBox=void 0,i.mutateFeature=void 0,i.readFeature=void 0,i.undoRedo=void 0,i.updateOptions(e),i}s(e,t);var i=e.prototype;return i.updateOptions=function(e){var i=this;if(t.prototype.updateOptions.call(this,e),null!=e&&e.cursors&&(this.cursors=r({},this.cursors,e.cursors)),null===(null==e?void 0:e.keyEvents)?this.keyEvents={cancel:null,finish:null}:null!=e&&e.keyEvents&&(this.keyEvents=r({},this.keyEvents,e.keyEvents)),null!=e&&e.snapping&&(this.snapping=e.snapping),void 0!==(null==e?void 0:e.editable)&&(this.editable=e.editable),void 0!==(null==e?void 0:e.pointerEvents)&&(this.pointerEvents=e.pointerEvents),void 0!==(null==e?void 0:e.showCoordinatePoints))if(this.showCoordinatePoints=e.showCoordinatePoints,this.coordinatePoints&&!0===e.showCoordinatePoints)this.store.copyAllWhere(function(t){return t.mode===i.mode}).filter(function(t){return"Polygon"===t.geometry.type}).forEach(function(t){i.coordinatePoints.createOrUpdate({featureId:t.id,featureCoordinates:t.geometry.coordinates})});else if(this.coordinatePoints&&!1===this.showCoordinatePoints){var n=this.store.copyAllWhere(function(t){return t.mode===i.mode&&Boolean(t[y.COORDINATE_POINT_IDS])}).filter(function(t){return"Polygon"===t.geometry.type});this.coordinatePoints.deletePointsByFeatureIds(n.map(function(t){return t.id}))}},i.close=function(){var t;if(void 0!==this.currentId&&!(this.readFeature.getCoordinates(this.currentId).length<5)){var e=this.mutateFeature.updatePolygon({featureId:this.currentId,coordinateMutations:[{type:it,index:-2}],propertyMutations:(t={},t[y.CURRENTLY_DRAWING]=void 0,t[y.COMMITTED_COORDINATE_COUNT]=void 0,t[y.PROVISIONAL_COORDINATE_COUNT]=void 0,t),context:{updateType:u.Finish,action:h}});if(e){this.showCoordinatePoints&&this.coordinatePoints.createOrUpdate({featureId:this.currentId,featureCoordinates:e.geometry.coordinates}),"drawing"===this.state&&this.setStarted(),this.editedPointId&&(this.mutateFeature.deleteFeatureIfPresent(this.editedPointId),this.editedPointId=void 0),this.snappedPointId&&(this.mutateFeature.deleteFeatureIfPresent(this.snappedPointId),this.snappedPointId=void 0),this.closingPoints.delete();var i=this.currentId;this.currentCoordinate=0,this.currentId=void 0,this.undoRedo.clear(),this.onFinish(i,{mode:this.mode,action:h})}}},i.registerBehaviors=function(t){this.readFeature=new ht(t),this.mutateFeature=new ot(t,{validate:this.validate}),this.clickBoundingBox=new ft(t),this.pixelDistance=new yt(t),this.lineSnapping=new _t(t,this.pixelDistance,this.clickBoundingBox),this.coordinateSnapping=new vt(t,this.pixelDistance,this.clickBoundingBox),this.featureSnapping=new Tt(this.coordinateSnapping,this.lineSnapping),this.closingPoints=new Wt(t,this.pixelDistance,this.mutateFeature,this.readFeature),this.coordinatePoints=new Ut(t,this.readFeature,this.mutateFeature),this.undoRedo=new At({maxStackSize:t.undoRedoMaxStackSize})},i.start=function(){this.setStarted(),this.setCursor(this.cursors.start)},i.stop=function(){this.cleanUp(),this.setStopped(),this.setCursor("unset")},i.updateSnappedCoordinate=function(t){var e=this.snapCoordinate(t);e?(this.snappedPointId?this.mutateFeature.updateGuidancePoints([{featureId:this.snappedPointId,coordinate:e}]):this.snappedPointId=this.mutateFeature.createGuidancePoint({coordinate:e,type:y.SNAPPING_POINT}),t.lng=e[0],t.lat=e[1]):this.snappedPointId&&(this.mutateFeature.deleteFeatureIfPresent(this.snappedPointId),this.snappedPointId=void 0)},i.undoSize=function(){return this.undoRedo.undoSize()},i.clearHistory=function(){this.undoRedo.clear()},i.pushHistorySnapshot=function(t,e){var i=this.readFeature.getGeometry(t);this.undoRedo.recordSnapshot({featureCoordinates:i.coordinates,currentCoordinate:e})},i.updateSnappedGuidancePointFromLastMouseMove=function(){this.snapping&&this.lastMouseMoveEvent?this.updateSnappedCoordinate(this.lastMouseMoveEvent):this.snappedPointId&&(this.mutateFeature.deleteFeatureIfPresent(this.snappedPointId),this.snappedPointId=void 0)},i.syncClosingPoints=function(t){this.currentCoordinate>=3?this.closingPoints.ids.length?this.closingPoints.update(t):this.closingPoints.create(t):this.closingPoints.delete()},i.undo=function(){var t;if("drawing"===this.state&&this.currentId){var e=this.undoRedo.beginUndo();if(e){var i=e.previousEntry;if(!i){var n=this.currentId;return this.currentId=void 0,this.currentCoordinate=0,this.closingPoints.delete(),"drawing"===this.state&&this.setStarted(),this.showCoordinatePoints&&this.coordinatePoints.deletePointsByFeatureIds([n]),this.mutateFeature.deleteFeatureIfPresent(n),void this.updateSnappedGuidancePointFromLastMouseMove()}var o=this.mutateFeature.updatePolygon({featureId:this.currentId,coordinateMutations:{type:nt,coordinates:i.featureCoordinates},propertyMutations:(t={},t[y.CURRENTLY_DRAWING]=!0,t[y.COMMITTED_COORDINATE_COUNT]=i.currentCoordinate,t[y.PROVISIONAL_COORDINATE_COUNT]=i.currentCoordinate,t),context:{updateType:u.Commit}});o&&(this.currentCoordinate=i.currentCoordinate,this.syncClosingPoints(o.geometry.coordinates),this.showCoordinatePoints&&this.coordinatePoints.createOrUpdate({featureId:this.currentId,featureCoordinates:o.geometry.coordinates}),this.updateSnappedGuidancePointFromLastMouseMove())}}},i.redoSize=function(){return this.undoRedo.redoSize()},i.redo=function(){var t=this.undoRedo.takeRedo();if(t){if(this.currentId){var e,i=this.mutateFeature.updatePolygon({featureId:this.currentId,coordinateMutations:{type:nt,coordinates:t.featureCoordinates},propertyMutations:(e={},e[y.CURRENTLY_DRAWING]=!0,e[y.COMMITTED_COORDINATE_COUNT]=t.currentCoordinate,e[y.PROVISIONAL_COORDINATE_COUNT]=t.currentCoordinate,e),context:{updateType:u.Commit}});if(!i)return;this.currentCoordinate=t.currentCoordinate,this.syncClosingPoints(i.geometry.coordinates),this.showCoordinatePoints&&this.coordinatePoints.createOrUpdate({featureId:this.currentId,featureCoordinates:i.geometry.coordinates})}else{var n,o=this.undoRedo.cloneCoordinates(t.featureCoordinates)[0],r=this.mutateFeature.createPolygon({coordinates:o,properties:(n={mode:this.mode},n[y.CURRENTLY_DRAWING]=!0,n[y.COMMITTED_COORDINATE_COUNT]=t.currentCoordinate,n[y.PROVISIONAL_COORDINATE_COUNT]=t.currentCoordinate,n)}),s=r.id,a=r.geometry;this.currentId=s,this.currentCoordinate=t.currentCoordinate,"started"===this.state&&this.setDrawing(),this.syncClosingPoints(a.coordinates),this.showCoordinatePoints&&this.coordinatePoints.createOrUpdate({featureId:s,featureCoordinates:a.coordinates})}this.undoRedo.commitRedo(t),this.updateSnappedGuidancePointFromLastMouseMove()}},i.onMouseMove=function(t){var e;if(this.mouseMove=!0,this.setCursor(this.cursors.start),this.lastMouseMoveEvent=t,this.updateSnappedCoordinate(t),void 0!==this.currentId&&0!==this.currentCoordinate){var i,n=this.readFeature.getCoordinate(this.currentId,0),o=[t.lng,t.lat];if(1===this.currentCoordinate)i=[{type:et,index:1,coordinate:o},{type:et,index:2,coordinate:[t.lng,t.lat]}];else if(2===this.currentCoordinate)i=[{type:et,index:2,coordinate:o}];else{var r=this.closingPoints.isPolygonClosingPoints(t);r.isPreviousClosing||r.isClosing?(this.snappedPointId&&(this.mutateFeature.deleteFeatureIfPresent(this.snappedPointId),this.snappedPointId=void 0),this.setCursor(this.cursors.close),i=[{type:et,index:-1,coordinate:n},{type:et,index:-2,coordinate:n}]):i=[{type:et,index:-2,coordinate:o},{type:et,index:-1,coordinate:n}]}var s=this.mutateFeature.updatePolygon({featureId:this.currentId,coordinateMutations:i,propertyMutations:(e={},e[y.PROVISIONAL_COORDINATE_COUNT]=this.currentCoordinate+1,e),context:{updateType:u.Provisional}});s&&this.showCoordinatePoints&&this.coordinatePoints.createOrUpdate({featureId:this.currentId,featureCoordinates:s.geometry.coordinates})}},i.snapCoordinate=function(t){var e,i,n,o,r,s,a=this,d=void 0;if(null!=(e=this.snapping)&&e.toLine&&(r=this.currentId?this.lineSnapping.getSnappableCoordinate(t,this.currentId):this.lineSnapping.getSnappableCoordinateFirstClick(t))&&(d=r),null!=(i=this.snapping)&&i.toCoordinate&&(s=this.currentId?this.coordinateSnapping.getSnappableCoordinate(t,this.currentId):this.coordinateSnapping.getSnappableCoordinateFirstClick(t))&&(d=s),null!=(n=this.snapping)&&n.toFeature){var u,h=this.featureSnapping.getSnappable(t,this.currentId,null==(u=this.snapping)?void 0:u.toFeature.filter,{toLine:this.snapping.toFeature.toLine,toCoordinate:this.snapping.toFeature.toCoordinate});h.coordinate&&(d=h.coordinate)}if(null!=(o=this.snapping)&&o.toCustom){var l=this.snapping.toCustom(t,{currentCoordinate:this.currentCoordinate,currentId:this.currentId,getCurrentGeometrySnapshot:this.currentId?function(){return a.readFeature.getGeometry(a.currentId)}:function(){return null},project:this.project,unproject:this.unproject});l&&(d=l)}return d},i.polygonFilter=function(t){return Boolean("Polygon"===t.geometry.type&&t.properties&&t.properties.mode===this.mode)},i.onRightClick=function(t){var e=this;if(this.editable&&"started"===this.state){var i=this.coordinateSnapping.getSnappable(t,function(t){return e.polygonFilter(t)}),n=i.featureId,o=i.featureCoordinateIndex;if(n&&void 0!==o){var r=this.readFeature.getGeometry(n);if("Polygon"===r.type){var s=r.coordinates[0];if(!(s.length<=4)){var a=this.mutateFeature.updatePolygon({featureId:n,coordinateMutations:0===o||o===s.length-1?[{type:it,index:0},{type:it,index:-1},{type:tt,index:-1,coordinate:s[1]}]:[{type:it,index:o}],context:{updateType:u.Finish,action:l}});if(a){if(this.showCoordinatePoints&&this.coordinatePoints.createOrUpdate({featureId:n,featureCoordinates:a.geometry.coordinates}),this.snappedPointId&&(this.mutateFeature.deleteFeatureIfPresent(this.snappedPointId),this.snappedPointId=void 0,this.snapping)){var d=this.snapCoordinate(t);if(d){var h=this.mutateFeature.createGuidancePoints({type:y.SNAPPING_POINT,coordinates:[d]});this.snappedPointId=h[0]}}this.onFinish(n,{mode:this.mode,action:l})}}}}}},i.onLeftClick=function(t){this.snappedPointId&&(this.mutateFeature.deleteFeatureIfPresent(this.snappedPointId),this.snappedPointId=void 0);var e=this.snapCoordinate(t)||[t.lng,t.lat];if(0===this.currentCoordinate){var i,n=this.mutateFeature.createPolygon({coordinates:[e,e,e,e],properties:(i={mode:this.mode},i[y.CURRENTLY_DRAWING]=!0,i[y.COMMITTED_COORDINATE_COUNT]=this.currentCoordinate+1,i[y.PROVISIONAL_COORDINATE_COUNT]=this.currentCoordinate+1,i)}),o=n.id;this.showCoordinatePoints&&this.coordinatePoints.createOrUpdate({featureId:o,featureCoordinates:n.geometry.coordinates}),this.currentId=o,this.currentCoordinate++,this.pushHistorySnapshot(this.currentId,this.currentCoordinate),this.setDrawing()}else if(1===this.currentCoordinate&&this.currentId){var r;if(this.readFeature.coordinateAtIndexIsIdentical({featureId:this.currentId,newCoordinate:e,index:0}))return;var s=this.mutateFeature.updatePolygon({featureId:this.currentId,coordinateMutations:[{type:et,index:1,coordinate:e},{type:et,index:2,coordinate:e}],propertyMutations:(r={},r[y.COMMITTED_COORDINATE_COUNT]=this.currentCoordinate+1,r),context:{updateType:u.Commit}});if(!s)return;this.showCoordinatePoints&&this.coordinatePoints.createOrUpdate({featureId:this.currentId,featureCoordinates:s.geometry.coordinates}),this.currentCoordinate++,this.pushHistorySnapshot(this.currentId,this.currentCoordinate)}else if(2===this.currentCoordinate&&this.currentId){var a;if(this.readFeature.coordinateAtIndexIsIdentical({featureId:this.currentId,newCoordinate:e,index:1}))return;var d=this.mutateFeature.updatePolygon({featureId:this.currentId,coordinateMutations:[{type:et,index:2,coordinate:e},{type:tt,index:2,coordinate:e}],propertyMutations:(a={},a[y.COMMITTED_COORDINATE_COUNT]=this.currentCoordinate+1,a),context:{updateType:u.Commit}});if(!d)return;this.showCoordinatePoints&&this.coordinatePoints.createOrUpdate({featureId:this.currentId,featureCoordinates:d.geometry.coordinates}),2===this.currentCoordinate&&this.closingPoints.create(d.geometry.coordinates),this.currentCoordinate++,this.pushHistorySnapshot(this.currentId,this.currentCoordinate)}else if(this.currentId){var h=this.closingPoints.isPolygonClosingPoints(t);if(h.isPreviousClosing||h.isClosing)this.close();else{var l;if(this.readFeature.coordinateAtIndexIsIdentical({featureId:this.currentId,newCoordinate:e,index:this.currentCoordinate-1}))return;var c=this.mutateFeature.updatePolygon({featureId:this.currentId,coordinateMutations:[{type:Q,index:-1,coordinate:e}],propertyMutations:(l={},l[y.COMMITTED_COORDINATE_COUNT]=this.currentCoordinate+1,l),context:{updateType:u.Commit}});if(!c)return;this.showCoordinatePoints&&this.coordinatePoints.createOrUpdate({featureId:this.currentId,featureCoordinates:c.geometry.coordinates}),this.currentCoordinate++,this.pushHistorySnapshot(this.currentId,this.currentCoordinate),this.closingPoints.ids.length&&this.closingPoints.update(c.geometry.coordinates)}}},i.onClick=function(t){this.currentCoordinate>0&&!this.mouseMove&&this.onMouseMove(t),this.mouseMove=!1,"right"===t.button&&this.allowPointerEvent(this.pointerEvents.rightClick,t)||t.isContextMenu&&this.allowPointerEvent(this.pointerEvents.contextMenu,t)?this.onRightClick(t):"left"===t.button&&this.allowPointerEvent(this.pointerEvents.leftClick,t)&&this.onLeftClick(t)},i.onKeyUp=function(t){t.key===this.keyEvents.cancel?this.cleanUp():t.key===this.keyEvents.finish&&this.close()},i.onKeyDown=function(){},i.onDragStart=function(t,e){var i=this;if(this.allowPointerEvent(this.pointerEvents.onDragStart,t)&&this.editable){var n=void 0;if("started"===this.state){var o=this.lineSnapping.getSnappable(t,function(t){return i.polygonFilter(t)});o.coordinate&&(this.editedSnapType="line",this.editedFeatureCoordinateIndex=o.featureCoordinateIndex,this.editedFeatureId=o.featureId,n=o.coordinate);var r=this.coordinateSnapping.getSnappable(t,function(t){return i.polygonFilter(t)});r.coordinate&&(this.editedSnapType="coordinate",this.editedFeatureCoordinateIndex=r.featureCoordinateIndex,this.editedFeatureId=r.featureId,n=r.coordinate)}this.editedFeatureId&&n&&(this.editedPointId||(this.editedPointId=this.mutateFeature.createGuidancePoint({coordinate:n,type:y.EDITED})),this.setCursor(this.cursors.dragStart),e(!1))}},i.onDrag=function(t,e){var i;if(this.allowPointerEvent(this.pointerEvents.onDrag,t)&&void 0!==this.editedFeatureId&&void 0!==this.editedFeatureCoordinateIndex){var n=this.readFeature.getGeometry(this.editedFeatureId),o=[t.lng,t.lat],r=[];if("coordinate"===this.editedSnapType||"line"===this.editedSnapType&&void 0!==this.editedInsertIndex?r=0===this.editedFeatureCoordinateIndex||this.editedFeatureCoordinateIndex===n.coordinates[0].length-1?[{type:et,index:0,coordinate:o},{type:et,index:-1,coordinate:o}]:[{type:et,index:this.editedFeatureCoordinateIndex,coordinate:o}]:"line"===this.editedSnapType&&void 0===this.editedInsertIndex&&(this.editedInsertIndex=this.editedFeatureCoordinateIndex+1,r=[{type:Q,index:this.editedInsertIndex,coordinate:o}],this.editedFeatureCoordinateIndex++),0!==r.length){var s=this.mutateFeature.updatePolygon({featureId:this.editedFeatureId,coordinateMutations:r,propertyMutations:(i={},i[y.EDITED]=!0,i),context:{updateType:u.Provisional}});s&&(this.showCoordinatePoints&&(this.editedInsertIndex?this.coordinatePoints.createOrUpdate({featureId:this.editedFeatureId,featureCoordinates:s.geometry.coordinates}):this.coordinatePoints.updateOneAtIndex(this.editedFeatureId,this.editedFeatureCoordinateIndex,s.geometry.coordinates[0][this.editedFeatureCoordinateIndex])),this.snapping&&this.snappedPointId&&(this.mutateFeature.deleteFeatureIfPresent(this.snappedPointId),this.snappedPointId=void 0),this.editedPointId&&this.mutateFeature.updateGuidancePoints([{featureId:this.editedPointId,coordinate:o}]))}}},i.onDragEnd=function(t,e){var i;if(this.allowPointerEvent(this.pointerEvents.onDragEnd,t)&&void 0!==this.editedFeatureId&&(this.setCursor(this.cursors.dragEnd),this.mutateFeature.updatePolygon({featureId:this.editedFeatureId,propertyMutations:(i={},i[y.EDITED]=!1,i),context:{updateType:u.Finish,action:l}}))){var n=this.editedFeatureId;this.editedPointId&&(this.mutateFeature.deleteFeatureIfPresent(this.editedPointId),this.editedPointId=void 0),this.snappedPointId&&(this.mutateFeature.deleteFeatureIfPresent(this.snappedPointId),this.snappedPointId=void 0),this.editedFeatureId=void 0,this.editedFeatureCoordinateIndex=void 0,this.editedInsertIndex=void 0,this.editedSnapType=void 0,e(!0),this.onFinish(n,{mode:this.mode,action:l})}},i.cleanUp=function(){var t=this.currentId,e=this.snappedPointId,i=this.editedPointId;this.currentId=void 0,this.snappedPointId=void 0,this.editedPointId=void 0,this.editedFeatureId=void 0,this.editedFeatureCoordinateIndex=void 0,this.editedInsertIndex=void 0,this.editedSnapType=void 0,this.currentCoordinate=0,this.undoRedo.clear(),"drawing"===this.state&&this.setStarted(),t&&this.coordinatePoints.deletePointsByFeatureIds([t]),this.mutateFeature.deleteFeatureIfPresent(t),this.mutateFeature.deleteFeatureIfPresent(i),this.mutateFeature.deleteFeatureIfPresent(e),this.closingPoints.ids.length&&this.closingPoints.delete()},i.styleFeature=function(t){var e=r({},{polygonFillColor:"#3f97e0",polygonOutlineColor:"#3f97e0",polygonOutlineWidth:4,polygonOutlineOpacity:1,polygonFillOpacity:.3,pointColor:"#3f97e0",pointOpacity:1,pointOutlineColor:"#ffffff",pointOutlineOpacity:1,pointOutlineWidth:0,pointWidth:6,lineStringColor:"#3f97e0",lineStringWidth:4,lineStringOpacity:1,zIndex:0,markerUrl:void 0,markerHeight:void 0,markerWidth:void 0,lineStringDash:void 0});if(t.properties.mode===this.mode){if("Polygon"===t.geometry.type)return e.polygonFillColor=this.getHexColorStylingValue(this.styles.fillColor,e.polygonFillColor,t),e.polygonOutlineColor=this.getHexColorStylingValue(this.styles.outlineColor,e.polygonOutlineColor,t),e.polygonOutlineWidth=this.getNumericStylingValue(this.styles.outlineWidth,e.polygonOutlineWidth,t),e.polygonFillOpacity=this.getNumericStylingValue(this.styles.fillOpacity,e.polygonFillOpacity,t),e.polygonOutlineOpacity=this.getNumericStylingValue(this.styles.outlineOpacity,1,t),e.zIndex=v,e;if("Point"===t.geometry.type){var i=t.properties[y.EDITED],n=t.properties[y.COORDINATE_POINT],o=i?"editedPoint":t.properties[y.CLOSING_POINT]?"closingPoint":t.properties[y.SNAPPING_POINT]?"snappingPoint":n?"coordinatePoint":void 0;if(!o)return e;var s={editedPoint:{width:this.styles.editedPointOutlineWidth,color:this.styles.editedPointColor,opacity:this.styles.editedPointOpacity,outlineColor:this.styles.editedPointOutlineColor,outlineWidth:this.styles.editedPointOutlineWidth,outlineOpacity:this.styles.editedPointOutlineOpacity},closingPoint:{width:this.styles.closingPointWidth,color:this.styles.closingPointColor,opacity:this.styles.closingPointOpacity,outlineColor:this.styles.closingPointOutlineColor,outlineWidth:this.styles.closingPointOutlineWidth,outlineOpacity:this.styles.closingPointOutlineOpacity},snappingPoint:{width:this.styles.snappingPointWidth,color:this.styles.snappingPointColor,opacity:this.styles.snappingPointOpacity,outlineColor:this.styles.snappingPointOutlineColor,outlineWidth:this.styles.snappingPointOutlineWidth,outlineOpacity:this.styles.snappingPointOutlineOpacity},coordinatePoint:{width:this.styles.coordinatePointWidth,color:this.styles.coordinatePointColor,opacity:this.styles.coordinatePointOpacity,outlineColor:this.styles.coordinatePointOutlineColor,outlineWidth:this.styles.coordinatePointOutlineWidth,outlineOpacity:this.styles.coordinatePointOutlineOpacity}};return e.pointWidth=this.getNumericStylingValue(s[o].width,e.pointWidth,t),e.pointOpacity=this.getNumericStylingValue(s[o].opacity,1,t),e.pointColor=this.getHexColorStylingValue(s[o].color,e.pointColor,t),e.pointOutlineColor=this.getHexColorStylingValue(s[o].outlineColor,e.pointOutlineColor,t),e.pointOutlineOpacity=this.getNumericStylingValue(s[o].outlineOpacity,1,t),e.pointOutlineWidth=this.getNumericStylingValue(s[o].outlineWidth,2,t),e.zIndex=i?40:n?20:30,e}}return e},i.afterFeatureAdded=function(t){this.showCoordinatePoints&&this.coordinatePoints.createOrUpdate({featureId:t.id,featureCoordinates:t.geometry.coordinates})},i.afterFeatureUpdated=function(t){this.showCoordinatePoints&&this.coordinatePoints.createOrUpdate({featureId:t.id,featureCoordinates:t.geometry.coordinates}),this.editedFeatureId===t.id&&this.editedPointId&&(this.mutateFeature.deleteFeatureIfPresent(this.editedPointId),this.editedPointId=void 0,this.editedFeatureId=void 0,this.editedFeatureCoordinateIndex=void 0,this.editedSnapType=void 0),this.snappedPointId&&this.lastMouseMoveEvent&&this.updateSnappedCoordinate(this.lastMouseMoveEvent),this.currentId===t.id&&(this.currentCoordinate=0,this.currentId=void 0,this.undoRedo.clear(),this.closingPoints.delete(),"drawing"===this.state&&this.setStarted())},i.validateFeature=function(t){var e=this;return this.validateModeFeature(t,function(t){return q(t,e.coordinatePrecision)})},e}(O),ie={cancel:"Escape",finish:"Enter"},ne={start:"crosshair"},oe=/*#__PURE__*/function(t){function e(e){var i;return(i=t.call(this,e,!0)||this).mode="rectangle",i.startPosition=void 0,i.endPosition=void 0,i.currentRectangleId=void 0,i.keyEvents=ie,i.cursors=ne,i.drawInteraction="click-move",i.drawType=void 0,i.mutateFeature=void 0,i.readFeature=void 0,i.updateOptions(e),i}s(e,t);var i=e.prototype;return i.updateOptions=function(e){t.prototype.updateOptions.call(this,e),null!=e&&e.cursors&&(this.cursors=r({},this.cursors,e.cursors)),null===(null==e?void 0:e.keyEvents)?this.keyEvents={cancel:null,finish:null}:null!=e&&e.keyEvents&&(this.keyEvents=r({},this.keyEvents,e.keyEvents)),null!=e&&e.drawInteraction&&(this.drawInteraction=e.drawInteraction)},i.updateRectangle=function(t,e){var i;if(this.startPosition&&this.currentRectangleId){var n=e===u.Finish;return this.mutateFeature.updatePolygon({featureId:this.currentRectangleId,coordinateMutations:[{type:et,index:1,coordinate:[t[0],this.startPosition[1]]},{type:et,index:2,coordinate:t},{type:et,index:3,coordinate:[this.startPosition[0],t[1]]}],propertyMutations:n?(i={},i[y.CURRENTLY_DRAWING]=void 0,i):{},context:n?{updateType:e,action:h}:{updateType:e}})}},i.close=function(){if(this.currentRectangleId&&this.endPosition&&this.updateRectangle(this.endPosition,u.Finish)){var t=this.currentRectangleId;this.startPosition=void 0,this.currentRectangleId=void 0,this.drawType=void 0,"drawing"===this.state&&this.setStarted(),this.onFinish(t,{mode:this.mode,action:h})}},i.beginDrawing=function(t,e){var i;void 0===e&&(e="click"),this.startPosition=[t.lng,t.lat],this.endPosition=[t.lng,t.lat];var n=this.mutateFeature.createPolygon({coordinates:[[t.lng,t.lat],[t.lng,t.lat],[t.lng,t.lat],[t.lng,t.lat],[t.lng,t.lat]],properties:(i={mode:this.mode},i[y.CURRENTLY_DRAWING]=!0,i)});this.currentRectangleId=n.id,this.drawType=e,this.setDrawing()},i.moveDrawAllowed=function(){return"click-move"===this.drawInteraction||"click-move-or-drag"===this.drawInteraction},i.dragDrawAllowed=function(){return"click-drag"===this.drawInteraction||"click-move-or-drag"===this.drawInteraction},i.start=function(){this.setStarted(),this.setCursor(this.cursors.start)},i.stop=function(){this.cleanUp(),this.setStopped(),this.setCursor("unset")},i.onClick=function(t){this.moveDrawAllowed()&&("right"===t.button&&this.allowPointerEvent(this.pointerEvents.rightClick,t)||"left"===t.button&&this.allowPointerEvent(this.pointerEvents.leftClick,t)||t.isContextMenu&&this.allowPointerEvent(this.pointerEvents.contextMenu,t))&&(this.startPosition?(this.endPosition=[t.lng,t.lat],this.close()):this.beginDrawing(t))},i.onMouseMove=function(t){this.endPosition=[t.lng,t.lat],this.updateRectangle(this.endPosition,u.Provisional)},i.onKeyDown=function(){},i.onKeyUp=function(t){t.key===this.keyEvents.cancel?this.cleanUp():t.key===this.keyEvents.finish&&this.close()},i.onDragStart=function(t,e){"drawing"!==this.state&&this.allowPointerEvent(this.pointerEvents.onDragStart,t)&&this.dragDrawAllowed()&&(this.beginDrawing(t,"drag"),e(!1))},i.onDrag=function(t,e){this.allowPointerEvent(this.pointerEvents.onDrag,t)&&this.dragDrawAllowed()&&"drag"===this.drawType&&(this.endPosition=[t.lng,t.lat],this.updateRectangle(this.endPosition,u.Provisional))},i.onDragEnd=function(t,e){this.allowPointerEvent(this.pointerEvents.onDragEnd,t)&&this.dragDrawAllowed()&&"drag"===this.drawType&&(this.endPosition=[t.lng,t.lat],this.close(),e(!0))},i.cleanUp=function(){var t=this.currentRectangleId;this.startPosition=void 0,this.currentRectangleId=void 0,this.drawType=void 0,"drawing"===this.state&&this.setStarted(),this.mutateFeature.deleteFeatureIfPresent(t)},i.styleFeature=function(t){var e=r({},{polygonFillColor:"#3f97e0",polygonOutlineColor:"#3f97e0",polygonOutlineWidth:4,polygonOutlineOpacity:1,polygonFillOpacity:.3,pointColor:"#3f97e0",pointOpacity:1,pointOutlineColor:"#ffffff",pointOutlineOpacity:1,pointOutlineWidth:0,pointWidth:6,lineStringColor:"#3f97e0",lineStringWidth:4,lineStringOpacity:1,zIndex:0,markerUrl:void 0,markerHeight:void 0,markerWidth:void 0,lineStringDash:void 0});return"Feature"===t.type&&"Polygon"===t.geometry.type&&t.properties.mode===this.mode?(e.polygonFillColor=this.getHexColorStylingValue(this.styles.fillColor,e.polygonFillColor,t),e.polygonOutlineColor=this.getHexColorStylingValue(this.styles.outlineColor,e.polygonOutlineColor,t),e.polygonOutlineOpacity=this.getNumericStylingValue(this.styles.outlineOpacity,1,t),e.polygonOutlineWidth=this.getNumericStylingValue(this.styles.outlineWidth,e.polygonOutlineWidth,t),e.polygonFillOpacity=this.getNumericStylingValue(this.styles.fillOpacity,e.polygonFillOpacity,t),e.zIndex=v,e):e},i.validateFeature=function(t){var e=this;return this.validateModeFeature(t,function(t){return Z(t,e.coordinatePrecision)})},i.afterFeatureUpdated=function(t){this.currentRectangleId===t.id&&(this.startPosition=void 0,this.currentRectangleId=void 0,this.drawType=void 0,"drawing"===this.state&&this.setStarted())},i.registerBehaviors=function(t){this.readFeature=new ht(t),this.mutateFeature=new ot(t,{validate:this.validate})},e}(O),re=/*#__PURE__*/function(t){function e(e){var i;if(!e.modeName)throw new Error("Mode name is required for TerraDrawRenderMode");return(i=t.call(this,e,!0)||this).type=I.Render,i.mode="render",i.updateOptions(e),i}s(e,t);var i=e.prototype;return i.updateOptions=function(e){t.prototype.updateOptions.call(this,e)},i.registerBehaviors=function(t){this.mode=t.mode},i.start=function(){this.setStarted()},i.stop=function(){this.setStopped()},i.onKeyUp=function(){},i.onKeyDown=function(){},i.onClick=function(){},i.onDragStart=function(){},i.onDrag=function(){},i.onDragEnd=function(){},i.onMouseMove=function(){},i.cleanUp=function(){},i.styleFeature=function(t){return{pointColor:this.getHexColorStylingValue(this.styles.pointColor,"#3f97e0",t),pointWidth:this.getNumericStylingValue(this.styles.pointWidth,6,t),pointOpacity:this.getNumericStylingValue(this.styles.pointOpacity,1,t),pointOutlineColor:this.getHexColorStylingValue(this.styles.pointOutlineColor,"#ffffff",t),pointOutlineWidth:this.getNumericStylingValue(this.styles.pointOutlineWidth,0,t),pointOutlineOpacity:this.getNumericStylingValue(this.styles.pointOutlineOpacity,1,t),polygonFillColor:this.getHexColorStylingValue(this.styles.polygonFillColor,"#3f97e0",t),polygonFillOpacity:this.getNumericStylingValue(this.styles.polygonFillOpacity,.3,t),polygonOutlineColor:this.getHexColorStylingValue(this.styles.polygonOutlineColor,"#3f97e0",t),polygonOutlineWidth:this.getNumericStylingValue(this.styles.polygonOutlineWidth,4,t),lineStringWidth:this.getNumericStylingValue(this.styles.lineStringWidth,4,t),lineStringColor:this.getHexColorStylingValue(this.styles.lineStringColor,"#3f97e0",t),lineStringOpacity:this.getNumericStylingValue(this.styles.lineStringOpacity,1,t),zIndex:this.getNumericStylingValue(this.styles.zIndex,0,t),lineStringDash:void 0}},i.validateFeature=function(e){var i=t.prototype.validateFeature.call(this,e);if(i.valid){var n=e,o=qt(n,this.coordinatePrecision).valid||q(n,this.coordinatePrecision).valid||wt(n,this.coordinatePrecision).valid;return o?{valid:!0}:{valid:o,reason:"Feature is not a valid Point, Polygon or LineString feature"}}return i},e}(O);function se(t,e){var i=t,n=e,o=D(i[1]),r=D(n[1]),s=D(n[0]-i[0]);s>Math.PI&&(s-=2*Math.PI),s<-Math.PI&&(s+=2*Math.PI);var a=Math.log(Math.tan(r/2+Math.PI/4)/Math.tan(o/2+Math.PI/4)),d=(b(Math.atan2(s,a))+360)%360;return d>180?-(360-d):d}function ae(t,e,i){var n=e;e<0&&(n=-Math.abs(n));var o=n/E,r=t[0]*Math.PI/180,s=D(t[1]),a=D(i),d=o*Math.cos(a),u=s+d;Math.abs(u)>Math.PI/2&&(u=u>0?Math.PI-u:-Math.PI-u);var h=Math.log(Math.tan(u/2+Math.PI/4)/Math.tan(s/2+Math.PI/4)),l=Math.abs(h)>1e-11?d/h:Math.cos(s),c=[(180*(r+o*Math.sin(a)/l)/Math.PI+540)%360-180,180*u/Math.PI];return c[0]+=c[0]-t[0]>180?-360:t[0]-c[0]>180?360:0,c}function de(t,e,i,n,o){var r=n(t[0],t[1]),s=n(e[0],e[1]),a=o((r.x+s.x)/2,(r.y+s.y)/2),d=a.lat;return[_(a.lng,i),_(d,i)]}function ue(t,e,i){var n=ae(t,1e3*w(t,e)/2,se(t,e));return[_(n[0],i),_(n[1],i)]}function he(t){for(var e=t.featureCoords,i=t.precision,n=t.unproject,o=t.project,r=t.projection,s=[],a=0;a(i=t)[1]!=(o=d[l])[1]>i[1]&&i[0]<(o[0]-n[0])*(i[1]-n[1])/(o[1]-n[1])+n[0]&&(r=!r);return r}var ge=function(t,e,i){var n=function(t){return t*t},o=function(t,e){return n(t.x-e.x)+n(t.y-e.y)};return Math.sqrt(function(t,e,i){var n=o(e,i);if(0===n)return o(t,e);var r=((t.x-e.x)*(i.x-e.x)+(t.y-e.y)*(i.y-e.y))/n;return r=Math.max(0,Math.min(1,r)),o(t,{x:e.x+r*(i.x-e.x),y:e.y+r*(i.y-e.y)})}(t,e,i))},fe=/*#__PURE__*/function(t){function e(e,i,n){var o;return(o=t.call(this,e)||this).config=void 0,o.createClickBoundingBox=void 0,o.pixelDistance=void 0,o.config=e,o.createClickBoundingBox=i,o.pixelDistance=n,o}return s(e,t),e.prototype.find=function(t,e){for(var i=void 0,n=Infinity,o=void 0,r=Infinity,s=void 0,a=this.createClickBoundingBox.create(t),d=this.store.search(a),u=0;u180||a<-180||d>90||d<-90)return!1;n[r]=[a,d]}"Polygon"===e.type&&(n[n.length-1]=[n[0][0],n[0][1]]);var y=this.draggedFeatureId,v=null;if("Polygon"===e.type)v=this.mutateFeature.updatePolygon({featureId:y,coordinateMutations:{type:nt,coordinates:[n]},context:{updateType:u.Provisional}});else{if("LineString"!==e.type)return;v=this.mutateFeature.updateLineString({featureId:y,coordinateMutations:{type:nt,coordinates:n},context:{updateType:u.Provisional}})}if(!v)return!1;var m=v.geometry.coordinates;this.midPoints.updateAllInPlace({featureCoordinates:m}),this.selectionPoints.updateAllInPlace({featureCoordinates:m}),this.coordinatePoints.updateAllInPlace({featureId:y,featureCoordinates:m}),this.dragPosition=[t.lng,t.lat]}else"Point"===e.type&&(this.mutateFeature.updatePoint({featureId:this.draggedFeatureId,coordinateMutations:{type:nt,coordinates:i},context:{updateType:u.Provisional}}),this.dragPosition=[t.lng,t.lat])}},e}(J),ve=/*#__PURE__*/function(t){function e(e,i,n,o,r,s,a,d,u){var h;return(h=t.call(this,e)||this).config=void 0,h.pixelDistance=void 0,h.selectionPoints=void 0,h.midPoints=void 0,h.coordinatePoints=void 0,h.coordinateSnapping=void 0,h.lineSnapping=void 0,h.readFeature=void 0,h.mutateFeature=void 0,h.featureSnapping=void 0,h.draggedCoordinate={id:null,index:-1},h.config=e,h.pixelDistance=i,h.selectionPoints=n,h.midPoints=o,h.coordinatePoints=r,h.coordinateSnapping=s,h.lineSnapping=a,h.readFeature=d,h.mutateFeature=u,h.featureSnapping=new Tt(h.coordinateSnapping,h.lineSnapping),h}s(e,t);var i=e.prototype;return i.getClosestCoordinate=function(t,e){var i,n={dist:Infinity,index:-1,isFirstOrLastPolygonCoord:!1};if("LineString"===e.type)i=e.coordinates;else{if("Polygon"!==e.type)return n;i=e.coordinates[0]}for(var o=0;o180||t.lng<-180||t.lat>90||t.lat<-90)return!1;if(d){var l=a.length-1;a[0]=h,a[l]=h}else a[o]=h;if("Point"!==r.type&&!e&&B({type:"Feature",geometry:r,properties:{}}))return!1;var c=n,p=null;return"Polygon"===r.type?p=this.mutateFeature.updatePolygon({featureId:c,coordinateMutations:{type:nt,coordinates:[a]},context:{updateType:u.Provisional}}):"LineString"===r.type&&(p=this.mutateFeature.updateLineString({featureId:c,coordinateMutations:{type:nt,coordinates:a},context:{updateType:u.Provisional}})),!!p&&(this.midPoints.updateOneAtIndex(o>0?o-1:-1,a),this.midPoints.updateOneAtIndex(o,a),this.selectionPoints.updateOneAtIndex(o,h),this.coordinatePoints.updateOneAtIndex(c,o,h),!0)},i.isDragging=function(){return null!==this.draggedCoordinate.id},i.startDragging=function(t,e){this.draggedCoordinate={id:t,index:e}},i.stopDragging=function(){this.draggedCoordinate={id:null,index:-1}},e}(J);function me(t){var e=0,i=0,n=0;return("Polygon"===t.geometry.type?t.geometry.coordinates[0].slice(0,-1):t.geometry.coordinates).forEach(function(t){e+=t[0],i+=t[1],n++},!0),[e/n,i/n]}var Ce=function(t,e){if(0===e||360===e||-360===e)return t;var i=.017453292519943295*e,n=("Polygon"===t.geometry.type?t.geometry.coordinates[0]:t.geometry.coordinates).map(function(t){return L(t[0],t[1])}),o=n.reduce(function(t,e){return{x:t.x+e.x,y:t.y+e.y}},{x:0,y:0});o.x/=n.length,o.y/=n.length;var r=n.map(function(t){return{x:o.x+(t.x-o.x)*Math.cos(i)-(t.y-o.y)*Math.sin(i),y:o.y+(t.x-o.x)*Math.sin(i)+(t.y-o.y)*Math.cos(i)}}).map(function(t){var e=t.x,i=t.y;return[W(e,i).lng,W(e,i).lat]});return"Polygon"===t.geometry.type?t.geometry.coordinates[0]=r:t.geometry.coordinates=r,t};function Pe(t){var e=("Polygon"===t.geometry.type?t.geometry.coordinates[0]:t.geometry.coordinates).map(function(t){var e=L(t[0],t[1]);return[e.x,e.y]});return"Polygon"===t.geometry.type?function(t){for(var e=0,i=0,n=0,o=t.length,r=0;r180?-360:e[0]-t[0]>180?360:0;var i=E,n=e[1]*Math.PI/180,o=t[1]*Math.PI/180,r=o-n,s=Math.abs(t[0]-e[0])*Math.PI/180;s>Math.PI&&(s-=2*Math.PI);var a=Math.log(Math.tan(o/2+Math.PI/4)/Math.tan(n/2+Math.PI/4)),d=Math.abs(a)>1e-11?r/a:Math.cos(n);return Math.sqrt(r*r+d*d*s*s)*i}(i,t),r=ae(i,o,n);t[0]=r[0],t[1]=r[1]})}(s,-(this.lastBearing-(o+180)))}var d="Polygon"===n.type?n.coordinates[0]:n.coordinates;d.forEach(function(t){t[0]=_(t[0],i.coordinatePrecision),t[1]=_(t[1],i.coordinatePrecision)});var h={featureId:e,coordinateMutations:{type:nt,coordinates:"Polygon"===n.type?[d]:d},context:{updateType:u.Provisional}},l=null;if("Polygon"===s.geometry.type)l=this.mutateFeature.updatePolygon(h);else{if("LineString"!==s.geometry.type)return;l=this.mutateFeature.updateLineString(h)}if(!l)return!1;var c=l.geometry.coordinates;this.midPoints.updateAllInPlace({featureCoordinates:c}),this.selectionPoints.updateAllInPlace({featureCoordinates:c}),this.coordinatePoints.updateAllInPlace({featureId:e,featureCoordinates:c}),"web-mercator"===this.projection?this.lastBearing=o:"globe"===this.projection&&(this.lastBearing=o+180)}},e}(J),Se=/*#__PURE__*/function(t){function e(e,i){var n;return(n=t.call(this,e)||this).config=void 0,n.dragCoordinateResizeBehavior=void 0,n.config=e,n.dragCoordinateResizeBehavior=i,n}s(e,t);var i=e.prototype;return i.scale=function(t,e){if(!this.dragCoordinateResizeBehavior.isDragging()){var i=this.dragCoordinateResizeBehavior.getDraggableIndex(t,e);this.dragCoordinateResizeBehavior.startDragging(e,i)}this.dragCoordinateResizeBehavior.drag(t,"center-fixed")},i.reset=function(){this.dragCoordinateResizeBehavior.stopDragging()},e}(J);function Fe(t){var e=t.originX,i=t.originY,n=t.xScale,o=t.yScale;1===n&&1===o||t.coordinates.forEach(function(t){var r=L(t[0],t[1]),s=W(e+(r.x-e)*n,i+(r.y-i)*o),a=s.lat;t[0]=s.lng,t[1]=a})}var xe=/*#__PURE__*/function(t){function e(e,i,n,o,r,s,a){var d;return(d=t.call(this,e)||this).config=void 0,d.pixelDistance=void 0,d.selectionPoints=void 0,d.midPoints=void 0,d.coordinatePoints=void 0,d.readFeature=void 0,d.mutateFeature=void 0,d.minimumScale=1e-4,d.draggedCoordinate={id:null,index:-1},d.boundingBoxMaps={opposite:{0:4,1:5,2:6,3:7,4:0,5:1,6:2,7:3}},d.config=e,d.pixelDistance=i,d.selectionPoints=n,d.midPoints=o,d.coordinatePoints=r,d.readFeature=s,d.mutateFeature=a,d}s(e,t);var i=e.prototype;return i.getClosestCoordinate=function(t,e){var i,n={dist:Infinity,index:-1,isFirstOrLastPolygonCoord:!1};if("LineString"===e.type)i=e.coordinates;else{if("Polygon"!==e.type)return n;i=e.coordinates[0]}for(var o=0;o=0)return!1;break;case 1:if(i>=0)return!1;break;case 2:if(e>=0||i>=0)return!1;break;case 3:if(e>=0)return!1;break;case 4:if(e>=0||i<=0)return!1;break;case 5:if(i<=0)return!1;break;case 6:if(e<=0||i<=0)return!1;break;case 7:if(e<=0)return!1}return!0},i.getSelectedFeatureDataWebMercator=function(){if(!this.draggedCoordinate.id||-1===this.draggedCoordinate.index)return null;var t=this.getFeature(this.draggedCoordinate.id);if(!t)return null;var e=this.getNormalisedCoordinates(t.geometry);return{boundingBox:this.getBBoxWebMercator(e),feature:t,updatedCoords:e,selectedCoordinate:e[this.draggedCoordinate.index]}},i.centerWebMercatorDrag=function(t){var e=this.getSelectedFeatureDataWebMercator();if(!e)return null;var i=e.boundingBox,n=e.updatedCoords,o=e.selectedCoordinate,r=Pe(e.feature);if(!r)return null;var s=L(o[0],o[1]),a=this.getIndexesWebMercator(i,s).closestBBoxIndex,d=L(t.lng,t.lat);return this.scaleWebMercator({closestBBoxIndex:a,updatedCoords:n,webMercatorCursor:d,webMercatorSelected:s,webMercatorOrigin:r}),n},i.centerFixedWebMercatorDrag=function(t){var e=this.getSelectedFeatureDataWebMercator();if(!e)return null;var i=e.boundingBox,n=e.updatedCoords,o=e.selectedCoordinate,r=Pe(e.feature);if(!r)return null;var s=L(o[0],o[1]),a=this.getIndexesWebMercator(i,s).closestBBoxIndex,d=L(t.lng,t.lat);return this.scaleFixedWebMercator({closestBBoxIndex:a,updatedCoords:n,webMercatorCursor:d,webMercatorSelected:s,webMercatorOrigin:r}),n},i.scaleFixedWebMercator=function(t){var e=t.webMercatorOrigin,i=t.webMercatorSelected,n=t.webMercatorCursor,o=t.updatedCoords;if(!this.isValidDragWebMercator(t.closestBBoxIndex,e.x-n.x,e.y-n.y))return null;var r=dt(e,n)/dt(e,i);return r<0&&(r=this.minimumScale),Fe({coordinates:o,originX:e.x,originY:e.y,xScale:r,yScale:r}),o},i.oppositeFixedWebMercatorDrag=function(t){var e=this.getSelectedFeatureDataWebMercator();if(!e)return null;var i=e.boundingBox,n=e.updatedCoords,o=e.selectedCoordinate,r=L(o[0],o[1]),s=this.getIndexesWebMercator(i,r),a=s.oppositeBboxIndex,d=s.closestBBoxIndex,u={x:i[a][0],y:i[a][1]},h=L(t.lng,t.lat);return this.scaleFixedWebMercator({closestBBoxIndex:d,updatedCoords:n,webMercatorCursor:h,webMercatorSelected:r,webMercatorOrigin:u}),n},i.oppositeWebMercatorDrag=function(t){var e=this.getSelectedFeatureDataWebMercator();if(!e)return null;var i=e.boundingBox,n=e.updatedCoords,o=e.selectedCoordinate,r=L(o[0],o[1]),s=this.getIndexesWebMercator(i,r),a=s.oppositeBboxIndex,d=s.closestBBoxIndex,u={x:i[a][0],y:i[a][1]},h=L(t.lng,t.lat);return this.scaleWebMercator({closestBBoxIndex:d,updatedCoords:n,webMercatorCursor:h,webMercatorSelected:r,webMercatorOrigin:u}),n},i.scaleWebMercator=function(t){var e=t.closestBBoxIndex,i=t.webMercatorOrigin,n=t.webMercatorSelected,o=t.webMercatorCursor,r=t.updatedCoords,s=i.x-o.x,a=i.y-o.y;if(!this.isValidDragWebMercator(e,s,a))return null;var d=1;0!==s&&1!==e&&5!==e&&(d=1-(i.x-n.x-s)/s);var u=1;return 0!==a&&3!==e&&7!==e&&(u=1-(i.y-n.y-a)/a),this.validateScale(d,u)?(d<0&&(d=this.minimumScale),u<0&&(u=this.minimumScale),this.performWebMercatorScale(r,i.x,i.y,d,u),r):null},i.getFeature=function(t){if(null===this.draggedCoordinate.id)return null;var e=this.readFeature.getGeometry(t);return"Polygon"!==e.type&&"LineString"!==e.type?null:{id:t,type:"Feature",geometry:e,properties:{}}},i.getNormalisedCoordinates=function(t){return"Polygon"===t.type?t.coordinates[0]:t.coordinates},i.validateScale=function(t,e){var i=!isNaN(t)&&ee[2]&&(e[2]=i),n>e[3]&&(e[3]=n)});var i=e[0],n=e[1],o=e[2],r=e[3];return[[i,r],[(i+o)/2,r],[o,r],[o,r+(n-r)/2],[o,n],[(i+o)/2,n],[i,n],[i,r+(n-r)/2]]},i.getIndexesWebMercator=function(t,e){for(var i,n=Infinity,o=0;o0).clickedFeature,i=this.midPoints.getNearestMidPoint(t),n=this.selected[0];if(n){var o,r=this.getSelectedFlags(n).featureFlags;if(null!=r&&null!=(o=r.coordinates)&&o.midpoints&&i){if(r.coordinates.draggable){var s=this.pixelDistance.measure(t,this.readFeature.getGeometry(i).coordinates),a=this.dragCoordinate.getDraggable(t,n).dist;if(void 0!==a&&s>a)return}return this.midPoints.insert({featureId:n,midPointId:i}),void this.onFinish(this.selected[0],{action:p,mode:this.mode})}}if(null!=e&&e.id)this.allowManualSelection&&this.select(e.id,!0);else if(this.selected.length&&this.allowManualDeselection)return void this.deselect(this.selected[0])},i.start=function(){this.setStarted(),this.setSelecting()},i.stop=function(){this.cleanUp(),this.setStarted(),this.setStopped()},i.onClick=function(t){"right"===t.button&&this.allowPointerEvent(this.pointerEvents.rightClick,t)||t.isContextMenu&&this.allowPointerEvent(this.pointerEvents.contextMenu,t)?this.onRightClick(t):"left"===t.button&&this.allowPointerEvent(this.pointerEvents.leftClick,t)&&this.onLeftClick(t)},i.canScale=function(t){return this.keyEvents.scale&&this.keyEvents.scale.every(function(e){return t.heldKeys.includes(e)})},i.canRotate=function(t){return this.keyEvents.rotate&&this.keyEvents.rotate.every(function(e){return t.heldKeys.includes(e)})},i.preventDefaultKeyEvent=function(t){var e=this.canRotate(t),i=this.canScale(t);(e||i)&&t.preventDefault()},i.onKeyDown=function(t){this.preventDefaultKeyEvent(t)},i.onKeyUp=function(t){if(this.preventDefaultKeyEvent(t),this.keyEvents.delete&&t.key===this.keyEvents.delete){if(!this.selected.length)return;var e=this.selected[0];this.onDeselect(this.selected[0]),this.coordinatePoints.deletePointsByFeatureIds([e]),this.deleteSelected(),this.selectionPoints.delete(),this.midPoints.delete()}else this.keyEvents.deselect&&t.key===this.keyEvents.deselect&&this.cleanUp()},i.cleanUp=function(){this.selected.length&&this.deselect(this.selected[0])},i.onDragStart=function(t,e){if(this.allowPointerEvent(this.pointerEvents.onDragStart,t)){var i=this.selected[0];if(i){var n=this.getSelectedFlags(i),o=n.featureFlags,r=n.coordinatesFlags;if(n.hasDraggableFlags){this.dragEventCount=0;var s="none"!==this.dragTarget.type&&this.dragTarget.featureId===i?this.dragTarget:{type:"none"},a="coordinate"===s.type?s.coordinateIndex:this.dragCoordinate.getDraggableIndex(t,i),d="resize"===s.type?s.coordinateIndex:this.dragCoordinateResizeFeature.getDraggableIndex(t,i),u=(null==r?void 0:r.resizable)&&-1!==d,h=(null==r?void 0:r.draggable)&&-1!==a,l=r&&"object"==typeof r.midpoints&&r.midpoints.draggable,c=(null==o?void 0:o.draggable)&&("feature"===s.type||this.dragFeature.canDrag(t,i));if(u)return this.setCursor(this.cursors.dragStart),this.dragCoordinateResizeFeature.startDragging(i,d),void e(!1);if(h)return this.setCursor(this.cursors.dragStart),this.dragCoordinate.startDragging(i,a),void e(!1);if(l){var g="midpoint"===s.type?s.midPointId:this.midPoints.getNearestMidPoint(t);if(this.selected.length&&g){this.midPoints.insert({featureId:i,midPointId:g}),this.onFinish(this.selected[0],{action:p,mode:this.mode});var f=this.dragCoordinate.getDraggableIndex(t,i);return this.dragCoordinate.startDragging(i,f),void e(!1)}}if(c)return this.setCursor(this.cursors.dragStart),this.dragFeature.startDragging(t,i),void e(!1);this.setCursor("unset")}}}},i.onDrag=function(t,e){if(this.allowPointerEvent(this.pointerEvents.onDrag,t)){var i=this.selected[0];if(i){var n=this.readFeature.getProperties(i),o=this.flags[n.mode],r=!0===(o&&o.feature&&o.feature.selfIntersectable);if(this.dragEventCount++,this.dragEventCount%this.dragEventThrottle!=0){if(o&&o.feature&&o.feature.rotateable&&this.canRotate(t))return e(!1),void this.rotateFeature.rotate(t,i);if(o&&o.feature&&o.feature.scaleable&&this.canScale(t))return e(!1),void this.scaleFeature.scale(t,i);if(this.dragCoordinateResizeFeature.isDragging()&&o.feature&&o.feature.coordinates&&o.feature.coordinates.resizable){if("globe"===this.projection)throw new Error("Globe is currently unsupported projection for resizable");return e(!1),void this.dragCoordinateResizeFeature.drag(t,o.feature.coordinates.resizable)}if(this.dragCoordinate.isDragging()){var s,a=null==(s=o.feature)||null==(s=s.coordinates)?void 0:s.snappable,d={toCoordinate:!1};return!0===a?d={toCoordinate:!0}:"object"==typeof a&&(d=a),void this.dragCoordinate.drag(t,r,d)}this.dragFeature.isDragging()?this.dragFeature.drag(t):e(!0)}}}},i.onDragEnd=function(t,e){this.allowPointerEvent(this.pointerEvents.onDragEnd,t)&&(this.setCursor(this.cursors.dragEnd),this.dragCoordinate.isDragging()?this.onFinish(this.selected[0],{mode:this.mode,action:"dragCoordinate"}):this.dragFeature.isDragging()?this.onFinish(this.selected[0],{mode:this.mode,action:"dragFeature"}):this.dragCoordinateResizeFeature.isDragging()&&this.onFinish(this.selected[0],{mode:this.mode,action:"dragCoordinateResize"}),this.dragCoordinate.stopDragging(),this.dragFeature.stopDragging(),this.dragCoordinateResizeFeature.stopDragging(),this.rotateFeature.reset(),this.scaleFeature.reset(),e(!0))},i.onMouseMove=function(t){var e=this.selected[0];if(e){if(!(this.dragFeature.isDragging()||this.dragCoordinate.isDragging()||this.dragCoordinateResizeFeature.isDragging())){var i=this.getSelectedFlags(e).featureFlags;if(i){var n=void 0,o=i.coordinates;if(null!=o&&o.midpoints&&(n=this.midPoints.getNearestMidPoint(t))&&(this.dragTarget={type:"midpoint",featureId:e,midPointId:n},this.setCursor(this.cursors.insertMidpoint)),o&&o.draggable){var r=this.dragCoordinate.getDraggable(t,e),s=r.index,a=r.dist;if(s>-1){if(n&&this.pixelDistance.measure(t,this.readFeature.getGeometry(n).coordinates)-1)return this.dragTarget={type:"resize",featureId:e,coordinateIndex:d},void this.setCursor(this.getPointerOverResizeHandleCursor())}if(i.draggable&&this.dragFeature.canDrag(t,e)){if(n)return;return this.dragTarget={type:"feature",featureId:e},void this.setCursor(this.getPointerOverFeatureCursor())}n||this.clearDragTargetAndCursor()}else this.clearDragTargetAndCursor()}}else this.clearDragTargetAndCursor()},i.styleFeature=function(t){var e=r({},{polygonFillColor:"#3f97e0",polygonOutlineColor:"#3f97e0",polygonOutlineWidth:4,polygonOutlineOpacity:1,polygonFillOpacity:.3,pointColor:"#3f97e0",pointOpacity:1,pointOutlineColor:"#ffffff",pointOutlineOpacity:1,pointOutlineWidth:0,pointWidth:6,lineStringColor:"#3f97e0",lineStringWidth:4,lineStringOpacity:1,zIndex:0,markerUrl:void 0,markerHeight:void 0,markerWidth:void 0,lineStringDash:void 0});if(t.properties.mode===this.mode&&"Point"===t.geometry.type){if(t.properties[f.SELECTION_POINT])return e.pointColor=this.getHexColorStylingValue(this.styles.selectionPointColor,e.pointColor,t),e.pointOpacity=this.getNumericStylingValue(this.styles.selectionPointOpacity,1,t),e.pointOutlineColor=this.getHexColorStylingValue(this.styles.selectionPointOutlineColor,e.pointOutlineColor,t),e.pointWidth=this.getNumericStylingValue(this.styles.selectionPointWidth,e.pointWidth,t),e.pointOutlineOpacity=this.getNumericStylingValue(this.styles.selectionPointOutlineOpacity,1,t),e.pointOutlineWidth=this.getNumericStylingValue(this.styles.selectionPointOutlineWidth,2,t),e.zIndex=30,e;if(t.properties[f.MID_POINT])return e.pointColor=this.getHexColorStylingValue(this.styles.midPointColor,e.pointColor,t),e.pointOpacity=this.getNumericStylingValue(this.styles.midPointOpacity,1,t),e.pointOutlineColor=this.getHexColorStylingValue(this.styles.midPointOutlineColor,e.pointOutlineColor,t),e.pointWidth=this.getNumericStylingValue(this.styles.midPointWidth,4,t),e.pointOutlineOpacity=this.getNumericStylingValue(this.styles.midPointOutlineOpacity,1,t),e.pointOutlineWidth=this.getNumericStylingValue(this.styles.midPointOutlineWidth,2,t),e.zIndex=50,e}else if(t.properties[f.SELECTED]){if("Point"===t.geometry.type&&t.properties[y.MARKER])return e.markerUrl=this.getUrlStylingValue(this.styles.selectedMarkerUrl,g,t),e.markerHeight=this.getNumericStylingValue(this.styles.selectedMarkerHeight,40,t),e.markerWidth=this.getNumericStylingValue(this.styles.selectedMarkerWidth,32,t),e;if("Polygon"===t.geometry.type)return e.polygonFillColor=this.getHexColorStylingValue(this.styles.selectedPolygonColor,e.polygonFillColor,t),e.polygonOutlineWidth=this.getNumericStylingValue(this.styles.selectedPolygonOutlineWidth,e.polygonOutlineWidth,t),e.polygonOutlineColor=this.getHexColorStylingValue(this.styles.selectedPolygonOutlineColor,e.polygonOutlineColor,t),e.polygonOutlineOpacity=this.getNumericStylingValue(this.styles.selectedPolygonOutlineOpacity,1,t),e.polygonFillOpacity=this.getNumericStylingValue(this.styles.selectedPolygonFillOpacity,e.polygonFillOpacity,t),e.zIndex=v,e;if("LineString"===t.geometry.type)return e.lineStringColor=this.getHexColorStylingValue(this.styles.selectedLineStringColor,e.lineStringColor,t),e.lineStringWidth=this.getNumericStylingValue(this.styles.selectedLineStringWidth,e.lineStringWidth,t),e.lineStringOpacity=this.getNumericStylingValue(this.styles.selectedLineStringOpacity,1,t),e.lineStringDash=this.getDashArrayStylingValue(this.styles.selectedLineStringDash,void 0,t),e.zIndex=v,e;if("Point"===t.geometry.type)return e.pointWidth=this.getNumericStylingValue(this.styles.selectedPointWidth,e.pointWidth,t),e.pointColor=this.getHexColorStylingValue(this.styles.selectedPointColor,e.pointColor,t),e.pointOpacity=this.getNumericStylingValue(this.styles.selectedPointOpacity,1,t),e.pointOutlineColor=this.getHexColorStylingValue(this.styles.selectedPointOutlineColor,e.pointOutlineColor,t),e.pointOutlineOpacity=this.getNumericStylingValue(this.styles.selectedPointOutlineOpacity,1,t),e.pointOutlineWidth=this.getNumericStylingValue(this.styles.selectedPointOutlineWidth,e.pointOutlineWidth,t),e.zIndex=v,e}return e},i.afterFeatureUpdated=function(t){if(this.selected.length&&t.id===this.selected[0]){var e,i,n=this.flags[t.properties.mode];if(null==n||null==(e=n.feature)||!e.coordinates)return;var o=t.geometry.type,r=t.id;if(this.selectionPoints.delete(),this.midPoints.delete(),"LineString"!==o&&"Polygon"!==o)return;var s=t.geometry.coordinates;this.selectionPoints.create({featureCoordinates:s,featureId:r}),null!=n&&null!=(i=n.feature)&&null!=(i=i.coordinates)&&i.midpoints&&this.midPoints.create({featureCoordinates:s,featureId:r})}},e}(M),Ee=/*#__PURE__*/function(t){function e(){for(var e,i=arguments.length,n=new Array(i),o=0;oi;){if(n-i>600){var r=n-i+1,s=e-i+1,a=Math.log(r),d=.5*Math.exp(2*a/3),u=.5*Math.sqrt(a*d*(r-d)/r)*(s-r/2<0?-1:1);De(t,e,Math.max(i,Math.floor(e-s*d/r+u)),Math.min(n,Math.floor(e+(r-s)*d/r+u)),o)}var h=t[e],l=i,c=n;for(ke(t,i,e),o(t[n],h)>0&&ke(t,i,n);l0;)c--}0===o(t[i],h)?ke(t,i,c):ke(t,++c,n),c<=e&&(i=c+1),e<=c&&(n=c-1)}}function ke(t,e,i){var n=t[e];t[e]=t[i],t[i]=n}function be(t,e){_e(t,0,t.children.length,e,t)}function _e(t,e,i,n,o){o||(o=Be([])),o.minX=Infinity,o.minY=Infinity,o.maxX=-Infinity,o.maxY=-Infinity;for(var r=e;r=t.minX&&e.maxY>=t.minY}function Be(t){return{children:t,height:1,leaf:!0,minX:Infinity,minY:Infinity,maxX:-Infinity,maxY:-Infinity}}function ze(t,e,i,n,o){for(var r=[e,i];r.length;)if(!((i=r.pop())-(e=r.pop())<=n)){var s=e+Math.ceil((i-e)/n/2)*n;De(t,s,e,i,o),r.push(e,s,s,i)}}var He=/*#__PURE__*/function(){function t(t){this._maxEntries=void 0,this._minEntries=void 0,this.data=void 0,this._maxEntries=Math.max(4,t),this._minEntries=Math.max(2,Math.ceil(.4*this._maxEntries)),this.clear()}var e=t.prototype;return e.search=function(t){var e=this.data,i=[];if(!Ae(t,e))return i;for(var n=this.toBBox,o=[];e;){for(var r=0;r=0&&o[e].children.length>this._maxEntries;)this._split(o,e),e--;this._adjustParentBBoxes(n,o,e)},e._split=function(t,e){var i=t[e],n=i.children.length,o=this._minEntries;this._chooseSplitAxis(i,o,n);var r=this._chooseSplitIndex(i,o,n),s=Be(i.children.splice(r,i.children.length-r));s.height=i.height,s.leaf=i.leaf,be(i,this.toBBox),be(s,this.toBBox),e?t[e-1].children.push(s):this._splitRoot(i,s)},e._splitRoot=function(t,e){this.data=Be([t,e]),this.data.height=t.height+1,this.data.leaf=!1,be(this.data,this.toBBox)},e._chooseSplitIndex=function(t,e,i){for(var n,o,r,s,a,d,u,h=Infinity,l=Infinity,c=e;c<=i-e;c++){var p=_e(t,0,c,this.toBBox),g=_e(t,c,i,this.toBBox),f=(o=p,r=g,s=Math.max(o.minX,r.minX),a=Math.max(o.minY,r.minY),d=Math.min(o.maxX,r.maxX),u=Math.min(o.maxY,r.maxY),Math.max(0,d-s)*Math.max(0,u-a)),y=Le(p)+Le(g);f=e;h--){var l=t.children[h];Te(s,t.leaf?o(l):l),a+=We(s)}return a},e._adjustParentBBoxes=function(t,e,i){for(var n=i;n>=0;n--)Te(e[n],t)},e._condense=function(t){for(var e,i=t.length-1;i>=0;i--)0===t[i].children.length?i>0?(e=t[i-1].children).splice(e.indexOf(t[i]),1):this.clear():be(t[i],this.toBBox)},t}(),Ve=/*#__PURE__*/function(){function t(t){this.tree=void 0,this.idToNode=void 0,this.nodeToId=void 0,this.tree=new He(t&&t.maxEntries?t.maxEntries:9),this.idToNode=new Map,this.nodeToId=new Map}var e=t.prototype;return e.setMaps=function(t,e){this.idToNode.set(t.id,e),this.nodeToId.set(e,t.id)},e.toBBox=function(t){var e,i=[],n=[];if("Polygon"===t.geometry.type)e=t.geometry.coordinates[0];else if("LineString"===t.geometry.type)e=t.geometry.coordinates;else{if("Point"!==t.geometry.type)throw new Error("Not a valid feature to turn into a bounding box");e=[t.geometry.coordinates]}for(var o=0;o0&&(this._onChange(d,"create",n),i&&a.forEach(function(t){i(t)})),s},e.search=function(t,e){var i=this,n=this.spatialIndex.search(t).map(function(t){return i.store[t]});return this.clone(e?n.filter(e):n)},e.registerOnChange=function(t){this._onChange=function(e,i,n){t(e,i,n)}},e.getGeometryCopy=function(t){var e=this.store[t];if(!e)throw new Error("No feature with this id ("+t+"), can not get geometry copy");return this.clone(e.geometry)},e.getPropertiesCopy=function(t){var e=this.store[t];if(!e)throw new Error("No feature with this id ("+t+"), can not get properties copy");return this.clone(e.properties)},e.updateProperty=function(t,e){var i=this,n=new Set;t.forEach(function(t){var e=t.id,o=t.property,r=t.value,s=i.store[e];if(!s)throw new Error("No feature with this ("+e+"), can not update geometry");s.properties[o]!==r&&(n.add(e),void 0===r?delete s.properties[o]:s.properties[o]=r,i.tracked&&(s.properties.updatedAt=+new Date))}),this._onChange&&n.size>0&&this._onChange(Array.from(n),"update",e?r({},e,Ke):Ke)},e.updateGeometry=function(t,e){var i=this,n=new Set;t.forEach(function(t){var e=t.id,o=t.geometry;n.add(e);var r=i.store[e];if(!r)throw new Error("No feature with this ("+e+"), can not update geometry");r.geometry=i.clone(o),i.spatialIndex.update(r),i.tracked&&(r.properties.updatedAt=+new Date)}),this._onChange&&n.size>0&&this._onChange(Array.from(n),"update",e?r({},e,je):je)},e.create=function(t,e){var i=this,n=[];return t.forEach(function(t){var e,o=t.geometry,s=t.properties,a=r({},s);i.tracked&&(e=+new Date,s?(a.createdAt="number"==typeof s.createdAt?s.createdAt:e,a.updatedAt="number"==typeof s.updatedAt?s.updatedAt:e):a={createdAt:e,updatedAt:e});var d=i.getId(),u={id:d,type:"Feature",geometry:o,properties:a};i.store[d]=u,i.spatialIndex.insert(u),n.push(d)}),this._onChange&&this._onChange([].concat(n),"create",e),n},e.delete=function(t,e){var i=this;t.forEach(function(t){if(!i.store[t])throw new Error("No feature with id "+t+", can not delete");delete i.store[t],i.spatialIndex.remove(t)}),this._onChange&&this._onChange([].concat(t),"delete",e)},e.copy=function(t){return this.clone(this.store[t])},e.copyAll=function(){var t=this;return this.clone(Object.keys(this.store).map(function(e){return t.store[e]}))},e.copyAllWhere=function(t){var e=this;return this.clone(Object.keys(this.store).map(function(t){return e.store[t]}).filter(function(e){return e.properties&&t(e.properties)}))},e.clear=function(t){var e=Object.keys(this.store);this.store={},this.spatialIndex.clear(),this._onChange(e,"delete",t)},e.size=function(){return Object.keys(this.store).length},t}();function Xe(t){var e=t.coordinates,i=0;if(e&&e.length>0){i+=Math.abs(Je(e[0]));for(var n=1;n=e?(n+2)%e:n+2][0]*Ze-t[n][0]*Ze)*Math.sin(t[n+1===e?0:n+1][1]*Ze),n++;return i*qe}var $e="Feature is smaller than the minimum area",Qe="Feature is not a Polygon or LineString",ti="Feature intersects itself";function ei(t,e,i){var n=It(t,e),o=It(e,i)-n;return o<0&&(o+=360),180-Math.abs(o-90-90)}var ii={cancel:"Escape",finish:"Enter"},ni={start:"crosshair",close:"pointer"},oi=/*#__PURE__*/function(t){function e(e){var i;return(i=t.call(this,e,!0)||this).mode="angled-rectangle",i.currentCoordinate=0,i.currentId=void 0,i.keyEvents=ii,i.cursors=ni,i.mouseMove=!1,i.mutateFeature=void 0,i.readFeature=void 0,i.updateOptions(e),i}s(e,t);var i=e.prototype;return i.updateOptions=function(e){t.prototype.updateOptions.call(this,e),null!=e&&e.cursors&&(this.cursors=r({},this.cursors,e.cursors)),null===(null==e?void 0:e.keyEvents)?this.keyEvents={cancel:null,finish:null}:null!=e&&e.keyEvents&&(this.keyEvents=r({},this.keyEvents,e.keyEvents))},i.close=function(){var t;if(void 0!==this.currentId&&this.mutateFeature.updatePolygon({featureId:this.currentId,propertyMutations:(t={},t[y.CURRENTLY_DRAWING]=void 0,t),context:{updateType:u.Finish,action:h}})){var e=this.currentId;this.currentCoordinate=0,this.currentId=void 0,"drawing"===this.state&&this.setStarted(),this.onFinish(e,{mode:this.mode,action:h})}},i.start=function(){this.setStarted(),this.setCursor(this.cursors.start)},i.stop=function(){this.cleanUp(),this.setStopped(),this.setCursor("unset")},i.onMouseMove=function(t){if(this.mouseMove=!0,this.setCursor(this.cursors.start),void 0!==this.currentId&&0!==this.currentCoordinate){var e=[];if(1===this.currentCoordinate)e=this.getUpdateForSecondCoordinate(t);else{if(2!==this.currentCoordinate)return;e=this.getNewSecondAndThirdCoordinates(t)}this.mutateFeature.updatePolygon({featureId:this.currentId,coordinateMutations:e,context:{updateType:u.Provisional}})}},i.getUpdateForSecondCoordinate=function(t){return[{type:et,index:1,coordinate:[t.lng,t.lat]},{type:et,index:2,coordinate:[t.lng,t.lat]}]},i.getNewSecondAndThirdCoordinates=function(t){if(!this.currentId)throw new Error("No current feature being drawn");var e,i,n,o,r=this.readFeature.getCoordinate(this.currentId,0),s=this.readFeature.getCoordinate(this.currentId,1),a=de(r,s,this.coordinatePrecision,this.project,this.unproject),d=L(r[0],r[1]),u=L(a[0],a[1]),h=L(s[0],s[1]),l=L(t.lng,t.lat),c=dt(l,d)1e-10?"left":o<-1e-10?"right":"left")?-90:90),m=Ct(d,y,v),C=Ct(h,y,v),P=W(m.x,m.y),I=W(C.x,C.y);return[{type:et,index:2,coordinate:[_(I.lng,this.coordinatePrecision),_(I.lat,this.coordinatePrecision)]},{type:et,index:3,coordinate:[_(P.lng,this.coordinatePrecision),_(P.lat,this.coordinatePrecision)]}]},i.onClick=function(t){if("right"===t.button&&this.allowPointerEvent(this.pointerEvents.rightClick,t)||"left"===t.button&&this.allowPointerEvent(this.pointerEvents.leftClick,t)||t.isContextMenu&&this.allowPointerEvent(this.pointerEvents.contextMenu,t))if(this.currentCoordinate>0&&!this.mouseMove&&this.onMouseMove(t),this.mouseMove=!1,0===this.currentCoordinate){var e,i=this.mutateFeature.createPolygon({coordinates:[[t.lng,t.lat],[t.lng,t.lat],[t.lng,t.lat],[t.lng,t.lat]],properties:(e={mode:this.mode},e[y.CURRENTLY_DRAWING]=!0,e)});this.currentId=i.id,this.currentCoordinate++,this.setDrawing()}else if(1===this.currentCoordinate&&this.currentId){var n=this.readFeature.getCoordinate(this.currentId,0);if(ut([t.lng,t.lat],n))return;if(!this.mutateFeature.updatePolygon({featureId:this.currentId,coordinateMutations:[{type:et,index:1,coordinate:[t.lng,t.lat]},{type:tt,index:1,coordinate:[t.lng,t.lat]}],context:{updateType:u.Commit}}))return;this.currentCoordinate++}else 2===this.currentCoordinate&&this.currentId&&this.close()},i.onKeyUp=function(t){if(t.key===this.keyEvents.cancel)this.cleanUp();else if(t.key===this.keyEvents.finish){if(this.currentCoordinate<2)return void this.cleanUp();this.close()}},i.onKeyDown=function(){},i.onDragStart=function(){},i.onDrag=function(){},i.onDragEnd=function(){},i.cleanUp=function(){var t=this.currentId;this.currentId=void 0,this.currentCoordinate=0,"drawing"===this.state&&this.setStarted(),this.mutateFeature.deleteFeatureIfPresent(t)},i.styleFeature=function(t){var e=r({},{polygonFillColor:"#3f97e0",polygonOutlineColor:"#3f97e0",polygonOutlineWidth:4,polygonOutlineOpacity:1,polygonFillOpacity:.3,pointColor:"#3f97e0",pointOpacity:1,pointOutlineColor:"#ffffff",pointOutlineOpacity:1,pointOutlineWidth:0,pointWidth:6,lineStringColor:"#3f97e0",lineStringWidth:4,lineStringOpacity:1,zIndex:0,markerUrl:void 0,markerHeight:void 0,markerWidth:void 0,lineStringDash:void 0});return t.properties.mode===this.mode&&"Polygon"===t.geometry.type&&(e.polygonFillColor=this.getHexColorStylingValue(this.styles.fillColor,e.polygonFillColor,t),e.polygonOutlineColor=this.getHexColorStylingValue(this.styles.outlineColor,e.polygonOutlineColor,t),e.polygonOutlineWidth=this.getNumericStylingValue(this.styles.outlineWidth,e.polygonOutlineWidth,t),e.polygonOutlineOpacity=this.getNumericStylingValue(this.styles.outlineOpacity,1,t),e.polygonFillOpacity=this.getNumericStylingValue(this.styles.fillOpacity,e.polygonFillOpacity,t),e.zIndex=v),e},i.validateFeature=function(t){var e=this;return this.validateModeFeature(t,function(t){return Z(t,e.coordinatePrecision)})},i.afterFeatureUpdated=function(t){this.currentId===t.id&&(this.currentId=void 0,this.currentCoordinate=0,"drawing"===this.state&&this.setStarted())},i.registerBehaviors=function(t){this.readFeature=new ht(t),this.mutateFeature=new ot(t,{validate:this.validate})},e}(O);function ri(t,e,i){return(e.x-t.x)*(i.y-t.y)-(e.y-t.y)*(i.x-t.x)<=0}var si={cancel:"Escape",finish:"Enter"},ai={start:"crosshair",close:"pointer"},di=/*#__PURE__*/function(t){function e(e){var i;return(i=t.call(this,e,!0)||this).mode="sector",i.currentCoordinate=0,i.currentId=void 0,i.keyEvents=si,i.direction=void 0,i.arcPoints=64,i.cursors=ai,i.mouseMove=!1,i.readFeature=void 0,i.mutateFeature=void 0,i.updateOptions(e),i}s(e,t);var i=e.prototype;return i.updateOptions=function(e){t.prototype.updateOptions.call(this,e),null!=e&&e.cursors&&(this.cursors=r({},this.cursors,e.cursors)),null===(null==e?void 0:e.keyEvents)?this.keyEvents={cancel:null,finish:null}:null!=e&&e.keyEvents&&(this.keyEvents=r({},this.keyEvents,e.keyEvents)),null!=e&&e.arcPoints&&(this.arcPoints=e.arcPoints)},i.close=function(){var t;if(void 0!==this.currentId&&this.mutateFeature.updatePolygon({featureId:this.currentId,propertyMutations:(t={},t[y.CURRENTLY_DRAWING]=void 0,t),coordinateMutations:{coordinates:this.readFeature.getGeometry(this.currentId).coordinates,type:nt},context:{updateType:u.Finish,action:h}})){var e=this.currentId;this.currentCoordinate=0,this.currentId=void 0,this.direction=void 0,"drawing"===this.state&&this.setStarted(),this.onFinish(e,{mode:this.mode,action:h})}},i.getSectorCoordinates=function(t){var e=this.readFeature.getCoordinates(this.currentId),i=e[0],n=e[1],o=[t.lng,t.lat],r=L(i[0],i[1]),s=L(n[0],n[1]),a=L(o[0],o[1]);if(void 0===this.direction){var d=ri(r,s,a);this.direction=d?"clockwise":"anticlockwise"}var u,h=dt(r,s),l=It(r,s),c=It(r,a),p=this.arcPoints,g=[i],f=St(l),y=St(c);"anticlockwise"===this.direction?(u=y-f)<0&&(u+=360):(u=f-y)<0&&(u+=360);var v=("anticlockwise"===this.direction?1:-1)*u/p;g.push(n);for(var m=0;m<=p;m++){var C=Ct(r,h,f+m*v),P=W(C.x,C.y),I=P.lat,S=[_(P.lng,this.coordinatePrecision),_(I,this.coordinatePrecision)];S[0]!==g[g.length-1][0]&&S[1]!==g[g.length-1][1]&&g.push(S)}return g.push(i),g},i.start=function(){this.setStarted(),this.setCursor(this.cursors.start)},i.stop=function(){this.cleanUp(),this.setStopped(),this.setCursor("unset")},i.onMouseMove=function(t){if(this.mouseMove=!0,this.setCursor(this.cursors.start),void 0!==this.currentId&&0!==this.currentCoordinate){var e;if(1===this.currentCoordinate)e=[{type:et,index:1,coordinate:[t.lng,t.lat]},{type:et,index:2,coordinate:[t.lng,t.lat]}];else{if(2!==this.currentCoordinate)return;var i=this.getSectorCoordinates(t);if(!i)return;e={type:nt,coordinates:[i]}}this.mutateFeature.updatePolygon({featureId:this.currentId,coordinateMutations:e,context:{updateType:u.Provisional}})}},i.onClick=function(t){if("right"===t.button&&this.allowPointerEvent(this.pointerEvents.rightClick,t)||"left"===t.button&&this.allowPointerEvent(this.pointerEvents.leftClick,t)||t.isContextMenu&&this.allowPointerEvent(this.pointerEvents.contextMenu,t))if(this.currentCoordinate>0&&!this.mouseMove&&this.onMouseMove(t),this.mouseMove=!1,0===this.currentCoordinate){var e,i=this.mutateFeature.createPolygon({coordinates:[[t.lng,t.lat],[t.lng,t.lat],[t.lng,t.lat],[t.lng,t.lat]],properties:(e={mode:this.mode},e[y.CURRENTLY_DRAWING]=!0,e)});this.currentId=null==i?void 0:i.id,this.currentCoordinate++,this.setDrawing()}else if(1===this.currentCoordinate&&this.currentId){if(this.readFeature.coordinateAtIndexIsIdentical({featureId:this.currentId,index:0,newCoordinate:[t.lng,t.lat]}))return;if(!this.mutateFeature.updatePolygon({featureId:this.currentId,coordinateMutations:[{type:et,index:1,coordinate:[t.lng,t.lat]},{type:et,index:2,coordinate:[t.lng,t.lat]}],context:{updateType:u.Provisional}}))return;this.currentCoordinate++}else 2===this.currentCoordinate&&this.currentId&&this.close()},i.onKeyUp=function(t){t.key===this.keyEvents.cancel?this.cleanUp():t.key===this.keyEvents.finish&&this.close()},i.onKeyDown=function(){},i.onDragStart=function(){},i.onDrag=function(){},i.onDragEnd=function(){},i.cleanUp=function(){var t=this.currentId;this.currentId=void 0,this.direction=void 0,this.currentCoordinate=0,"drawing"===this.state&&this.setStarted(),this.mutateFeature.deleteFeatureIfPresent(t)},i.styleFeature=function(t){var e=r({},{polygonFillColor:"#3f97e0",polygonOutlineColor:"#3f97e0",polygonOutlineWidth:4,polygonOutlineOpacity:1,polygonFillOpacity:.3,pointColor:"#3f97e0",pointOpacity:1,pointOutlineColor:"#ffffff",pointOutlineOpacity:1,pointOutlineWidth:0,pointWidth:6,lineStringColor:"#3f97e0",lineStringWidth:4,lineStringOpacity:1,zIndex:0,markerUrl:void 0,markerHeight:void 0,markerWidth:void 0,lineStringDash:void 0});return t.properties.mode===this.mode&&"Polygon"===t.geometry.type&&(e.polygonFillColor=this.getHexColorStylingValue(this.styles.fillColor,e.polygonFillColor,t),e.polygonOutlineColor=this.getHexColorStylingValue(this.styles.outlineColor,e.polygonOutlineColor,t),e.polygonOutlineWidth=this.getNumericStylingValue(this.styles.outlineWidth,e.polygonOutlineWidth,t),e.polygonOutlineOpacity=this.getNumericStylingValue(this.styles.outlineOpacity,1,t),e.polygonFillOpacity=this.getNumericStylingValue(this.styles.fillOpacity,e.polygonFillOpacity,t),e.zIndex=v),e},i.validateFeature=function(t){var e=this;return this.validateModeFeature(t,function(t){return Z(t,e.coordinatePrecision)})},i.afterFeatureUpdated=function(t){this.currentId===t.id&&(this.currentId=void 0,this.direction=void 0,this.currentCoordinate=0,"drawing"===this.state&&this.setStarted())},i.registerBehaviors=function(t){this.readFeature=new ht(t),this.mutateFeature=new ot(t,{validate:this.validate})},e}(O),ui={cancel:"Escape",finish:"Enter"},hi={start:"crosshair",close:"pointer"},li=/*#__PURE__*/function(t){function e(e){var i;return(i=t.call(this,e,!0)||this).mode="sensor",i.currentCoordinate=0,i.currentId=void 0,i.currentInitialArcId=void 0,i.currentStartingPointId=void 0,i.keyEvents=ui,i.direction=void 0,i.arcPoints=64,i.cursors=hi,i.mouseMove=!1,i.readFeature=void 0,i.mutateFeature=void 0,i.updateOptions(e),i}s(e,t);var i=e.prototype;return i.updateOptions=function(e){t.prototype.updateOptions.call(this,e),null!=e&&e.cursors&&(this.cursors=r({},this.cursors,e.cursors)),null===(null==e?void 0:e.keyEvents)?this.keyEvents={cancel:null,finish:null}:null!=e&&e.keyEvents&&(this.keyEvents=r({},this.keyEvents,e.keyEvents)),null!=e&&e.arcPoints&&(this.arcPoints=e.arcPoints)},i.start=function(){this.setStarted(),this.setCursor(this.cursors.start)},i.stop=function(){this.cleanUp(),this.setStopped(),this.setCursor("unset")},i.onMouseMove=function(t){if(this.mouseMove=!0,this.setCursor(this.cursors.start),void 0!==this.currentInitialArcId&&void 0!==this.currentStartingPointId&&0!==this.currentCoordinate)if(2===this.currentCoordinate){var e=this.getUpdatedLineStringCoordinates(t);if(!e)return;this.mutateFeature.updateLineString({featureId:this.currentInitialArcId,coordinateMutations:{type:nt,coordinates:e},context:{updateType:u.Provisional}})}else if(3===this.currentCoordinate){var i=this.getUpdatedPolygonCoordinates(t);if(!i)return;if(this.currentId)this.mutateFeature.updatePolygon({featureId:this.currentId,coordinateMutations:{type:nt,coordinates:[i]},context:{updateType:u.Provisional}});else{var n,o=this.mutateFeature.createPolygon({coordinates:i,properties:(n={mode:this.mode},n[y.CURRENTLY_DRAWING]=!0,n)});if(!o)return;this.currentId=o.id}}},i.onClick=function(t){if("right"===t.button&&this.allowPointerEvent(this.pointerEvents.rightClick,t)||"left"===t.button&&this.allowPointerEvent(this.pointerEvents.leftClick,t)||t.isContextMenu&&this.allowPointerEvent(this.pointerEvents.contextMenu,t))if(this.currentCoordinate>0&&!this.mouseMove&&this.onMouseMove(t),this.mouseMove=!1,0===this.currentCoordinate){var e=this.mutateFeature.createPoint({coordinates:[t.lng,t.lat],properties:{mode:this.mode}});if(!e)return;this.currentStartingPointId=e.id,this.currentCoordinate++,this.setDrawing()}else if(1===this.currentCoordinate&&this.currentStartingPointId){var i=this.mutateFeature.createLineString({coordinates:[[t.lng,t.lat],[t.lng,t.lat]],properties:{mode:this.mode}});if(!i)return;this.currentInitialArcId=i.id,this.currentCoordinate++}else 2===this.currentCoordinate&&this.currentStartingPointId?this.currentCoordinate++:3===this.currentCoordinate&&this.currentStartingPointId&&this.close()},i.onKeyUp=function(t){t.key===this.keyEvents.cancel?this.cleanUp():t.key===this.keyEvents.finish&&this.close()},i.onKeyDown=function(){},i.onDragStart=function(){},i.onDrag=function(){},i.onDragEnd=function(){},i.cleanUp=function(){this.mutateFeature.deleteFeatureIfPresent(this.currentStartingPointId),this.mutateFeature.deleteFeatureIfPresent(this.currentInitialArcId),this.mutateFeature.deleteFeatureIfPresent(this.currentId),this.currentStartingPointId=void 0,this.direction=void 0,this.currentId=void 0,this.currentCoordinate=0,"drawing"===this.state&&this.setStarted()},i.styleFeature=function(t){var e=r({},{polygonFillColor:"#3f97e0",polygonOutlineColor:"#3f97e0",polygonOutlineWidth:4,polygonOutlineOpacity:1,polygonFillOpacity:.3,pointColor:"#3f97e0",pointOpacity:1,pointOutlineColor:"#ffffff",pointOutlineOpacity:1,pointOutlineWidth:0,pointWidth:6,lineStringColor:"#3f97e0",lineStringWidth:4,lineStringOpacity:1,zIndex:0,markerUrl:void 0,markerHeight:void 0,markerWidth:void 0,lineStringDash:void 0});return t.properties.mode===this.mode&&("Polygon"===t.geometry.type?(e.polygonFillColor=this.getHexColorStylingValue(this.styles.fillColor,e.polygonFillColor,t),e.polygonOutlineColor=this.getHexColorStylingValue(this.styles.outlineColor,e.polygonOutlineColor,t),e.polygonOutlineWidth=this.getNumericStylingValue(this.styles.outlineWidth,e.polygonOutlineWidth,t),e.polygonOutlineOpacity=this.getNumericStylingValue(this.styles.outlineOpacity,1,t),e.polygonFillOpacity=this.getNumericStylingValue(this.styles.fillOpacity,e.polygonFillOpacity,t),e.zIndex=v):"LineString"===t.geometry.type?(e.lineStringColor=this.getHexColorStylingValue(this.styles.outlineColor,e.polygonOutlineColor,t),e.lineStringWidth=this.getNumericStylingValue(this.styles.outlineWidth,e.polygonOutlineWidth,t),e.zIndex=v):"Point"===t.geometry.type&&(e.pointColor=this.getHexColorStylingValue(this.styles.centerPointColor,e.pointColor,t),e.pointOpacity=this.getNumericStylingValue(this.styles.centerPointOpacity,1,t),e.pointWidth=this.getNumericStylingValue(this.styles.centerPointWidth,e.pointWidth,t),e.pointOutlineColor=this.getHexColorStylingValue(this.styles.centerPointOutlineColor,e.pointOutlineColor,t),e.pointOutlineOpacity=this.getNumericStylingValue(this.styles.centerPointOutlineOpacity,1,t),e.pointOutlineWidth=this.getNumericStylingValue(this.styles.centerPointOutlineWidth,e.pointOutlineWidth,t),e.zIndex=20)),e},i.validateFeature=function(t){var e=this;return this.validateModeFeature(t,function(t){return Z(t,e.coordinatePrecision)})},i.afterFeatureUpdated=function(t){this.currentId===t.id&&(this.mutateFeature.deleteFeatureIfPresent(this.currentStartingPointId),this.mutateFeature.deleteFeatureIfPresent(this.currentInitialArcId),this.currentStartingPointId=void 0,this.direction=void 0,this.currentId=void 0,this.currentCoordinate=0,"drawing"===this.state&&this.setStarted())},i.registerBehaviors=function(t){this.readFeature=new ht(t),this.mutateFeature=new ot(t,{validate:this.validate})},i.close=function(){if(void 0!==this.currentStartingPointId){var t,e=this.currentStartingPointId,i=this.currentInitialArcId;if(this.currentId&&!this.mutateFeature.updatePolygon({featureId:this.currentId,propertyMutations:(t={},t[y.CURRENTLY_DRAWING]=void 0,t),coordinateMutations:{coordinates:this.readFeature.getGeometry(this.currentId).coordinates,type:nt},context:{updateType:u.Finish,action:h}}))return;var n=this.currentId;this.mutateFeature.deleteFeatureIfPresent(e),this.mutateFeature.deleteFeatureIfPresent(i),this.currentCoordinate=0,this.currentStartingPointId=void 0,this.currentInitialArcId=void 0,this.currentId=void 0,this.direction=void 0,"drawing"===this.state&&this.setStarted(),n&&this.onFinish(n,{mode:this.mode,action:h})}},i.getUpdatedPolygonCoordinates=function(t){if(!(void 0===this.currentInitialArcId||void 0===this.currentStartingPointId||this.currentCoordinate<3)){var e=this.readFeature.getCoordinates(this.currentInitialArcId);if(!(e.length<2)&&this.direction){var i=this.readFeature.getGeometry(this.currentStartingPointId).coordinates,n=e[0],o=e[e.length-1],r=L(t.lng,t.lat),s=L(n[0],n[1]),a=L(o[0],o[1]),d=L(i[0],i[1]),u=dt(d,s),h=dt(d,r)=i&&e<=n:e>=i||e<=n:i>=n?e<=i&&e>=n:e<=i||e>=n},e}(O),ci=function(t){var e=this,i=t.name,n=t.callback,o=t.unregister,r=t.register;this.name=void 0,this.callback=void 0,this.registered=!1,this.register=void 0,this.unregister=void 0,this.name=i,this.register=function(){e.registered||(e.registered=!0,r(n))},this.unregister=function(){e.register&&(e.registered=!1,o(n))},this.callback=n},pi={__proto__:null,GeoJSONStore:Ye,TerraDrawBaseDrawMode:O,TerraDrawBaseSelectMode:M,TerraDrawBaseAdapter:/*#__PURE__*/function(){function t(t){this._nextKeyUpIsContextMenu=!1,this._lastPointerDownEventTarget=void 0,this._ignoreMismatchedPointerEvents=!1,this._minPixelDragDistance=void 0,this._minPixelDragDistanceDrawing=void 0,this._minPixelDragDistanceSelecting=void 0,this._lastDrawEvent=void 0,this._coordinatePrecision=void 0,this._heldKeys=new Set,this._listeners=[],this._dragState="not-dragging",this._currentModeCallbacks=void 0,this._ignoreMismatchedPointerEvents="boolean"==typeof t.ignoreMismatchedPointerEvents&&t.ignoreMismatchedPointerEvents,this._minPixelDragDistance="number"==typeof t.minPixelDragDistance?t.minPixelDragDistance:1,this._minPixelDragDistanceSelecting="number"==typeof t.minPixelDragDistanceSelecting?t.minPixelDragDistanceSelecting:1,this._minPixelDragDistanceDrawing="number"==typeof t.minPixelDragDistanceDrawing?t.minPixelDragDistanceDrawing:8,this._coordinatePrecision="number"==typeof t.coordinatePrecision?t.coordinatePrecision:9}var e=t.prototype;return e.getButton=function(t){return-1===t.button?"neither":0===t.button?"left":1===t.button?"middle":2===t.button?"right":"neither"},e.getMapElementXYPosition=function(t){var e=this.getMapEventElement(t.type).getBoundingClientRect();return{containerX:t.clientX-e.left,containerY:t.clientY-e.top}},e.getDrawEventFromEvent=function(t,e){void 0===e&&(e=!1);var i=this.getLngLatFromEvent(t);if(!i)return null;var n=i.lng,o=i.lat,r=this.getMapElementXYPosition(t),s=r.containerX,a=r.containerY,d=this.getButton(t),u=Array.from(this._heldKeys);return{lng:_(n,this._coordinatePrecision),lat:_(o,this._coordinatePrecision),containerX:s,containerY:a,button:d,heldKeys:u,isContextMenu:e}},e.register=function(t){this._currentModeCallbacks=t,this._listeners=this.getAdapterListeners(),this._listeners.forEach(function(t){t.register()})},e.getCoordinatePrecision=function(){return this._coordinatePrecision},e.getAdapterListeners=function(){var t=this;return[new ci({name:"pointerdown",callback:function(e){if(t._currentModeCallbacks&&e.isPrimary){var i=t.getDrawEventFromEvent(e);i&&(t._dragState="pre-dragging",t._lastDrawEvent=i,t._lastPointerDownEventTarget=e.target?e.target:void 0)}},register:function(e){t.getMapEventElement("pointerdown").addEventListener("pointerdown",e)},unregister:function(e){t.getMapEventElement("pointerdown").removeEventListener("pointerdown",e)}}),new ci({name:"pointermove",callback:function(e){if(t._currentModeCallbacks&&e.isPrimary){e.preventDefault();var i=t.getDrawEventFromEvent(e);if(i)if("not-dragging"===t._dragState)t._currentModeCallbacks.onMouseMove(i),t._lastDrawEvent=i;else if("pre-dragging"===t._dragState){if(!t._lastDrawEvent)return;var n={x:t._lastDrawEvent.containerX,y:t._lastDrawEvent.containerY},o={x:i.containerX,y:i.containerY},r=t._currentModeCallbacks.getState(),s=dt(n,o);if("drawing"===r?s0},e.canRedo=function(){return!!this.inDrawingState()&&this.getHistorySizes().redoSize>0},e.undo=function(){return!(!this.canUndo()||!this.undoMode||(this.undoMode(),this.emitHistoryChange(Mi),0))},e.redo=function(){return!(!this.canRedo()||!this.redoMode||(this.redoMode(),this.emitHistoryChange(wi),0))},e.clearHistory=function(){this.clearModeHistory&&this.clearModeHistory(),this.lastHistorySizes={undoSize:0,redoSize:0}},e.getHistorySizes=function(){return this.getModeHistorySizes?this.getModeHistorySizes():{undoSize:0,redoSize:0}},e.undoSize=function(){return this.getHistorySizes().undoSize},e.redoSize=function(){return this.getHistorySizes().redoSize},e.emitPushIfHistoryChangedFromLastSnapshot=function(){if(this.inDrawingState()){var t=this.getHistorySizes();t.undoSize===this.lastHistorySizes.undoSize&&t.redoSize===this.lastHistorySizes.redoSize||this.emitHistoryChange(Ei)}},e.emitPushIfHistoryChanged=function(t){if(this.inDrawingState()){var e=this.getHistorySizes();e.undoSize===t.undoSize&&e.redoSize===t.redoSize||this.emitHistoryChange(Ei)}},e.emitHistoryChange=function(t){if(this.onHistoryChange){var e=this.getHistorySizes(),i=e.undoSize,n=e.redoSize;this.lastHistorySizes={undoSize:i,redoSize:n},this.onHistoryChange({cause:t,stack:Di,undoStackSize:i,redoStackSize:n})}},t}(),_i=/*#__PURE__*/function(){function t(t){var e=this;this.draw=void 0,this.onHistoryChange=void 0,this.maxStackSize=void 0,this.historyById={},this.undoStack=[],this.ignoreProgrammaticCreate={},this.ignoreProgrammaticDelete={},this.deletedFeatureIds={},this.redoStack=[],this.isReplayingHistory=!1,this.emitStackChange=function(t){e.onHistoryChange&&e.onHistoryChange({cause:t,stack:ki,undoStackSize:e.undoStack.length,redoStackSize:e.redoStack.length})},this.handleChange=function(t,i,n){if(e.draw&&!e.isDrawing()&&0!==e.maxStackSize)if("update"!==i){if("delete"===i||"create"===i)if("create"!==i){for(var r,s=!1,a=[],d=o(Array.isArray(t)?t:[t]);!(r=d()).done;){var u=r.value,h=String(u);if(e.ignoreProgrammaticDelete[u])delete e.ignoreProgrammaticDelete[u];else if(e.historyById[h]){var l=e.historyById[h].length-1;if(l>=0){var c=e.historyById[h][l];if(!c)continue;a.push({id:u,toIndex:l,snapshot:c}),e.deletedFeatureIds[u]=!0,s=!0}}}if(a.length>1)e.pushUndoStackEntry({id:a[0].id,toIndex:a[0].toIndex,action:"batch-delete",metadata:{entries:a}});else if(1===a.length){var p=a[0];e.pushUndoStackEntry({id:p.id,toIndex:p.toIndex,action:"single"})}s&&(e.redoStack.length=0,e.emitStackChange(Ei))}else{if(void 0===n||!("origin"in n)||"api"!==n.origin)return;for(var g,f=!1,y=[],v=o(Array.isArray(t)?t:[t]);!(g=v()).done;){var m=g.value;if(e.ignoreProgrammaticCreate[m])delete e.ignoreProgrammaticCreate[m],delete e.deletedFeatureIds[m];else{var C=String(m),P=e.draw.getSnapshotFeature(m);P&&(e.deletedFeatureIds[m]&&(e.historyById[C]=[],delete e.deletedFeatureIds[m]),e.historyById[C]||(e.historyById[C]=[]),e.historyById[C].push(P),y.push({id:m,toIndex:e.historyById[C].length-1,snapshot:P}),f=!0)}}if(y.length>1)e.pushUndoStackEntry({id:y[0].id,toIndex:y[0].toIndex,action:"batch-create",metadata:{entries:y}});else if(1===y.length){var I=y[0];e.pushUndoStackEntry({id:I.id,toIndex:I.toIndex,action:"single"})}f&&(e.redoStack.length=0,e.emitStackChange(Ei))}}else{if(void 0===n||!("origin"in n)||"api"!==n.origin||e.isReplayingHistory)return;for(var S,F=!1,x=o(Array.isArray(t)?t:[t]);!(S=x()).done;){var O=S.value;if(null!=O){var M=String(O),w=e.draw.getSnapshotFeature(O);w&&(e.historyById[M]||(e.historyById[M]=[]),e.historyById[M].push(w),e.pushUndoStackEntry({id:O,toIndex:e.historyById[M].length-1,action:"single"}),F=!0)}}F&&(e.redoStack.length=0,e.emitStackChange(Ei))}},this.handleFinish=function(t){if(e.draw&&0!==e.maxStackSize&&!e.isReplayingHistory)for(var i,n=!1,r=o(Array.isArray(t)?t:[t]);!(i=r()).done;){var s=i.value;if(null!=s){var a=String(s),d=e.draw.getSnapshotFeature(s);d&&(e.historyById[a]||(e.historyById[a]=[]),e.historyById[a].push(d),n||(e.redoStack.length=0,n=!0),e.pushUndoStackEntry({id:s,toIndex:e.historyById[a].length-1,action:"single"}),e.emitStackChange(Ei))}}},this.maxStackSize=Oi(null==t?void 0:t.maxStackSize)}var e=t.prototype;return e.register=function(t){this.draw!==t.draw?(this.draw&&(this.draw.off("change",this.handleChange),this.draw.off("finish",this.handleFinish)),this.draw=t.draw,this.draw.on("change",this.handleChange),this.draw.on("finish",this.handleFinish),this.onHistoryChange=t.onHistoryChange):this.onHistoryChange=t.onHistoryChange},e.pushUndoStackEntry=function(t){0!==this.maxStackSize&&(this.undoStack.push(t),this.undoStack.length>this.maxStackSize&&this.undoStack.shift())},e.pushRedoStackEntry=function(t){0!==this.maxStackSize&&(this.redoStack.push(t),this.redoStack.length>this.maxStackSize&&this.redoStack.shift())},e.isDrawing=function(){return!!this.draw&&"drawing"===this.draw.getModeState()},e.applySnapshotDuringReplay=function(t,e){if(this.draw){this.isReplayingHistory=!0;try{this.draw.hasFeature(t)&&(this.ignoreProgrammaticDelete[t]=!0,this.draw.removeFeatures([t])),this.ignoreProgrammaticCreate[t]=!0,delete this.deletedFeatureIds[t],this.draw.addFeatures([e])}finally{this.isReplayingHistory=!1}}},e.canUndo=function(){return!(!this.draw||this.isDrawing())&&this.undoStack.length>0},e.canRedo=function(){return!(!this.draw||this.isDrawing())&&this.redoStack.length>0},e.undo=function(){var t=this;if(!this.canUndo())return!1;if(!this.draw)return!1;var e=this.undoStack.pop();if(!e)return this.emitStackChange(Mi),!1;if("batch-create"===e.action){var i,n=(null==(i=e.metadata)?void 0:i.entries)||[];if(0===n.length)return this.emitStackChange(Mi),!1;var o=n.map(function(t){return t.id});return o.forEach(function(e){t.ignoreProgrammaticDelete[e]=!0,t.deletedFeatureIds[e]=!0}),this.draw.removeFeatures(o),this.pushRedoStackEntry({id:n[0].id,toIndex:n[0].toIndex,action:"batch-create",metadata:{entries:n}}),this.emitStackChange(Mi),!0}if("batch-delete"===e.action){var r,s=(null==(r=e.metadata)?void 0:r.entries)||[];if(0===s.length)return this.emitStackChange(Mi),!1;var a=s.map(function(t){return t.snapshot}).filter(function(t){return void 0!==t});return a.length>0&&(s.forEach(function(e){t.ignoreProgrammaticCreate[e.id]=!0,delete t.deletedFeatureIds[e.id]}),this.draw.addFeatures(a)),this.pushRedoStackEntry({id:s[0].id,toIndex:s[0].toIndex,action:"batch-delete",metadata:{entries:s}}),this.emitStackChange(Mi),!0}var d=e.id,u=e.toIndex,h=String(d),l=this.historyById[h];if(!l||0===l.length)return this.emitStackChange(Mi),!1;var c=Math.min(u,l.length-1);if(!this.draw.hasFeature(d)){var p=l[c];return p?(this.ignoreProgrammaticCreate[d]=!0,delete this.deletedFeatureIds[d],this.draw.addFeatures([p]),this.pushRedoStackEntry({id:d,toIndex:c,action:"delete",snapshot:p}),this.emitStackChange(Mi),!0):(this.emitStackChange(Mi),!1)}if(c<=0)return this.pushRedoStackEntry({id:d,toIndex:0,action:"create"}),this.ignoreProgrammaticDelete[d]=!0,this.deletedFeatureIds[d]=!0,this.draw.removeFeatures([d]),this.undoStack=this.undoStack.filter(function(t){return t.id!==d}),this.emitStackChange(Mi),!0;var g=l[c],f=l[c-1];return g&&this.pushRedoStackEntry({id:d,toIndex:c,snapshot:g,action:"update"}),this.applySnapshotDuringReplay(d,f),l.length=c,this.emitStackChange(Mi),!0},e.redo=function(){var t=this;if(!this.canRedo())return!1;if(!this.draw)return!1;var e=this.redoStack.pop(),i=e.id,n=e.toIndex,o=e.snapshot,r=e.action,s=e.metadata;if("batch-create"===r){var a=(null==s?void 0:s.entries)||[];if(0===a.length)return this.emitStackChange(wi),!1;var d=a.map(function(t){return t.snapshot}).filter(function(t){return void 0!==t});return d.length>0&&(a.forEach(function(e){t.ignoreProgrammaticCreate[e.id]=!0}),this.draw.addFeatures(d)),this.pushUndoStackEntry({id:a[0].id,toIndex:a[0].toIndex,action:"batch-create",metadata:{entries:a}}),this.emitStackChange(wi),!0}if("batch-delete"===r){var u=(null==s?void 0:s.entries)||[];if(0===u.length)return this.emitStackChange(wi),!1;var h=u.map(function(t){return t.id});return h.forEach(function(e){t.ignoreProgrammaticDelete[e]=!0,t.deletedFeatureIds[e]=!0}),this.draw.removeFeatures(h),this.pushUndoStackEntry({id:u[0].id,toIndex:u[0].toIndex,action:"batch-delete",metadata:{entries:u}}),this.emitStackChange(wi),!0}var l=String(i),c=this.historyById[l]||(this.historyById[l]=[]);if("delete"===r)return this.ignoreProgrammaticDelete[i]=!0,this.deletedFeatureIds[i]=!0,this.draw.removeFeatures([i]),this.pushUndoStackEntry({id:i,toIndex:n,action:"single"}),this.emitStackChange(wi),!0;if(n<=0){var p=c[0];return!!p&&(this.ignoreProgrammaticCreate[i]=!0,this.draw.addFeatures([p]),this.pushUndoStackEntry({id:i,toIndex:0,action:"single"}),this.emitStackChange(wi),!0)}var g=o||c[n];return!!g&&(c.length===n?c.push(g):(c[n]=g,c.length=n+1),this.applySnapshotDuringReplay(i,g),this.pushUndoStackEntry({id:i,toIndex:n,action:"single"}),this.emitStackChange(wi),!0)},e.clearHistory=function(){var t={};if(this.draw&&!this.isDrawing())for(var e,i=o(this.draw.getSnapshot());!(e=i()).done;){var n=e.value;t[String(n.id)]=[n]}this.historyById=t,this.undoStack=[],this.ignoreProgrammaticCreate={},this.ignoreProgrammaticDelete={},this.deletedFeatureIds={},this.redoStack=[]},e.undoSize=function(){return this.undoStack.length},e.redoSize=function(){return this.redoStack.length},t}(),Ti=/*#__PURE__*/function(){function t(t){var e;this.modeLevel=void 0,this.sessionLevel=void 0,this.shouldPreferMode=void 0,this.onHistoryChange=void 0,this.shouldEmitHistoryChange=void 0,this.modeLevel=t.modeLevel,this.sessionLevel=t.sessionLevel,this.shouldPreferMode=t.shouldPreferMode,this.onHistoryChange=t.onHistoryChange,this.shouldEmitHistoryChange=null!=(e=t.shouldEmitHistoryChange)?e:function(){return!0}}var e=t.prototype;return e.emitStackHistoryChange=function(t){this.shouldEmitHistoryChange()&&this.onHistoryChange&&this.onHistoryChange({cause:t.cause,stack:t.stack,undoSize:t.undoStackSize,redoSize:t.redoStackSize})},e.hasSessionUndo=function(){return Boolean(this.sessionLevel&&this.sessionLevel.canUndo())},e.hasSessionRedo=function(){return Boolean(this.sessionLevel&&this.sessionLevel.canRedo())},e.activeStackForUndo=function(){var t,e;return this.shouldPreferMode()&&null!=(t=this.modeLevel)&&t.canUndo()?Di:this.hasSessionUndo()?ki:null!=(e=this.modeLevel)&&e.canUndo()?Di:void 0},e.activeStackForRedo=function(){var t,e;return this.shouldPreferMode()&&null!=(t=this.modeLevel)&&t.canRedo()?Di:this.hasSessionRedo()?ki:null!=(e=this.modeLevel)&&e.canRedo()?Di:void 0},e.canUndo=function(){return void 0!==this.activeStackForUndo()},e.canRedo=function(){return void 0!==this.activeStackForRedo()},e.undo=function(){var t=this.activeStackForUndo();return!!t&&(t===Di?!!this.modeLevel&&this.modeLevel.undo():!(!this.sessionLevel||!this.sessionLevel.canUndo())&&this.sessionLevel.undo())},e.redo=function(){var t=this.activeStackForRedo();return!!t&&(t===Di?!!this.modeLevel&&this.modeLevel.redo():!(!this.sessionLevel||!this.sessionLevel.canRedo())&&this.sessionLevel.redo())},e.clearHistory=function(){this.modeLevel&&this.modeLevel.clearHistory(),this.sessionLevel&&this.sessionLevel.clearHistory()},e.emitHistoryPushForCompletedAction=function(){this.sessionLevel?this.emitStackHistoryChange({cause:Ei,undoStackSize:this.sessionLevel.undoSize(),redoStackSize:this.sessionLevel.redoSize(),stack:ki}):this.modeLevel&&this.emitStackHistoryChange({cause:Ei,undoStackSize:this.modeLevel.undoSize(),redoStackSize:this.modeLevel.redoSize(),stack:Di})},t}();t.TerraDraw=/*#__PURE__*/function(){function t(t){var e,i,n,o,s=this;this._modes=void 0,this._mode=void 0,this._adapter=void 0,this._enabled=!1,this._store=void 0,this._eventListeners=void 0,this._instanceSelectModes=void 0,this.sessionUndoRedoEnabled=!1,this.keyboardShortcutsMatcher=void 0,this.drawingUndoRedo=void 0,this.sessionUndoRedo=void 0,this.undoRedoCoordinator=void 0,this._adapter=t.adapter,this._instanceSelectModes=[];var a=null==t||null==(e=t.undoRedo)?void 0:e.modeLevel;a&&(this.drawingUndoRedo=a);var d=null==t||null==(i=t.undoRedo)?void 0:i.keyboardShortcuts;d&&(this.keyboardShortcutsMatcher=d),this.sessionUndoRedoEnabled=Boolean(null==t||null==(n=t.undoRedo)?void 0:n.sessionLevel);var u=null==t||null==(o=t.undoRedo)?void 0:o.sessionLevel;this._mode=new Ee;var h=new Set,l=t.modes.reduce(function(t,e){if(h.has(e.mode))throw new Error("There is already a "+e.mode+" mode provided");return h.add(e.mode),t[e.mode]=e,t},{}),c=Object.keys(l);if(0===c.length)throw new Error("No modes provided");c.forEach(function(t){l[t].type===I.Select&&s._instanceSelectModes.push(t)}),this._modes=r({},l,{static:this._mode}),this._eventListeners={change:[],select:[],deselect:[],finish:[],ready:[],history:[]},this._store=new Ye({tracked:!!t.tracked,idStrategy:t.idStrategy?t.idStrategy:void 0});var p=function(t){var e=[],i=s._store.copyAll().filter(function(i){return!t.includes(i.id)||(e.push(i),!1)});return{changed:e,unchanged:i}},g=function(t,e){var i;s._enabled&&(s._eventListeners.finish.forEach(function(i){i(t,e)}),null==(i=s.undoRedoCoordinator)||i.emitHistoryPushForCompletedAction())},f=function(t,e,i){if(s._enabled){s._eventListeners.change.forEach(function(n){n(t,e,i)}),s.emitDrawingPushIfHistoryChangedFromLastSnapshot();var n=p(t),o=n.changed,r=n.unchanged;"create"===e?s._adapter.render({created:o,deletedIds:[],unchanged:r,updated:[]},s.getModeStyles()):"update"===e?s._adapter.render({created:[],deletedIds:[],unchanged:r,updated:o},s.getModeStyles()):"delete"===e?s._adapter.render({created:[],deletedIds:t,unchanged:r,updated:[]},s.getModeStyles()):"styling"===e&&s._adapter.render({created:[],deletedIds:[],unchanged:r,updated:[]},s.getModeStyles())}},y=function(t){if(s._enabled){s._eventListeners.select.forEach(function(e){e(t)});var e=p([t]);s._adapter.render({created:[],deletedIds:[],unchanged:e.unchanged,updated:e.changed},s.getModeStyles())}},v=function(t){if(s._enabled){s._eventListeners.deselect.forEach(function(e){e(t)});var e=p([t]),i=e.changed;i&&s._adapter.render({created:[],deletedIds:[],unchanged:e.unchanged,updated:i},s.getModeStyles())}};Object.keys(this._modes).forEach(function(t){var e;s._modes[t].register({mode:t,store:s._store,setCursor:s._adapter.setCursor.bind(s._adapter),project:s._adapter.project.bind(s._adapter),unproject:s._adapter.unproject.bind(s._adapter),setDoubleClickToZoom:s._adapter.setDoubleClickToZoom.bind(s._adapter),onChange:f,onSelect:y,onDeselect:v,onFinish:g,coordinatePrecision:s._adapter.getCoordinatePrecision(),undoRedoMaxStackSize:null==(e=s.drawingUndoRedo)||null==e.getMaxStackSize?void 0:e.getMaxStackSize()})}),this.sessionUndoRedoEnabled&&u&&(this.sessionUndoRedo=u,u.register({draw:this,onHistoryChange:function(t){var e;null==(e=s.undoRedoCoordinator)||e.emitStackHistoryChange(t)}})),this.drawingUndoRedo&&this.drawingUndoRedo.register({getModeState:function(){return s.getModeState()},getModeHistorySizes:function(){return s.getDrawingHistorySizes()},undoMode:function(){s._mode.undo&&s._mode.undo()},redoMode:function(){s._mode.redo&&s._mode.redo()},clearModeHistory:function(){var t=s._mode;t.clearHistory&&t.clearHistory()},onHistoryChange:function(t){var e;null==(e=s.undoRedoCoordinator)||e.emitStackHistoryChange(t)}}),this.undoRedoCoordinator=new Ti({modeLevel:this.drawingUndoRedo,sessionLevel:this.sessionUndoRedo,shouldPreferMode:function(){return"drawing"===s.getModeState()},onHistoryChange:function(t){s._eventListeners.history.forEach(function(e){e(t)})},shouldEmitHistoryChange:function(){return s._enabled}})}var e=t.prototype;return e.checkEnabled=function(){if(!this._enabled)throw new Error("Terra Draw is not enabled")},e.handleUndoRedoKeyboardShortcut=function(t){if(!this.drawingUndoRedo&&!this.sessionUndoRedoEnabled)return!1;if(!this.keyboardShortcutsMatcher)return!1;var e=this.keyboardShortcutsMatcher.isUndoKeyboardShortcut(t),i=this.keyboardShortcutsMatcher.isRedoKeyboardShortcut(t);if(e){if(!this.canUndo())return!1;var n=this.undo();return n&&t.preventDefault(),n}if(i){if(!this.canRedo())return!1;var o=this.redo();return o&&t.preventDefault(),o}return!1},e.getDrawingHistorySizes=function(){return{undoSize:this._mode.undoSize&&"function"==typeof this._mode.undoSize?this._mode.undoSize():0,redoSize:this._mode.redoSize&&"function"==typeof this._mode.redoSize?this._mode.redoSize():0}},e.emitDrawingPushIfHistoryChangedFromLastSnapshot=function(){this.drawingUndoRedo&&this.drawingUndoRedo.emitPushIfHistoryChangedFromLastSnapshot()},e.emitDrawingPushIfHistoryChanged=function(t){this.drawingUndoRedo&&this.drawingUndoRedo.emitPushIfHistoryChanged(t)},e.getModeStyles=function(){var t=this,e={},i=this._instanceSelectModes.includes(this._mode.mode)?this._mode.mode:void 0;return Object.keys(this._modes).forEach(function(n){e[n]=function(e){return i&&e.properties[f.SELECTED]?t._modes[i].styleFeature.bind(t._modes[i])(e):t._modes[n].styleFeature.bind(t._modes[n])(e)}}),e},e.featuresAtLocation=function(t,e){var i=t.lng,n=t.lat,r=e&&void 0!==e.pointerDistance?e.pointerDistance:30,s=!e||void 0===e.ignoreSelectFeatures||e.ignoreSelectFeatures,a=!(!e||void 0===e.ignoreCoordinatePoints)&&e.ignoreCoordinatePoints,d=!(!e||void 0===e.ignoreCurrentlyDrawing)&&e.ignoreCurrentlyDrawing,u=!(!e||void 0===e.ignoreClosingPoints)&&e.ignoreClosingPoints,h=!(!e||void 0===e.ignoreSnappingPoints)&&e.ignoreSnappingPoints,l=this._adapter.unproject.bind(this._adapter),c=this._adapter.project.bind(this._adapter),p=c(i,n),g=gt({unproject:l,point:p,pointerDistance:r});return this._store.search(g).filter(function(t){if(s&&(t.properties[f.MID_POINT]||t.properties[f.SELECTION_POINT]))return!1;if(a&&t.properties[y.COORDINATE_POINT])return!1;if(u&&t.properties[y.CLOSING_POINT])return!1;if(d&&t.properties[y.CURRENTLY_DRAWING])return!1;if(h&&t.properties[y.SNAPPING_POINT])return!1;if("Point"===t.geometry.type){var l=t.geometry.coordinates,g=c(l[0],l[1]);return dt(p,g)e?{valid:!1,reason:"Feature is larger than the maximum area"}:{valid:!0}},t.ValidateMinAreaSquareMeters=function(t,e){return"Polygon"!==t.geometry.type?{valid:!1,reason:S}:Xe(t.geometry)