@geolibre/core 3.3.0 → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +0,0 @@
1
- {"version":3,"file":"joins-CGcRoTpc.mjs","names":[],"sources":["../src/ellipsoids.ts","../src/geojson-z.ts","../src/polyline.ts","../src/selection.ts","../src/expressions.ts","../src/virtual-fields.ts","../src/joins.ts"],"sourcesContent":["/**\n * Celestial-body ellipsoids and the planetary basemaps that pair with them.\n *\n * GeoLibre is Earth-centric by construction: MapLibre only renders Web Mercator\n * and all vector data is kept as WGS84 lon/lat GeoJSON. This module does *not*\n * change that — MapLibre still treats the planet as a unit sphere and there is\n * no true multi-CRS rendering (see maplibre-gl-js#168). What it adds is a\n * per-project notion of *which body* the coordinates describe, so that:\n *\n * - distance / area / scale measurements use that body's radius instead of a\n * hardcoded Earth radius, and\n * - Moon / Mars basemaps (published in a Web-Mercator tiling scheme) can be\n * selected like any other basemap.\n *\n * The active ellipsoid is a lightweight module-level singleton kept in sync with\n * the project's map preferences (see the store's `setPreferences`). Measurement\n * helpers read it lazily at call time, so callers in other packages don't need\n * the value threaded through their signatures — a deliberate prototype-friendly\n * shortcut over a full CRS/context refactor.\n */\n\n/** A biaxial (rotational) ellipsoid describing a celestial body. */\nexport interface Ellipsoid {\n /** Stable id persisted in the project (`map.ellipsoidId`). */\n id: string;\n /** Human-readable name shown in the UI. */\n name: string;\n /** Equatorial (semi-major) radius in metres — the \"web mercator\" radius. */\n semiMajorAxisMeters: number;\n /**\n * Inverse flattening `1/f`. `0` denotes a perfect sphere (Moon), in which case\n * the polar radius equals {@link semiMajorAxisMeters}.\n */\n inverseFlattening: number;\n}\n\n/**\n * Built-in ellipsoids. Earth is WGS 84; every other body uses IAU-adopted\n * figures. Only Earth and Mars are appreciably oblate; the rest are modelled as\n * spheres (`inverseFlattening: 0`), which is how the IAU/USGS simple-cylindrical\n * products treat them and is well within the accuracy MapLibre's unit-sphere\n * rendering can represent anyway.\n */\nexport const ELLIPSOIDS = [\n {\n id: \"earth\",\n name: \"Earth (WGS 84)\",\n semiMajorAxisMeters: 6378137,\n inverseFlattening: 298.257223563,\n },\n {\n id: \"moon\",\n name: \"Moon\",\n semiMajorAxisMeters: 1737400,\n inverseFlattening: 0,\n },\n {\n id: \"mars\",\n name: \"Mars (IAU 2000)\",\n semiMajorAxisMeters: 3396190,\n inverseFlattening: 169.894447,\n },\n {\n id: \"mercury\",\n name: \"Mercury\",\n semiMajorAxisMeters: 2439400,\n inverseFlattening: 0,\n },\n {\n id: \"venus\",\n name: \"Venus\",\n semiMajorAxisMeters: 6051800,\n inverseFlattening: 0,\n },\n {\n id: \"io\",\n name: \"Io\",\n semiMajorAxisMeters: 1821600,\n inverseFlattening: 0,\n },\n {\n id: \"europa\",\n name: \"Europa\",\n semiMajorAxisMeters: 1560800,\n inverseFlattening: 0,\n },\n {\n id: \"ganymede\",\n name: \"Ganymede\",\n semiMajorAxisMeters: 2631200,\n inverseFlattening: 0,\n },\n {\n id: \"callisto\",\n name: \"Callisto\",\n semiMajorAxisMeters: 2410300,\n inverseFlattening: 0,\n },\n {\n id: \"titan\",\n name: \"Titan\",\n semiMajorAxisMeters: 2574730,\n inverseFlattening: 0,\n },\n {\n id: \"pluto\",\n name: \"Pluto\",\n semiMajorAxisMeters: 1188300,\n inverseFlattening: 0,\n },\n {\n id: \"charon\",\n name: \"Charon\",\n semiMajorAxisMeters: 606000,\n inverseFlattening: 0,\n },\n] as const satisfies readonly Ellipsoid[];\n\nexport type EllipsoidId = (typeof ELLIPSOIDS)[number][\"id\"];\n\nexport const DEFAULT_ELLIPSOID_ID: EllipsoidId = \"earth\";\n\n/** Look an ellipsoid up by id, falling back to Earth for unknown ids. */\nexport function getEllipsoid(id: string | undefined): Ellipsoid {\n return (\n ELLIPSOIDS.find((e) => e.id === id) ?? ELLIPSOIDS.find((e) => e.id === DEFAULT_ELLIPSOID_ID)!\n );\n}\n\n/**\n * Mean radius `R = (2a + b) / 3` in metres, where `b` is the polar radius\n * derived from the inverse flattening. This is the radius used for spherical\n * (haversine) distance and area math.\n */\nexport function meanRadiusMeters(ellipsoid: Ellipsoid): number {\n const a = ellipsoid.semiMajorAxisMeters;\n if (!ellipsoid.inverseFlattening) return a;\n const f = 1 / ellipsoid.inverseFlattening;\n const b = a * (1 - f);\n return (2 * a + b) / 3;\n}\n\n/** Earth's mean radius in metres — the radius Turf.js and MapLibre bake in. */\nexport const EARTH_MEAN_RADIUS_METERS = meanRadiusMeters(ELLIPSOIDS.find((e) => e.id === \"earth\")!);\n\n// --- Active ellipsoid singleton -------------------------------------------\n\nlet activeEllipsoidId: EllipsoidId = DEFAULT_ELLIPSOID_ID;\n\n/**\n * Point the measurement helpers at a body. Unknown ids fall back to Earth so a\n * malformed project can never break measurements. Safe to call on every\n * preferences change; it is a cheap assignment.\n */\nexport function setActiveEllipsoidId(id: string | undefined): void {\n activeEllipsoidId = getEllipsoid(id).id as EllipsoidId;\n}\n\nexport function getActiveEllipsoid(): Ellipsoid {\n return getEllipsoid(activeEllipsoidId);\n}\n\n/** Mean radius (metres) of the active body — for haversine distance/area. */\nexport function getActiveMeanRadiusMeters(): number {\n return meanRadiusMeters(getActiveEllipsoid());\n}\n\n/** Semi-major axis (metres) of the active body — for its Web-Mercator scale. */\nexport function getActiveSemiMajorAxisMeters(): number {\n return getActiveEllipsoid().semiMajorAxisMeters;\n}\n\n// --- Earth-locked geodesy correction ---------------------------------------\n\n/**\n * The active body's mean radius as a fraction of Earth's — `R_body / R_earth`,\n * and exactly `1` on Earth.\n *\n * Everything GeoLibre measures ultimately comes from lon/lat *angles*, and the\n * only thing that turns an angle into a ground distance is the radius it is\n * multiplied by. Turf.js hardcodes Earth's, with no per-call override (that is\n * the \"Turf is Earth-locked\" half of GeoLibre#1128), so rather than patch or\n * replace Turf we post-scale what it returns and pre-scale what we hand it. The\n * result is exact for a sphere, which is how every non-Earth body GeoLibre\n * offers is modelled anyway, and within Mars' 0.6% flattening at worst.\n *\n * Suggested by @thareUSGS (USGS Astrogeology) on GeoLibre#1128 as the practical\n * workaround planetary web maps have long used on Earth-locked engines.\n */\nexport function getActiveBodyRadiusRatio(): number {\n return getActiveMeanRadiusMeters() / EARTH_MEAN_RADIUS_METERS;\n}\n\n/**\n * Convert a length Turf.js measured on Earth into the active body's true ground\n * length. A no-op on Earth.\n *\n * Use on anything Turf *returns* — a distance, a length, a perimeter.\n *\n * The correction is a dimensionless ratio, so it is unit-agnostic: pass the\n * length in whatever unit Turf gave it back (metres, kilometres, miles) and the\n * result is in that same unit. There is no hidden unit conversion here.\n */\nexport function earthLengthToBody(length: number): number {\n return length * getActiveBodyRadiusRatio();\n}\n\n/**\n * Convert a true ground length on the active body into the Earth-equivalent\n * length to hand Turf.js. A no-op on Earth.\n *\n * Use on anything passed *into* Turf as a distance — a buffer width, a circle\n * or sector radius, a search threshold — so the resulting geometry spans that\n * distance on this body rather than on Earth.\n *\n * Unit-agnostic like {@link earthLengthToBody}: pass the length in whatever\n * unit you are about to hand Turf alongside it, and the result is in that unit.\n */\nexport function bodyLengthToEarth(length: number): number {\n return length / getActiveBodyRadiusRatio();\n}\n\n/**\n * Convert an area Turf.js measured on Earth into the active body's true ground\n * area. A no-op on Earth.\n *\n * Areas scale with the *square* of the radius ratio, so this is not the same\n * correction as {@link earthLengthToBody}. Unit-agnostic in the same way, for\n * whatever squared unit the area is expressed in.\n */\nexport function earthAreaToBody(area: number): number {\n const ratio = getActiveBodyRadiusRatio();\n return area * ratio * ratio;\n}\n\n// --- Planetary basemaps ----------------------------------------------------\n\n/**\n * A raster basemap for a celestial body — the Moon and Mars mosaics, plus the\n * Earth satellite imagery the planet switcher pairs with Earth. The tiles are\n * XYZ (or TMS, see {@link scheme}) images in that body's Web-Mercator scheme, so\n * MapLibre renders them directly. The `styleUrl` is a `geolibre://basemap/<id>`\n * sentinel; the map controller expands it into a raster style at apply time (it\n * is not a fetchable URL).\n */\nexport interface PlanetaryBasemap {\n id: string;\n name: string;\n /** Sentinel stored as the basemap style URL. */\n styleUrl: string;\n /** XYZ (or TMS, see {@link scheme}) tile template. */\n tileUrl: string;\n /**\n * Tile row ordering. OpenPlanetaryMap's single-layer raster mosaics (the S3\n * datasets) are published as **TMS** (tile origin bottom-left, Y flipped),\n * whereas the CARTO `opmbuilder` named maps are standard **XYZ**. Omit for\n * XYZ; MapLibre defaults to `\"xyz\"` when `scheme` is absent.\n */\n scheme?: \"tms\";\n /** Max native zoom of the source (MapLibre overzooms beyond this). */\n maxZoom: number;\n /** Attribution shown on the map. */\n attribution: string;\n /** The body this basemap depicts, so selecting it can set the ellipsoid. */\n ellipsoidId: EllipsoidId;\n}\n\nexport const PLANETARY_BASEMAP_SENTINEL_PREFIX = \"geolibre://basemap/\";\n\nconst OPM_ATTRIBUTION = '<a href=\"https://www.openplanetary.org/opm\">OpenPlanetaryMap</a>';\n\n/** Data-source credit joined with the OpenPlanetaryMap attribution. */\nconst opmCredit = (source: string) => `${source} · ${OPM_ATTRIBUTION}`;\n\n// The GeoLibre tiles Worker (workers/tiles), which adds CORS to the OPM S3\n// mosaics that lack it. Its dataset keys mirror the DATASETS map in that Worker.\n// Tile path: `${TILE_PROXY_BASE}/<dataset>/{z}/{x}/{y}.png`.\nconst TILE_PROXY_BASE = \"https://tiles.geolibre.app/opm\";\n\n// The GeoLibre tiles Worker's reprojection endpoint, which warps the USGS\n// Astrogeology equirectangular WMS layers to Web Mercator so MapLibre can render\n// them (the USGS server offers no EPSG:3857 for these bodies). Its dataset keys\n// mirror the WMS_DATASETS map in that Worker (workers/tiles/src/index.ts).\n// Tile path: `${WMS_PROXY_BASE}/<dataset>/{z}/{x}/{y}.png` — standard XYZ.\nconst WMS_PROXY_BASE = \"https://tiles.geolibre.app/wms\";\n\n// USGS Astrogeology, the origin of every reprojected WMS basemap below.\nconst USGS_ASTRO_ATTRIBUTION = '<a href=\"https://astrogeology.usgs.gov/\">USGS Astrogeology</a>';\n\n/** Data-source credit joined with the USGS Astrogeology attribution. */\nconst usgsCredit = (source: string) => `${source} · ${USGS_ASTRO_ATTRIBUTION}`;\n\n// The OpenPlanetaryMap Mars and Moon basemaps\n// (https://openplanetarymap.org/basemaps/). Every one is a pre-rendered raster\n// served from a CDN — fast and reliable, unlike the USGS Astrogeology MapServer\n// these replace, which rendered every tile per request from a cgi-bin.\n//\n// Two tiling schemes are in play (see PlanetaryBasemap.scheme):\n// - The single-layer OPM mosaics (MOLA/Viking/hillshade/Moon albedo) are TMS.\n// - The multi-layer CARTO `opmbuilder` named maps are standard XYZ.\n// maxZoom is each source's probed max native zoom, so MapLibre overzooms (blurs)\n// rather than 404s.\n//\n// CORS: MapLibre GL fetches raster tiles with `fetch()`, which enforces CORS.\n// The CARTO `opmbuilder` named maps send `Access-Control-Allow-Origin: *`, so\n// they are referenced directly. The single-layer OPM mosaics are served from S3\n// buckets that send NO CORS header, so the browser blocks them — those go\n// through the GeoLibre tiles Worker (workers/tiles, tiles.geolibre.app), which\n// re-emits each tile with CORS and edge-caches it. See TILE_PROXY_BASE.\nexport const PLANETARY_BASEMAPS: readonly PlanetaryBasemap[] = [\n // --- Mars ---------------------------------------------------------------\n {\n id: \"mars-colour-mola-elevation\",\n name: \"Colour MOLA Elevation\",\n styleUrl: `${PLANETARY_BASEMAP_SENTINEL_PREFIX}mars-colour-mola-elevation`,\n tileUrl: `${TILE_PROXY_BASE}/mars-mola-color-noshade/{z}/{x}/{y}.png`,\n scheme: \"tms\",\n maxZoom: 6,\n attribution: opmCredit(\"NASA / MOLA\"),\n ellipsoidId: \"mars\",\n },\n {\n id: \"mars-viking-mdim21\",\n name: \"Viking MDIM2.1\",\n styleUrl: `${PLANETARY_BASEMAP_SENTINEL_PREFIX}mars-viking-mdim21`,\n tileUrl: `${TILE_PROXY_BASE}/mars-viking-mdim21/{z}/{x}/{y}.png`,\n scheme: \"tms\",\n maxZoom: 7,\n attribution: opmCredit(\"NASA / Viking / USGS\"),\n ellipsoidId: \"mars\",\n },\n {\n id: \"mars-hillshade\",\n name: \"Hillshade\",\n styleUrl: `${PLANETARY_BASEMAP_SENTINEL_PREFIX}mars-hillshade`,\n tileUrl: `${TILE_PROXY_BASE}/mars-hillshade/{z}/{x}/{y}.png`,\n scheme: \"tms\",\n maxZoom: 6,\n attribution: opmCredit(\"NASA / MOLA\"),\n ellipsoidId: \"mars\",\n },\n {\n id: \"mars-basemap-v0-2\",\n name: \"OPM Basemap v0.2\",\n styleUrl: `${PLANETARY_BASEMAP_SENTINEL_PREFIX}mars-basemap-v0-2`,\n tileUrl:\n \"https://cartocdn-gusc.global.ssl.fastly.net/opmbuilder/api/v1/map/named/opm-mars-basemap-v0-2/all/{z}/{x}/{y}.png\",\n maxZoom: 6,\n attribution: OPM_ATTRIBUTION,\n ellipsoidId: \"mars\",\n },\n {\n id: \"mars-shaded-colour-mola-elevation\",\n name: \"Shaded Colour MOLA Elevation\",\n styleUrl: `${PLANETARY_BASEMAP_SENTINEL_PREFIX}mars-shaded-colour-mola-elevation`,\n tileUrl: `${TILE_PROXY_BASE}/mars-mola-color/{z}/{x}/{y}.png`,\n scheme: \"tms\",\n maxZoom: 6,\n attribution: opmCredit(\"NASA / MOLA\"),\n ellipsoidId: \"mars\",\n },\n {\n id: \"mars-shaded-grayscale-mola-elevation\",\n name: \"Shaded Grayscale MOLA Elevation\",\n styleUrl: `${PLANETARY_BASEMAP_SENTINEL_PREFIX}mars-shaded-grayscale-mola-elevation`,\n tileUrl: `${TILE_PROXY_BASE}/mars-mola-gray/{z}/{x}/{y}.png`,\n scheme: \"tms\",\n maxZoom: 9,\n attribution: opmCredit(\"NASA / MOLA\"),\n ellipsoidId: \"mars\",\n },\n // --- The Moon -----------------------------------------------------------\n {\n id: \"moon-hillshaded-albedo\",\n name: \"Hillshaded Albedo\",\n styleUrl: `${PLANETARY_BASEMAP_SENTINEL_PREFIX}moon-hillshaded-albedo`,\n tileUrl: `${TILE_PROXY_BASE}/moon-hillshaded-albedo/{z}/{x}/{y}.png`,\n scheme: \"tms\",\n maxZoom: 6,\n attribution: opmCredit(\"NASA / LOLA / USGS\"),\n ellipsoidId: \"moon\",\n },\n {\n id: \"moon-basemap-v0-1\",\n name: \"OPM Basemap v0.1\",\n styleUrl: `${PLANETARY_BASEMAP_SENTINEL_PREFIX}moon-basemap-v0-1`,\n tileUrl:\n \"https://cartocdn-gusc.global.ssl.fastly.net/opmbuilder/api/v1/map/named/opm-moon-basemap-v0-1/all/{z}/{x}/{y}.png\",\n maxZoom: 6,\n attribution: OPM_ATTRIBUTION,\n ellipsoidId: \"moon\",\n },\n // --- Mercury ------------------------------------------------------------\n // USGS Astrogeology WMS layers reprojected to Web Mercator by the tiles\n // Worker (see WMS_PROXY_BASE). Standard XYZ, so no `scheme`.\n {\n id: \"mercury-messenger-color\",\n name: \"MESSENGER Colour Mosaic\",\n styleUrl: `${PLANETARY_BASEMAP_SENTINEL_PREFIX}mercury-messenger-color`,\n tileUrl: `${WMS_PROXY_BASE}/mercury-messenger-color/{z}/{x}/{y}.png`,\n maxZoom: 7,\n attribution: usgsCredit(\"NASA / JHU APL / CIW\"),\n ellipsoidId: \"mercury\",\n },\n {\n id: \"mercury-messenger\",\n name: \"MESSENGER Basemap\",\n styleUrl: `${PLANETARY_BASEMAP_SENTINEL_PREFIX}mercury-messenger`,\n tileUrl: `${WMS_PROXY_BASE}/mercury-messenger/{z}/{x}/{y}.png`,\n maxZoom: 7,\n attribution: usgsCredit(\"NASA / JHU APL\"),\n ellipsoidId: \"mercury\",\n },\n // --- Venus --------------------------------------------------------------\n {\n id: \"venus-magellan\",\n name: \"Magellan FMAP\",\n styleUrl: `${PLANETARY_BASEMAP_SENTINEL_PREFIX}venus-magellan`,\n tileUrl: `${WMS_PROXY_BASE}/venus-magellan/{z}/{x}/{y}.png`,\n maxZoom: 6,\n attribution: usgsCredit(\"NASA / JPL\"),\n ellipsoidId: \"venus\",\n },\n {\n id: \"venus-magellan-color\",\n name: \"Magellan C3-MDIR Colour\",\n styleUrl: `${PLANETARY_BASEMAP_SENTINEL_PREFIX}venus-magellan-color`,\n tileUrl: `${WMS_PROXY_BASE}/venus-magellan-color/{z}/{x}/{y}.png`,\n maxZoom: 6,\n attribution: usgsCredit(\"NASA / JPL\"),\n ellipsoidId: \"venus\",\n },\n // --- Jupiter's Galilean moons -------------------------------------------\n {\n id: \"io-galileo-color\",\n name: \"Galileo SSI Colour\",\n styleUrl: `${PLANETARY_BASEMAP_SENTINEL_PREFIX}io-galileo-color`,\n tileUrl: `${WMS_PROXY_BASE}/io-galileo-color/{z}/{x}/{y}.png`,\n maxZoom: 6,\n attribution: usgsCredit(\"NASA / JPL\"),\n ellipsoidId: \"io\",\n },\n {\n id: \"europa-galileo-voyager\",\n name: \"Galileo / Voyager\",\n styleUrl: `${PLANETARY_BASEMAP_SENTINEL_PREFIX}europa-galileo-voyager`,\n tileUrl: `${WMS_PROXY_BASE}/europa-galileo-voyager/{z}/{x}/{y}.png`,\n maxZoom: 6,\n attribution: usgsCredit(\"NASA / JPL\"),\n ellipsoidId: \"europa\",\n },\n {\n id: \"ganymede-galileo-voyager\",\n name: \"Galileo / Voyager\",\n styleUrl: `${PLANETARY_BASEMAP_SENTINEL_PREFIX}ganymede-galileo-voyager`,\n tileUrl: `${WMS_PROXY_BASE}/ganymede-galileo-voyager/{z}/{x}/{y}.png`,\n maxZoom: 6,\n attribution: usgsCredit(\"NASA / JPL\"),\n ellipsoidId: \"ganymede\",\n },\n {\n id: \"callisto-galileo-voyager\",\n name: \"Galileo / Voyager\",\n styleUrl: `${PLANETARY_BASEMAP_SENTINEL_PREFIX}callisto-galileo-voyager`,\n tileUrl: `${WMS_PROXY_BASE}/callisto-galileo-voyager/{z}/{x}/{y}.png`,\n maxZoom: 6,\n attribution: usgsCredit(\"NASA / JPL\"),\n ellipsoidId: \"callisto\",\n },\n // --- Saturn's moon Titan ------------------------------------------------\n {\n id: \"titan-cassini\",\n name: \"Cassini ISS Mosaic\",\n styleUrl: `${PLANETARY_BASEMAP_SENTINEL_PREFIX}titan-cassini`,\n tileUrl: `${WMS_PROXY_BASE}/titan-cassini/{z}/{x}/{y}.png`,\n maxZoom: 6,\n attribution: usgsCredit(\"NASA / JPL / SSI\"),\n ellipsoidId: \"titan\",\n },\n {\n id: \"titan-hisar\",\n name: \"Cassini HiSAR Mosaic\",\n styleUrl: `${PLANETARY_BASEMAP_SENTINEL_PREFIX}titan-hisar`,\n tileUrl: `${WMS_PROXY_BASE}/titan-hisar/{z}/{x}/{y}.png`,\n maxZoom: 6,\n attribution: usgsCredit(\"NASA / JPL / USGS\"),\n ellipsoidId: \"titan\",\n },\n // --- Pluto & Charon -----------------------------------------------------\n {\n id: \"pluto-mosaic\",\n name: \"New Horizons Mosaic\",\n styleUrl: `${PLANETARY_BASEMAP_SENTINEL_PREFIX}pluto-mosaic`,\n tileUrl: `${WMS_PROXY_BASE}/pluto-mosaic/{z}/{x}/{y}.png`,\n maxZoom: 7,\n attribution: usgsCredit(\"NASA / JHU APL / SwRI\"),\n ellipsoidId: \"pluto\",\n },\n {\n id: \"pluto-color\",\n name: \"New Horizons Colour Shaded Relief\",\n styleUrl: `${PLANETARY_BASEMAP_SENTINEL_PREFIX}pluto-color`,\n tileUrl: `${WMS_PROXY_BASE}/pluto-color/{z}/{x}/{y}.png`,\n maxZoom: 7,\n attribution: usgsCredit(\"NASA / JHU APL / SwRI\"),\n ellipsoidId: \"pluto\",\n },\n {\n id: \"charon-mosaic\",\n name: \"New Horizons Mosaic\",\n styleUrl: `${PLANETARY_BASEMAP_SENTINEL_PREFIX}charon-mosaic`,\n tileUrl: `${WMS_PROXY_BASE}/charon-mosaic/{z}/{x}/{y}.png`,\n maxZoom: 6,\n attribution: usgsCredit(\"NASA / JHU APL / SwRI\"),\n ellipsoidId: \"charon\",\n },\n // --- Earth --------------------------------------------------------------\n // Satellite imagery the planet switcher pairs with Earth. Not shown in the\n // basemap picker's Moon/Mars sections (PLANETARY_BODY_ORDER excludes Earth) —\n // Earth basemaps live in the OpenFreeMap/Protomaps picker. USGS's National Map\n // ImageryOnly tiles are global Web-Mercator XYZ with open CORS.\n {\n id: \"earth-usgs-imagery\",\n name: \"USGS Imagery\",\n styleUrl: `${PLANETARY_BASEMAP_SENTINEL_PREFIX}earth-usgs-imagery`,\n tileUrl:\n \"https://basemap.nationalmap.gov/arcgis/rest/services/USGSImageryOnly/MapServer/tile/{z}/{y}/{x}\",\n maxZoom: 16,\n attribution:\n '<a href=\"https://www.usgs.gov/programs/national-geospatial-program/national-map\">USGS The National Map</a>',\n ellipsoidId: \"earth\",\n },\n] as const;\n\n/**\n * The section a planetary basemap is grouped under in the New Project and\n * Change Basemap pickers. The Moon and Mars keep dedicated sections (they are\n * the most-used bodies and each has several mosaics); every other body is\n * collapsed into a single \"other\" section so the picker isn't a wall of\n * one-item headings.\n */\nexport type PlanetaryBasemapSectionId = \"moon\" | \"mars\" | \"other\";\n\n/** A picker section paired with the planetary basemaps it lists. */\nexport interface PlanetaryBasemapGroup {\n id: PlanetaryBasemapSectionId;\n basemaps: readonly PlanetaryBasemap[];\n}\n\n// Bodies that get their own picker section. Earth is excluded entirely (its\n// basemaps live in the OpenFreeMap/Protomaps picker); everything else lands in\n// \"other\".\nconst DEDICATED_SECTION_BODIES: readonly EllipsoidId[] = [\"moon\", \"mars\"];\n\n/**\n * {@link PLANETARY_BASEMAPS} grouped for the pickers: one section each for the\n * Moon and Mars, then a single \"Other celestial bodies\" section for the rest,\n * in {@link PLANETARY_BASEMAPS} order (grouped by body). Empty sections are\n * dropped.\n */\nexport const PLANETARY_BASEMAP_GROUPS: readonly PlanetaryBasemapGroup[] = (\n [\n { id: \"moon\", ellipsoidId: \"moon\" },\n { id: \"mars\", ellipsoidId: \"mars\" },\n { id: \"other\", ellipsoidId: null },\n ] as const\n)\n .map(({ id, ellipsoidId }) => {\n const basemaps = PLANETARY_BASEMAPS.filter((b) =>\n ellipsoidId\n ? b.ellipsoidId === ellipsoidId\n : b.ellipsoidId !== \"earth\" && !DEDICATED_SECTION_BODIES.includes(b.ellipsoidId),\n );\n // The combined \"other\" section spans many bodies, so order it alphabetically\n // by body name; a stable sort keeps each body's basemaps grouped together.\n return {\n id,\n basemaps:\n id === \"other\"\n ? [...basemaps].sort((a, b) =>\n getEllipsoid(a.ellipsoidId).name.localeCompare(getEllipsoid(b.ellipsoidId).name),\n )\n : basemaps,\n };\n })\n .filter((group) => group.basemaps.length > 0);\n\n// Basemap ids the OpenPlanetaryMap migration renamed or dropped, mapped to the\n// nearest current basemap. Lets a project saved before the migration keep a\n// planetary basemap (instead of falling back to Earth) the next time it opens:\n// the two OPM composites kept their exact tiles under new ids, Viking maps to\n// the equivalent OPM mosaic, and the retired LRO imagery maps to the flagship\n// Moon basemap.\nconst LEGACY_PLANETARY_BASEMAP_IDS: Record<string, string> = {\n \"mars-opm\": \"mars-basemap-v0-2\",\n \"moon-opm\": \"moon-basemap-v0-1\",\n \"mars-viking\": \"mars-viking-mdim21\",\n \"moon-lroc\": \"moon-basemap-v0-1\",\n};\n\n/** Resolve a `geolibre://basemap/<id>` sentinel to its planetary basemap. */\nexport function getPlanetaryBasemapByStyleUrl(\n styleUrl: string | undefined,\n): PlanetaryBasemap | undefined {\n if (!styleUrl?.startsWith(PLANETARY_BASEMAP_SENTINEL_PREFIX)) return undefined;\n const id = styleUrl.slice(PLANETARY_BASEMAP_SENTINEL_PREFIX.length);\n const resolvedId = Object.prototype.hasOwnProperty.call(LEGACY_PLANETARY_BASEMAP_IDS, id)\n ? LEGACY_PLANETARY_BASEMAP_IDS[id]\n : id;\n return PLANETARY_BASEMAPS.find((b) => b.id === resolvedId);\n}\n\n/** Look a planetary basemap up by its stable id. */\nexport function getPlanetaryBasemapById(id: string): PlanetaryBasemap | undefined {\n return PLANETARY_BASEMAPS.find((b) => b.id === id);\n}\n\n/**\n * The celestial bodies offered by the Layers-panel planet switcher, in menu\n * order (like Google Earth's planet dropdown). Each body is paired with the\n * basemap the switcher applies for it — USGS satellite imagery for Earth, the\n * OpenPlanetaryMap Hillshaded Albedo mosaic for the Moon, and the OpenPlanetaryMap\n * Viking mosaic for Mars.\n */\nexport const PLANET_SWITCHER_OPTIONS = [\n // The three most-used bodies lead; the rest follow alphabetically.\n { ellipsoidId: \"earth\", basemapId: \"earth-usgs-imagery\" },\n { ellipsoidId: \"moon\", basemapId: \"moon-hillshaded-albedo\" },\n { ellipsoidId: \"mars\", basemapId: \"mars-viking-mdim21\" },\n { ellipsoidId: \"callisto\", basemapId: \"callisto-galileo-voyager\" },\n { ellipsoidId: \"charon\", basemapId: \"charon-mosaic\" },\n { ellipsoidId: \"europa\", basemapId: \"europa-galileo-voyager\" },\n { ellipsoidId: \"ganymede\", basemapId: \"ganymede-galileo-voyager\" },\n { ellipsoidId: \"io\", basemapId: \"io-galileo-color\" },\n { ellipsoidId: \"mercury\", basemapId: \"mercury-messenger-color\" },\n { ellipsoidId: \"pluto\", basemapId: \"pluto-mosaic\" },\n { ellipsoidId: \"titan\", basemapId: \"titan-cassini\" },\n { ellipsoidId: \"venus\", basemapId: \"venus-magellan-color\" },\n] as const satisfies readonly {\n ellipsoidId: EllipsoidId;\n basemapId: string;\n}[];\n","import type { Feature, FeatureCollection, GeoJSON, Geometry, Position } from \"geojson\";\n\n/**\n * Helpers for vector data whose coordinates carry a Z value (elevation), e.g.\n * GPX tracks with `<ele>` readings or LineStringZ/PointZ geometries. MapLibre's\n * 2D style layers ignore the third coordinate, so layers that want to render\n * their Z values use these helpers to detect and rescale elevations before\n * handing the data to a deck.gl overlay. The same data can carry its elevation\n * in a `bbox` member too, which `horizontalBbox` trims back to two dimensions.\n */\n\n/**\n * Reduces a bounding box to its horizontal extent, `[west, south, east, north]`.\n *\n * RFC 7946 §5 lets a `bbox` member carry elevation, in which case it holds six\n * values — `[west, south, minAltitude, east, north, maxAltitude]` — and\n * `@turf/bbox` returns a collection's own member verbatim rather than\n * recomputing it. A consumer reading such a box as four values takes the\n * altitude for a longitude and the east edge for a latitude; that is how a 3D\n * feed reached MapLibre as an out-of-range latitude (#2358).\n *\n * Returns null when there is no usable horizontal extent: a box of any other\n * length, or one carrying a non-finite value anywhere — an empty collection, or\n * one whose features all have a null geometry, bboxes to ±Infinity, and a box\n * whose altitudes are not finite is not one to trust the rest of.\n *\n * @param box - A GeoJSON or Turf bounding box, of four or six values.\n */\nexport function horizontalBbox(\n box: readonly number[] | null | undefined,\n): [number, number, number, number] | null {\n if (!box) return null;\n if (box.length !== 4 && box.length !== 6) return null;\n if (!box.every((value) => Number.isFinite(value))) return null;\n return box.length === 6 ? [box[0], box[1], box[3], box[4]] : [box[0], box[1], box[2], box[3]];\n}\n\n// Proving the *negative* (no Z anywhere) walks every coordinate, so cache the\n// verdict per GeoJSON object — the map sync, the deck overlay, and the Style\n// panel all ask the same question about the same (immutable) data.\nconst hasZCache = new WeakMap<object, boolean>();\nconst hasFiniteZCache = new WeakMap<object, boolean>();\n\n/**\n * Returns true when any coordinate in the GeoJSON carries a finite, non-zero\n * Z value. All-zero Z arrays are treated as flat data because rendering them\n * \"in 3D\" would be indistinguishable from the 2D result. The result is\n * cached per GeoJSON object, so repeated calls on the same data are free.\n *\n * @param geojson - Any GeoJSON object (geometry, feature, or collection).\n * @param includeZero - Accept zero elevations when explicit absolute-height placement matters.\n */\nexport function geojsonHasZCoordinates(\n geojson: GeoJSON | null | undefined,\n includeZero = false,\n): boolean {\n if (!geojson) return false;\n const cache = includeZero ? hasFiniteZCache : hasZCache;\n const cached = cache.get(geojson);\n if (cached !== undefined) return cached;\n const result = someGeometry(geojson, (geometry) =>\n somePosition(geometry, (position) => {\n const z = position[2];\n return typeof z === \"number\" && Number.isFinite(z) && (includeZero || z !== 0);\n }),\n );\n cache.set(geojson, result);\n return result;\n}\n\n/**\n * Returns a copy of the GeoJSON with every coordinate's Z value mapped to\n * `z * verticalScale + offset` (missing or non-finite Z treated as 0). Used\n * to apply vertical exaggeration and a constant altitude offset before 3D\n * rendering. The identity transform (`verticalScale === 1 && offset === 0`)\n * still produces a copy so the non-finite-Z sanitization applies on every\n * path — WebGL does not handle NaN positions gracefully.\n *\n * @param geojson - The feature collection to transform.\n * @param verticalScale - Multiplier applied to each Z value.\n * @param offset - Constant altitude in meters added after scaling.\n */\nexport function transformGeojsonElevation(\n geojson: FeatureCollection,\n verticalScale: number,\n offset: number,\n): FeatureCollection {\n // Positions are normalized to [x, y, z]; a 4th measure value (M), which\n // some producers emit, is intentionally dropped — nothing downstream of\n // this render path consumes it.\n const mapPosition = (position: Position): Position => [\n position[0],\n position[1],\n (typeof position[2] === \"number\" && Number.isFinite(position[2]) ? position[2] : 0) *\n verticalScale +\n offset,\n ];\n return {\n ...geojson,\n features: geojson.features.map((feature) => ({\n ...feature,\n geometry: mapGeometryPositions(feature.geometry, mapPosition),\n })),\n };\n}\n\nfunction someGeometry(geojson: GeoJSON, predicate: (geometry: Geometry) => boolean): boolean {\n switch (geojson.type) {\n case \"FeatureCollection\":\n return geojson.features.some((feature) =>\n feature.geometry ? someGeometry(feature.geometry, predicate) : false,\n );\n case \"Feature\":\n return geojson.geometry ? someGeometry(geojson.geometry, predicate) : false;\n case \"GeometryCollection\":\n return geojson.geometries.some((geometry) => someGeometry(geometry, predicate));\n default:\n return predicate(geojson);\n }\n}\n\nfunction somePosition(geometry: Geometry, predicate: (position: Position) => boolean): boolean {\n switch (geometry.type) {\n case \"Point\":\n return predicate(geometry.coordinates);\n case \"MultiPoint\":\n case \"LineString\":\n return geometry.coordinates.some(predicate);\n case \"MultiLineString\":\n case \"Polygon\":\n return geometry.coordinates.some((ring) => ring.some(predicate));\n case \"MultiPolygon\":\n return geometry.coordinates.some((polygon) => polygon.some((ring) => ring.some(predicate)));\n case \"GeometryCollection\":\n return geometry.geometries.some((child) => somePosition(child, predicate));\n default:\n return false;\n }\n}\n\nfunction mapGeometryPositions(\n geometry: Feature[\"geometry\"],\n mapPosition: (position: Position) => Position,\n): Feature[\"geometry\"] {\n if (!geometry) return geometry;\n switch (geometry.type) {\n case \"Point\":\n return { ...geometry, coordinates: mapPosition(geometry.coordinates) };\n case \"MultiPoint\":\n case \"LineString\":\n return { ...geometry, coordinates: geometry.coordinates.map(mapPosition) };\n case \"MultiLineString\":\n case \"Polygon\":\n return {\n ...geometry,\n coordinates: geometry.coordinates.map((ring) => ring.map(mapPosition)),\n };\n case \"MultiPolygon\":\n return {\n ...geometry,\n coordinates: geometry.coordinates.map((polygon) =>\n polygon.map((ring) => ring.map(mapPosition)),\n ),\n };\n case \"GeometryCollection\":\n return {\n ...geometry,\n geometries: geometry.geometries.map(\n (child) => mapGeometryPositions(child, mapPosition) as Geometry,\n ),\n };\n default:\n return geometry;\n }\n}\n","import type {\n Feature,\n FeatureCollection,\n GeoJsonProperties,\n LineString,\n MultiLineString,\n} from \"geojson\";\n\n/**\n * Pure TypeScript Google Encoded Polyline algorithm codec.\n *\n * Supports arbitrary precision:\n * - precision = 5: Google Maps standard, OSRM, HERE (factor 1e5, ~1.1m precision)\n * - precision = 6: Valhalla, Mapbox, Open Source Routing Machine 6 (factor 1e6, ~0.11m precision)\n *\n * Coordinates are represented as `[lon, lat]` pairs in GeoJSON format.\n */\n\n/**\n * Unescapes backslashes in a polyline string.\n *\n * When polyline strings are copied from JSON payloads, log files, or source code,\n * backslashes are frequently double-escaped as `\\\\` or formatted with escape sequences.\n *\n * @param str - Input string with potentially escaped backslashes.\n * @returns Cleaned polyline string.\n */\nexport function unescapePolyline(str: string): string {\n if (!str || typeof str !== \"string\") return \"\";\n return str.replace(/\\\\\\\\/g, \"\\\\\").replace(/\\\\\"/g, '\"').replace(/\\\\'/g, \"'\");\n}\n\nexport interface PolylineDecodeResult {\n coordinates: [number, number][];\n complete: boolean;\n}\n\n/**\n * Decodes an encoded polyline string into an array of `[lon, lat]` coordinates,\n * along with a `complete` flag indicating whether the entire string was consumed\n * as complete coordinate pairs without truncation or malformed characters.\n *\n * @param encoded - The ASCII-encoded polyline string.\n * @param precision - Number of decimal digits (default: 5).\n * @param unescape - Whether to unescape double-escaped backslashes before decoding (default: false).\n * @returns Object with decoded `coordinates` and `complete` boolean status.\n */\nexport function decodePolylineDetailed(\n encoded: string,\n precision = 5,\n unescape = false,\n): PolylineDecodeResult {\n if (!encoded || typeof encoded !== \"string\") {\n return { coordinates: [], complete: true };\n }\n const cleanEncoded = unescape ? unescapePolyline(encoded) : encoded;\n const factor = 10 ** precision;\n const len = cleanEncoded.length;\n const coordinates: [number, number][] = [];\n let index = 0;\n let lat = 0;\n let lon = 0;\n\n while (index < len) {\n let shift = 0;\n let result = 0;\n let byte: number;\n\n // Decode latitude delta\n let latComplete = false;\n do {\n if (index >= len) return { coordinates, complete: false };\n byte = cleanEncoded.charCodeAt(index++) - 63;\n if (byte < 0 || byte > 63) return { coordinates, complete: false };\n if (shift > 30 || (shift === 30 && (byte & 0x1f) > 0x03)) {\n return { coordinates, complete: false };\n }\n result |= (byte & 0x1f) << shift;\n shift += 5;\n if (byte < 0x20) {\n latComplete = true;\n break;\n }\n } while (byte >= 0x20);\n\n if (!latComplete) return { coordinates, complete: false };\n\n // Unsigned right shift (>>>) for 32-bit safe zigzag decoding\n lat += result & 1 ? ~(result >>> 1) : result >>> 1;\n\n shift = 0;\n result = 0;\n\n // Decode longitude delta\n let lonComplete = false;\n do {\n if (index >= len) return { coordinates, complete: false };\n byte = cleanEncoded.charCodeAt(index++) - 63;\n if (byte < 0 || byte > 63) return { coordinates, complete: false };\n if (shift > 30 || (shift === 30 && (byte & 0x1f) > 0x03)) {\n return { coordinates, complete: false };\n }\n result |= (byte & 0x1f) << shift;\n shift += 5;\n if (byte < 0x20) {\n lonComplete = true;\n break;\n }\n } while (byte >= 0x20);\n\n if (!lonComplete) return { coordinates, complete: false };\n\n lon += result & 1 ? ~(result >>> 1) : result >>> 1;\n\n coordinates.push([lon / factor, lat / factor]);\n }\n\n return { coordinates, complete: true };\n}\n\n/**\n * Decodes an encoded polyline string into an array of `[lon, lat]` coordinates.\n *\n * @param encoded - The ASCII-encoded polyline string.\n * @param precision - Number of decimal digits (default: 5).\n * @param unescape - Whether to unescape double-escaped backslashes before decoding (default: false).\n * @returns Array of `[lon, lat]` coordinate pairs in GeoJSON order.\n */\nexport function decodePolyline(\n encoded: string,\n precision = 5,\n unescape = false,\n): [number, number][] {\n return decodePolylineDetailed(encoded, precision, unescape).coordinates;\n}\n\n/**\n * Encodes a single integer delta value into polyline character chunks.\n */\nfunction encodeSignedNumber(num: number): string {\n let sgnNum = num < 0 ? ~(num << 1) : num << 1;\n let out = \"\";\n while (sgnNum >= 0x20) {\n out += String.fromCharCode((0x20 | (sgnNum & 0x1f)) + 63);\n sgnNum >>>= 5;\n }\n out += String.fromCharCode(sgnNum + 63);\n return out;\n}\n\n/**\n * Encodes an array of `[lon, lat]` coordinates into a Google Encoded Polyline string.\n *\n * @param coordinates - Array of `[lon, lat]` coordinate pairs.\n * @param precision - Number of decimal digits (default: 5).\n * @returns The encoded polyline string.\n */\nexport function encodePolyline(coordinates: [number, number][], precision = 5): string {\n if (!Array.isArray(coordinates) || coordinates.length === 0) return \"\";\n const factor = 10 ** precision;\n let output = \"\";\n let prevLat = 0;\n let prevLon = 0;\n\n for (const [lon, lat] of coordinates) {\n if (!Number.isFinite(lon) || !Number.isFinite(lat)) continue;\n const roundLat = Math.round(lat * factor);\n const roundLon = Math.round(lon * factor);\n\n const deltaLat = roundLat - prevLat;\n const deltaLon = roundLon - prevLon;\n\n output += encodeSignedNumber(deltaLat);\n output += encodeSignedNumber(deltaLon);\n\n prevLat = roundLat;\n prevLon = roundLon;\n }\n\n return output;\n}\n\n/**\n * Decodes an encoded polyline string into a GeoJSON `Feature<LineString>`.\n *\n * @param encoded - The polyline string.\n * @param precision - Coordinate precision (default: 5).\n * @param properties - Optional feature properties.\n * @returns A GeoJSON LineString Feature.\n */\nexport function polylineStrToGeoJSON(\n encoded: string,\n precision = 5,\n properties: GeoJsonProperties = {},\n): Feature<LineString> {\n return {\n type: \"Feature\",\n properties: { ...properties },\n geometry: {\n type: \"LineString\",\n coordinates: decodePolyline(encoded, precision),\n },\n };\n}\n\n/**\n * Encodes a GeoJSON LineString, MultiLineString, Feature, or FeatureCollection into encoded polyline string(s).\n *\n * @param geojson - The GeoJSON input geometry or feature.\n * @param precision - Coordinate precision (default: 5).\n * @returns An encoded polyline string for LineString, or an array of strings for MultiLineString / FeatureCollection.\n */\nexport function geoJSONToPolylineStr(\n geojson:\n | LineString\n | MultiLineString\n | Feature<LineString | MultiLineString>\n | FeatureCollection<LineString | MultiLineString>,\n precision = 5,\n): string | string[] {\n if (!geojson) return \"\";\n\n // Handle Feature wrapper\n if (geojson.type === \"Feature\") {\n return geoJSONToPolylineStr(geojson.geometry, precision);\n }\n\n // Handle FeatureCollection\n if (geojson.type === \"FeatureCollection\") {\n const results: string[] = [];\n for (const feature of geojson.features) {\n const res = geoJSONToPolylineStr(feature.geometry, precision);\n if (Array.isArray(res)) results.push(...res);\n else if (res) results.push(res);\n }\n return results;\n }\n\n // Handle LineString\n if (geojson.type === \"LineString\") {\n return encodePolyline(geojson.coordinates as [number, number][], precision);\n }\n\n // Handle MultiLineString\n if (geojson.type === \"MultiLineString\") {\n return geojson.coordinates.map((lineCoords) =>\n encodePolyline(lineCoords as [number, number][], precision),\n );\n }\n\n return \"\";\n}\n\nexport interface PolylineBatchOptions {\n /** Coordinate precision (default: 5) */\n precision?: number;\n /** Whether to unescape `\\\\` backslashes (default: true) */\n unescape?: boolean;\n /** Custom delimiter string or RegExp separating individual polylines (default: newline) */\n delimiter?: string | RegExp;\n /** Whether to merge lines into a single MultiLineString feature (default: false) */\n asMultiLine?: boolean;\n /** Optional base properties to assign to output features */\n baseProperties?: GeoJsonProperties;\n}\n\n/**\n * Parses and batch-decodes multiple polylines from a text block or file content.\n *\n * @param input - Multiline string or delimited text containing encoded polylines.\n * @param options - Decoding and parsing configuration.\n * @returns A FeatureCollection containing LineString (or MultiLineString) features.\n */\nexport function batchDecodePolylines(\n input: string,\n options: PolylineBatchOptions = {},\n): FeatureCollection<LineString | MultiLineString> {\n if (!input || typeof input !== \"string\") {\n return { type: \"FeatureCollection\", features: [] };\n }\n\n const {\n precision = 5,\n unescape = true,\n delimiter = /\\r?\\n/,\n asMultiLine = false,\n baseProperties = {},\n } = options;\n\n const rawChunks = input.split(delimiter);\n const validLineCoords: [number, number][][] = [];\n const features: Feature<LineString>[] = [];\n\n for (let i = 0; i < rawChunks.length; i++) {\n const raw = rawChunks[i].trim();\n if (!raw) continue;\n // Strip optional surrounding quotes (e.g. from CSV or JSON extract)\n const cleaned = raw.replace(/^[\"']|[\"']$/g, \"\").trim();\n if (!cleaned) continue;\n\n const decodeResult = decodePolylineDetailed(cleaned, precision, unescape);\n if (decodeResult.complete && decodeResult.coordinates.length >= 2) {\n const coords = decodeResult.coordinates;\n validLineCoords.push(coords);\n features.push({\n type: \"Feature\",\n properties: {\n ...baseProperties,\n line_index: features.length + 1,\n point_count: coords.length,\n },\n geometry: {\n type: \"LineString\",\n coordinates: coords,\n },\n });\n }\n }\n\n if (asMultiLine && validLineCoords.length > 0) {\n const multiFeature: Feature<MultiLineString> = {\n type: \"Feature\",\n properties: {\n ...baseProperties,\n line_count: validLineCoords.length,\n point_count: validLineCoords.reduce((acc, c) => acc + c.length, 0),\n },\n geometry: {\n type: \"MultiLineString\",\n coordinates: validLineCoords,\n },\n };\n return {\n type: \"FeatureCollection\",\n features: [multiFeature],\n };\n }\n\n return {\n type: \"FeatureCollection\",\n features,\n };\n}\n","import type { Feature } from \"geojson\";\n\n/**\n * How a freshly matched feature set combines with the existing selection,\n * mirroring QGIS's four selection behaviors: replace the selection, add to\n * it, remove from it, or keep only features in both.\n */\nexport type SelectionMode = \"new\" | \"add\" | \"remove\" | \"intersect\";\n\n/** Selection modes in display order. */\nexport const SELECTION_MODES: readonly SelectionMode[] = [\"new\", \"add\", \"remove\", \"intersect\"];\n\n/**\n * The id under which a feature participates in the selection model. Mirrors\n * the convention shared by the attribute table and the map highlight\n * (`String(feature.id ?? index)`): the feature's own `id` when present,\n * otherwise its index in the layer's feature array.\n */\nexport function featureSelectionId(feature: Feature, index: number): string {\n return String(feature.id ?? index);\n}\n\n/**\n * Combines the current selection with a freshly matched id set according to\n * `mode`. The result is deduplicated and order-stable: \"new\" follows the\n * matched order, \"add\" appends unseen matches after the current ids, and\n * \"remove\"/\"intersect\" preserve the current selection's order.\n */\nexport function applySelectionMode(\n current: readonly string[],\n matched: readonly string[],\n mode: SelectionMode,\n): string[] {\n const matchedSet = new Set(matched);\n switch (mode) {\n case \"new\":\n return Array.from(matchedSet);\n case \"add\": {\n const merged = new Set(current);\n for (const id of matched) merged.add(id);\n return Array.from(merged);\n }\n case \"remove\":\n return Array.from(new Set(current.filter((id) => !matchedSet.has(id))));\n case \"intersect\":\n return Array.from(new Set(current.filter((id) => matchedSet.has(id))));\n }\n}\n\n/**\n * The complement of `current` within `allIds` (QGIS \"Invert selection\"):\n * every feature id not currently selected, in layer order. With an empty\n * selection this selects everything.\n */\nexport function invertSelection(allIds: readonly string[], current: readonly string[]): string[] {\n const selected = new Set(current);\n return allIds.filter((id) => !selected.has(id));\n}\n","import { Color, createExpression } from \"@maplibre/maplibre-gl-style-spec\";\nimport type { StyleExpression } from \"@maplibre/maplibre-gl-style-spec\";\nimport type { Feature } from \"geojson\";\nimport { featureSelectionId } from \"./selection\";\n\n/**\n * Shared Expression Builder logic (GH #1306): a curated MapLibre expression\n * function reference, real parse/type validation via the MapLibre style spec,\n * live preview evaluation against a sample feature, `@`-style variable\n * substitution, and attribute field type inference. The UI dialog that\n * consumes this lives in the desktop app; keeping the logic here lets every\n * expression entry point (rule filters, expression style mode, labels, and\n * later the field calculator and atlas) share one implementation.\n */\n\n/** One documented function/operator the builder can insert. */\nexport interface ExpressionFunctionDoc {\n /** The MapLibre operator name, e.g. `get` or `==`. */\n name: string;\n /** The snippet inserted into the expression text (valid JSON). */\n snippet: string;\n /**\n * i18n key suffix (under `style.expressionBuilder.functions`) for the\n * one-line description. Kept as a suffix so this package stays free of\n * i18next; the app resolves it with `t()`.\n */\n docKey: string;\n}\n\n/** A group of related functions shown as one section of the reference tree. */\nexport interface ExpressionFunctionCategory {\n /** Stable key, also the i18n suffix under `style.expressionBuilder.categories`. */\n key: string;\n functions: ExpressionFunctionDoc[];\n}\n\nconst fn = (name: string, snippet: string, docKey: string): ExpressionFunctionDoc => ({\n name,\n snippet,\n docKey,\n});\n\n/**\n * The curated function reference, grouped by category. Snippets are valid,\n * standalone-compilable MapLibre expressions (enforced by tests) so inserting\n * one into an empty editor always yields a working starting point.\n */\nexport const EXPRESSION_FUNCTION_CATEGORIES: ExpressionFunctionCategory[] = [\n {\n key: \"data\",\n functions: [\n fn(\"get\", '[\"get\", \"field\"]', \"get\"),\n fn(\"has\", '[\"has\", \"field\"]', \"has\"),\n fn(\"id\", '[\"id\"]', \"id\"),\n fn(\"properties\", '[\"properties\"]', \"properties\"),\n fn(\"geometry-type\", '[\"geometry-type\"]', \"geometryType\"),\n fn(\"at\", '[\"at\", 0, [\"literal\", [1, 2, 3]]]', \"at\"),\n fn(\"in\", '[\"in\", \"value\", [\"get\", \"field\"]]', \"in\"),\n fn(\"index-of\", '[\"index-of\", \"value\", [\"get\", \"field\"]]', \"indexOf\"),\n fn(\"length\", '[\"length\", [\"get\", \"field\"]]', \"length\"),\n fn(\"literal\", '[\"literal\", [\"a\", \"b\"]]', \"literal\"),\n fn(\"typeof\", '[\"typeof\", [\"get\", \"field\"]]', \"typeofOp\"),\n ],\n },\n {\n key: \"decision\",\n functions: [\n fn(\"case\", '[\"case\", [\"==\", [\"get\", \"field\"], \"value\"], \"#ff0000\", \"#cccccc\"]', \"caseOp\"),\n fn(\n \"match\",\n '[\"match\", [\"get\", \"field\"], \"a\", \"#2563eb\", \"b\", \"#16a34a\", \"#94a3b8\"]',\n \"match\",\n ),\n fn(\"coalesce\", '[\"coalesce\", [\"get\", \"field\"], \"fallback\"]', \"coalesce\"),\n fn(\"==\", '[\"==\", [\"get\", \"field\"], \"value\"]', \"eq\"),\n fn(\"!=\", '[\"!=\", [\"get\", \"field\"], \"value\"]', \"neq\"),\n fn(\">\", '[\">\", [\"get\", \"field\"], 0]', \"gt\"),\n fn(\">=\", '[\">=\", [\"get\", \"field\"], 0]', \"gte\"),\n fn(\"<\", '[\"<\", [\"get\", \"field\"], 0]', \"lt\"),\n fn(\"<=\", '[\"<=\", [\"get\", \"field\"], 0]', \"lte\"),\n fn(\"all\", '[\"all\", [\">\", [\"get\", \"field\"], 0], [\"<\", [\"get\", \"field\"], 100]]', \"all\"),\n fn(\"any\", '[\"any\", [\"==\", [\"get\", \"field\"], \"a\"], [\"==\", [\"get\", \"field\"], \"b\"]]', \"any\"),\n fn(\"!\", '[\"!\", [\"has\", \"field\"]]', \"not\"),\n ],\n },\n {\n key: \"math\",\n functions: [\n fn(\"+\", '[\"+\", [\"get\", \"field\"], 1]', \"add\"),\n fn(\"-\", '[\"-\", [\"get\", \"field\"], 1]', \"subtract\"),\n fn(\"*\", '[\"*\", [\"get\", \"field\"], 2]', \"multiply\"),\n fn(\"/\", '[\"/\", [\"get\", \"field\"], 2]', \"divide\"),\n fn(\"%\", '[\"%\", [\"get\", \"field\"], 2]', \"modulo\"),\n fn(\"^\", '[\"^\", [\"get\", \"field\"], 2]', \"power\"),\n fn(\"abs\", '[\"abs\", [\"get\", \"field\"]]', \"abs\"),\n fn(\"ceil\", '[\"ceil\", [\"get\", \"field\"]]', \"ceil\"),\n fn(\"floor\", '[\"floor\", [\"get\", \"field\"]]', \"floor\"),\n fn(\"round\", '[\"round\", [\"get\", \"field\"]]', \"round\"),\n fn(\"sqrt\", '[\"sqrt\", [\"get\", \"field\"]]', \"sqrt\"),\n fn(\"ln\", '[\"ln\", [\"get\", \"field\"]]', \"ln\"),\n fn(\"log10\", '[\"log10\", [\"get\", \"field\"]]', \"log10\"),\n fn(\"min\", '[\"min\", [\"get\", \"field\"], 0]', \"min\"),\n fn(\"max\", '[\"max\", [\"get\", \"field\"], 0]', \"max\"),\n ],\n },\n {\n key: \"string\",\n functions: [\n fn(\"concat\", '[\"concat\", [\"get\", \"field\"], \" suffix\"]', \"concat\"),\n fn(\"upcase\", '[\"upcase\", [\"get\", \"field\"]]', \"upcase\"),\n fn(\"downcase\", '[\"downcase\", [\"get\", \"field\"]]', \"downcase\"),\n fn(\"slice\", '[\"slice\", [\"get\", \"field\"], 0, 3]', \"slice\"),\n fn(\n \"number-format\",\n '[\"number-format\", [\"get\", \"field\"], {\"locale\": \"en-US\", \"max-fraction-digits\": 2}]',\n \"numberFormat\",\n ),\n ],\n },\n {\n key: \"conversion\",\n functions: [\n fn(\"to-number\", '[\"to-number\", [\"get\", \"field\"]]', \"toNumber\"),\n fn(\"to-string\", '[\"to-string\", [\"get\", \"field\"]]', \"toString\"),\n fn(\"to-boolean\", '[\"to-boolean\", [\"get\", \"field\"]]', \"toBoolean\"),\n fn(\"to-color\", '[\"to-color\", \"#2563eb\"]', \"toColor\"),\n ],\n },\n {\n key: \"camera\",\n functions: [\n fn(\"zoom\", '[\"zoom\"]', \"zoom\"),\n fn(\n \"interpolate\",\n '[\"interpolate\", [\"linear\"], [\"zoom\"], 5, [\"to-color\", \"#2563eb\"], 12, [\"to-color\", \"#dc2626\"]]',\n \"interpolate\",\n ),\n fn(\"step\", '[\"step\", [\"zoom\"], \"#2563eb\", 10, \"#dc2626\"]', \"step\"),\n fn(\"rgb\", '[\"rgb\", 37, 99, 235]', \"rgb\"),\n fn(\"rgba\", '[\"rgba\", 37, 99, 235, 0.5]', \"rgba\"),\n ],\n },\n];\n\n/**\n * Strips commas that directly precede a closing bracket/brace outside of\n * strings, so user-typed expressions with trailing commas still parse.\n * Shared by {@link parseJsonExpression} (vector-color) and the builder.\n */\nexport function removeTrailingJsonCommas(value: string): string {\n let result = \"\";\n let inString = false;\n let escaped = false;\n\n for (let index = 0; index < value.length; index += 1) {\n const char = value[index];\n\n if (inString) {\n result += char;\n if (escaped) {\n escaped = false;\n } else if (char === \"\\\\\") {\n escaped = true;\n } else if (char === '\"') {\n inString = false;\n }\n continue;\n }\n\n if (char === '\"') {\n inString = true;\n result += char;\n continue;\n }\n\n if (char === \",\") {\n const nextSignificant = value.slice(index + 1).match(/\\S/)?.[0];\n if (nextSignificant === \"]\" || nextSignificant === \"}\") continue;\n }\n\n result += char;\n }\n\n return result;\n}\n\n/** Result types the builder can require of a whole expression. */\nexport type ExpressionExpectedType = \"boolean\" | \"color\" | \"string\" | \"number\";\n\n/** Options for {@link validateMapExpression}. */\nexport interface ValidateMapExpressionOptions {\n /**\n * Variables substituted before compiling, so a numeric `@token` used in a\n * numeric slot type-checks against its value instead of the raw string.\n */\n variables?: ExpressionVariable[];\n /**\n * When set, the style spec type-checks the expression's result against\n * this type (e.g. a filter must produce a boolean), rejecting expressions\n * that compile but cannot fit the destination.\n */\n expectedType?: ExpressionExpectedType;\n}\n\n/**\n * The `rootKey` `createExpression` (style-spec v26+) requires as its second\n * argument — a location label it only surfaces when attaching a runtime\n * warning to `console.warn` during evaluation. These expressions come from the\n * Expression Builder dialog, not a style JSON layer, so a generic label is the\n * honest value; it never appears in the parsing errors we report.\n */\nconst EXPRESSION_ROOT_KEY = \"expression\";\n\n/**\n * Builds the minimal property spec that makes `createExpression` enforce a\n * result type while still allowing zoom- and feature-dependent input.\n *\n * This mirrors the (unexported) `StylePropertySpecification` shape that\n * `@maplibre/maplibre-gl-style-spec` expects — the cast below means the\n * compiler cannot catch a change to that contract, so whenever the\n * style-spec package is bumped (including Dependabot PRs) re-check that\n * expected-type enforcement still works, and that the property spec is still\n * `createExpression`'s third parameter (v26 inserted a `rootKey` at index 1,\n * shifting it from `[1]` to `[2]`). The \"enforces an expected result type\"\n * test in `tests/expressions.test.ts` fails if this shape stops being honored.\n */\nfunction propertySpecFor(expectedType: ExpressionExpectedType) {\n return {\n type: expectedType,\n \"property-type\": \"data-driven\",\n expression: { parameters: [\"zoom\", \"feature\"] },\n } as unknown as NonNullable<Parameters<typeof createExpression>[2]>;\n}\n\n/** Outcome of validating an expression source string. */\nexport interface ExpressionValidation {\n ok: boolean;\n /**\n * Failure class, for callers that want to localize the shape errors:\n * `not-json` / `not-array` / `not-operator` are structural, `compile` means\n * the style spec rejected it (with messages in {@link errors}).\n */\n code?: \"not-json\" | \"not-array\" | \"not-operator\" | \"compile\";\n /** Human-readable problems; empty when `ok`. */\n errors: string[];\n /** The parsed JSON array when the source at least parsed as JSON. */\n parsed?: unknown[];\n}\n\n/**\n * Validates a user-entered MapLibre expression: tolerant JSON parse, shape\n * checks, then a real compile through the MapLibre style spec so operator\n * misuse (wrong arity, unknown operator, type mismatch) is caught in the\n * dialog instead of silently failing on the map. Variables are substituted\n * before compiling (so tokens type-check as their values), and\n * `expectedType` additionally enforces the destination's result type. The\n * returned `parsed` array is the raw, unsubstituted parse. An empty/blank\n * source is valid (surfaces treat it as \"no expression\").\n */\nexport function validateMapExpression(\n source: string,\n options: ValidateMapExpressionOptions = {},\n): ExpressionValidation {\n return compileMapExpression(source, options).validation;\n}\n\n/**\n * The single parse + substitute + compile pass shared by validation and\n * preview evaluation, so a preview never compiles the same source twice.\n * `expression` is set only when the validation succeeded on a non-empty\n * source.\n */\nfunction compileMapExpression(\n source: string,\n options: ValidateMapExpressionOptions,\n): { validation: ExpressionValidation; expression?: StyleExpression } {\n const trimmed = source.trim();\n if (!trimmed) return { validation: { ok: true, errors: [] } };\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(removeTrailingJsonCommas(trimmed));\n } catch (error) {\n return {\n validation: {\n ok: false,\n code: \"not-json\",\n errors: [error instanceof Error ? error.message : \"Invalid JSON\"],\n },\n };\n }\n if (!Array.isArray(parsed)) {\n return { validation: { ok: false, code: \"not-array\", errors: [] } };\n }\n if (typeof parsed[0] !== \"string\") {\n return {\n validation: { ok: false, code: \"not-operator\", errors: [], parsed },\n };\n }\n\n const substituted = substituteExpressionVariables(parsed, options.variables ?? []) as unknown[];\n const compiled = createExpression(\n substituted,\n EXPRESSION_ROOT_KEY,\n options.expectedType ? propertySpecFor(options.expectedType) : undefined,\n );\n if (compiled.result === \"error\") {\n return {\n validation: {\n ok: false,\n code: \"compile\",\n errors: compiled.value.map((issue) =>\n issue.key ? `${issue.key}: ${issue.message}` : issue.message,\n ),\n parsed,\n },\n };\n }\n return { validation: { ok: true, errors: [], parsed }, expression: compiled.value };\n}\n\n/** A named `@` variable with its current value. */\nexport interface ExpressionVariable {\n /** Token including the `@` prefix, e.g. `@project_name`. */\n token: string;\n value: string | number | boolean;\n}\n\n/**\n * Replaces every string node that exactly matches a known `@token` with that\n * variable's value, returning a new structure (the input is not mutated).\n * Unknown `@` strings are left untouched so field values that happen to start\n * with `@` never get mangled.\n */\nexport function substituteExpressionVariables(\n node: unknown,\n variables: ExpressionVariable[],\n): unknown {\n if (typeof node === \"string\" && node.startsWith(\"@\")) {\n const match = variables.find((variable) => variable.token === node);\n return match ? match.value : node;\n }\n if (Array.isArray(node)) {\n return node.map((entry) => substituteExpressionVariables(entry, variables));\n }\n if (node && typeof node === \"object\") {\n return Object.fromEntries(\n Object.entries(node as Record<string, unknown>).map(([key, value]) => [\n key,\n substituteExpressionVariables(value, variables),\n ]),\n );\n }\n return node;\n}\n\n/** Result of a live preview evaluation. */\nexport interface ExpressionPreview {\n kind: \"empty\" | \"error\" | \"value\";\n /** Problems when `kind` is \"error\" (parse or runtime). */\n errors?: string[];\n /** The evaluated value when `kind` is \"value\". */\n value?: unknown;\n}\n\n/** Options for {@link evaluateMapExpression}. */\nexport interface EvaluateMapExpressionOptions {\n /** The sample feature the expression is evaluated against. */\n feature?: Feature | null;\n /** Map zoom used for `[\"zoom\"]`; defaults to 0. */\n zoom?: number;\n /** Variables substituted before compiling. */\n variables?: ExpressionVariable[];\n /** Enforce the destination's result type, as in validation. */\n expectedType?: ExpressionExpectedType;\n}\n\n/**\n * Evaluates an expression source against a sample feature for the builder's\n * live preview. Variables are substituted first, then the expression is\n * compiled with the MapLibre style spec and evaluated with the given zoom.\n * Runtime failures (e.g. `to-color` on garbage) come back as errors instead\n * of throwing.\n */\nexport function evaluateMapExpression(\n source: string,\n options: EvaluateMapExpressionOptions = {},\n): ExpressionPreview {\n const trimmed = source.trim();\n if (!trimmed) return { kind: \"empty\" };\n\n const { validation, expression } = compileMapExpression(trimmed, {\n variables: options.variables,\n expectedType: options.expectedType,\n });\n if (!validation.ok || !expression) {\n return { kind: \"error\", errors: validation.errors };\n }\n\n const feature = options.feature ?? null;\n const geometryType = feature?.geometry?.type ?? \"Unknown\";\n try {\n // evaluateWithoutErrorHandling: the plain evaluate() swallows runtime\n // failures into console.warn, which (a) hides the error from the preview\n // and (b) feeds the app's diagnostics console interceptor from inside a\n // React render, which can re-render the panel and re-evaluate in an\n // endless loop. Throwing lets the catch below surface the message.\n const value = expression.evaluateWithoutErrorHandling({ zoom: options.zoom ?? 0 }, {\n type: geometryType,\n properties: feature?.properties ?? {},\n ...(feature?.id !== undefined ? { id: feature.id } : {}),\n geometry: feature?.geometry,\n } as never);\n return { kind: \"value\", value };\n } catch (error) {\n return {\n kind: \"error\",\n errors: [error instanceof Error ? error.message : String(error)],\n };\n }\n}\n\n/**\n * A compiled per-feature evaluator: the expression is parsed and compiled\n * once, then `evaluate` runs it against each feature. `evaluate` is absent\n * when compilation failed (see `errors`); it throws on runtime evaluation\n * failures (same rationale as {@link evaluateMapExpression}: throwing keeps\n * errors out of console.warn) so callers decide per-feature error handling.\n */\nexport interface CompiledFeatureExpression {\n ok: boolean;\n /** Parse/compile problems when `ok` is false. */\n errors: string[];\n /**\n * Runs the expression against one feature. `zoom` overrides the zoom the\n * expression was compiled with, for callers that re-evaluate a\n * zoom-dependent expression as the camera moves.\n */\n evaluate?: (feature: Feature, zoom?: number) => unknown;\n}\n\n/**\n * Compiles an expression source once for bulk per-feature evaluation (virtual\n * fields, and any other caller that runs one expression over a whole layer).\n * Unlike {@link evaluateMapExpression} the compile cost is paid once, not per\n * feature. An empty source is reported as a failure with no errors — there is\n * nothing to evaluate.\n */\nexport function compileFeatureExpression(\n source: string,\n options: {\n zoom?: number;\n variables?: ExpressionVariable[];\n expectedType?: ExpressionExpectedType;\n } = {},\n): CompiledFeatureExpression {\n const trimmed = source.trim();\n if (!trimmed) return { ok: false, errors: [] };\n\n const { validation, expression } = compileMapExpression(trimmed, {\n variables: options.variables,\n expectedType: options.expectedType,\n });\n if (!validation.ok || !expression) {\n return { ok: false, errors: validation.errors };\n }\n const compiledZoom = options.zoom ?? 0;\n return {\n ok: true,\n errors: [],\n evaluate: (feature, zoom = compiledZoom) =>\n expression.evaluateWithoutErrorHandling({ zoom }, {\n type: feature.geometry?.type ?? \"Unknown\",\n properties: feature.properties ?? {},\n ...(feature.id !== undefined ? { id: feature.id } : {}),\n geometry: feature.geometry,\n } as never),\n };\n}\n\n/** Result of matching a feature array against a boolean expression. */\nexport interface FeatureExpressionMatches {\n /** False when the expression failed to parse or compile. */\n ok: boolean;\n /** Parse/compile problems when `ok` is false. */\n errors: string[];\n /** Selection ids ({@link featureSelectionId}) of the matched features. */\n ids: string[];\n /**\n * Features whose evaluation threw at runtime (e.g. a boolean assertion on\n * a string field). Counted as non-matches so one bad feature cannot abort\n * the whole selection, but surfaced so the UI can warn.\n */\n errorCount: number;\n}\n\n/**\n * Evaluates a boolean expression against every feature and returns the\n * selection ids of the matches (Select by Expression). Unlike\n * {@link evaluateMapExpression} this compiles the source once and reuses the\n * compiled expression across the whole array, so it stays fast on large\n * layers. An empty source is reported as `ok: false` with no errors — there\n * is nothing to select by.\n */\nexport function matchFeaturesByExpression(\n features: readonly Feature[],\n source: string,\n options: { zoom?: number; variables?: ExpressionVariable[] } = {},\n): FeatureExpressionMatches {\n const trimmed = source.trim();\n if (!trimmed) return { ok: false, errors: [], ids: [], errorCount: 0 };\n\n const { validation, expression } = compileMapExpression(trimmed, {\n variables: options.variables,\n expectedType: \"boolean\",\n });\n if (!validation.ok || !expression) {\n return { ok: false, errors: validation.errors, ids: [], errorCount: 0 };\n }\n\n const ids: string[] = [];\n let errorCount = 0;\n features.forEach((feature, index) => {\n try {\n // Same rationale as evaluateMapExpression: evaluateWithoutErrorHandling\n // so runtime failures throw instead of feeding console.warn.\n const value = expression.evaluateWithoutErrorHandling({ zoom: options.zoom ?? 0 }, {\n type: feature.geometry?.type ?? \"Unknown\",\n properties: feature.properties ?? {},\n ...(feature.id !== undefined ? { id: feature.id } : {}),\n geometry: feature.geometry,\n } as never);\n if (value === true) ids.push(featureSelectionId(feature, index));\n } catch {\n errorCount += 1;\n }\n });\n return { ok: true, errors: [], ids, errorCount };\n}\n\n/**\n * True when a preview value is a real style-spec `Color` instance (its\n * evaluated color representation: premultiplied r/g/b/a floats). Shared by\n * the preview formatter and the dialog's color-swatch rendering so the two\n * checks cannot drift apart. An instanceof check (not duck typing) so user\n * attribute data that happens to carry numeric r/g/b/a fields (e.g. via\n * `[\"properties\"]`) is never misclassified as a color.\n */\nexport function isStyleSpecColor(\n value: unknown,\n): value is { r: number; g: number; b: number; a: number } {\n return value instanceof Color;\n}\n\n/**\n * Renders a preview value as a short display string: style-spec Color\n * instances become rgba() strings, plain values render as JSON, and\n * `null`/`undefined` render as \"null\".\n */\nexport function formatExpressionPreviewValue(value: unknown): string {\n if (value === null || value === undefined) return \"null\";\n if (isStyleSpecColor(value)) {\n const color = value;\n // Style-spec colors are premultiplied floats in [0, 1]; undo the\n // premultiplication so the displayed rgba matches the authored color.\n const alpha = color.a;\n const channel = (component: number) => Math.round((alpha === 0 ? 0 : component / alpha) * 255);\n return `rgba(${channel(color.r)}, ${channel(color.g)}, ${channel(color.b)}, ${Number(alpha.toFixed(3))})`;\n }\n try {\n return JSON.stringify(value) ?? String(value);\n } catch {\n return String(value);\n }\n}\n\n/** Attribute field types the builder badges fields with. */\nexport type ExpressionFieldType = \"string\" | \"number\" | \"boolean\" | \"mixed\" | \"unknown\";\n\n/**\n * Infers a display type for each named field by scanning feature properties:\n * a single consistent primitive type wins, disagreements become \"mixed\", and\n * fields with no non-null values are \"unknown\".\n */\nexport function inferFieldTypes(\n features: ReadonlyArray<{ properties?: Record<string, unknown> | null }>,\n names: string[],\n): Record<string, ExpressionFieldType> {\n const result: Record<string, ExpressionFieldType> = {};\n for (const name of names) result[name] = \"unknown\";\n\n for (const feature of features) {\n const properties = feature.properties;\n if (!properties) continue;\n for (const name of names) {\n const value = properties[name];\n if (value === null || value === undefined) continue;\n const valueType = typeof value;\n const fieldType: ExpressionFieldType =\n valueType === \"string\" || valueType === \"number\" || valueType === \"boolean\"\n ? valueType\n : \"mixed\";\n if (result[name] === \"unknown\") result[name] = fieldType;\n else if (result[name] !== fieldType) result[name] = \"mixed\";\n }\n }\n return result;\n}\n","import type { Feature, GeoJsonProperties } from \"geojson\";\nimport {\n compileFeatureExpression,\n formatExpressionPreviewValue,\n isStyleSpecColor,\n} from \"./expressions\";\nimport type { LayerVirtualField } from \"./types\";\n\n/**\n * Virtual fields (QGIS Field Calculator → \"Create virtual field\", issue\n * #1321): expression-backed columns that recompute live instead of being\n * written once as static values.\n *\n * The engine mirrors the persistent-joins engine (`joins.ts`): computed\n * values are materialized into feature properties, so every consumer of\n * attributes — the attribute table, Expression Builder, data-driven styling,\n * labels, selection, export — sees the column with no further wiring.\n * Idempotency uses the same bookkeeping: each applied field records the\n * column it actually added (`addedField`), applying always strips those\n * first, and an existing column always wins a name collision (the virtual\n * field is skipped entirely), so stripping exactly restores the pre-apply\n * properties.\n *\n * Expressions are declarative MapLibre expressions compiled through the\n * style spec — never arbitrary code — so persisting them in `.geolibre.json`\n * and re-evaluating them on project load is safe (unlike the attribute\n * table's Field Calculator, whose JavaScript evaluator must never run\n * persisted expressions). Fields apply in list order and each sees the\n * columns materialized by earlier fields, so a virtual field can build on\n * another. Zoom-dependent expressions evaluate at zoom 0 and `@` variables\n * are not substituted: a virtual field is a property of the data, not of the\n * current view.\n *\n * Known trade-off, shared with the joins engine (see `joins.ts`): when a\n * layer's data is replaced wholesale, the replacement is stripped with the\n * *previous* bookkeeping. That is required because a replacement can also be\n * a write-back of the derived output (the attribute table round-trips\n * `layer.geojson`), which must not freeze a stale computed value into base\n * data — but it means a replacement dataset's own column whose name matches a\n * previously-materialized virtual column is replaced by the expression's\n * value for that column. Renaming or removing the virtual field first keeps\n * such collisions from arising.\n */\n\n/**\n * Remove every column previously added by `fields` (per their `addedField`\n * bookkeeping) from a copy of `features`, restoring the pre-apply properties.\n * Features without any tracked column are returned unchanged (same\n * reference).\n */\nexport function stripVirtualFieldColumns(\n features: Feature[],\n fields: LayerVirtualField[] | undefined,\n): Feature[] {\n const tracked = new Set<string>();\n for (const field of fields ?? []) {\n if (field.addedField) tracked.add(field.addedField);\n }\n if (tracked.size === 0) return features;\n return features.map((feature) => {\n const props = feature.properties;\n if (!props) return feature;\n let hasTracked = false;\n for (const key of tracked) {\n if (key in props) {\n hasTracked = true;\n break;\n }\n }\n if (!hasTracked) return feature;\n const next: GeoJsonProperties = {};\n for (const [key, value] of Object.entries(props)) {\n if (!tracked.has(key)) next[key] = value;\n }\n return { ...feature, properties: next };\n });\n}\n\n/** Result of {@link applyLayerVirtualFields}: features plus refreshed bookkeeping. */\nexport interface ApplyVirtualFieldsResult {\n features: Feature[];\n /** Input fields with `addedField`/`error`/`errorCount` recomputed for this run. */\n fields: LayerVirtualField[];\n}\n\n/**\n * Normalize an evaluated expression value into a property value: `undefined`\n * and non-finite numbers become null (a clean empty cell), style-spec Color\n * instances become their rgba() string (a Color object would neither\n * serialize nor display usefully), everything else passes through.\n */\nfunction normalizeComputedValue(value: unknown): unknown {\n if (value === undefined) return null;\n if (typeof value === \"number\" && !Number.isFinite(value)) return null;\n if (isStyleSpecColor(value)) return formatExpressionPreviewValue(value);\n return value;\n}\n\n/**\n * Apply `fields` in order to base (already-stripped) `features`, returning\n * new feature objects with each computed column merged into their properties.\n *\n * Semantics per field: a disabled field, an empty/colliding output name, or\n * an expression that fails to compile contributes nothing (with the compile\n * error recorded on the field); a runtime evaluation failure nulls that one\n * feature's cell and increments the field's `errorCount` instead of aborting\n * the column. Fields evaluate sequentially, so a later field's expression\n * can `[\"get\", ...]` an earlier field's column.\n */\nexport function applyLayerVirtualFields(\n features: Feature[],\n fields: LayerVirtualField[] | undefined,\n): ApplyVirtualFieldsResult {\n const fieldList = fields ?? [];\n const clearBookkeeping = (field: LayerVirtualField): LayerVirtualField => ({\n ...field,\n addedField: undefined,\n error: undefined,\n errorCount: undefined,\n });\n // Only bail out when no field is active. A zero-feature layer still runs\n // the per-field pass below: compiling validates the expression (so a real\n // compile error is surfaced, not swallowed) and a free name is still\n // recorded as `addedField` — otherwise an empty dataset would be\n // indistinguishable from a name collision in the UI.\n const active = fieldList.filter((field) => field.enabled !== false);\n if (active.length === 0) {\n return { features, fields: fieldList.map(clearBookkeeping) };\n }\n\n // Existing columns always win a name collision: a virtual field never\n // shadows a base column, a joined column, or an earlier virtual field.\n const usedNames = new Set<string>();\n for (const feature of features) {\n for (const key of Object.keys(feature.properties ?? {})) usedNames.add(key);\n }\n\n // One clone up front; per-field application then mutates our own copies.\n const out = features.map((feature) => ({\n ...feature,\n properties: { ...(feature.properties ?? {}) },\n }));\n\n const outFields = fieldList.map((field): LayerVirtualField => {\n if (field.enabled === false) return clearBookkeeping(field);\n const name = field.name.trim();\n if (!name || usedNames.has(name)) return clearBookkeeping(field);\n\n const compiled = compileFeatureExpression(field.expression);\n if (!compiled.ok || !compiled.evaluate) {\n return {\n ...clearBookkeeping(field),\n error: compiled.errors[0] ?? \"Invalid expression\",\n };\n }\n\n usedNames.add(name);\n let errorCount = 0;\n for (const feature of out) {\n let value: unknown = null;\n try {\n value = normalizeComputedValue(compiled.evaluate(feature));\n } catch {\n errorCount += 1;\n }\n feature.properties[name] = value;\n }\n return {\n ...clearBookkeeping(field),\n addedField: name,\n ...(errorCount > 0 ? { errorCount } : {}),\n };\n });\n\n return { features: out, fields: outFields };\n}\n","import type { Feature, FeatureCollection, GeoJsonProperties } from \"geojson\";\nimport type { GeoLibreLayer, LayerJoin, LayerVirtualField } from \"./types\";\nimport { applyLayerVirtualFields, stripVirtualFieldColumns } from \"./virtual-fields\";\n\n/**\n * Persistent attribute joins (QGIS Layer Properties → Joins), issue #1315.\n *\n * A layer's `joins` are live left joins that materialize columns from another\n * layer's attribute table into this layer's feature properties. Materializing\n * (rather than resolving lazily) means every consumer of attributes — the\n * attribute table, Expression Builder, data-driven styling, labels, diagrams,\n * export — sees the joined columns with no further wiring.\n *\n * Idempotency without a duplicate base copy: each applied join records the\n * output column names it added (`addedFields`), and applying joins always\n * strips those first. Base columns win every name collision (a joined column\n * whose output name already exists is skipped entirely), so stripping the\n * added columns exactly restores the pre-join properties.\n *\n * Known trade-off of that bookkeeping: when a layer's data is replaced\n * wholesale (file reload), the replacement is stripped with the *previous*\n * `addedFields`. That is required because a replacement can also be a\n * write-back of the joined output (the attribute table round-trips\n * `layer.geojson`), which must not freeze stale joined values into base data —\n * but it means a reloaded base column whose name collides with a\n * previously-joined output column is replaced by the join's value for that\n * column. A field-name prefix (the QGIS convention the UI suggests) keeps\n * such collisions from arising.\n *\n * The data is already in memory as JS feature objects, so the join is a plain\n * hash join here rather than the DuckDB-WASM SQL statement sketched in the\n * issue — the result is identical for equality keys and the engine stays\n * synchronous and dependency-free. Key semantics deliberately mirror the\n * Processing → Vector attribute join (and the sidecar's `_attribute_join_key`):\n * empty values never match, and non-empty values compare stringified.\n */\n\n/** Canonical JSON for object values (sorted keys), matching the processing engine. */\nfunction stableStringify(value: unknown): string {\n if (Array.isArray(value)) {\n return `[${value.map(stableStringify).join(\",\")}]`;\n }\n if (value !== null && typeof value === \"object\") {\n const entries = Object.entries(value as Record<string, unknown>)\n .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))\n .map(([k, v]) => `${JSON.stringify(k)}:${stableStringify(v)}`);\n return `{${entries.join(\",\")}}`;\n }\n return JSON.stringify(value) ?? \"null\";\n}\n\nfunction valueToString(value: unknown): string {\n if (typeof value === \"boolean\") return value ? \"true\" : \"false\";\n if (value !== null && typeof value === \"object\") return stableStringify(value);\n return String(value);\n}\n\n/**\n * Match key for a persistent join: empty values (null/undefined/NaN/empty\n * string) never match a row, mirroring a SQL/pandas NaN join key. Non-empty\n * values are keyed by their string form, so a numeric `5` and the string `\"5\"`\n * join while a zero-padded code like `\"01001\"` only matches another `\"01001\"`.\n * Kept in sync with the Processing attribute join's `attributeJoinKey`.\n */\nexport function layerJoinKey(value: unknown): string | null {\n const isEmpty =\n value === null ||\n value === undefined ||\n (typeof value === \"number\" && Number.isNaN(value)) ||\n valueToString(value) === \"\";\n return isEmpty ? null : valueToString(value);\n}\n\n/** GeoJSON columns are own properties; inherited object members are not data. */\nfunction fieldValue(properties: GeoJsonProperties, field: string): unknown {\n return properties && Object.hasOwn(properties, field) ? properties[field] : undefined;\n}\n\n/**\n * Remove every column previously added by `joins` (per their `addedFields`\n * bookkeeping) from a copy of `features`, restoring the pre-join properties.\n * Features without any tracked column are returned unchanged (same reference).\n */\nexport function stripJoinFields(features: Feature[], joins: LayerJoin[] | undefined): Feature[] {\n const tracked = new Set<string>();\n for (const join of joins ?? []) {\n for (const field of join.addedFields ?? []) tracked.add(field);\n }\n if (tracked.size === 0) return features;\n return features.map((feature) => {\n const props = feature.properties;\n if (!props) return feature;\n let hasTracked = false;\n for (const key of tracked) {\n if (key in props) {\n hasTracked = true;\n break;\n }\n }\n if (!hasTracked) return feature;\n const next: GeoJsonProperties = {};\n for (const [key, value] of Object.entries(props)) {\n if (!tracked.has(key)) next[key] = value;\n }\n return { ...feature, properties: next };\n });\n}\n\n/** Result of {@link applyLayerJoins}: joined features plus refreshed join records. */\nexport interface ApplyLayerJoinsResult {\n features: Feature[];\n /** Input joins with `addedFields` and `stats` recomputed for this run. */\n joins: LayerJoin[];\n}\n\n/**\n * Apply `joins` in order to base (already-stripped) `features`, returning new\n * feature objects with the joined columns merged into their properties.\n *\n * Semantics per join: left join, first matching join row wins, and joined\n * columns are null-filled on unmatched features so the schema stays\n * consistent. An output name (prefix + field) that collides with an existing\n * column — from the base data or an earlier join — drops that one column;\n * the join's other columns still apply. A disabled join, or one whose source\n * cannot be resolved, contributes nothing and gets empty `addedFields` and no\n * stats.\n *\n * @param features - The layer's base features (strip previous joins first).\n * @param joins - Join definitions in application order.\n * @param resolveSource - Maps a join's `joinLayerId` to that layer's current\n * feature collection, or `undefined` when the layer is gone (or is the\n * target itself; self-joins are refused by the caller).\n */\nexport function applyLayerJoins(\n features: Feature[],\n joins: LayerJoin[] | undefined,\n resolveSource: (joinLayerId: string) => FeatureCollection | undefined,\n): ApplyLayerJoinsResult {\n const joinList = joins ?? [];\n // Resolve each source once, shared between the early-exit check and the\n // per-join application below.\n const resolved = new Map<string, FeatureCollection | undefined>();\n const resolveOnce = (joinLayerId: string): FeatureCollection | undefined => {\n if (!resolved.has(joinLayerId)) {\n resolved.set(joinLayerId, resolveSource(joinLayerId));\n }\n return resolved.get(joinLayerId);\n };\n const active = joinList.filter((join) => join.enabled !== false && resolveOnce(join.joinLayerId));\n if (active.length === 0) {\n return {\n features,\n joins: joinList.map((join) => ({\n ...join,\n addedFields: [],\n stats: undefined,\n })),\n };\n }\n\n // One clone up front; per-join application then mutates our own copies.\n const out = features.map((feature) => ({\n ...feature,\n properties: { ...(feature.properties ?? {}) },\n }));\n\n // Schema-level collision tracking: a joined column never shadows a base\n // column (or an earlier join's column) on any feature.\n const usedNames = new Set<string>();\n for (const feature of features) {\n for (const key of Object.keys(feature.properties ?? {})) usedNames.add(key);\n }\n\n const outJoins = joinList.map((join): LayerJoin => {\n const source = join.enabled === false ? undefined : resolveOnce(join.joinLayerId);\n if (!source) return { ...join, addedFields: [], stats: undefined };\n\n const joinFeatures = (source.features ?? []).filter(Boolean);\n\n // Collect join-table columns in first-seen order for a deterministic schema.\n const joinKeysOrder: string[] = [];\n const joinKeySet = new Set<string>();\n for (const jf of joinFeatures) {\n for (const key of Object.keys(jf.properties ?? {})) {\n if (!joinKeySet.has(key)) {\n joinKeySet.add(key);\n joinKeysOrder.push(key);\n }\n }\n }\n\n // An explicit `fields` array is honored verbatim (an empty subset joins no\n // columns); only an absent array means \"every field except the key\".\n const requested =\n join.fields !== undefined\n ? join.fields.filter((field) => joinKeySet.has(field))\n : joinKeysOrder.filter((key) => key !== join.joinField);\n const prefix = join.prefix ?? \"\";\n const fieldPairs: Array<[source: string, output: string]> = [];\n for (const field of requested) {\n const outputName = prefix + field;\n if (usedNames.has(outputName)) continue;\n usedNames.add(outputName);\n fieldPairs.push([field, outputName]);\n }\n\n // First-match lookup: when several join rows share a key, the first wins.\n const lookup = new Map<string, GeoJsonProperties>();\n for (const jf of joinFeatures) {\n const key = layerJoinKey(fieldValue(jf.properties, join.joinField));\n if (key === null || lookup.has(key)) continue;\n lookup.set(key, jf.properties ?? {});\n }\n\n let matched = 0;\n const targetKeys = new Set<string>();\n for (const feature of out) {\n const props = feature.properties;\n const key = layerJoinKey(fieldValue(props, join.targetField));\n if (key !== null) targetKeys.add(key);\n const row = key === null ? undefined : lookup.get(key);\n if (row) {\n matched += 1;\n for (const [field, outputName] of fieldPairs) {\n props[outputName] = fieldValue(row, field) ?? null;\n }\n } else {\n for (const [, outputName] of fieldPairs) props[outputName] = null;\n }\n }\n\n // Counts rows, not unique keys: duplicate unmatched rows each count, as\n // the stat (and the UI copy) promise.\n let unmatchedJoin = 0;\n for (const jf of joinFeatures) {\n const key = layerJoinKey(fieldValue(jf.properties, join.joinField));\n if (key !== null && !targetKeys.has(key)) unmatchedJoin += 1;\n }\n\n return {\n ...join,\n addedFields: fieldPairs.map(([, outputName]) => outputName),\n stats: {\n matchedCount: matched,\n unmatchedTargetCount: out.length - matched,\n unmatchedJoinCount: unmatchedJoin,\n },\n };\n });\n\n return { features: out, joins: outJoins };\n}\n\n/**\n * Strip-and-reapply this layer's derived columns — persistent joins, then\n * virtual fields (so an expression can read joined columns) — resolving join\n * sources from `allLayers`. Pass `nextJoins`/`nextVirtualFields` to replace\n * the definitions (the layer's current bookkeeping still drives the strip, so\n * removed definitions clean up after themselves); omit them to refresh the\n * existing definitions against current data. Layers without a feature\n * collection are returned unchanged.\n */\nexport function applyJoinsToLayer(\n layer: GeoLibreLayer,\n allLayers: GeoLibreLayer[],\n nextJoins?: LayerJoin[],\n nextVirtualFields?: LayerVirtualField[],\n): GeoLibreLayer {\n const geojson = layer.geojson;\n const joins = nextJoins ?? layer.joins ?? [];\n const virtualFields = nextVirtualFields ?? layer.virtualFields ?? [];\n if (!geojson) {\n return {\n ...layer,\n joins: joins.length > 0 ? joins : undefined,\n virtualFields: virtualFields.length > 0 ? virtualFields : undefined,\n };\n }\n // Virtual columns strip before join columns so a join output name held by a\n // stale virtual column frees up; the reverse order would also work today\n // (both strips are pure column removals), but this matches apply order.\n const base = stripJoinFields(\n stripVirtualFieldColumns(geojson.features ?? [], layer.virtualFields),\n layer.joins,\n );\n const applied = applyLayerJoins(base, joins, (joinLayerId) => {\n if (joinLayerId === layer.id) return undefined;\n return allLayers.find((candidate) => candidate.id === joinLayerId)?.geojson;\n });\n const withVirtual = applyLayerVirtualFields(applied.features, virtualFields);\n return {\n ...layer,\n geojson: { ...geojson, features: withVirtual.features },\n joins: applied.joins.length > 0 ? applied.joins : undefined,\n virtualFields: withVirtual.fields.length > 0 ? withVirtual.fields : undefined,\n };\n}\n\n/**\n * Ids of every layer whose data (directly or transitively) feeds `layerId`'s\n * joins, following `joinLayerId` edges through each source's own joins.\n * Disabled joins count too: re-enabling one must not spring a cycle. The Joins\n * UI uses this to keep a layer that already consumes the target — however\n * indirectly — out of the join-source picker, so circular joins cannot be\n * authored (the refresh cascade still breaks them defensively for hand-edited\n * projects).\n */\nexport function collectTransitiveJoinSourceIds(\n layers: GeoLibreLayer[],\n layerId: string,\n): Set<string> {\n const byId = new Map(layers.map((layer) => [layer.id, layer]));\n const visited = new Set<string>();\n const queue = [layerId];\n while (queue.length > 0) {\n const current = byId.get(queue.shift() as string);\n for (const join of current?.joins ?? []) {\n if (visited.has(join.joinLayerId)) continue;\n visited.add(join.joinLayerId);\n queue.push(join.joinLayerId);\n }\n }\n return visited;\n}\n\n/**\n * Order `candidates` (layers with joins) so every layer comes after the\n * candidates its joins consume — Kahn's algorithm over \"join source → join\n * target\" edges within the candidate set. When a cycle blocks progress\n * (possible only in hand-edited projects; the UI refuses circular joins), an\n * actual cycle member is forced through — found by walking unmet-source edges\n * until a node repeats — so consumers *downstream* of the cycle still order\n * after it rather than falling back ahead of it.\n */\nfunction topologicalJoinOrder(candidates: GeoLibreLayer[]): string[] {\n const candidateIds = new Set(candidates.map((layer) => layer.id));\n const indegree = new Map<string, number>();\n const dependents = new Map<string, string[]>();\n const sourcesOf = new Map<string, string[]>();\n for (const layer of candidates) indegree.set(layer.id, 0);\n for (const layer of candidates) {\n for (const join of layer.joins ?? []) {\n if (\n join.enabled === false ||\n join.joinLayerId === layer.id ||\n !candidateIds.has(join.joinLayerId)\n ) {\n continue;\n }\n indegree.set(layer.id, (indegree.get(layer.id) ?? 0) + 1);\n const list = dependents.get(join.joinLayerId) ?? [];\n list.push(layer.id);\n dependents.set(join.joinLayerId, list);\n const sources = sourcesOf.get(layer.id) ?? [];\n sources.push(join.joinLayerId);\n sourcesOf.set(layer.id, sources);\n }\n }\n const order: string[] = [];\n const orderedSet = new Set<string>();\n const queue = candidates.filter((layer) => indegree.get(layer.id) === 0).map((layer) => layer.id);\n while (order.length < candidates.length) {\n if (queue.length === 0) {\n // Every unordered layer has at least one unordered source, so walking\n // unmet-source edges from any unordered layer must revisit a node, and\n // that node sits on a cycle.\n const start = candidates.find((layer) => !orderedSet.has(layer.id));\n if (!start) break;\n let cursor = start.id;\n const walked = new Set<string>();\n while (!walked.has(cursor)) {\n walked.add(cursor);\n const next = (sourcesOf.get(cursor) ?? []).find((source) => !orderedSet.has(source));\n if (next === undefined) break;\n cursor = next;\n }\n queue.push(cursor);\n }\n const id = queue.shift() as string;\n if (orderedSet.has(id)) continue;\n orderedSet.add(id);\n order.push(id);\n for (const dependent of dependents.get(id) ?? []) {\n const remaining = (indegree.get(dependent) ?? 1) - 1;\n indegree.set(dependent, remaining);\n if (remaining === 0 && !orderedSet.has(dependent)) queue.push(dependent);\n }\n }\n return order;\n}\n\n/**\n * Refresh every layer whose joins (directly or transitively) consume the\n * layer identified by `seedId`, after that layer's data changed — or after it\n * was removed (a gone source resolves to nothing, so its frozen columns strip\n * away). The affected layers re-derive in topological dependency order, so a\n * layer joining two other affected layers sees both of them fresh regardless\n * of their positions in the layer panel. The seed itself is not touched.\n */\nexport function cascadeLayerJoinRefresh(layers: GeoLibreLayer[], seedId: string): GeoLibreLayer[] {\n // Collect the transitive dependents of the seed.\n const affected = new Set<string>();\n const queue = [seedId];\n while (queue.length > 0) {\n const sourceId = queue.shift() as string;\n for (const layer of layers) {\n if (layer.id === seedId || affected.has(layer.id)) continue;\n if (layer.joins?.some((join) => join.enabled !== false && join.joinLayerId === sourceId)) {\n affected.add(layer.id);\n queue.push(layer.id);\n }\n }\n }\n if (affected.size === 0) return layers;\n\n let current = layers;\n const order = topologicalJoinOrder(layers.filter((layer) => affected.has(layer.id)));\n for (const id of order) {\n current = current.map((layer) => (layer.id === id ? applyJoinsToLayer(layer, current) : layer));\n }\n return current;\n}\n\n/**\n * Re-resolve every layer's persistent joins against the freshly loaded layer\n * set (project open). Layers re-derive in topological order of their join\n * dependencies, so a chain (`C joins A, A joins B`) resolves A before C; a\n * hand-edited cycle is broken by forcing one of its members through first\n * (see {@link topologicalJoinOrder}), so consumers downstream of the cycle\n * still re-derive after it. Layers with virtual fields but no joins re-derive\n * too (their expressions run against the freshly loaded features). Layer sets\n * without joins or virtual fields pass through by reference.\n */\nexport function reapplyLayerJoins(layers: GeoLibreLayer[]): GeoLibreLayer[] {\n const joined = layers.filter((layer) => layer.joins?.length || layer.virtualFields?.length);\n if (joined.length === 0) return layers;\n\n let current = layers;\n for (const id of topologicalJoinOrder(joined)) {\n current = current.map((layer) => (layer.id === id ? applyJoinsToLayer(layer, current) : layer));\n }\n return current;\n}\n"],"mappings":";;;;;;;;;AA2CA,MAAa,aAAa;CACxB;EACE,IAAI;EACJ,MAAM;EACN,qBAAqB;EACrB,mBAAmB;CACrB;CACA;EACE,IAAI;EACJ,MAAM;EACN,qBAAqB;EACrB,mBAAmB;CACrB;CACA;EACE,IAAI;EACJ,MAAM;EACN,qBAAqB;EACrB,mBAAmB;CACrB;CACA;EACE,IAAI;EACJ,MAAM;EACN,qBAAqB;EACrB,mBAAmB;CACrB;CACA;EACE,IAAI;EACJ,MAAM;EACN,qBAAqB;EACrB,mBAAmB;CACrB;CACA;EACE,IAAI;EACJ,MAAM;EACN,qBAAqB;EACrB,mBAAmB;CACrB;CACA;EACE,IAAI;EACJ,MAAM;EACN,qBAAqB;EACrB,mBAAmB;CACrB;CACA;EACE,IAAI;EACJ,MAAM;EACN,qBAAqB;EACrB,mBAAmB;CACrB;CACA;EACE,IAAI;EACJ,MAAM;EACN,qBAAqB;EACrB,mBAAmB;CACrB;CACA;EACE,IAAI;EACJ,MAAM;EACN,qBAAqB;EACrB,mBAAmB;CACrB;CACA;EACE,IAAI;EACJ,MAAM;EACN,qBAAqB;EACrB,mBAAmB;CACrB;CACA;EACE,IAAI;EACJ,MAAM;EACN,qBAAqB;EACrB,mBAAmB;CACrB;AACF;AAIA,MAAa,uBAAoC;;AAGjD,SAAgB,aAAa,IAAmC;CAC9D,OACE,WAAW,MAAM,MAAM,EAAE,OAAO,EAAE,KAAK,WAAW,MAAM,MAAM,EAAE,OAAA,OAA2B;AAE/F;;;;;;AAOA,SAAgB,iBAAiB,WAA8B;CAC7D,MAAM,IAAI,UAAU;CACpB,IAAI,CAAC,UAAU,mBAAmB,OAAO;CAEzC,MAAM,IAAI,KAAK,IADL,IAAI,UAAU;CAExB,QAAQ,IAAI,IAAI,KAAK;AACvB;;AAGA,MAAa,2BAA2B,iBAAiB,WAAW,MAAM,MAAM,EAAE,OAAO,OAAO,CAAE;AAIlG,IAAI,oBAAiC;;;;;;AAOrC,SAAgB,qBAAqB,IAA8B;CACjE,oBAAoB,aAAa,EAAE,CAAC,CAAC;AACvC;AAEA,SAAgB,qBAAgC;CAC9C,OAAO,aAAa,iBAAiB;AACvC;;AAGA,SAAgB,4BAAoC;CAClD,OAAO,iBAAiB,mBAAmB,CAAC;AAC9C;;AAGA,SAAgB,+BAAuC;CACrD,OAAO,mBAAmB,CAAC,CAAC;AAC9B;;;;;;;;;;;;;;;;AAmBA,SAAgB,2BAAmC;CACjD,OAAO,0BAA0B,IAAI;AACvC;;;;;;;;;;;AAYA,SAAgB,kBAAkB,QAAwB;CACxD,OAAO,SAAS,yBAAyB;AAC3C;;;;;;;;;;;;AAaA,SAAgB,kBAAkB,QAAwB;CACxD,OAAO,SAAS,yBAAyB;AAC3C;;;;;;;;;AAUA,SAAgB,gBAAgB,MAAsB;CACpD,MAAM,QAAQ,yBAAyB;CACvC,OAAO,OAAO,QAAQ;AACxB;AAkCA,MAAa,oCAAoC;AAEjD,MAAM,kBAAkB;;AAGxB,MAAM,aAAa,WAAmB,GAAG,OAAO,KAAK;AAKrD,MAAM,kBAAkB;AAOxB,MAAM,iBAAiB;AAGvB,MAAM,yBAAyB;;AAG/B,MAAM,cAAc,WAAmB,GAAG,OAAO,KAAK;AAmBtD,MAAa,qBAAkD;CAE7D;EACE,IAAI;EACJ,MAAM;EACN,UAAU,GAAG,kCAAkC;EAC/C,SAAS,GAAG,gBAAgB;EAC5B,QAAQ;EACR,SAAS;EACT,aAAa,UAAU,aAAa;EACpC,aAAa;CACf;CACA;EACE,IAAI;EACJ,MAAM;EACN,UAAU,GAAG,kCAAkC;EAC/C,SAAS,GAAG,gBAAgB;EAC5B,QAAQ;EACR,SAAS;EACT,aAAa,UAAU,sBAAsB;EAC7C,aAAa;CACf;CACA;EACE,IAAI;EACJ,MAAM;EACN,UAAU,GAAG,kCAAkC;EAC/C,SAAS,GAAG,gBAAgB;EAC5B,QAAQ;EACR,SAAS;EACT,aAAa,UAAU,aAAa;EACpC,aAAa;CACf;CACA;EACE,IAAI;EACJ,MAAM;EACN,UAAU,GAAG,kCAAkC;EAC/C,SACE;EACF,SAAS;EACT,aAAa;EACb,aAAa;CACf;CACA;EACE,IAAI;EACJ,MAAM;EACN,UAAU,GAAG,kCAAkC;EAC/C,SAAS,GAAG,gBAAgB;EAC5B,QAAQ;EACR,SAAS;EACT,aAAa,UAAU,aAAa;EACpC,aAAa;CACf;CACA;EACE,IAAI;EACJ,MAAM;EACN,UAAU,GAAG,kCAAkC;EAC/C,SAAS,GAAG,gBAAgB;EAC5B,QAAQ;EACR,SAAS;EACT,aAAa,UAAU,aAAa;EACpC,aAAa;CACf;CAEA;EACE,IAAI;EACJ,MAAM;EACN,UAAU,GAAG,kCAAkC;EAC/C,SAAS,GAAG,gBAAgB;EAC5B,QAAQ;EACR,SAAS;EACT,aAAa,UAAU,oBAAoB;EAC3C,aAAa;CACf;CACA;EACE,IAAI;EACJ,MAAM;EACN,UAAU,GAAG,kCAAkC;EAC/C,SACE;EACF,SAAS;EACT,aAAa;EACb,aAAa;CACf;CAIA;EACE,IAAI;EACJ,MAAM;EACN,UAAU,GAAG,kCAAkC;EAC/C,SAAS,GAAG,eAAe;EAC3B,SAAS;EACT,aAAa,WAAW,sBAAsB;EAC9C,aAAa;CACf;CACA;EACE,IAAI;EACJ,MAAM;EACN,UAAU,GAAG,kCAAkC;EAC/C,SAAS,GAAG,eAAe;EAC3B,SAAS;EACT,aAAa,WAAW,gBAAgB;EACxC,aAAa;CACf;CAEA;EACE,IAAI;EACJ,MAAM;EACN,UAAU,GAAG,kCAAkC;EAC/C,SAAS,GAAG,eAAe;EAC3B,SAAS;EACT,aAAa,WAAW,YAAY;EACpC,aAAa;CACf;CACA;EACE,IAAI;EACJ,MAAM;EACN,UAAU,GAAG,kCAAkC;EAC/C,SAAS,GAAG,eAAe;EAC3B,SAAS;EACT,aAAa,WAAW,YAAY;EACpC,aAAa;CACf;CAEA;EACE,IAAI;EACJ,MAAM;EACN,UAAU,GAAG,kCAAkC;EAC/C,SAAS,GAAG,eAAe;EAC3B,SAAS;EACT,aAAa,WAAW,YAAY;EACpC,aAAa;CACf;CACA;EACE,IAAI;EACJ,MAAM;EACN,UAAU,GAAG,kCAAkC;EAC/C,SAAS,GAAG,eAAe;EAC3B,SAAS;EACT,aAAa,WAAW,YAAY;EACpC,aAAa;CACf;CACA;EACE,IAAI;EACJ,MAAM;EACN,UAAU,GAAG,kCAAkC;EAC/C,SAAS,GAAG,eAAe;EAC3B,SAAS;EACT,aAAa,WAAW,YAAY;EACpC,aAAa;CACf;CACA;EACE,IAAI;EACJ,MAAM;EACN,UAAU,GAAG,kCAAkC;EAC/C,SAAS,GAAG,eAAe;EAC3B,SAAS;EACT,aAAa,WAAW,YAAY;EACpC,aAAa;CACf;CAEA;EACE,IAAI;EACJ,MAAM;EACN,UAAU,GAAG,kCAAkC;EAC/C,SAAS,GAAG,eAAe;EAC3B,SAAS;EACT,aAAa,WAAW,kBAAkB;EAC1C,aAAa;CACf;CACA;EACE,IAAI;EACJ,MAAM;EACN,UAAU,GAAG,kCAAkC;EAC/C,SAAS,GAAG,eAAe;EAC3B,SAAS;EACT,aAAa,WAAW,mBAAmB;EAC3C,aAAa;CACf;CAEA;EACE,IAAI;EACJ,MAAM;EACN,UAAU,GAAG,kCAAkC;EAC/C,SAAS,GAAG,eAAe;EAC3B,SAAS;EACT,aAAa,WAAW,uBAAuB;EAC/C,aAAa;CACf;CACA;EACE,IAAI;EACJ,MAAM;EACN,UAAU,GAAG,kCAAkC;EAC/C,SAAS,GAAG,eAAe;EAC3B,SAAS;EACT,aAAa,WAAW,uBAAuB;EAC/C,aAAa;CACf;CACA;EACE,IAAI;EACJ,MAAM;EACN,UAAU,GAAG,kCAAkC;EAC/C,SAAS,GAAG,eAAe;EAC3B,SAAS;EACT,aAAa,WAAW,uBAAuB;EAC/C,aAAa;CACf;CAMA;EACE,IAAI;EACJ,MAAM;EACN,UAAU,GAAG,kCAAkC;EAC/C,SACE;EACF,SAAS;EACT,aACE;EACF,aAAa;CACf;AACF;AAoBA,MAAM,2BAAmD,CAAC,QAAQ,MAAM;;;;;;;AAQxE,MAAa,2BACX;CACE;EAAE,IAAI;EAAQ,aAAa;CAAO;CAClC;EAAE,IAAI;EAAQ,aAAa;CAAO;CAClC;EAAE,IAAI;EAAS,aAAa;CAAK;AACnC,CAAC,CAEA,KAAK,EAAE,IAAI,kBAAkB;CAC5B,MAAM,WAAW,mBAAmB,QAAQ,MAC1C,cACI,EAAE,gBAAgB,cAClB,EAAE,gBAAgB,WAAW,CAAC,yBAAyB,SAAS,EAAE,WAAW,CACnF;CAGA,OAAO;EACL;EACA,UACE,OAAO,UACH,CAAC,GAAG,QAAQ,CAAC,CAAC,MAAM,GAAG,MACrB,aAAa,EAAE,WAAW,CAAC,CAAC,KAAK,cAAc,aAAa,EAAE,WAAW,CAAC,CAAC,IAAI,CACjF,IACA;CACR;AACF,CAAC,CAAC,CACD,QAAQ,UAAU,MAAM,SAAS,SAAS,CAAC;AAQ9C,MAAM,+BAAuD;CAC3D,YAAY;CACZ,YAAY;CACZ,eAAe;CACf,aAAa;AACf;;AAGA,SAAgB,8BACd,UAC8B;CAC9B,IAAI,CAAC,UAAU,WAAA,qBAA4C,GAAG,OAAO,KAAA;CACrE,MAAM,KAAK,SAAS,MAAM,EAAwC;CAClE,MAAM,aAAa,OAAO,UAAU,eAAe,KAAK,8BAA8B,EAAE,IACpF,6BAA6B,MAC7B;CACJ,OAAO,mBAAmB,MAAM,MAAM,EAAE,OAAO,UAAU;AAC3D;;AAGA,SAAgB,wBAAwB,IAA0C;CAChF,OAAO,mBAAmB,MAAM,MAAM,EAAE,OAAO,EAAE;AACnD;;;;;;;;AASA,MAAa,0BAA0B;CAErC;EAAE,aAAa;EAAS,WAAW;CAAqB;CACxD;EAAE,aAAa;EAAQ,WAAW;CAAyB;CAC3D;EAAE,aAAa;EAAQ,WAAW;CAAqB;CACvD;EAAE,aAAa;EAAY,WAAW;CAA2B;CACjE;EAAE,aAAa;EAAU,WAAW;CAAgB;CACpD;EAAE,aAAa;EAAU,WAAW;CAAyB;CAC7D;EAAE,aAAa;EAAY,WAAW;CAA2B;CACjE;EAAE,aAAa;EAAM,WAAW;CAAmB;CACnD;EAAE,aAAa;EAAW,WAAW;CAA0B;CAC/D;EAAE,aAAa;EAAS,WAAW;CAAe;CAClD;EAAE,aAAa;EAAS,WAAW;CAAgB;CACnD;EAAE,aAAa;EAAS,WAAW;CAAuB;AAC5D;;;;;;;;;;;;;;;;;;;;;;;;;;;;AClmBA,SAAgB,eACd,KACyC;CACzC,IAAI,CAAC,KAAK,OAAO;CACjB,IAAI,IAAI,WAAW,KAAK,IAAI,WAAW,GAAG,OAAO;CACjD,IAAI,CAAC,IAAI,OAAO,UAAU,OAAO,SAAS,KAAK,CAAC,GAAG,OAAO;CAC1D,OAAO,IAAI,WAAW,IAAI;EAAC,IAAI;EAAI,IAAI;EAAI,IAAI;EAAI,IAAI;CAAE,IAAI;EAAC,IAAI;EAAI,IAAI;EAAI,IAAI;EAAI,IAAI;CAAE;AAC9F;AAKA,MAAM,4BAAY,IAAI,QAAyB;AAC/C,MAAM,kCAAkB,IAAI,QAAyB;;;;;;;;;;AAWrD,SAAgB,uBACd,SACA,cAAc,OACL;CACT,IAAI,CAAC,SAAS,OAAO;CACrB,MAAM,QAAQ,cAAc,kBAAkB;CAC9C,MAAM,SAAS,MAAM,IAAI,OAAO;CAChC,IAAI,WAAW,KAAA,GAAW,OAAO;CACjC,MAAM,SAAS,aAAa,UAAU,aACpC,aAAa,WAAW,aAAa;EACnC,MAAM,IAAI,SAAS;EACnB,OAAO,OAAO,MAAM,YAAY,OAAO,SAAS,CAAC,MAAM,eAAe,MAAM;CAC9E,CAAC,CACH;CACA,MAAM,IAAI,SAAS,MAAM;CACzB,OAAO;AACT;;;;;;;;;;;;;AAcA,SAAgB,0BACd,SACA,eACA,QACmB;CAInB,MAAM,eAAe,aAAiC;EACpD,SAAS;EACT,SAAS;GACR,OAAO,SAAS,OAAO,YAAY,OAAO,SAAS,SAAS,EAAE,IAAI,SAAS,KAAK,KAC/E,gBACA;CACJ;CACA,OAAO;EACL,GAAG;EACH,UAAU,QAAQ,SAAS,KAAK,aAAa;GAC3C,GAAG;GACH,UAAU,qBAAqB,QAAQ,UAAU,WAAW;EAC9D,EAAE;CACJ;AACF;AAEA,SAAS,aAAa,SAAkB,WAAqD;CAC3F,QAAQ,QAAQ,MAAhB;EACE,KAAK,qBACH,OAAO,QAAQ,SAAS,MAAM,YAC5B,QAAQ,WAAW,aAAa,QAAQ,UAAU,SAAS,IAAI,KACjE;EACF,KAAK,WACH,OAAO,QAAQ,WAAW,aAAa,QAAQ,UAAU,SAAS,IAAI;EACxE,KAAK,sBACH,OAAO,QAAQ,WAAW,MAAM,aAAa,aAAa,UAAU,SAAS,CAAC;EAChF,SACE,OAAO,UAAU,OAAO;CAC5B;AACF;AAEA,SAAS,aAAa,UAAoB,WAAqD;CAC7F,QAAQ,SAAS,MAAjB;EACE,KAAK,SACH,OAAO,UAAU,SAAS,WAAW;EACvC,KAAK;EACL,KAAK,cACH,OAAO,SAAS,YAAY,KAAK,SAAS;EAC5C,KAAK;EACL,KAAK,WACH,OAAO,SAAS,YAAY,MAAM,SAAS,KAAK,KAAK,SAAS,CAAC;EACjE,KAAK,gBACH,OAAO,SAAS,YAAY,MAAM,YAAY,QAAQ,MAAM,SAAS,KAAK,KAAK,SAAS,CAAC,CAAC;EAC5F,KAAK,sBACH,OAAO,SAAS,WAAW,MAAM,UAAU,aAAa,OAAO,SAAS,CAAC;EAC3E,SACE,OAAO;CACX;AACF;AAEA,SAAS,qBACP,UACA,aACqB;CACrB,IAAI,CAAC,UAAU,OAAO;CACtB,QAAQ,SAAS,MAAjB;EACE,KAAK,SACH,OAAO;GAAE,GAAG;GAAU,aAAa,YAAY,SAAS,WAAW;EAAE;EACvE,KAAK;EACL,KAAK,cACH,OAAO;GAAE,GAAG;GAAU,aAAa,SAAS,YAAY,IAAI,WAAW;EAAE;EAC3E,KAAK;EACL,KAAK,WACH,OAAO;GACL,GAAG;GACH,aAAa,SAAS,YAAY,KAAK,SAAS,KAAK,IAAI,WAAW,CAAC;EACvE;EACF,KAAK,gBACH,OAAO;GACL,GAAG;GACH,aAAa,SAAS,YAAY,KAAK,YACrC,QAAQ,KAAK,SAAS,KAAK,IAAI,WAAW,CAAC,CAC7C;EACF;EACF,KAAK,sBACH,OAAO;GACL,GAAG;GACH,YAAY,SAAS,WAAW,KAC7B,UAAU,qBAAqB,OAAO,WAAW,CACpD;EACF;EACF,SACE,OAAO;CACX;AACF;;;;;;;;;;;;;;;;;;;;;ACnJA,SAAgB,iBAAiB,KAAqB;CACpD,IAAI,CAAC,OAAO,OAAO,QAAQ,UAAU,OAAO;CAC5C,OAAO,IAAI,QAAQ,SAAS,IAAI,CAAC,CAAC,QAAQ,QAAQ,IAAG,CAAC,CAAC,QAAQ,QAAQ,GAAG;AAC5E;;;;;;;;;;;AAiBA,SAAgB,uBACd,SACA,YAAY,GACZ,WAAW,OACW;CACtB,IAAI,CAAC,WAAW,OAAO,YAAY,UACjC,OAAO;EAAE,aAAa,CAAC;EAAG,UAAU;CAAK;CAE3C,MAAM,eAAe,WAAW,iBAAiB,OAAO,IAAI;CAC5D,MAAM,SAAS,MAAM;CACrB,MAAM,MAAM,aAAa;CACzB,MAAM,cAAkC,CAAC;CACzC,IAAI,QAAQ;CACZ,IAAI,MAAM;CACV,IAAI,MAAM;CAEV,OAAO,QAAQ,KAAK;EAClB,IAAI,QAAQ;EACZ,IAAI,SAAS;EACb,IAAI;EAGJ,IAAI,cAAc;EAClB,GAAG;GACD,IAAI,SAAS,KAAK,OAAO;IAAE;IAAa,UAAU;GAAM;GACxD,OAAO,aAAa,WAAW,OAAO,IAAI;GAC1C,IAAI,OAAO,KAAK,OAAO,IAAI,OAAO;IAAE;IAAa,UAAU;GAAM;GACjE,IAAI,QAAQ,MAAO,UAAU,OAAO,OAAO,MAAQ,GACjD,OAAO;IAAE;IAAa,UAAU;GAAM;GAExC,WAAW,OAAO,OAAS;GAC3B,SAAS;GACT,IAAI,OAAO,IAAM;IACf,cAAc;IACd;GACF;EACF,SAAS,QAAQ;EAEjB,IAAI,CAAC,aAAa,OAAO;GAAE;GAAa,UAAU;EAAM;EAGxD,OAAO,SAAS,IAAI,EAAE,WAAW,KAAK,WAAW;EAEjD,QAAQ;EACR,SAAS;EAGT,IAAI,cAAc;EAClB,GAAG;GACD,IAAI,SAAS,KAAK,OAAO;IAAE;IAAa,UAAU;GAAM;GACxD,OAAO,aAAa,WAAW,OAAO,IAAI;GAC1C,IAAI,OAAO,KAAK,OAAO,IAAI,OAAO;IAAE;IAAa,UAAU;GAAM;GACjE,IAAI,QAAQ,MAAO,UAAU,OAAO,OAAO,MAAQ,GACjD,OAAO;IAAE;IAAa,UAAU;GAAM;GAExC,WAAW,OAAO,OAAS;GAC3B,SAAS;GACT,IAAI,OAAO,IAAM;IACf,cAAc;IACd;GACF;EACF,SAAS,QAAQ;EAEjB,IAAI,CAAC,aAAa,OAAO;GAAE;GAAa,UAAU;EAAM;EAExD,OAAO,SAAS,IAAI,EAAE,WAAW,KAAK,WAAW;EAEjD,YAAY,KAAK,CAAC,MAAM,QAAQ,MAAM,MAAM,CAAC;CAC/C;CAEA,OAAO;EAAE;EAAa,UAAU;CAAK;AACvC;;;;;;;;;AAUA,SAAgB,eACd,SACA,YAAY,GACZ,WAAW,OACS;CACpB,OAAO,uBAAuB,SAAS,WAAW,QAAQ,CAAC,CAAC;AAC9D;;;;AAKA,SAAS,mBAAmB,KAAqB;CAC/C,IAAI,SAAS,MAAM,IAAI,EAAE,OAAO,KAAK,OAAO;CAC5C,IAAI,MAAM;CACV,OAAO,UAAU,IAAM;EACrB,OAAO,OAAO,cAAc,KAAQ,SAAS,MAAS,EAAE;EACxD,YAAY;CACd;CACA,OAAO,OAAO,aAAa,SAAS,EAAE;CACtC,OAAO;AACT;;;;;;;;AASA,SAAgB,eAAe,aAAiC,YAAY,GAAW;CACrF,IAAI,CAAC,MAAM,QAAQ,WAAW,KAAK,YAAY,WAAW,GAAG,OAAO;CACpE,MAAM,SAAS,MAAM;CACrB,IAAI,SAAS;CACb,IAAI,UAAU;CACd,IAAI,UAAU;CAEd,KAAK,MAAM,CAAC,KAAK,QAAQ,aAAa;EACpC,IAAI,CAAC,OAAO,SAAS,GAAG,KAAK,CAAC,OAAO,SAAS,GAAG,GAAG;EACpD,MAAM,WAAW,KAAK,MAAM,MAAM,MAAM;EACxC,MAAM,WAAW,KAAK,MAAM,MAAM,MAAM;EAExC,MAAM,WAAW,WAAW;EAC5B,MAAM,WAAW,WAAW;EAE5B,UAAU,mBAAmB,QAAQ;EACrC,UAAU,mBAAmB,QAAQ;EAErC,UAAU;EACV,UAAU;CACZ;CAEA,OAAO;AACT;;;;;;;;;AAUA,SAAgB,qBACd,SACA,YAAY,GACZ,aAAgC,CAAC,GACZ;CACrB,OAAO;EACL,MAAM;EACN,YAAY,EAAE,GAAG,WAAW;EAC5B,UAAU;GACR,MAAM;GACN,aAAa,eAAe,SAAS,SAAS;EAChD;CACF;AACF;;;;;;;;AASA,SAAgB,qBACd,SAKA,YAAY,GACO;CACnB,IAAI,CAAC,SAAS,OAAO;CAGrB,IAAI,QAAQ,SAAS,WACnB,OAAO,qBAAqB,QAAQ,UAAU,SAAS;CAIzD,IAAI,QAAQ,SAAS,qBAAqB;EACxC,MAAM,UAAoB,CAAC;EAC3B,KAAK,MAAM,WAAW,QAAQ,UAAU;GACtC,MAAM,MAAM,qBAAqB,QAAQ,UAAU,SAAS;GAC5D,IAAI,MAAM,QAAQ,GAAG,GAAG,QAAQ,KAAK,GAAG,GAAG;QACtC,IAAI,KAAK,QAAQ,KAAK,GAAG;EAChC;EACA,OAAO;CACT;CAGA,IAAI,QAAQ,SAAS,cACnB,OAAO,eAAe,QAAQ,aAAmC,SAAS;CAI5E,IAAI,QAAQ,SAAS,mBACnB,OAAO,QAAQ,YAAY,KAAK,eAC9B,eAAe,YAAkC,SAAS,CAC5D;CAGF,OAAO;AACT;;;;;;;;AAsBA,SAAgB,qBACd,OACA,UAAgC,CAAC,GACgB;CACjD,IAAI,CAAC,SAAS,OAAO,UAAU,UAC7B,OAAO;EAAE,MAAM;EAAqB,UAAU,CAAC;CAAE;CAGnD,MAAM,EACJ,YAAY,GACZ,WAAW,MACX,YAAY,SACZ,cAAc,OACd,iBAAiB,CAAC,MAChB;CAEJ,MAAM,YAAY,MAAM,MAAM,SAAS;CACvC,MAAM,kBAAwC,CAAC;CAC/C,MAAM,WAAkC,CAAC;CAEzC,KAAK,IAAI,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;EACzC,MAAM,MAAM,UAAU,EAAE,CAAC,KAAK;EAC9B,IAAI,CAAC,KAAK;EAEV,MAAM,UAAU,IAAI,QAAQ,gBAAgB,EAAE,CAAC,CAAC,KAAK;EACrD,IAAI,CAAC,SAAS;EAEd,MAAM,eAAe,uBAAuB,SAAS,WAAW,QAAQ;EACxE,IAAI,aAAa,YAAY,aAAa,YAAY,UAAU,GAAG;GACjE,MAAM,SAAS,aAAa;GAC5B,gBAAgB,KAAK,MAAM;GAC3B,SAAS,KAAK;IACZ,MAAM;IACN,YAAY;KACV,GAAG;KACH,YAAY,SAAS,SAAS;KAC9B,aAAa,OAAO;IACtB;IACA,UAAU;KACR,MAAM;KACN,aAAa;IACf;GACF,CAAC;EACH;CACF;CAEA,IAAI,eAAe,gBAAgB,SAAS,GAa1C,OAAO;EACL,MAAM;EACN,UAAU,CAAC;GAbX,MAAM;GACN,YAAY;IACV,GAAG;IACH,YAAY,gBAAgB;IAC5B,aAAa,gBAAgB,QAAQ,KAAK,MAAM,MAAM,EAAE,QAAQ,CAAC;GACnE;GACA,UAAU;IACR,MAAM;IACN,aAAa;GACf;EAIsB,CAAC;CACzB;CAGF,OAAO;EACL,MAAM;EACN;CACF;AACF;;;;AC5UA,MAAa,kBAA4C;CAAC;CAAO;CAAO;CAAU;AAAW;;;;;;;AAQ7F,SAAgB,mBAAmB,SAAkB,OAAuB;CAC1E,OAAO,OAAO,QAAQ,MAAM,KAAK;AACnC;;;;;;;AAQA,SAAgB,mBACd,SACA,SACA,MACU;CACV,MAAM,aAAa,IAAI,IAAI,OAAO;CAClC,QAAQ,MAAR;EACE,KAAK,OACH,OAAO,MAAM,KAAK,UAAU;EAC9B,KAAK,OAAO;GACV,MAAM,SAAS,IAAI,IAAI,OAAO;GAC9B,KAAK,MAAM,MAAM,SAAS,OAAO,IAAI,EAAE;GACvC,OAAO,MAAM,KAAK,MAAM;EAC1B;EACA,KAAK,UACH,OAAO,MAAM,KAAK,IAAI,IAAI,QAAQ,QAAQ,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,CAAC;EACxE,KAAK,aACH,OAAO,MAAM,KAAK,IAAI,IAAI,QAAQ,QAAQ,OAAO,WAAW,IAAI,EAAE,CAAC,CAAC,CAAC;CACzE;AACF;;;;;;AAOA,SAAgB,gBAAgB,QAA2B,SAAsC;CAC/F,MAAM,WAAW,IAAI,IAAI,OAAO;CAChC,OAAO,OAAO,QAAQ,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC;AAChD;;;ACrBA,MAAM,MAAM,MAAc,SAAiB,YAA2C;CACpF;CACA;CACA;AACF;;;;;;AAOA,MAAa,iCAA+D;CAC1E;EACE,KAAK;EACL,WAAW;GACT,GAAG,OAAO,wBAAoB,KAAK;GACnC,GAAG,OAAO,wBAAoB,KAAK;GACnC,GAAG,MAAM,YAAU,IAAI;GACvB,GAAG,cAAc,oBAAkB,YAAY;GAC/C,GAAG,iBAAiB,uBAAqB,cAAc;GACvD,GAAG,MAAM,yCAAqC,IAAI;GAClD,GAAG,MAAM,6CAAqC,IAAI;GAClD,GAAG,YAAY,mDAA2C,SAAS;GACnE,GAAG,UAAU,sCAAgC,QAAQ;GACrD,GAAG,WAAW,iCAA2B,SAAS;GAClD,GAAG,UAAU,sCAAgC,UAAU;EACzD;CACF;CACA;EACE,KAAK;EACL,WAAW;GACT,GAAG,QAAQ,mFAAqE,QAAQ;GACxF,GACE,SACA,0FACA,OACF;GACA,GAAG,YAAY,sDAA8C,UAAU;GACvE,GAAG,MAAM,6CAAqC,IAAI;GAClD,GAAG,MAAM,6CAAqC,KAAK;GACnD,GAAG,KAAK,oCAA8B,IAAI;GAC1C,GAAG,MAAM,qCAA+B,KAAK;GAC7C,GAAG,KAAK,oCAA8B,IAAI;GAC1C,GAAG,MAAM,qCAA+B,KAAK;GAC7C,GAAG,OAAO,mFAAqE,KAAK;GACpF,GAAG,OAAO,2FAAyE,KAAK;GACxF,GAAG,KAAK,iCAA2B,KAAK;EAC1C;CACF;CACA;EACE,KAAK;EACL,WAAW;GACT,GAAG,KAAK,oCAA8B,KAAK;GAC3C,GAAG,KAAK,oCAA8B,UAAU;GAChD,GAAG,KAAK,oCAA8B,UAAU;GAChD,GAAG,KAAK,oCAA8B,QAAQ;GAC9C,GAAG,KAAK,oCAA8B,QAAQ;GAC9C,GAAG,KAAK,oCAA8B,OAAO;GAC7C,GAAG,OAAO,mCAA6B,KAAK;GAC5C,GAAG,QAAQ,oCAA8B,MAAM;GAC/C,GAAG,SAAS,qCAA+B,OAAO;GAClD,GAAG,SAAS,qCAA+B,OAAO;GAClD,GAAG,QAAQ,oCAA8B,MAAM;GAC/C,GAAG,MAAM,kCAA4B,IAAI;GACzC,GAAG,SAAS,qCAA+B,OAAO;GAClD,GAAG,OAAO,sCAAgC,KAAK;GAC/C,GAAG,OAAO,sCAAgC,KAAK;EACjD;CACF;CACA;EACE,KAAK;EACL,WAAW;GACT,GAAG,UAAU,mDAA2C,QAAQ;GAChE,GAAG,UAAU,sCAAgC,QAAQ;GACrD,GAAG,YAAY,wCAAkC,UAAU;GAC3D,GAAG,SAAS,2CAAqC,OAAO;GACxD,GACE,iBACA,kGACA,cACF;EACF;CACF;CACA;EACE,KAAK;EACL,WAAW;GACT,GAAG,aAAa,yCAAmC,UAAU;GAC7D,GAAG,aAAa,yCAAmC,UAAU;GAC7D,GAAG,cAAc,0CAAoC,WAAW;GAChE,GAAG,YAAY,+BAA2B,SAAS;EACrD;CACF;CACA;EACE,KAAK;EACL,WAAW;GACT,GAAG,QAAQ,cAAY,MAAM;GAC7B,GACE,eACA,gHACA,aACF;GACA,GAAG,QAAQ,wDAAgD,MAAM;GACjE,GAAG,OAAO,0BAAwB,KAAK;GACvC,GAAG,QAAQ,gCAA8B,MAAM;EACjD;CACF;AACF;;;;;;AAOA,SAAgB,yBAAyB,OAAuB;CAC9D,IAAI,SAAS;CACb,IAAI,WAAW;CACf,IAAI,UAAU;CAEd,KAAK,IAAI,QAAQ,GAAG,QAAQ,MAAM,QAAQ,SAAS,GAAG;EACpD,MAAM,OAAO,MAAM;EAEnB,IAAI,UAAU;GACZ,UAAU;GACV,IAAI,SACF,UAAU;QACL,IAAI,SAAS,MAClB,UAAU;QACL,IAAI,SAAS,MAClB,WAAW;GAEb;EACF;EAEA,IAAI,SAAS,MAAK;GAChB,WAAW;GACX,UAAU;GACV;EACF;EAEA,IAAI,SAAS,KAAK;GAChB,MAAM,kBAAkB,MAAM,MAAM,QAAQ,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,GAAG;GAC7D,IAAI,oBAAoB,OAAO,oBAAoB,KAAK;EAC1D;EAEA,UAAU;CACZ;CAEA,OAAO;AACT;;;;;;;;AA2BA,MAAM,sBAAsB;;;;;;;;;;;;;;AAe5B,SAAS,gBAAgB,cAAsC;CAC7D,OAAO;EACL,MAAM;EACN,iBAAiB;EACjB,YAAY,EAAE,YAAY,CAAC,QAAQ,SAAS,EAAE;CAChD;AACF;;;;;;;;;;;AA2BA,SAAgB,sBACd,QACA,UAAwC,CAAC,GACnB;CACtB,OAAO,qBAAqB,QAAQ,OAAO,CAAC,CAAC;AAC/C;;;;;;;AAQA,SAAS,qBACP,QACA,SACoE;CACpE,MAAM,UAAU,OAAO,KAAK;CAC5B,IAAI,CAAC,SAAS,OAAO,EAAE,YAAY;EAAE,IAAI;EAAM,QAAQ,CAAC;CAAE,EAAE;CAE5D,IAAI;CACJ,IAAI;EACF,SAAS,KAAK,MAAM,yBAAyB,OAAO,CAAC;CACvD,SAAS,OAAO;EACd,OAAO,EACL,YAAY;GACV,IAAI;GACJ,MAAM;GACN,QAAQ,CAAC,iBAAiB,QAAQ,MAAM,UAAU,cAAc;EAClE,EACF;CACF;CACA,IAAI,CAAC,MAAM,QAAQ,MAAM,GACvB,OAAO,EAAE,YAAY;EAAE,IAAI;EAAO,MAAM;EAAa,QAAQ,CAAC;CAAE,EAAE;CAEpE,IAAI,OAAO,OAAO,OAAO,UACvB,OAAO,EACL,YAAY;EAAE,IAAI;EAAO,MAAM;EAAgB,QAAQ,CAAC;EAAG;CAAO,EACpE;CAGF,MAAM,cAAc,8BAA8B,QAAQ,QAAQ,aAAa,CAAC,CAAC;CACjF,MAAM,WAAW,iBACf,aACA,qBACA,QAAQ,eAAe,gBAAgB,QAAQ,YAAY,IAAI,KAAA,CACjE;CACA,IAAI,SAAS,WAAW,SACtB,OAAO,EACL,YAAY;EACV,IAAI;EACJ,MAAM;EACN,QAAQ,SAAS,MAAM,KAAK,UAC1B,MAAM,MAAM,GAAG,MAAM,IAAI,IAAI,MAAM,YAAY,MAAM,OACvD;EACA;CACF,EACF;CAEF,OAAO;EAAE,YAAY;GAAE,IAAI;GAAM,QAAQ,CAAC;GAAG;EAAO;EAAG,YAAY,SAAS;CAAM;AACpF;;;;;;;AAeA,SAAgB,8BACd,MACA,WACS;CACT,IAAI,OAAO,SAAS,YAAY,KAAK,WAAW,GAAG,GAAG;EACpD,MAAM,QAAQ,UAAU,MAAM,aAAa,SAAS,UAAU,IAAI;EAClE,OAAO,QAAQ,MAAM,QAAQ;CAC/B;CACA,IAAI,MAAM,QAAQ,IAAI,GACpB,OAAO,KAAK,KAAK,UAAU,8BAA8B,OAAO,SAAS,CAAC;CAE5E,IAAI,QAAQ,OAAO,SAAS,UAC1B,OAAO,OAAO,YACZ,OAAO,QAAQ,IAA+B,CAAC,CAAC,KAAK,CAAC,KAAK,WAAW,CACpE,KACA,8BAA8B,OAAO,SAAS,CAChD,CAAC,CACH;CAEF,OAAO;AACT;;;;;;;;AA8BA,SAAgB,sBACd,QACA,UAAwC,CAAC,GACtB;CACnB,MAAM,UAAU,OAAO,KAAK;CAC5B,IAAI,CAAC,SAAS,OAAO,EAAE,MAAM,QAAQ;CAErC,MAAM,EAAE,YAAY,eAAe,qBAAqB,SAAS;EAC/D,WAAW,QAAQ;EACnB,cAAc,QAAQ;CACxB,CAAC;CACD,IAAI,CAAC,WAAW,MAAM,CAAC,YACrB,OAAO;EAAE,MAAM;EAAS,QAAQ,WAAW;CAAO;CAGpD,MAAM,UAAU,QAAQ,WAAW;CACnC,MAAM,eAAe,SAAS,UAAU,QAAQ;CAChD,IAAI;EAYF,OAAO;GAAE,MAAM;GAAS,OANV,WAAW,6BAA6B,EAAE,MAAM,QAAQ,QAAQ,EAAE,GAAG;IACjF,MAAM;IACN,YAAY,SAAS,cAAc,CAAC;IACpC,GAAI,SAAS,OAAO,KAAA,IAAY,EAAE,IAAI,QAAQ,GAAG,IAAI,CAAC;IACtD,UAAU,SAAS;GACrB,CAC4B;EAAE;CAChC,SAAS,OAAO;EACd,OAAO;GACL,MAAM;GACN,QAAQ,CAAC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;EACjE;CACF;AACF;;;;;;;;AA4BA,SAAgB,yBACd,QACA,UAII,CAAC,GACsB;CAC3B,MAAM,UAAU,OAAO,KAAK;CAC5B,IAAI,CAAC,SAAS,OAAO;EAAE,IAAI;EAAO,QAAQ,CAAC;CAAE;CAE7C,MAAM,EAAE,YAAY,eAAe,qBAAqB,SAAS;EAC/D,WAAW,QAAQ;EACnB,cAAc,QAAQ;CACxB,CAAC;CACD,IAAI,CAAC,WAAW,MAAM,CAAC,YACrB,OAAO;EAAE,IAAI;EAAO,QAAQ,WAAW;CAAO;CAEhD,MAAM,eAAe,QAAQ,QAAQ;CACrC,OAAO;EACL,IAAI;EACJ,QAAQ,CAAC;EACT,WAAW,SAAS,OAAO,iBACzB,WAAW,6BAA6B,EAAE,KAAK,GAAG;GAChD,MAAM,QAAQ,UAAU,QAAQ;GAChC,YAAY,QAAQ,cAAc,CAAC;GACnC,GAAI,QAAQ,OAAO,KAAA,IAAY,EAAE,IAAI,QAAQ,GAAG,IAAI,CAAC;GACrD,UAAU,QAAQ;EACpB,CAAU;CACd;AACF;;;;;;;;;AA0BA,SAAgB,0BACd,UACA,QACA,UAA+D,CAAC,GACtC;CAC1B,MAAM,UAAU,OAAO,KAAK;CAC5B,IAAI,CAAC,SAAS,OAAO;EAAE,IAAI;EAAO,QAAQ,CAAC;EAAG,KAAK,CAAC;EAAG,YAAY;CAAE;CAErE,MAAM,EAAE,YAAY,eAAe,qBAAqB,SAAS;EAC/D,WAAW,QAAQ;EACnB,cAAc;CAChB,CAAC;CACD,IAAI,CAAC,WAAW,MAAM,CAAC,YACrB,OAAO;EAAE,IAAI;EAAO,QAAQ,WAAW;EAAQ,KAAK,CAAC;EAAG,YAAY;CAAE;CAGxE,MAAM,MAAgB,CAAC;CACvB,IAAI,aAAa;CACjB,SAAS,SAAS,SAAS,UAAU;EACnC,IAAI;GASF,IANc,WAAW,6BAA6B,EAAE,MAAM,QAAQ,QAAQ,EAAE,GAAG;IACjF,MAAM,QAAQ,UAAU,QAAQ;IAChC,YAAY,QAAQ,cAAc,CAAC;IACnC,GAAI,QAAQ,OAAO,KAAA,IAAY,EAAE,IAAI,QAAQ,GAAG,IAAI,CAAC;IACrD,UAAU,QAAQ;GACpB,CACQ,MAAM,MAAM,IAAI,KAAK,mBAAmB,SAAS,KAAK,CAAC;EACjE,QAAQ;GACN,cAAc;EAChB;CACF,CAAC;CACD,OAAO;EAAE,IAAI;EAAM,QAAQ,CAAC;EAAG;EAAK;CAAW;AACjD;;;;;;;;;AAUA,SAAgB,iBACd,OACyD;CACzD,OAAO,iBAAiB;AAC1B;;;;;;AAOA,SAAgB,6BAA6B,OAAwB;CACnE,IAAI,UAAU,QAAQ,UAAU,KAAA,GAAW,OAAO;CAClD,IAAI,iBAAiB,KAAK,GAAG;EAC3B,MAAM,QAAQ;EAGd,MAAM,QAAQ,MAAM;EACpB,MAAM,WAAW,cAAsB,KAAK,OAAO,UAAU,IAAI,IAAI,YAAY,SAAS,GAAG;EAC7F,OAAO,QAAQ,QAAQ,MAAM,CAAC,EAAE,IAAI,QAAQ,MAAM,CAAC,EAAE,IAAI,QAAQ,MAAM,CAAC,EAAE,IAAI,OAAO,MAAM,QAAQ,CAAC,CAAC,EAAE;CACzG;CACA,IAAI;EACF,OAAO,KAAK,UAAU,KAAK,KAAK,OAAO,KAAK;CAC9C,QAAQ;EACN,OAAO,OAAO,KAAK;CACrB;AACF;;;;;;AAUA,SAAgB,gBACd,UACA,OACqC;CACrC,MAAM,SAA8C,CAAC;CACrD,KAAK,MAAM,QAAQ,OAAO,OAAO,QAAQ;CAEzC,KAAK,MAAM,WAAW,UAAU;EAC9B,MAAM,aAAa,QAAQ;EAC3B,IAAI,CAAC,YAAY;EACjB,KAAK,MAAM,QAAQ,OAAO;GACxB,MAAM,QAAQ,WAAW;GACzB,IAAI,UAAU,QAAQ,UAAU,KAAA,GAAW;GAC3C,MAAM,YAAY,OAAO;GACzB,MAAM,YACJ,cAAc,YAAY,cAAc,YAAY,cAAc,YAC9D,YACA;GACN,IAAI,OAAO,UAAU,WAAW,OAAO,QAAQ;QAC1C,IAAI,OAAO,UAAU,WAAW,OAAO,QAAQ;EACtD;CACF;CACA,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC7iBA,SAAgB,yBACd,UACA,QACW;CACX,MAAM,0BAAU,IAAI,IAAY;CAChC,KAAK,MAAM,SAAS,UAAU,CAAC,GAC7B,IAAI,MAAM,YAAY,QAAQ,IAAI,MAAM,UAAU;CAEpD,IAAI,QAAQ,SAAS,GAAG,OAAO;CAC/B,OAAO,SAAS,KAAK,YAAY;EAC/B,MAAM,QAAQ,QAAQ;EACtB,IAAI,CAAC,OAAO,OAAO;EACnB,IAAI,aAAa;EACjB,KAAK,MAAM,OAAO,SAChB,IAAI,OAAO,OAAO;GAChB,aAAa;GACb;EACF;EAEF,IAAI,CAAC,YAAY,OAAO;EACxB,MAAM,OAA0B,CAAC;EACjC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,GAC7C,IAAI,CAAC,QAAQ,IAAI,GAAG,GAAG,KAAK,OAAO;EAErC,OAAO;GAAE,GAAG;GAAS,YAAY;EAAK;CACxC,CAAC;AACH;;;;;;;AAeA,SAAS,uBAAuB,OAAyB;CACvD,IAAI,UAAU,KAAA,GAAW,OAAO;CAChC,IAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,GAAG,OAAO;CACjE,IAAI,iBAAiB,KAAK,GAAG,OAAO,6BAA6B,KAAK;CACtE,OAAO;AACT;;;;;;;;;;;;AAaA,SAAgB,wBACd,UACA,QAC0B;CAC1B,MAAM,YAAY,UAAU,CAAC;CAC7B,MAAM,oBAAoB,WAAiD;EACzE,GAAG;EACH,YAAY,KAAA;EACZ,OAAO,KAAA;EACP,YAAY,KAAA;CACd;CAOA,IADe,UAAU,QAAQ,UAAU,MAAM,YAAY,KACpD,CAAC,CAAC,WAAW,GACpB,OAAO;EAAE;EAAU,QAAQ,UAAU,IAAI,gBAAgB;CAAE;CAK7D,MAAM,4BAAY,IAAI,IAAY;CAClC,KAAK,MAAM,WAAW,UACpB,KAAK,MAAM,OAAO,OAAO,KAAK,QAAQ,cAAc,CAAC,CAAC,GAAG,UAAU,IAAI,GAAG;CAI5E,MAAM,MAAM,SAAS,KAAK,aAAa;EACrC,GAAG;EACH,YAAY,EAAE,GAAI,QAAQ,cAAc,CAAC,EAAG;CAC9C,EAAE;CAiCF,OAAO;EAAE,UAAU;EAAK,QA/BN,UAAU,KAAK,UAA6B;GAC5D,IAAI,MAAM,YAAY,OAAO,OAAO,iBAAiB,KAAK;GAC1D,MAAM,OAAO,MAAM,KAAK,KAAK;GAC7B,IAAI,CAAC,QAAQ,UAAU,IAAI,IAAI,GAAG,OAAO,iBAAiB,KAAK;GAE/D,MAAM,WAAW,yBAAyB,MAAM,UAAU;GAC1D,IAAI,CAAC,SAAS,MAAM,CAAC,SAAS,UAC5B,OAAO;IACL,GAAG,iBAAiB,KAAK;IACzB,OAAO,SAAS,OAAO,MAAM;GAC/B;GAGF,UAAU,IAAI,IAAI;GAClB,IAAI,aAAa;GACjB,KAAK,MAAM,WAAW,KAAK;IACzB,IAAI,QAAiB;IACrB,IAAI;KACF,QAAQ,uBAAuB,SAAS,SAAS,OAAO,CAAC;IAC3D,QAAQ;KACN,cAAc;IAChB;IACA,QAAQ,WAAW,QAAQ;GAC7B;GACA,OAAO;IACL,GAAG,iBAAiB,KAAK;IACzB,YAAY;IACZ,GAAI,aAAa,IAAI,EAAE,WAAW,IAAI,CAAC;GACzC;EACF,CAEwC;CAAE;AAC5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACzIA,SAAS,gBAAgB,OAAwB;CAC/C,IAAI,MAAM,QAAQ,KAAK,GACrB,OAAO,IAAI,MAAM,IAAI,eAAe,CAAC,CAAC,KAAK,GAAG,EAAE;CAElD,IAAI,UAAU,QAAQ,OAAO,UAAU,UAIrC,OAAO,IAHS,OAAO,QAAQ,KAAgC,CAAC,CAC7D,MAAM,CAAC,IAAI,CAAC,OAAQ,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,CAAE,CAAC,CAChD,KAAK,CAAC,GAAG,OAAO,GAAG,KAAK,UAAU,CAAC,EAAE,GAAG,gBAAgB,CAAC,GAC3C,CAAC,CAAC,KAAK,GAAG,EAAE;CAE/B,OAAO,KAAK,UAAU,KAAK,KAAK;AAClC;AAEA,SAAS,cAAc,OAAwB;CAC7C,IAAI,OAAO,UAAU,WAAW,OAAO,QAAQ,SAAS;CACxD,IAAI,UAAU,QAAQ,OAAO,UAAU,UAAU,OAAO,gBAAgB,KAAK;CAC7E,OAAO,OAAO,KAAK;AACrB;;;;;;;;AASA,SAAgB,aAAa,OAA+B;CAM1D,OAJE,UAAU,QACV,UAAU,KAAA,KACT,OAAO,UAAU,YAAY,OAAO,MAAM,KAAK,KAChD,cAAc,KAAK,MAAM,KACV,OAAO,cAAc,KAAK;AAC7C;;AAGA,SAAS,WAAW,YAA+B,OAAwB;CACzE,OAAO,cAAc,OAAO,OAAO,YAAY,KAAK,IAAI,WAAW,SAAS,KAAA;AAC9E;;;;;;AAOA,SAAgB,gBAAgB,UAAqB,OAA2C;CAC9F,MAAM,0BAAU,IAAI,IAAY;CAChC,KAAK,MAAM,QAAQ,SAAS,CAAC,GAC3B,KAAK,MAAM,SAAS,KAAK,eAAe,CAAC,GAAG,QAAQ,IAAI,KAAK;CAE/D,IAAI,QAAQ,SAAS,GAAG,OAAO;CAC/B,OAAO,SAAS,KAAK,YAAY;EAC/B,MAAM,QAAQ,QAAQ;EACtB,IAAI,CAAC,OAAO,OAAO;EACnB,IAAI,aAAa;EACjB,KAAK,MAAM,OAAO,SAChB,IAAI,OAAO,OAAO;GAChB,aAAa;GACb;EACF;EAEF,IAAI,CAAC,YAAY,OAAO;EACxB,MAAM,OAA0B,CAAC;EACjC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,GAC7C,IAAI,CAAC,QAAQ,IAAI,GAAG,GAAG,KAAK,OAAO;EAErC,OAAO;GAAE,GAAG;GAAS,YAAY;EAAK;CACxC,CAAC;AACH;;;;;;;;;;;;;;;;;;;AA2BA,SAAgB,gBACd,UACA,OACA,eACuB;CACvB,MAAM,WAAW,SAAS,CAAC;CAG3B,MAAM,2BAAW,IAAI,IAA2C;CAChE,MAAM,eAAe,gBAAuD;EAC1E,IAAI,CAAC,SAAS,IAAI,WAAW,GAC3B,SAAS,IAAI,aAAa,cAAc,WAAW,CAAC;EAEtD,OAAO,SAAS,IAAI,WAAW;CACjC;CAEA,IADe,SAAS,QAAQ,SAAS,KAAK,YAAY,SAAS,YAAY,KAAK,WAAW,CACtF,CAAC,CAAC,WAAW,GACpB,OAAO;EACL;EACA,OAAO,SAAS,KAAK,UAAU;GAC7B,GAAG;GACH,aAAa,CAAC;GACd,OAAO,KAAA;EACT,EAAE;CACJ;CAIF,MAAM,MAAM,SAAS,KAAK,aAAa;EACrC,GAAG;EACH,YAAY,EAAE,GAAI,QAAQ,cAAc,CAAC,EAAG;CAC9C,EAAE;CAIF,MAAM,4BAAY,IAAI,IAAY;CAClC,KAAK,MAAM,WAAW,UACpB,KAAK,MAAM,OAAO,OAAO,KAAK,QAAQ,cAAc,CAAC,CAAC,GAAG,UAAU,IAAI,GAAG;CAgF5E,OAAO;EAAE,UAAU;EAAK,OA7EP,SAAS,KAAK,SAAoB;GACjD,MAAM,SAAS,KAAK,YAAY,QAAQ,KAAA,IAAY,YAAY,KAAK,WAAW;GAChF,IAAI,CAAC,QAAQ,OAAO;IAAE,GAAG;IAAM,aAAa,CAAC;IAAG,OAAO,KAAA;GAAU;GAEjE,MAAM,gBAAgB,OAAO,YAAY,CAAC,EAAA,CAAG,OAAO,OAAO;GAG3D,MAAM,gBAA0B,CAAC;GACjC,MAAM,6BAAa,IAAI,IAAY;GACnC,KAAK,MAAM,MAAM,cACf,KAAK,MAAM,OAAO,OAAO,KAAK,GAAG,cAAc,CAAC,CAAC,GAC/C,IAAI,CAAC,WAAW,IAAI,GAAG,GAAG;IACxB,WAAW,IAAI,GAAG;IAClB,cAAc,KAAK,GAAG;GACxB;GAMJ,MAAM,YACJ,KAAK,WAAW,KAAA,IACZ,KAAK,OAAO,QAAQ,UAAU,WAAW,IAAI,KAAK,CAAC,IACnD,cAAc,QAAQ,QAAQ,QAAQ,KAAK,SAAS;GAC1D,MAAM,SAAS,KAAK,UAAU;GAC9B,MAAM,aAAsD,CAAC;GAC7D,KAAK,MAAM,SAAS,WAAW;IAC7B,MAAM,aAAa,SAAS;IAC5B,IAAI,UAAU,IAAI,UAAU,GAAG;IAC/B,UAAU,IAAI,UAAU;IACxB,WAAW,KAAK,CAAC,OAAO,UAAU,CAAC;GACrC;GAGA,MAAM,yBAAS,IAAI,IAA+B;GAClD,KAAK,MAAM,MAAM,cAAc;IAC7B,MAAM,MAAM,aAAa,WAAW,GAAG,YAAY,KAAK,SAAS,CAAC;IAClE,IAAI,QAAQ,QAAQ,OAAO,IAAI,GAAG,GAAG;IACrC,OAAO,IAAI,KAAK,GAAG,cAAc,CAAC,CAAC;GACrC;GAEA,IAAI,UAAU;GACd,MAAM,6BAAa,IAAI,IAAY;GACnC,KAAK,MAAM,WAAW,KAAK;IACzB,MAAM,QAAQ,QAAQ;IACtB,MAAM,MAAM,aAAa,WAAW,OAAO,KAAK,WAAW,CAAC;IAC5D,IAAI,QAAQ,MAAM,WAAW,IAAI,GAAG;IACpC,MAAM,MAAM,QAAQ,OAAO,KAAA,IAAY,OAAO,IAAI,GAAG;IACrD,IAAI,KAAK;KACP,WAAW;KACX,KAAK,MAAM,CAAC,OAAO,eAAe,YAChC,MAAM,cAAc,WAAW,KAAK,KAAK,KAAK;IAElD,OACE,KAAK,MAAM,GAAG,eAAe,YAAY,MAAM,cAAc;GAEjE;GAIA,IAAI,gBAAgB;GACpB,KAAK,MAAM,MAAM,cAAc;IAC7B,MAAM,MAAM,aAAa,WAAW,GAAG,YAAY,KAAK,SAAS,CAAC;IAClE,IAAI,QAAQ,QAAQ,CAAC,WAAW,IAAI,GAAG,GAAG,iBAAiB;GAC7D;GAEA,OAAO;IACL,GAAG;IACH,aAAa,WAAW,KAAK,GAAG,gBAAgB,UAAU;IAC1D,OAAO;KACL,cAAc;KACd,sBAAsB,IAAI,SAAS;KACnC,oBAAoB;IACtB;GACF;EACF,CAEsC;CAAE;AAC1C;;;;;;;;;;AAWA,SAAgB,kBACd,OACA,WACA,WACA,mBACe;CACf,MAAM,UAAU,MAAM;CACtB,MAAM,QAAQ,aAAa,MAAM,SAAS,CAAC;CAC3C,MAAM,gBAAgB,qBAAqB,MAAM,iBAAiB,CAAC;CACnE,IAAI,CAAC,SACH,OAAO;EACL,GAAG;EACH,OAAO,MAAM,SAAS,IAAI,QAAQ,KAAA;EAClC,eAAe,cAAc,SAAS,IAAI,gBAAgB,KAAA;CAC5D;CASF,MAAM,UAAU,gBAJH,gBACX,yBAAyB,QAAQ,YAAY,CAAC,GAAG,MAAM,aAAa,GACpE,MAAM,KAE2B,GAAG,QAAQ,gBAAgB;EAC5D,IAAI,gBAAgB,MAAM,IAAI,OAAO,KAAA;EACrC,OAAO,UAAU,MAAM,cAAc,UAAU,OAAO,WAAW,CAAC,EAAE;CACtE,CAAC;CACD,MAAM,cAAc,wBAAwB,QAAQ,UAAU,aAAa;CAC3E,OAAO;EACL,GAAG;EACH,SAAS;GAAE,GAAG;GAAS,UAAU,YAAY;EAAS;EACtD,OAAO,QAAQ,MAAM,SAAS,IAAI,QAAQ,QAAQ,KAAA;EAClD,eAAe,YAAY,OAAO,SAAS,IAAI,YAAY,SAAS,KAAA;CACtE;AACF;;;;;;;;;;AAWA,SAAgB,+BACd,QACA,SACa;CACb,MAAM,OAAO,IAAI,IAAI,OAAO,KAAK,UAAU,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC;CAC7D,MAAM,0BAAU,IAAI,IAAY;CAChC,MAAM,QAAQ,CAAC,OAAO;CACtB,OAAO,MAAM,SAAS,GAAG;EACvB,MAAM,UAAU,KAAK,IAAI,MAAM,MAAM,CAAW;EAChD,KAAK,MAAM,QAAQ,SAAS,SAAS,CAAC,GAAG;GACvC,IAAI,QAAQ,IAAI,KAAK,WAAW,GAAG;GACnC,QAAQ,IAAI,KAAK,WAAW;GAC5B,MAAM,KAAK,KAAK,WAAW;EAC7B;CACF;CACA,OAAO;AACT;;;;;;;;;;AAWA,SAAS,qBAAqB,YAAuC;CACnE,MAAM,eAAe,IAAI,IAAI,WAAW,KAAK,UAAU,MAAM,EAAE,CAAC;CAChE,MAAM,2BAAW,IAAI,IAAoB;CACzC,MAAM,6BAAa,IAAI,IAAsB;CAC7C,MAAM,4BAAY,IAAI,IAAsB;CAC5C,KAAK,MAAM,SAAS,YAAY,SAAS,IAAI,MAAM,IAAI,CAAC;CACxD,KAAK,MAAM,SAAS,YAClB,KAAK,MAAM,QAAQ,MAAM,SAAS,CAAC,GAAG;EACpC,IACE,KAAK,YAAY,SACjB,KAAK,gBAAgB,MAAM,MAC3B,CAAC,aAAa,IAAI,KAAK,WAAW,GAElC;EAEF,SAAS,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,EAAE,KAAK,KAAK,CAAC;EACxD,MAAM,OAAO,WAAW,IAAI,KAAK,WAAW,KAAK,CAAC;EAClD,KAAK,KAAK,MAAM,EAAE;EAClB,WAAW,IAAI,KAAK,aAAa,IAAI;EACrC,MAAM,UAAU,UAAU,IAAI,MAAM,EAAE,KAAK,CAAC;EAC5C,QAAQ,KAAK,KAAK,WAAW;EAC7B,UAAU,IAAI,MAAM,IAAI,OAAO;CACjC;CAEF,MAAM,QAAkB,CAAC;CACzB,MAAM,6BAAa,IAAI,IAAY;CACnC,MAAM,QAAQ,WAAW,QAAQ,UAAU,SAAS,IAAI,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,UAAU,MAAM,EAAE;CAChG,OAAO,MAAM,SAAS,WAAW,QAAQ;EACvC,IAAI,MAAM,WAAW,GAAG;GAItB,MAAM,QAAQ,WAAW,MAAM,UAAU,CAAC,WAAW,IAAI,MAAM,EAAE,CAAC;GAClE,IAAI,CAAC,OAAO;GACZ,IAAI,SAAS,MAAM;GACnB,MAAM,yBAAS,IAAI,IAAY;GAC/B,OAAO,CAAC,OAAO,IAAI,MAAM,GAAG;IAC1B,OAAO,IAAI,MAAM;IACjB,MAAM,QAAQ,UAAU,IAAI,MAAM,KAAK,CAAC,EAAA,CAAG,MAAM,WAAW,CAAC,WAAW,IAAI,MAAM,CAAC;IACnF,IAAI,SAAS,KAAA,GAAW;IACxB,SAAS;GACX;GACA,MAAM,KAAK,MAAM;EACnB;EACA,MAAM,KAAK,MAAM,MAAM;EACvB,IAAI,WAAW,IAAI,EAAE,GAAG;EACxB,WAAW,IAAI,EAAE;EACjB,MAAM,KAAK,EAAE;EACb,KAAK,MAAM,aAAa,WAAW,IAAI,EAAE,KAAK,CAAC,GAAG;GAChD,MAAM,aAAa,SAAS,IAAI,SAAS,KAAK,KAAK;GACnD,SAAS,IAAI,WAAW,SAAS;GACjC,IAAI,cAAc,KAAK,CAAC,WAAW,IAAI,SAAS,GAAG,MAAM,KAAK,SAAS;EACzE;CACF;CACA,OAAO;AACT;;;;;;;;;AAUA,SAAgB,wBAAwB,QAAyB,QAAiC;CAEhG,MAAM,2BAAW,IAAI,IAAY;CACjC,MAAM,QAAQ,CAAC,MAAM;CACrB,OAAO,MAAM,SAAS,GAAG;EACvB,MAAM,WAAW,MAAM,MAAM;EAC7B,KAAK,MAAM,SAAS,QAAQ;GAC1B,IAAI,MAAM,OAAO,UAAU,SAAS,IAAI,MAAM,EAAE,GAAG;GACnD,IAAI,MAAM,OAAO,MAAM,SAAS,KAAK,YAAY,SAAS,KAAK,gBAAgB,QAAQ,GAAG;IACxF,SAAS,IAAI,MAAM,EAAE;IACrB,MAAM,KAAK,MAAM,EAAE;GACrB;EACF;CACF;CACA,IAAI,SAAS,SAAS,GAAG,OAAO;CAEhC,IAAI,UAAU;CACd,MAAM,QAAQ,qBAAqB,OAAO,QAAQ,UAAU,SAAS,IAAI,MAAM,EAAE,CAAC,CAAC;CACnF,KAAK,MAAM,MAAM,OACf,UAAU,QAAQ,KAAK,UAAW,MAAM,OAAO,KAAK,kBAAkB,OAAO,OAAO,IAAI,KAAM;CAEhG,OAAO;AACT;;;;;;;;;;;AAYA,SAAgB,kBAAkB,QAA0C;CAC1E,MAAM,SAAS,OAAO,QAAQ,UAAU,MAAM,OAAO,UAAU,MAAM,eAAe,MAAM;CAC1F,IAAI,OAAO,WAAW,GAAG,OAAO;CAEhC,IAAI,UAAU;CACd,KAAK,MAAM,MAAM,qBAAqB,MAAM,GAC1C,UAAU,QAAQ,KAAK,UAAW,MAAM,OAAO,KAAK,kBAAkB,OAAO,OAAO,IAAI,KAAM;CAEhG,OAAO;AACT"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"joins-CRZZcLqX.d.mts","names":["GeoJSON","_$__cesium_imagery0.CesiumBasemapId","GeoJSON"],"sources":["../src/cesium-imagery.ts","../../../node_modules/@types/geojson/index.d.ts","../src/print-layout-config.ts","../src/types.ts","../src/ellipsoids.ts","../src/geojson-z.ts","../src/polyline.ts","../src/joins.ts"],"x_google_ignoreList":[1],"mappings":"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"}