@geolibre/core 2.9.0 → 3.0.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.
package/dist/index.d.mts CHANGED
@@ -1,3 +1,232 @@
1
+ //#region src/cesium-imagery.d.ts
2
+ /**
3
+ * Maps the project's basemap onto imagery the Cesium globe can render.
4
+ *
5
+ * The 2D panes render `basemapStyleUrl` through MapLibre, which understands
6
+ * vector GL styles and GeoLibre's `geolibre://` sentinels. Cesium understands
7
+ * neither: it draws imagery from tile providers only. So a globe pane that
8
+ * simply mounted the store basemap would show nothing, which is why the pane
9
+ * used to hardcode Ion World Imagery (with a token) or OpenStreetMap (without)
10
+ * and ignore the user's choice entirely — leaving a bright globe beside dark 2D
11
+ * panes and breaking the "same map, different projection" promise the multi-map
12
+ * grid makes.
13
+ *
14
+ * This module is the translation. It is deliberately **engine-free** — it
15
+ * returns a plain descriptor and never imports Cesium — so it lives in
16
+ * `@geolibre/core` beside the basemap catalogs it reads, the 2D and 3D
17
+ * renderers share one source of truth, and the Cesium chunk boundary in
18
+ * `vite.config.ts` stays intact.
19
+ *
20
+ * Three outcomes are possible, and the caller has to handle all three (see
21
+ * {@link CesiumBasemapImagery}): tiles to draw, nothing to draw, or "no raster
22
+ * equivalent exists — pick your own default".
23
+ */
24
+ /** Stable project IDs and the corresponding Cesium bundled thumbnails / ion assets. */
25
+ export declare const CESIUM_BASEMAPS: readonly [{
26
+ readonly id: "project";
27
+ readonly name: "Project basemap";
28
+ readonly icon: "naturalEarthII.png";
29
+ }, {
30
+ readonly id: "natural-earth";
31
+ readonly name: "Natural Earth II";
32
+ readonly icon: "naturalEarthII.png";
33
+ }, {
34
+ readonly id: "bing-aerial";
35
+ readonly name: "Bing Maps Aerial";
36
+ readonly icon: "bingAerial.png";
37
+ readonly assetId: 2;
38
+ }, {
39
+ readonly id: "bing-labels";
40
+ readonly name: "Bing Maps Aerial with Labels";
41
+ readonly icon: "bingAerialLabels.png";
42
+ readonly assetId: 3;
43
+ }, {
44
+ readonly id: "bing-roads";
45
+ readonly name: "Bing Maps Roads";
46
+ readonly icon: "bingRoads.png";
47
+ readonly assetId: 4;
48
+ }, {
49
+ readonly id: "sentinel-2";
50
+ readonly name: "Sentinel-2";
51
+ readonly icon: "sentinel-2.png";
52
+ readonly assetId: 3954;
53
+ }, {
54
+ readonly id: "blue-marble";
55
+ readonly name: "Blue Marble";
56
+ readonly icon: "blueMarble.png";
57
+ readonly assetId: 3845;
58
+ }, {
59
+ readonly id: "earth-at-night";
60
+ readonly name: "Earth at night";
61
+ readonly icon: "earthAtNight.png";
62
+ readonly assetId: 3812;
63
+ }, {
64
+ readonly id: "google-satellite";
65
+ readonly name: "Google Maps Satellite";
66
+ readonly icon: "googleSatellite.png";
67
+ readonly assetId: 3830182;
68
+ }, {
69
+ readonly id: "google-labels";
70
+ readonly name: "Google Maps Satellite with Labels";
71
+ readonly icon: "googleSatelliteLabels.png";
72
+ readonly assetId: 3830183;
73
+ }, {
74
+ readonly id: "google-roads";
75
+ readonly name: "Google Maps Roadmap";
76
+ readonly icon: "googleRoadmap.png";
77
+ readonly assetId: 3830184;
78
+ }, {
79
+ readonly id: "google-contour";
80
+ readonly name: "Google Maps Contour";
81
+ readonly icon: "googleContour.png";
82
+ readonly assetId: 3830186;
83
+ }, {
84
+ readonly id: "azure-aerial";
85
+ readonly name: "Azure Maps Aerial";
86
+ readonly icon: "azureAerial.png";
87
+ readonly assetId: 3891168;
88
+ }, {
89
+ readonly id: "azure-roads";
90
+ readonly name: "Azure Maps Roads";
91
+ readonly icon: "azureRoads.png";
92
+ readonly assetId: 3891169;
93
+ }, {
94
+ readonly id: "esri-imagery";
95
+ readonly name: "ArcGIS World Imagery";
96
+ readonly icon: "ArcGisMapServiceWorldImagery.png";
97
+ readonly category: "Other";
98
+ readonly service: "World_Imagery";
99
+ }, {
100
+ readonly id: "esri-hillshade";
101
+ readonly name: "ArcGIS World Hillshade";
102
+ readonly icon: "ArcGisMapServiceWorldHillshade.png";
103
+ readonly category: "Other";
104
+ readonly service: "Elevation/World_Hillshade";
105
+ }, {
106
+ readonly id: "esri-ocean";
107
+ readonly name: "Esri World Ocean";
108
+ readonly icon: "ArcGisMapServiceWorldOcean.png";
109
+ readonly category: "Other";
110
+ readonly service: "Ocean/World_Ocean_Base";
111
+ }, {
112
+ readonly id: "osm";
113
+ readonly name: "OpenStreetMap";
114
+ readonly icon: "openStreetMap.png";
115
+ readonly category: "Other";
116
+ }, {
117
+ readonly id: "stadia-watercolor";
118
+ readonly name: "Stadia x Stamen Watercolor";
119
+ readonly icon: "stamenWatercolor.png";
120
+ readonly category: "Other";
121
+ readonly stadiaStyle: "stamen_watercolor";
122
+ readonly maximumLevel: 16;
123
+ readonly extension: "jpg";
124
+ }, {
125
+ readonly id: "stadia-toner";
126
+ readonly name: "Stadia x Stamen Toner";
127
+ readonly icon: "stamenToner.png";
128
+ readonly category: "Other";
129
+ readonly stadiaStyle: "stamen_toner";
130
+ readonly maximumLevel: 20;
131
+ readonly extension: "png";
132
+ }, {
133
+ readonly id: "stadia-smooth";
134
+ readonly name: "Stadia Alidade Smooth";
135
+ readonly icon: "stadiaAlidadeSmooth.png";
136
+ readonly category: "Other";
137
+ readonly stadiaStyle: "alidade_smooth";
138
+ readonly maximumLevel: 20;
139
+ readonly extension: "png";
140
+ }, {
141
+ readonly id: "stadia-dark";
142
+ readonly name: "Stadia Alidade Smooth Dark";
143
+ readonly icon: "stadiaAlidadeSmoothDark.png";
144
+ readonly category: "Other";
145
+ readonly stadiaStyle: "alidade_smooth_dark";
146
+ readonly maximumLevel: 20;
147
+ readonly extension: "png";
148
+ }];
149
+ export type CesiumBasemapId = (typeof CESIUM_BASEMAPS)[number]["id"];
150
+ export declare function normalizeCesiumBasemap(value: unknown): CesiumBasemapId;
151
+ /** Missing credentials fall back to the project background without changing the saved choice. */
152
+ export declare function availableCesiumBasemap(value: unknown, hasIonToken: boolean): CesiumBasemapId;
153
+ /**
154
+ * What the globe should draw underneath the project's data layers.
155
+ *
156
+ * - `xyz` — a tile template to render, with the credit and zoom bounds that go
157
+ * with it.
158
+ * - `none` — the user chose the blank basemap; draw a bare ellipsoid.
159
+ * - `default` — this basemap has no raster equivalent (a custom style URL, a
160
+ * provider style, an offline archive). The renderer falls back to whatever it
161
+ * can offer, which is Ion World Imagery when a token is configured and
162
+ * OpenStreetMap otherwise.
163
+ */
164
+ export type CesiumBasemapImagery = {
165
+ kind: "none";
166
+ } | {
167
+ kind: "default";
168
+ } | {
169
+ kind: "ion";
170
+ assetId: number;
171
+ } | {
172
+ kind: "natural-earth";
173
+ } | {
174
+ kind: "arcgis";
175
+ url: string;
176
+ } | {
177
+ kind: "xyz";
178
+ /** Tile template with `{z}`/`{x}`/`{y}` placeholders. */
179
+ template: string;
180
+ /** Credentials are resolved at render time, never embedded in the descriptor. */
181
+ apiKeyProvider?: "stadia";
182
+ /** Credit to show on the globe, as the HTML the 2D map already uses. */
183
+ attribution: string;
184
+ /** Max native zoom of the source, so the globe overzooms rather than 404s. */
185
+ maximumLevel?: number;
186
+ /**
187
+ * Tile row ordering. `"tms"` numbers rows from the bottom; absent means
188
+ * standard XYZ. Cesium has no `scheme` option, so a TMS template needs
189
+ * `{y}` swapped for its `{reverseY}` placeholder at render time.
190
+ */
191
+ scheme?: "tms";
192
+ /**
193
+ * A transparent overlay drawn directly above {@link template} — the
194
+ * roads-and-labels tiles a hybrid basemap (Amap Hybrid) bakes in, so one
195
+ * basemap selection still yields a labelled satellite globe.
196
+ */
197
+ overlayTemplate?: string;
198
+ };
199
+ /**
200
+ * Whether two descriptors would draw the same thing.
201
+ *
202
+ * Descriptors are built fresh on every call, so two basemaps resolving to the
203
+ * same analogue — OpenFreeMap `liberty` and `bright` are both the streets
204
+ * tone — yield equal but distinct objects. A renderer that remembers the
205
+ * descriptor it drew (to skip redundant work) must compare by value: a
206
+ * reference check would miss that case and tear down and re-add an identical
207
+ * tile provider, costing a flash and a round of re-requested tiles for no
208
+ * visible change.
209
+ */
210
+ export declare function sameCesiumImagery(a: CesiumBasemapImagery, b: CesiumBasemapImagery): boolean;
211
+ /**
212
+ * Translate a basemap style URL into imagery for the Cesium globe.
213
+ *
214
+ * Planetary and regional basemaps are already raster tile sets, so they carry
215
+ * straight over — the globe shows the same Mars/Moon/Amap tiles the 2D panes
216
+ * do. GeoLibre's own vector styles map to a keyless raster basemap of matching
217
+ * tone, so switching the project to a dark basemap darkens the globe too.
218
+ * Everything else reports `default`, leaving the choice of fallback imagery to
219
+ * the renderer (which knows whether an Ion token is configured).
220
+ *
221
+ * A `geolibre://` sentinel that no longer resolves is treated as the default
222
+ * basemap, mirroring what `resolveMapStyle` does for the 2D map rather than
223
+ * handing the sentinel onward as if it were fetchable.
224
+ *
225
+ * @param styleUrl - The project's `basemapStyleUrl`.
226
+ * @returns What the globe should draw beneath the data layers.
227
+ */
228
+ export declare function basemapToCesiumImagery(styleUrl: string | undefined, cesiumBasemap?: CesiumBasemapId): CesiumBasemapImagery;
229
+ //#endregion
1
230
  //#region ../../node_modules/@types/geojson/index.d.ts
2
231
  /**
3
232
  * The value values for the "type" property of GeoJSON Objects.
@@ -198,16 +427,16 @@ interface FeatureCollection<G extends Geometry | null = Geometry, P = GeoJsonPro
198
427
  * a corner on one side without the other fails the build.
199
428
  */
200
429
  /** A page corner an overlay block can be pinned to. */
201
- type PrintLayoutCorner = "top-left" | "top-right" | "bottom-left" | "bottom-right";
430
+ export type PrintLayoutCorner = "top-left" | "top-right" | "bottom-left" | "bottom-right";
202
431
  /** Which features a data block covers when the atlas paginates the map. */
203
- type PrintLayoutPageFilter = "all" | "contained" | "intersecting";
432
+ export type PrintLayoutPageFilter = "all" | "contained" | "intersecting";
204
433
  /** One hand-authored swatch in the composer's user-defined legend. */
205
- interface PrintLayoutLegendEntry {
434
+ export interface PrintLayoutLegendEntry {
206
435
  id: string;
207
436
  label: string;
208
437
  color: string;
209
438
  }
210
- interface PrintLayoutConfig {
439
+ export interface PrintLayoutConfig {
211
440
  title: string;
212
441
  subtitle: string;
213
442
  titlePlacement: "outside" | "inside";
@@ -296,9 +525,9 @@ interface PrintLayoutConfig {
296
525
  * `printLayout` is filled out against. Also the dialog's initial state, so
297
526
  * "new project" and "a project saved before this feature" compose identically.
298
527
  */
299
- declare const DEFAULT_PRINT_LAYOUT: PrintLayoutConfig;
528
+ export declare const DEFAULT_PRINT_LAYOUT: PrintLayoutConfig;
300
529
  /** A fresh copy of the defaults, safe to hand to a store or a component. */
301
- declare function createDefaultPrintLayout(): PrintLayoutConfig;
530
+ export declare function createDefaultPrintLayout(): PrintLayoutConfig;
302
531
  /**
303
532
  * Coerce an untrusted (possibly hand-edited, possibly partial) `printLayout`
304
533
  * into a complete {@link PrintLayoutConfig}, filling every missing or
@@ -308,18 +537,18 @@ declare function createDefaultPrintLayout(): PrintLayoutConfig;
308
537
  * @returns The normalized config, or null when the project carries none, so
309
538
  * callers can tell "absent" from "explicitly default".
310
539
  */
311
- declare function normalizePrintLayoutConfig(value: unknown): PrintLayoutConfig | null;
540
+ export declare function normalizePrintLayoutConfig(value: unknown): PrintLayoutConfig | null;
312
541
  /**
313
542
  * Whether a config is still the untouched default, so a project that never
314
543
  * opened the composer serializes without a `printLayout` key and stays
315
544
  * byte-identical to one saved before this feature.
316
545
  */
317
- declare function isDefaultPrintLayout(config: PrintLayoutConfig): boolean;
546
+ export declare function isDefaultPrintLayout(config: PrintLayoutConfig): boolean;
318
547
  /**
319
548
  * Structural equality for two configs. Used to skip no-op store writes, so
320
549
  * merely opening the Print Layout dialog never marks a project dirty.
321
550
  */
322
- declare function printLayoutConfigsEqual(a: PrintLayoutConfig, b: PrintLayoutConfig): boolean;
551
+ export declare function printLayoutConfigsEqual(a: PrintLayoutConfig, b: PrintLayoutConfig): boolean;
323
552
  /**
324
553
  * Drop references to layers the project no longer carries, so a composer that
325
554
  * pointed at a since-deleted layer opens with the block cleared instead of
@@ -330,7 +559,7 @@ declare function printLayoutConfigsEqual(a: PrintLayoutConfig, b: PrintLayoutCon
330
559
  * @param existingLayerIds - Ids of the layers present in the project.
331
560
  * @returns The same object when nothing referenced a missing layer.
332
561
  */
333
- declare function scrubPrintLayoutForLayers(config: PrintLayoutConfig, existingLayerIds: ReadonlySet<string>): PrintLayoutConfig;
562
+ export declare function scrubPrintLayoutForLayers(config: PrintLayoutConfig, existingLayerIds: ReadonlySet<string>): PrintLayoutConfig;
334
563
  /**
335
564
  * The delete-time counterpart, matching `scrubLegendForRemovedLayers` and its
336
565
  * siblings: called when layers are removed from the open project so the saved
@@ -340,10 +569,10 @@ declare function scrubPrintLayoutForLayers(config: PrintLayoutConfig, existingLa
340
569
  * @param layerIds - The removed layer id, or ids.
341
570
  * @returns The same object when no block referenced a removed layer.
342
571
  */
343
- declare function scrubPrintLayoutForRemovedLayers(config: PrintLayoutConfig, layerIds: string | Iterable<string>): PrintLayoutConfig;
572
+ export declare function scrubPrintLayoutForRemovedLayers(config: PrintLayoutConfig, layerIds: string | Iterable<string>): PrintLayoutConfig;
344
573
  //#endregion
345
574
  //#region src/types.d.ts
346
- declare const OPENFREEMAP_BASEMAPS: readonly [{
575
+ export declare const OPENFREEMAP_BASEMAPS: readonly [{
347
576
  readonly id: "liberty";
348
577
  readonly name: "Liberty";
349
578
  readonly styleUrl: "https://tiles.openfreemap.org/styles/liberty";
@@ -375,7 +604,7 @@ declare const OPENFREEMAP_BASEMAPS: readonly [{
375
604
  * the GitHub Pages web demo), so consumers should hide these options when no
376
605
  * key is available.
377
606
  */
378
- declare const PROTOMAPS_BASEMAPS: readonly [{
607
+ export declare const PROTOMAPS_BASEMAPS: readonly [{
379
608
  readonly id: "protomaps-light";
380
609
  readonly name: "Light";
381
610
  readonly flavor: "light";
@@ -396,17 +625,17 @@ declare const PROTOMAPS_BASEMAPS: readonly [{
396
625
  readonly name: "Black";
397
626
  readonly flavor: "black";
398
627
  }];
399
- declare const DEFAULT_BASEMAP = "https://tiles.openfreemap.org/styles/liberty";
400
- declare const BLANK_BASEMAP = "";
401
- declare const PROJECT_VERSION = "0.2.0";
628
+ export declare const DEFAULT_BASEMAP = "https://tiles.openfreemap.org/styles/liberty";
629
+ export declare const BLANK_BASEMAP = "";
630
+ export declare const PROJECT_VERSION = "0.2.0";
402
631
  /**
403
632
  * Every layer type, as a runtime list so untrusted input (an imported Layer
404
633
  * Library bundle, a hand-edited project) can be validated against it.
405
634
  * {@link LayerType} is derived from this array, so the two cannot drift.
406
635
  */
407
- declare const LAYER_TYPES: readonly ["geojson", "raster", "wms", "wmts", "xyz", "vector-tiles", "arcgis", "pmtiles", "mbtiles", "zarr", "lidar", "gaussian-splat", "3d-tiles", "cog", "flatgeobuf", "geoparquet", "duckdb-query", "deckgl-viz", "video", "image"];
408
- type LayerType = (typeof LAYER_TYPES)[number];
409
- type VectorStyleMode = "single" | "graduated" | "categorized" | "rule-based" | "expression";
636
+ export declare const LAYER_TYPES: readonly ["geojson", "raster", "wms", "wmts", "xyz", "vector-tiles", "arcgis", "pmtiles", "mbtiles", "zarr", "lidar", "gaussian-splat", "3d-tiles", "cog", "flatgeobuf", "geoparquet", "duckdb-query", "deckgl-viz", "video", "image"];
637
+ export type LayerType = (typeof LAYER_TYPES)[number];
638
+ export type VectorStyleMode = "single" | "graduated" | "categorized" | "rule-based" | "expression";
410
639
  /**
411
640
  * One entry in a {@link LayerStyle.vectorRules} rule-based renderer. Each rule
412
641
  * pairs a MapLibre filter expression (a boolean expression array, serialized as
@@ -415,7 +644,7 @@ type VectorStyleMode = "single" | "graduated" | "categorized" | "rule-based" | "
415
644
  * the color for features no other rule matched. Mirrors the QGIS/ArcGIS
416
645
  * rule-based renderer.
417
646
  */
418
- interface VectorRule {
647
+ export interface VectorRule {
419
648
  id: string;
420
649
  /** Human-readable label shown in the editor and the legend. */
421
650
  label: string;
@@ -488,25 +717,25 @@ interface VectorRule {
488
717
  * named patterns are generated as recolorable sprite tiles; `"svg"` rasterizes
489
718
  * the user-supplied markup in {@link LayerStyle.fillPatternSvg}.
490
719
  */
491
- type FillPattern = "none" | "hatch" | "cross-hatch" | "horizontal" | "vertical" | "dots" | "svg";
720
+ export type FillPattern = "none" | "hatch" | "cross-hatch" | "horizontal" | "vertical" | "dots" | "svg";
492
721
  /**
493
722
  * The built-in marker shape for a point layer, or `"custom"` to rasterize the
494
723
  * user-supplied SVG in {@link LayerStyle.markerSvg}. Built-in shapes are drawn
495
724
  * on a sprite tile and recolored via {@link LayerStyle.markerColor}.
496
725
  */
497
- type MarkerShape = "circle" | "square" | "triangle" | "diamond" | "star" | "cross" | "pin" | "custom";
726
+ export type MarkerShape = "circle" | "square" | "triangle" | "diamond" | "star" | "cross" | "pin" | "custom";
498
727
  /**
499
728
  * How a point layer is rendered: as individual markers, a density heatmap, or
500
729
  * clustered bubbles. Only applies to point geometry.
501
730
  */
502
- type PointRenderer = "single" | "heatmap" | "cluster";
731
+ export type PointRenderer = "single" | "heatmap" | "cluster";
503
732
  /**
504
733
  * The repeated decoration symbol drawn along line features (and polygon
505
734
  * outlines), or `"none"` when decorations are off. Mirrors the QGIS
506
735
  * marker-line / arrow symbol layers: `"arrow"` renders directional arrowheads
507
736
  * that follow the line, the other shapes render as repeated markers.
508
737
  */
509
- type LineDecoration = "none" | "arrow" | "triangle" | "circle" | "square";
738
+ export type LineDecoration = "none" | "arrow" | "triangle" | "circle" | "square";
510
739
  /**
511
740
  * The per-feature derived geometry rendered by the geometry generator, or
512
741
  * `"none"` when the generator is off. Mirrors QGIS geometry-generator symbol
@@ -514,13 +743,13 @@ type LineDecoration = "none" | "arrow" | "triangle" | "circle" | "square";
514
743
  * hull, or a buffer) is drawn as an extra symbol over the layer's normal
515
744
  * symbology. `"centroid"` derives points; the rest derive polygons.
516
745
  */
517
- type GeometryGeneratorType = "none" | "centroid" | "bounding-box" | "convex-hull" | "buffer";
746
+ export type GeometryGeneratorType = "none" | "centroid" | "bounding-box" | "convex-hull" | "buffer";
518
747
  /**
519
748
  * Unit a stroke/line width is measured in. `"pixels"` is constant screen space;
520
749
  * `"meters"` is ground distance, so the rendered width scales with the map
521
750
  * scale (zoom). See {@link LayerStyle.strokeWidthUnit}.
522
751
  */
523
- type StrokeWidthUnit = "pixels" | "meters";
752
+ export type StrokeWidthUnit = "pixels" | "meters";
524
753
  /**
525
754
  * The chart drawn on top of each feature by the diagram renderer (QGIS-style
526
755
  * diagram symbology), or `"none"` when diagrams are off. Diagrams visualize
@@ -528,7 +757,7 @@ type StrokeWidthUnit = "pixels" | "meters";
528
757
  * party per county — and render through the shared deck.gl overlay on the
529
758
  * feature's point location or polygon centroid.
530
759
  */
531
- type DiagramType = "none" | "pie" | "donut" | "bar" | "stacked-bar";
760
+ export type DiagramType = "none" | "pie" | "donut" | "bar" | "stacked-bar";
532
761
  /**
533
762
  * How the overall diagram size is determined.
534
763
  *
@@ -539,21 +768,21 @@ type DiagramType = "none" | "pie" | "donut" | "bar" | "stacked-bar";
539
768
  * - `"attribute"`: scaled the same way by the single numeric attribute in
540
769
  * {@link LayerStyle.diagramSizeProperty}.
541
770
  */
542
- type DiagramSizeMode = "fixed" | "sum" | "attribute";
771
+ export type DiagramSizeMode = "fixed" | "sum" | "attribute";
543
772
  /** One attribute rendered as a slice/bar of a feature diagram. */
544
- interface DiagramField {
773
+ export interface DiagramField {
545
774
  /** Numeric feature property visualized by this slice/bar. */
546
775
  property: string;
547
776
  /** Slice/bar color (6-digit hex). */
548
777
  color: string;
549
778
  }
550
- interface VectorStyleStop {
779
+ export interface VectorStyleStop {
551
780
  value: string | number;
552
781
  color: string;
553
782
  label?: string;
554
783
  }
555
784
  /** Attribute-driven labeling for a vector layer (rendered as a MapLibre symbol layer). */
556
- interface LabelStyle {
785
+ export interface LabelStyle {
557
786
  /** Whether labels are shown for the layer. */
558
787
  enabled: boolean;
559
788
  /** Attribute field whose value becomes the label text. */
@@ -593,6 +822,22 @@ interface LabelStyle {
593
822
  maxWidth: number;
594
823
  /** Letter-case transform applied to the label text (MapLibre `text-transform`). */
595
824
  transform: LabelTransform;
825
+ /**
826
+ * Render a numeric {@link field} with the locale's thousands and decimal
827
+ * separators (issue #2336), so `1234567.5` labels as `1,234,567.5` instead
828
+ * of running together. Non-numeric values are unaffected, and it is not
829
+ * applied to {@link expression}, which formats its own output (MapLibre's
830
+ * `number-format`, offered in the Expression Builder).
831
+ */
832
+ numberFormatEnabled: boolean;
833
+ /** Decimal places kept while {@link numberFormatEnabled} is on (0-10). */
834
+ numberDecimals: number;
835
+ /**
836
+ * BCP 47 tag picking the separators for {@link numberFormatEnabled}, from
837
+ * {@link LABEL_NUMBER_LOCALES}. Empty (the default) follows the app's own
838
+ * language, the way popup number fields do.
839
+ */
840
+ numberLocale: string;
596
841
  /**
597
842
  * How to handle features that share a label.
598
843
  *
@@ -642,11 +887,11 @@ interface LabelStyle {
642
887
  priorityExpression: string;
643
888
  }
644
889
  /** MapLibre `text-anchor` positions offered for {@link LabelStyle.anchor}. */
645
- type LabelAnchor = "center" | "left" | "right" | "top" | "bottom" | "top-left" | "top-right" | "bottom-left" | "bottom-right";
890
+ export type LabelAnchor = "center" | "left" | "right" | "top" | "bottom" | "top-left" | "top-right" | "bottom-left" | "bottom-right";
646
891
  /** Letter-case transform offered for {@link LabelStyle.transform}. */
647
- type LabelTransform = "none" | "uppercase" | "lowercase";
892
+ export type LabelTransform = "none" | "uppercase" | "lowercase";
648
893
  /** Duplicate-label handling offered for {@link LabelStyle.dedupe}. */
649
- type LabelDedupe = "off" | "unique" | "concatenate";
894
+ export type LabelDedupe = "off" | "unique" | "concatenate";
650
895
  /**
651
896
  * Cartographic blend modes offered for {@link LayerStyle.blendMode}.
652
897
  *
@@ -670,13 +915,13 @@ type LabelDedupe = "off" | "unique" | "concatenate";
670
915
  * Every mode here leaves the canvas opaque and leaves the map untouched
671
916
  * wherever the layer contributes nothing. See `docs/user-guide/layers.md`.
672
917
  */
673
- declare const BLEND_MODES: readonly ["normal", "multiply", "screen", "lighten", "add"];
918
+ export declare const BLEND_MODES: readonly ["normal", "multiply", "screen", "lighten", "add"];
674
919
  /**
675
920
  * How a layer's pixels combine with the map beneath it. `"normal"` is ordinary
676
921
  * alpha compositing (the default, and what every layer did before blend modes
677
922
  * existed). See {@link BLEND_MODES}.
678
923
  */
679
- type BlendMode = (typeof BLEND_MODES)[number];
924
+ export type BlendMode = (typeof BLEND_MODES)[number];
680
925
  /**
681
926
  * The mode a layer renders with unless it says otherwise. Declared separately
682
927
  * from {@link DEFAULT_LAYER_STYLE} so consumers get a non-optional
@@ -684,8 +929,8 @@ type BlendMode = (typeof BLEND_MODES)[number];
684
929
  * {@link LayerStyle}, so `DEFAULT_LAYER_STYLE.blendMode` is typed
685
930
  * `BlendMode | undefined` however it is initialized.
686
931
  */
687
- declare const DEFAULT_BLEND_MODE: BlendMode;
688
- interface LayerStyle {
932
+ export declare const DEFAULT_BLEND_MODE: BlendMode;
933
+ export interface LayerStyle {
689
934
  minZoom: number;
690
935
  maxZoom: number;
691
936
  fillColor: string;
@@ -814,6 +1059,10 @@ interface LayerStyle {
814
1059
  pointRenderer: PointRenderer;
815
1060
  heatmapRadius: number;
816
1061
  heatmapIntensity: number;
1062
+ /** Built-in color ramp used by the heatmap density renderer. */
1063
+ heatmapColorRamp: string;
1064
+ /** Numeric feature property used as heatmap weight; blank gives every point equal weight. */
1065
+ heatmapWeightProperty: string;
817
1066
  clusterRadius: number;
818
1067
  clusterMaxZoom: number;
819
1068
  /**
@@ -898,13 +1147,13 @@ interface LayerStyle {
898
1147
  */
899
1148
  blendMode?: BlendMode;
900
1149
  }
901
- declare const DEFAULT_LAYER_STYLE: LayerStyle;
1150
+ export declare const DEFAULT_LAYER_STYLE: LayerStyle;
902
1151
  /**
903
1152
  * Read a layer style property, falling back to the shared default when the
904
1153
  * layer does not define it. Shared by `@geolibre/map` and the desktop app so
905
1154
  * the two consumers cannot drift.
906
1155
  */
907
- declare function styleValue<K extends keyof LayerStyle>(style: LayerStyle, key: K): LayerStyle[K];
1156
+ export declare function styleValue<K extends keyof LayerStyle>(style: LayerStyle, key: K): LayerStyle[K];
908
1157
  /**
909
1158
  * Feature-count threshold above which a local vector (GeoJSON) layer is rendered
910
1159
  * through client-side vector tiles (geojson-vt / supercluster served by a custom
@@ -912,7 +1161,7 @@ declare function styleValue<K extends keyof LayerStyle>(style: LayerStyle, key:
912
1161
  * `setData`. Small layers stay on the simpler inline path. Mirrors the
913
1162
  * `MAX_CEREUS_FEATURES` precedent in the desktop SQL engine.
914
1163
  */
915
- declare const LARGE_VECTOR_FEATURE_THRESHOLD = 50000;
1164
+ export declare const LARGE_VECTOR_FEATURE_THRESHOLD = 50000;
916
1165
  /**
917
1166
  * Decide whether a GeoJSON layer should use the tiled rendering path.
918
1167
  *
@@ -921,13 +1170,13 @@ declare const LARGE_VECTOR_FEATURE_THRESHOLD = 50000;
921
1170
  * @returns `true` when the collection exceeds
922
1171
  * {@link LARGE_VECTOR_FEATURE_THRESHOLD} features.
923
1172
  */
924
- declare function shouldUseTiledRendering(geojson: GeoJSON.FeatureCollection | undefined): boolean;
1173
+ export declare function shouldUseTiledRendering(geojson: GeoJSON.FeatureCollection | undefined): boolean;
925
1174
  /**
926
1175
  * Match statistics from the last time a {@link LayerJoin} was applied, shown in
927
1176
  * the Joins UI so silent key mismatches are visible (mirrors QGIS's join
928
1177
  * feedback). Recomputed on every apply; persisted harmlessly with the join.
929
1178
  */
930
- interface LayerJoinStats {
1179
+ export interface LayerJoinStats {
931
1180
  /** Target features whose key matched a join-table row. */
932
1181
  matchedCount: number;
933
1182
  /** Target features with no matching join-table row (their joined columns are null). */
@@ -945,7 +1194,7 @@ interface LayerJoinStats {
945
1194
  * table's data changes. Definitions persist in `.geolibre.json` and re-resolve
946
1195
  * on project load. See `joins.ts` for the engine.
947
1196
  */
948
- interface LayerJoin {
1197
+ export interface LayerJoin {
949
1198
  /** Stable id for list edits. */
950
1199
  id: string;
951
1200
  /** Id of the layer providing the joined columns (its geometry is ignored). */
@@ -975,9 +1224,9 @@ interface LayerJoin {
975
1224
  stats?: LayerJoinStats;
976
1225
  }
977
1226
  /** Edit-widget kinds the Attribute Form designer can assign to a field. */
978
- type AttributeFormWidget = "text" | "number" | "range" | "checkbox" | "date" | "valueMap";
1227
+ export type AttributeFormWidget = "text" | "number" | "range" | "checkbox" | "date" | "valueMap";
979
1228
  /** One selectable entry of a `valueMap` widget (stored value + display label). */
980
- interface AttributeFormValueMapEntry {
1229
+ export interface AttributeFormValueMapEntry {
981
1230
  /** The value written to the feature property (compared as a string). */
982
1231
  value: string;
983
1232
  /** Human-readable label shown in the dropdown; defaults to {@link value}. */
@@ -991,7 +1240,7 @@ interface AttributeFormValueMapEntry {
991
1240
  * inline editor and the Field Collection capture form; helpers live in
992
1241
  * `attribute-form.ts`.
993
1242
  */
994
- interface AttributeFormFieldConfig {
1243
+ export interface AttributeFormFieldConfig {
995
1244
  /** Feature property key this configuration applies to. */
996
1245
  field: string;
997
1246
  widget: AttributeFormWidget;
@@ -1027,7 +1276,7 @@ interface AttributeFormFieldConfig {
1027
1276
  visibilityExpression?: string;
1028
1277
  }
1029
1278
  /** The Attribute Form designer's whole per-layer configuration. */
1030
- interface AttributeFormConfig {
1279
+ export interface AttributeFormConfig {
1031
1280
  fields: AttributeFormFieldConfig[];
1032
1281
  }
1033
1282
  /**
@@ -1037,11 +1286,11 @@ interface AttributeFormConfig {
1037
1286
  * anything else stringified. The remaining kinds are explicit author choices
1038
1287
  * so a popup never has to guess from the value.
1039
1288
  */
1040
- type PopupFieldKind = "auto" | "text" | "number" | "date" | "link" | "image";
1289
+ export type PopupFieldKind = "auto" | "text" | "number" | "date" | "link" | "image";
1041
1290
  /** How a `"date"` field's value is written out. */
1042
- type PopupDateFormat = "date" | "datetime" | "time" | "iso" | "year";
1291
+ export type PopupDateFormat = "date" | "datetime" | "time" | "iso" | "year";
1043
1292
  /** Value formatting for one popup field. Every part is optional. */
1044
- interface PopupFieldFormat {
1293
+ export interface PopupFieldFormat {
1045
1294
  /** Fixed number of decimals for a `"number"` field. */
1046
1295
  decimals?: number;
1047
1296
  /** Group thousands with the locale's separator (`"number"` fields). */
@@ -1056,7 +1305,7 @@ interface PopupFieldFormat {
1056
1305
  linkLabel?: string;
1057
1306
  }
1058
1307
  /** One field's entry in a layer's popup configuration. */
1059
- interface PopupFieldConfig {
1308
+ export interface PopupFieldConfig {
1060
1309
  /** Feature property key. */
1061
1310
  field: string;
1062
1311
  /** Display label shown instead of the raw field name. */
@@ -1077,7 +1326,7 @@ interface PopupFieldConfig {
1077
1326
  * {@link GeoLibreLayer.fieldVisibility} stays authoritative — a `"hidden"` or
1078
1327
  * `"excluded"` field is dropped even when a popup config names it.
1079
1328
  */
1080
- interface LayerPopupConfig {
1329
+ export interface LayerPopupConfig {
1081
1330
  /** `false` suppresses the Identify popup for this layer. Defaults to `true`. */
1082
1331
  click?: boolean;
1083
1332
  /** `true` shows a hover tooltip built from the `hover` fields. Defaults to `false`. */
@@ -1116,7 +1365,7 @@ interface LayerPopupConfig {
1116
1365
  * project load; the expression is a declarative MapLibre expression (never
1117
1366
  * arbitrary code), so re-evaluating it from a shared project file is safe.
1118
1367
  */
1119
- interface LayerVirtualField {
1368
+ export interface LayerVirtualField {
1120
1369
  /** Stable id for list edits. */
1121
1370
  id: string;
1122
1371
  /** The output column name. A name already taken by a base column is skipped. */
@@ -1154,9 +1403,9 @@ interface LayerVirtualField {
1154
1403
  * and edited.
1155
1404
  */
1156
1405
  /** Which control a quick filter renders, and how it compiles. */
1157
- type QuickFilterKind = "categorical" | "range" | "date" | "text";
1406
+ export type QuickFilterKind = "categorical" | "range" | "date" | "text";
1158
1407
  /** The comparison a `text` quick filter applies (always case-insensitive). */
1159
- type QuickFilterTextOperator = "contains" | "startsWith" | "equals";
1408
+ export type QuickFilterTextOperator = "contains" | "startsWith" | "equals";
1160
1409
  /**
1161
1410
  * How a date field stores its values, deciding whether a `date` quick filter
1162
1411
  * compares ISO text or epoch numbers. `iso` covers both `YYYY-MM-DD` and full
@@ -1165,9 +1414,9 @@ type QuickFilterTextOperator = "contains" | "startsWith" | "equals";
1165
1414
  * a boundary. Mirrors (deliberately, in a smaller form) the value kinds the
1166
1415
  * Time Slider's `detectValueKind` reports.
1167
1416
  */
1168
- type QuickFilterDateKind = "iso" | "epochMs" | "epochS";
1417
+ export type QuickFilterDateKind = "iso" | "epochMs" | "epochS";
1169
1418
  /** A single filter control persisted on a layer. */
1170
- interface LayerQuickFilter {
1419
+ export interface LayerQuickFilter {
1171
1420
  /** Stable id, used as the React key and for edits/removal. */
1172
1421
  id: string;
1173
1422
  /** The feature property this control narrows. */
@@ -1201,7 +1450,7 @@ interface LayerQuickFilter {
1201
1450
  text?: string;
1202
1451
  }
1203
1452
  /** Persisted refresh policy and most recent synchronization result for a layer. */
1204
- interface LayerConnection {
1453
+ export interface LayerConnection {
1205
1454
  /** Owning layer id. Repeated here so records remain self-describing when exported. */
1206
1455
  layerId: string;
1207
1456
  /** Automatic refresh cadence in seconds, or null for manual synchronization only. */
@@ -1218,7 +1467,7 @@ interface LayerConnection {
1218
1467
  * Maintains `created_by`, `created_at`, `edited_by`, `edited_at` fields
1219
1468
  * automatically when features are created or updated.
1220
1469
  */
1221
- interface EditorTrackingConfig {
1470
+ export interface EditorTrackingConfig {
1222
1471
  /** `true` enables automatic creation/edit timestamp and author stamping. */
1223
1472
  enabled: boolean;
1224
1473
  /** Field name for creation author (default `"created_by"`). */
@@ -1235,12 +1484,12 @@ interface EditorTrackingConfig {
1235
1484
  * - "hidden": Not shown in the attribute table, identify popup, tooltips, or field pickers, but remains in the data.
1236
1485
  * - "excluded": Removed entirely from the data when the project is shared or exported.
1237
1486
  */
1238
- type FieldVisibility = "hidden" | "excluded";
1487
+ export type FieldVisibility = "hidden" | "excluded";
1239
1488
  /**
1240
1489
  * Explicit capability flags defining what actions a user/session may perform on a layer.
1241
1490
  * Any omitted capability falls back to the inferred default behavior for that layer's source.
1242
1491
  */
1243
- interface LayerCapabilities {
1492
+ export interface LayerCapabilities {
1244
1493
  /** Can the layer's features or attributes be queried / identified. */
1245
1494
  query?: boolean;
1246
1495
  /** Can new features be created/added to the layer. */
@@ -1255,16 +1504,16 @@ interface LayerCapabilities {
1255
1504
  /**
1256
1505
  * Application privilege identifiers defining discrete capabilities in GeoLibre.
1257
1506
  */
1258
- type AppPrivilege = "layers:edit" | "layers:add-remote" | "layers:add-local" | "processing:run" | "processing:sidecar" | "project:save" | "project:share" | "project:share-public" | "plugins:install" | "assistant:use" | "connections:manage" | "export:data" | "export:image" | "settings:manage";
1507
+ export type AppPrivilege = "layers:edit" | "layers:add-remote" | "layers:add-local" | "processing:run" | "processing:sidecar" | "project:save" | "project:share" | "project:share-public" | "plugins:install" | "assistant:use" | "connections:manage" | "export:data" | "export:image" | "settings:manage";
1259
1508
  /**
1260
1509
  * Standard named roles bundling application privileges.
1261
1510
  */
1262
- type AppRole = "viewer" | "editor" | "publisher" | "administrator" | "custom";
1511
+ export type AppRole = "viewer" | "editor" | "publisher" | "administrator" | "custom";
1263
1512
  /**
1264
1513
  * Ephemeral application capabilities state defining the active role, effective privileges,
1265
1514
  * and optional restriction reason for the current session/deployment.
1266
1515
  */
1267
- interface AppCapabilities {
1516
+ export interface AppCapabilities {
1268
1517
  /**
1269
1518
  * The assigned application role. `custom` once an ad-hoc `grantAppPrivilege` /
1270
1519
  * `revokeAppPrivilege` has moved the set away from the bundle a named role
@@ -1287,7 +1536,7 @@ interface AppCapabilities {
1287
1536
  */
1288
1537
  privilegeReasons?: Partial<Record<AppPrivilege, string>>;
1289
1538
  }
1290
- interface GeoLibreLayer {
1539
+ export interface GeoLibreLayer {
1291
1540
  id: string;
1292
1541
  name: string;
1293
1542
  type: LayerType;
@@ -1351,6 +1600,14 @@ interface GeoLibreLayer {
1351
1600
  timeFilter?: unknown[];
1352
1601
  /** Transient MapLibre expression applied by the iframe embed API. */
1353
1602
  embedFilter?: unknown[];
1603
+ /**
1604
+ * Project-persisted boolean MapLibre expression that narrows the features
1605
+ * rendered for this layer. Unlike a selection, this leaves the source data
1606
+ * intact and keeps non-matching features hidden until the filter is cleared.
1607
+ * It is composed with transient filters, quick filters, and rule visibility
1608
+ * by the map renderers.
1609
+ */
1610
+ filterExpression?: unknown[];
1354
1611
  /**
1355
1612
  * Data-driven filter controls authored in the layer's Quick Filters section
1356
1613
  * (issue #2114). Unlike {@link timeFilter} and {@link embedFilter} this is
@@ -1381,7 +1638,7 @@ interface GeoLibreLayer {
1381
1638
  * `source` fields MapLibre understands so an external plugin can register tile
1382
1639
  * layers without touching the map directly.
1383
1640
  */
1384
- interface AddTileLayerOptions {
1641
+ export interface AddTileLayerOptions {
1385
1642
  /**
1386
1643
  * One or more XYZ tile URL templates (with `{x}`/`{y}`/`{z}` placeholders).
1387
1644
  * At least one non-empty template is required, or the layer renders nothing.
@@ -1428,7 +1685,7 @@ interface AddTileLayerOptions {
1428
1685
  * child layer's effective render state by `applyGroupEffects` before the map
1429
1686
  * syncs, so children keep their own stored `visible`/`opacity` values.
1430
1687
  */
1431
- interface LayerGroup {
1688
+ export interface LayerGroup {
1432
1689
  id: string;
1433
1690
  name: string;
1434
1691
  /** Parent folder id, or undefined when this folder is at the panel root. */
@@ -1447,7 +1704,7 @@ interface LayerGroup {
1447
1704
  * (which owns the query/refresh logic) and `@geolibre/plugins` (which excludes
1448
1705
  * these layers from in-place geometry editing) share one value.
1449
1706
  */
1450
- declare const SQL_QUERY_SOURCE_KIND = "sql-query";
1707
+ export declare const SQL_QUERY_SOURCE_KIND = "sql-query";
1451
1708
  /**
1452
1709
  * Metadata `sourceKind` marking a NetCDF/HDF grid baked into an `image` overlay,
1453
1710
  * as opposed to the KML ground overlays that otherwise use that layer type.
@@ -1456,14 +1713,14 @@ declare const SQL_QUERY_SOURCE_KIND = "sql-query";
1456
1713
  * on these) and the desktop app (which owns the symbology panel, the pixel
1457
1714
  * readout, and the spectral profile) share one value.
1458
1715
  */
1459
- declare const NETCDF_IMAGE_SOURCE_KIND = "netcdf-image";
1716
+ export declare const NETCDF_IMAGE_SOURCE_KIND = "netcdf-image";
1460
1717
  /**
1461
1718
  * Detect a DuckDB query layer rendered through the plugin's external deck.gl
1462
1719
  * overlay. Shared by `@geolibre/map`, `@geolibre/plugins`, and the desktop
1463
1720
  * app so the detection criteria cannot drift.
1464
1721
  */
1465
- declare function isDuckDBQueryLayer(layer: Pick<GeoLibreLayer, "metadata" | "type"> | undefined): boolean;
1466
- interface MapViewState {
1722
+ export declare function isDuckDBQueryLayer(layer: Pick<GeoLibreLayer, "metadata" | "type"> | undefined): boolean;
1723
+ export interface MapViewState {
1467
1724
  center: [number, number];
1468
1725
  zoom: number;
1469
1726
  bearing: number;
@@ -1480,7 +1737,7 @@ interface MapViewState {
1480
1737
  * different panes can show different layers. When `syncView` is on,
1481
1738
  * panning/zooming any pane mirrors the camera to every other pane.
1482
1739
  */
1483
- interface MapGridLayout {
1740
+ export interface MapGridLayout {
1484
1741
  /** Grid rows (>= 1). */
1485
1742
  rows: number;
1486
1743
  /** Grid columns (>= 1). `rows * cols` is the total number of panes. */
@@ -1488,11 +1745,30 @@ interface MapGridLayout {
1488
1745
  /** When true, all panes share a synchronized camera. */
1489
1746
  syncView: boolean;
1490
1747
  }
1748
+ /**
1749
+ * Which engine draws a map pane.
1750
+ *
1751
+ * `"maplibre"` is the 2D MapLibre GL map that owns the app's plugin, styling,
1752
+ * and deck.gl integrations. `"cesium"` is the 3D globe (see `CesiumCanvas`),
1753
+ * which renders the same shared store state — camera, basemap, layers, group
1754
+ * effects — through CesiumJS.
1755
+ *
1756
+ * Used both for secondary panes ({@link SecondaryMapView.viewKind}) and for the
1757
+ * primary workspace ({@link GeoLibreProject.primaryRenderer}), so the two never
1758
+ * drift apart.
1759
+ */
1760
+ export type MapRendererKind = "maplibre" | "cesium";
1761
+ /**
1762
+ * The engine that draws the primary map area when a project says nothing. The
1763
+ * 2D map: it is the renderer every tool, plugin, and panel is wired to, so an
1764
+ * existing project (and a new one) opens exactly as it always did.
1765
+ */
1766
+ export declare const DEFAULT_PRIMARY_RENDERER: MapRendererKind;
1491
1767
  /**
1492
1768
  * A non-primary map pane: shares the primary map's basemap and layers, with its
1493
1769
  * own camera and per-layer visibility overrides.
1494
1770
  */
1495
- interface SecondaryMapView {
1771
+ export interface SecondaryMapView {
1496
1772
  /** Stable id, used as the React key and the sync-group registration id. */
1497
1773
  id: string;
1498
1774
  view: MapViewState;
@@ -1503,7 +1779,7 @@ interface SecondaryMapView {
1503
1779
  * map) when absent, so existing projects and panes are unchanged. `"cesium"`
1504
1780
  * renders a 3D globe (see {@link CesiumCanvas}) over the same shared layers.
1505
1781
  */
1506
- viewKind?: "maplibre" | "cesium";
1782
+ viewKind?: MapRendererKind;
1507
1783
  /**
1508
1784
  * Per-layer visibility overrides keyed by layer id. A layer absent from this
1509
1785
  * map inherits the primary map's visibility (`layer.visible`); an entry forces
@@ -1512,9 +1788,9 @@ interface SecondaryMapView {
1512
1788
  layerVisibility: Record<string, boolean>;
1513
1789
  }
1514
1790
  /** The default single-map grid (one pane, sync enabled so it turns on cleanly). */
1515
- declare const DEFAULT_MAP_GRID_LAYOUT: MapGridLayout;
1791
+ export declare const DEFAULT_MAP_GRID_LAYOUT: MapGridLayout;
1516
1792
  /** Maximum rows or columns in the map grid (so at most a 4x4 = 16-pane grid). */
1517
- declare const MAX_MAP_GRID_DIM = 4;
1793
+ export declare const MAX_MAP_GRID_DIM = 4;
1518
1794
  /**
1519
1795
  * Live multi-user collaboration (issue #307). These types describe the
1520
1796
  * *ephemeral* session state the store holds while a live session is active. It
@@ -1522,15 +1798,15 @@ declare const MAX_MAP_GRID_DIM = 4;
1522
1798
  * `project.ts` serializers never read it) and never tracked in undo history (the
1523
1799
  * store's `partialize` never lists it), so it resets cleanly on reload.
1524
1800
  */
1525
- type CollaborationRole = "host" | "guest";
1801
+ export type CollaborationRole = "host" | "guest";
1526
1802
  /** Whether guests may edit (`co-edit`) or only watch (`view-only`). */
1527
- type CollaborationMode = "view-only" | "co-edit";
1528
- interface ParticipantIdentity {
1803
+ export type CollaborationMode = "view-only" | "co-edit";
1804
+ export interface ParticipantIdentity {
1529
1805
  provider: string;
1530
1806
  userId: string;
1531
1807
  username: string;
1532
1808
  }
1533
- interface CollabInvite {
1809
+ export interface CollabInvite {
1534
1810
  token: string;
1535
1811
  role: CollaborationMode;
1536
1812
  createdAt: number;
@@ -1538,7 +1814,7 @@ interface CollabInvite {
1538
1814
  useCount: number;
1539
1815
  revoked: boolean;
1540
1816
  }
1541
- interface CollaborationParticipant {
1817
+ export interface CollaborationParticipant {
1542
1818
  clientId: string;
1543
1819
  displayName: string;
1544
1820
  color: string;
@@ -1553,7 +1829,7 @@ interface CollaborationParticipant {
1553
1829
  identity?: ParticipantIdentity | null;
1554
1830
  }
1555
1831
  /** A remote participant's live cursor + viewport, used to render presence. */
1556
- interface CollaborationPresence {
1832
+ export interface CollaborationPresence {
1557
1833
  displayName: string;
1558
1834
  color: string;
1559
1835
  cursor?: {
@@ -1563,7 +1839,7 @@ interface CollaborationPresence {
1563
1839
  view?: MapViewState | null;
1564
1840
  }
1565
1841
  /** One in-session chat message (#754). Ephemeral; never persisted to a project. */
1566
- interface CollaborationChatMessage {
1842
+ export interface CollaborationChatMessage {
1567
1843
  /** Server-assigned id (stable React key / dedupe). */
1568
1844
  id: string;
1569
1845
  /** clientId of the author. */
@@ -1579,7 +1855,7 @@ interface CollaborationChatMessage {
1579
1855
  /** Server-assigned epoch-ms timestamp. */
1580
1856
  ts: number;
1581
1857
  }
1582
- interface CollaborationState {
1858
+ export interface CollaborationState {
1583
1859
  /** True once connected and joined to a session. */
1584
1860
  isActive: boolean;
1585
1861
  /** True while connecting/reconnecting (UI shows a spinner). */
@@ -1614,13 +1890,13 @@ interface CollaborationState {
1614
1890
  error: string | null;
1615
1891
  }
1616
1892
  /** Map projection the renderer uses. Mirrors the GlobeControl toggle. */
1617
- type MapProjection = "globe" | "mercator";
1893
+ export type MapProjection = "globe" | "mercator";
1618
1894
  /**
1619
1895
  * Unit system the scale bar reports distances in. `"metric"` uses m/km,
1620
1896
  * `"imperial"` uses ft/mi, and `"nautical"` uses nautical miles.
1621
1897
  */
1622
- type MapScaleUnit = "metric" | "imperial" | "nautical";
1623
- interface MapPreferences {
1898
+ export type MapScaleUnit = "metric" | "imperial" | "nautical";
1899
+ export interface MapPreferences {
1624
1900
  restrictBounds: boolean;
1625
1901
  bounds: [number, number, number, number];
1626
1902
  minZoom: number;
@@ -1649,6 +1925,8 @@ interface MapPreferences {
1649
1925
  showPointerElevation: boolean;
1650
1926
  /** Whether the built-in 3D terrain control and terrain surface are enabled. */
1651
1927
  terrainEnabled: boolean;
1928
+ /** Cesium imagery override; absent follows the shared project basemap. */
1929
+ cesiumBasemap?: CesiumBasemapId;
1652
1930
  /**
1653
1931
  * Notation the status bar reports the pointer coordinate in: `"dd"` decimal
1654
1932
  * degrees (default), `"dms"` degrees/minutes/seconds, `"ddm"` degrees and
@@ -1659,7 +1937,7 @@ interface MapPreferences {
1659
1937
  */
1660
1938
  coordinateFormat: string;
1661
1939
  }
1662
- interface RuntimeEnvironmentVariable {
1940
+ export interface RuntimeEnvironmentVariable {
1663
1941
  key: string;
1664
1942
  value: string;
1665
1943
  enabled: boolean;
@@ -1675,7 +1953,7 @@ declare global {
1675
1953
  * provider so switching backends does not discard the others' keys. Empty
1676
1954
  * endpoint overrides fall back to the provider's default endpoints.
1677
1955
  */
1678
- interface GeocodingPreferences {
1956
+ export interface GeocodingPreferences {
1679
1957
  providerId: string;
1680
1958
  /** Per-provider API key / access token, keyed by provider id. */
1681
1959
  apiKeys: Record<string, string>;
@@ -1686,34 +1964,34 @@ interface GeocodingPreferences {
1686
1964
  /** Contact email sent to identify the client (used by Nominatim). */
1687
1965
  email?: string;
1688
1966
  }
1689
- interface ProjectPreferences {
1967
+ export interface ProjectPreferences {
1690
1968
  map: MapPreferences;
1691
1969
  environmentVariables: RuntimeEnvironmentVariable[];
1692
1970
  geocoding: GeocodingPreferences;
1693
1971
  }
1694
- type ProjectPluginControlPosition = "top-left" | "top-right" | "bottom-left" | "bottom-right";
1695
- interface ProjectPluginState {
1972
+ export type ProjectPluginControlPosition = "top-left" | "top-right" | "bottom-left" | "bottom-right";
1973
+ export interface ProjectPluginState {
1696
1974
  manifestUrls: string[];
1697
1975
  activePluginIds: string[];
1698
1976
  mapControlPositions: Record<string, ProjectPluginControlPosition>;
1699
1977
  settings: Record<string, unknown>;
1700
1978
  }
1701
- declare const DEFAULT_PROJECT_PREFERENCES: ProjectPreferences;
1979
+ export declare const DEFAULT_PROJECT_PREFERENCES: ProjectPreferences;
1702
1980
  /**
1703
1981
  * A single user override for one legend item, keyed in {@link LegendConfig.overrides}
1704
1982
  * by a stable item key (a layer id for a whole entry, or `${layerId}::${index}`
1705
1983
  * for an individual class within a graduated/categorized entry).
1706
1984
  */
1707
- interface LegendItemOverride {
1985
+ export interface LegendItemOverride {
1708
1986
  /** User-supplied label that replaces the auto-generated one. */
1709
1987
  label?: string;
1710
1988
  /** When true, the item is omitted from the rendered legend. */
1711
1989
  hidden?: boolean;
1712
1990
  }
1713
1991
  /** Swatch shape for a hand-authored legend item. */
1714
- type LegendCustomShape = "square" | "circle" | "line";
1992
+ export type LegendCustomShape = "square" | "circle" | "line";
1715
1993
  /** One hand-authored legend item: a color swatch plus its label. */
1716
- interface LegendCustomItem {
1994
+ export interface LegendCustomItem {
1717
1995
  /** Display label (e.g. an NLCD class name). */
1718
1996
  label: string;
1719
1997
  /** Swatch color as a CSS color (typically `#rrggbb`). */
@@ -1733,14 +2011,14 @@ interface LegendCustomItem {
1733
2011
  * impossible, e.g. a paletted land-cover raster like NLCD); keyed by a
1734
2012
  * `custom:` id it renders as a standalone section not tied to any layer.
1735
2013
  */
1736
- interface LegendCustomEntry {
2014
+ export interface LegendCustomEntry {
1737
2015
  /** Optional heading; a layer-keyed entry falls back to the layer name. */
1738
2016
  title?: string;
1739
2017
  /** The items to render, top to bottom. */
1740
2018
  items: LegendCustomItem[];
1741
2019
  }
1742
2020
  /** Map corner the on-map legend panel docks to. */
1743
- type LegendPanelPosition = "top-left" | "top-right" | "bottom-left" | "bottom-right";
2021
+ export type LegendPanelPosition = "top-left" | "top-right" | "bottom-left" | "bottom-right";
1744
2022
  /**
1745
2023
  * User customizations for the legend (the on-map Legend panel and the Print
1746
2024
  * Layout legend). The legend itself is always derived from the visible layers'
@@ -1748,7 +2026,7 @@ type LegendPanelPosition = "top-left" | "top-right" | "bottom-left" | "bottom-ri
1748
2026
  * per-item rename/hide, hand-authored entries), so it survives layer additions
1749
2027
  * and removals and is persisted in the `.geolibre.json` project.
1750
2028
  */
1751
- interface LegendConfig {
2029
+ export interface LegendConfig {
1752
2030
  /** Heading drawn above the legend entries. */
1753
2031
  title: string;
1754
2032
  /** When true, classes are grouped under a per-layer heading. */
@@ -1780,20 +2058,20 @@ interface LegendConfig {
1780
2058
  /** User-resized panel height in px. See {@link LegendConfig.panelWidth}. */
1781
2059
  panelHeight?: number;
1782
2060
  }
1783
- declare const DEFAULT_LEGEND_CONFIG: LegendConfig;
2061
+ export declare const DEFAULT_LEGEND_CONFIG: LegendConfig;
1784
2062
  /** Camera target captured for a story chapter. */
1785
- interface StoryChapterLocation {
2063
+ export interface StoryChapterLocation {
1786
2064
  center: [number, number];
1787
2065
  zoom: number;
1788
2066
  pitch: number;
1789
2067
  bearing: number;
1790
2068
  }
1791
2069
  /** Where a chapter's text panel sits over the map. */
1792
- type StoryChapterAlignment = "left" | "center" | "right" | "full";
2070
+ export type StoryChapterAlignment = "left" | "center" | "right" | "full";
1793
2071
  /** How the map transitions to a chapter's location. */
1794
- type StoryChapterAnimation = "flyTo" | "easeTo" | "jumpTo";
2072
+ export type StoryChapterAnimation = "flyTo" | "easeTo" | "jumpTo";
1795
2073
  /** A layer opacity change triggered when a chapter is entered or exited. */
1796
- interface StoryLayerOpacityChange {
2074
+ export interface StoryLayerOpacityChange {
1797
2075
  /** Stable identity for React list keys; optional for older project files. */
1798
2076
  id?: string;
1799
2077
  /** GeoLibre store layer id whose opacity should change. */
@@ -1803,7 +2081,7 @@ interface StoryLayerOpacityChange {
1803
2081
  duration?: number;
1804
2082
  }
1805
2083
  /** A single scene in a scroll-driven story map. */
1806
- interface StoryChapter {
2084
+ export interface StoryChapter {
1807
2085
  id: string;
1808
2086
  title: string;
1809
2087
  description: string;
@@ -1819,7 +2097,7 @@ interface StoryChapter {
1819
2097
  onChapterEnter: StoryLayerOpacityChange[];
1820
2098
  onChapterExit: StoryLayerOpacityChange[];
1821
2099
  }
1822
- type StoryInsetPosition = "top-left" | "top-right" | "bottom-left" | "bottom-right";
2100
+ export type StoryInsetPosition = "top-left" | "top-right" | "bottom-left" | "bottom-right";
1823
2101
  /**
1824
2102
  * A non-chapter intro/outro slide shown before the first or after the last
1825
2103
  * chapter (#998). `"none"` disables it. The remaining modes are:
@@ -1830,11 +2108,11 @@ type StoryInsetPosition = "top-left" | "top-right" | "bottom-left" | "bottom-rig
1830
2108
  * the start slide, the last chapter for the closing slide) with all text and
1831
2109
  * media hidden, so the presenter can zoom into the full content next.
1832
2110
  */
1833
- type StorySlideMode = "none" | "blank" | "black" | "global" | "adjacent";
2111
+ export type StorySlideMode = "none" | "blank" | "black" | "global" | "adjacent";
1834
2112
  /** A start/closing slide that is actually shown (every mode except `"none"`). */
1835
- type StoryActiveSlideMode = Exclude<StorySlideMode, "none">;
2113
+ export type StoryActiveSlideMode = Exclude<StorySlideMode, "none">;
1836
2114
  /** Scroll-driven story map authored on top of a GeoLibre project. */
1837
- interface StoryMap {
2115
+ export interface StoryMap {
1838
2116
  title: string;
1839
2117
  subtitle: string;
1840
2118
  byline: string;
@@ -1856,7 +2134,7 @@ interface StoryMap {
1856
2134
  endSlide: StorySlideMode;
1857
2135
  chapters: StoryChapter[];
1858
2136
  }
1859
- declare const DEFAULT_STORY_MAP: StoryMap;
2137
+ export declare const DEFAULT_STORY_MAP: StoryMap;
1860
2138
  /**
1861
2139
  * One step in a {@link ProcessingModel}: a processing tool invoked with a fixed
1862
2140
  * set of parameters. The runner chains steps by feeding each step's output layer
@@ -1864,7 +2142,7 @@ declare const DEFAULT_STORY_MAP: StoryMap;
1864
2142
  * so a step's stored `parameters` for that input is ignored for every step after
1865
2143
  * the first.
1866
2144
  */
1867
- interface ProcessingModelStep {
2145
+ export interface ProcessingModelStep {
1868
2146
  /** Stable id, unique within the model (used as the React key and run label). */
1869
2147
  id: string;
1870
2148
  /** The processing tool's registry id (e.g. `"buffer"`). */
@@ -1882,9 +2160,9 @@ interface ProcessingModelStep {
1882
2160
  * raster nodes exchange GeoTIFF bytes. A port declaring `"any"` accepts either
1883
2161
  * and is resolved to a concrete kind at run time by whatever is wired into it.
1884
2162
  */
1885
- type ModelPortKind = "vector" | "raster" | "any";
2163
+ export type ModelPortKind = "vector" | "raster" | "any";
1886
2164
  /** One connection point on a {@link ModelGraphNode}. */
1887
- interface ModelGraphPort {
2165
+ export interface ModelGraphPort {
1888
2166
  /**
1889
2167
  * Port id, unique within its node and direction. For a tool node's inputs
1890
2168
  * this is the underlying tool parameter id, so wiring an edge and setting the
@@ -1900,9 +2178,9 @@ interface ModelGraphPort {
1900
2178
  * What a node does. `input` sources an existing project layer, `tool` runs a
1901
2179
  * processing algorithm, and `output` names a result to add back to the map.
1902
2180
  */
1903
- type ModelGraphNodeKind = "input" | "tool" | "output";
2181
+ export type ModelGraphNodeKind = "input" | "tool" | "output";
1904
2182
  /** One node on the Model Builder canvas. */
1905
- interface ModelGraphNode {
2183
+ export interface ModelGraphNode {
1906
2184
  /** Stable id, unique within the graph; referenced by {@link ModelGraphEdge}. */
1907
2185
  id: string;
1908
2186
  kind: ModelGraphNodeKind;
@@ -1928,7 +2206,7 @@ interface ModelGraphNode {
1928
2206
  * port. Ports are named, so a tool with several inputs (Clip's target and
1929
2207
  * overlay, say) wires each one unambiguously.
1930
2208
  */
1931
- interface ModelGraphEdge {
2209
+ export interface ModelGraphEdge {
1932
2210
  id: string;
1933
2211
  from: string;
1934
2212
  fromPort: string;
@@ -1936,12 +2214,12 @@ interface ModelGraphEdge {
1936
2214
  toPort: string;
1937
2215
  }
1938
2216
  /** The node-and-edge graph authored on the Model Builder canvas. */
1939
- interface ProcessingModelGraph {
2217
+ export interface ProcessingModelGraph {
1940
2218
  nodes: ModelGraphNode[];
1941
2219
  edges: ModelGraphEdge[];
1942
2220
  }
1943
2221
  /** Which registry a {@link ModelGraphNode.toolId} is resolved against. */
1944
- type ModelToolProvider = "vector" | "whitebox";
2222
+ export type ModelToolProvider = "vector" | "whitebox";
1945
2223
  /**
1946
2224
  * A reusable processing pipeline ("model" in QGIS Graphical Modeler / ArcGIS
1947
2225
  * ModelBuilder terms), saved in the project file so it can be reloaded and
@@ -1954,7 +2232,7 @@ type ModelToolProvider = "vector" | "whitebox";
1954
2232
  * also writes a `steps` projection whenever its graph happens to be a single
1955
2233
  * chain, so older builds can still run it.
1956
2234
  */
1957
- interface ProcessingModel {
2235
+ export interface ProcessingModel {
1958
2236
  id: string;
1959
2237
  name: string;
1960
2238
  steps: ProcessingModelStep[];
@@ -1965,10 +2243,10 @@ interface ProcessingModel {
1965
2243
  * panel's re-run routing: each kind maps to the dialog (and store open-flag)
1966
2244
  * that can be reopened pre-filled with the run's parameters.
1967
2245
  */
1968
- type ProcessingRunKind = "vector" | "statistics" | "network" | "whitebox" | "raster" | "conversion" | "algorithm";
1969
- type ProcessingRunStatus = "success" | "error";
2246
+ export type ProcessingRunKind = "vector" | "statistics" | "network" | "whitebox" | "raster" | "conversion" | "algorithm";
2247
+ export type ProcessingRunStatus = "success" | "error";
1970
2248
  /** Upper bound on persisted processing-history entries (oldest are dropped). */
1971
- declare const MAX_PROCESSING_HISTORY = 100;
2249
+ export declare const MAX_PROCESSING_HISTORY = 100;
1972
2250
  /**
1973
2251
  * One recorded processing tool run (issue #1292). Appended by every processing
1974
2252
  * dialog when a run finishes and persisted in the project file, so a saved
@@ -1976,7 +2254,7 @@ declare const MAX_PROCESSING_HISTORY = 100;
1976
2254
  * stored exactly as the dialog dispatched them (layer parameters hold layer
1977
2255
  * ids), which is what re-run pre-fills and "Copy as Python" emit.
1978
2256
  */
1979
- interface ProcessingRun {
2257
+ export interface ProcessingRun {
1980
2258
  /** Stable id, unique within the project (React key and update key). */
1981
2259
  id: string;
1982
2260
  kind: ProcessingRunKind;
@@ -2010,7 +2288,7 @@ interface ProcessingRun {
2010
2288
  * parameter form) and clears it. `autoRun` asks the dialog to start the run
2011
2289
  * immediately after pre-filling (plain Re-run vs Edit & re-run).
2012
2290
  */
2013
- interface ProcessingRerunRequest {
2291
+ export interface ProcessingRerunRequest {
2014
2292
  kind: ProcessingRunKind;
2015
2293
  toolId: string;
2016
2294
  parameters: Record<string, unknown>;
@@ -2019,15 +2297,15 @@ interface ProcessingRerunRequest {
2019
2297
  autoRun?: boolean;
2020
2298
  }
2021
2299
  /** Column-count bounds for the Dashboard panel's widget grid. */
2022
- declare const MIN_DASHBOARD_COLUMNS = 1;
2023
- declare const MAX_DASHBOARD_COLUMNS = 6;
2024
- declare const DEFAULT_DASHBOARD_COLUMNS = 2;
2300
+ export declare const MIN_DASHBOARD_COLUMNS = 1;
2301
+ export declare const MAX_DASHBOARD_COLUMNS = 6;
2302
+ export declare const DEFAULT_DASHBOARD_COLUMNS = 2;
2025
2303
  /** The chart a {@link DashboardWidget} draws. Mirrors the attribute Charts
2026
2304
  * panel's types so a widget reuses the same rendering. The `"indicator"` type
2027
2305
  * is a non-chart KPI tile (issue #1381). */
2028
- type DashboardWidgetType = "histogram" | "scatter" | "bar" | "line" | "box" | "pie" | "indicator" | "selector" | "list";
2306
+ export type DashboardWidgetType = "histogram" | "scatter" | "bar" | "line" | "box" | "pie" | "indicator" | "selector" | "list";
2029
2307
  /** How a bar widget reduces its category groups. */
2030
- type DashboardWidgetAggregation = "count" | "sum" | "mean";
2308
+ export type DashboardWidgetAggregation = "count" | "sum" | "mean";
2031
2309
  /**
2032
2310
  * One chart in the Dashboard panel: a chart type bound to a layer and the
2033
2311
  * field(s) it plots. Which `field*`/`category`/`aggregation` keys apply depends
@@ -2036,7 +2314,7 @@ type DashboardWidgetAggregation = "count" | "sum" | "mean";
2036
2314
  * keys are simply ignored, so the record stays flat and easy to hand-edit.
2037
2315
  * Saved in the project file so a dashboard reopens with its widgets intact.
2038
2316
  */
2039
- interface DashboardWidget {
2317
+ export interface DashboardWidget {
2040
2318
  /** Stable id, unique within the project (React key and store key). */
2041
2319
  id: string;
2042
2320
  /** The layer whose features feed this widget. */
@@ -2083,7 +2361,7 @@ interface DashboardWidget {
2083
2361
  }
2084
2362
  /** Aggregation functions for indicator widgets (issue #1381). Extends the bar
2085
2363
  * widget aggregation with min, max, and median. */
2086
- type IndicatorAggregation = "count" | "sum" | "mean" | "min" | "max" | "median";
2364
+ export type IndicatorAggregation = "count" | "sum" | "mean" | "min" | "max" | "median";
2087
2365
  /**
2088
2366
  * What slice of a layer's styling a Style Manager entry captures (issue #1294).
2089
2367
  *
@@ -2095,7 +2373,7 @@ type IndicatorAggregation = "count" | "sum" | "mean" | "min" | "max" | "median";
2095
2373
  * count, classification scheme), independent of the attribute the target
2096
2374
  * layer classifies on.
2097
2375
  */
2098
- type StyleLibraryEntryKind = "style" | "symbol" | "labels" | "ramp";
2376
+ export type StyleLibraryEntryKind = "style" | "symbol" | "labels" | "ramp";
2099
2377
  /**
2100
2378
  * One saved, reusable style in the Style Manager library (issue #1294). The
2101
2379
  * payload is a {@link LayerStyle} subset chosen by {@link kind}; applying an
@@ -2103,7 +2381,7 @@ type StyleLibraryEntryKind = "style" | "symbol" | "labels" | "ramp";
2103
2381
  * in the app-level library (persisted across projects) or embedded in a
2104
2382
  * project file's `styleLibrary` array.
2105
2383
  */
2106
- interface StyleLibraryEntry {
2384
+ export interface StyleLibraryEntry {
2107
2385
  /** Stable id, used as the IndexedDB/store key; upserts overwrite by id. */
2108
2386
  id: string;
2109
2387
  /** Display name shown in the Style Manager. */
@@ -2130,7 +2408,7 @@ interface StyleLibraryEntry {
2130
2408
  * their features are embedded in {@link geojson} behind a size cap. See
2131
2409
  * `layer-library.ts` for how an entry is captured and re-added.
2132
2410
  */
2133
- interface LayerLibraryEntry {
2411
+ export interface LayerLibraryEntry {
2134
2412
  /** Stable id, used as the IndexedDB/store key; upserts overwrite by id. */
2135
2413
  id: string;
2136
2414
  /** Display name shown in the Browser panel's My Data section. */
@@ -2170,7 +2448,7 @@ interface LayerLibraryEntry {
2170
2448
  needsLocalFile?: boolean;
2171
2449
  }
2172
2450
  /** One saved template in the Template Library. */
2173
- interface ProjectTemplateEntry {
2451
+ export interface ProjectTemplateEntry {
2174
2452
  id: string;
2175
2453
  name: string;
2176
2454
  description?: string;
@@ -2178,7 +2456,7 @@ interface ProjectTemplateEntry {
2178
2456
  createdAt: string;
2179
2457
  updatedAt: string;
2180
2458
  }
2181
- interface GeoLibreProject {
2459
+ export interface GeoLibreProject {
2182
2460
  id?: string;
2183
2461
  version: string;
2184
2462
  name: string;
@@ -2229,6 +2507,17 @@ interface GeoLibreProject {
2229
2507
  secondaryMapViews?: SecondaryMapView[];
2230
2508
  /** User-entered label for the primary pane; omitted when empty. */
2231
2509
  primaryMapLabel?: string;
2510
+ /**
2511
+ * Which engine draws the primary map area (issue #2217). Omitted for the
2512
+ * default 2D map, so every project written before this existed — and every
2513
+ * project that never leaves MapLibre — is byte-identical to before. A project
2514
+ * saved as `"cesium"` reopens directly on the 3D globe.
2515
+ *
2516
+ * This is independent of {@link mapLayout}: a 1x1 workspace can be either
2517
+ * renderer, and a multi-pane grid can still mix the two through each pane's
2518
+ * {@link SecondaryMapView.viewKind}.
2519
+ */
2520
+ primaryRenderer?: MapRendererKind;
2232
2521
  /**
2233
2522
  * Project-scoped Style Manager entries (issue #1294), so a project can carry
2234
2523
  * its reusable styles to teammates. Omitted when empty; the app-level
@@ -2239,7 +2528,7 @@ interface GeoLibreProject {
2239
2528
  comments?: ProjectComment[];
2240
2529
  metadata: Record<string, unknown>;
2241
2530
  }
2242
- type CommentAnchor = {
2531
+ export type CommentAnchor = {
2243
2532
  type: "point";
2244
2533
  lngLat: [number, number];
2245
2534
  } | {
@@ -2248,17 +2537,17 @@ type CommentAnchor = {
2248
2537
  featureId: string | number;
2249
2538
  lngLat?: [number, number];
2250
2539
  };
2251
- interface CommentAuthor {
2540
+ export interface CommentAuthor {
2252
2541
  name: string;
2253
2542
  color: string;
2254
2543
  }
2255
- interface CommentReply {
2544
+ export interface CommentReply {
2256
2545
  id: string;
2257
2546
  author: CommentAuthor;
2258
2547
  body: string;
2259
2548
  createdAt: string;
2260
2549
  }
2261
- interface ProjectComment {
2550
+ export interface ProjectComment {
2262
2551
  id: string;
2263
2552
  anchor: CommentAnchor;
2264
2553
  author: CommentAuthor;
@@ -2267,7 +2556,7 @@ interface ProjectComment {
2267
2556
  resolved: boolean;
2268
2557
  replies: CommentReply[];
2269
2558
  }
2270
- interface RecentProjectEntry {
2559
+ export interface RecentProjectEntry {
2271
2560
  path: string;
2272
2561
  name: string;
2273
2562
  openedAt: string;
@@ -2285,10 +2574,10 @@ interface RecentProjectEntry {
2285
2574
  * same file behaved differently depending on how it was added, and no single
2286
2575
  * number could be documented.
2287
2576
  */
2288
- declare const DUCKDB_VECTOR_ROUTE_BYTES: number;
2289
- declare const DUCKDB_VECTOR_FEATURE_WARN_COUNT = 100000;
2577
+ export declare const DUCKDB_VECTOR_ROUTE_BYTES: number;
2578
+ export declare const DUCKDB_VECTOR_FEATURE_WARN_COUNT = 100000;
2290
2579
  /** A collection whose coordinates cannot be WGS84 longitude/latitude. */
2291
- interface NonGeographicCoordinates {
2580
+ export interface NonGeographicCoordinates {
2292
2581
  /** How many coordinates were inspected. */
2293
2582
  sampled: number;
2294
2583
  /** The largest |x| seen — a longitude may not exceed 180. */
@@ -2314,7 +2603,7 @@ interface NonGeographicCoordinates {
2314
2603
  *
2315
2604
  * @returns Details when a coordinate is out of geographic range, else null.
2316
2605
  */
2317
- declare function detectNonGeographicCoordinates(geojson: GeoJSON.FeatureCollection | undefined, sampleLimit?: number): NonGeographicCoordinates | null;
2606
+ export declare function detectNonGeographicCoordinates(geojson: GeoJSON.FeatureCollection | undefined, sampleLimit?: number): NonGeographicCoordinates | null;
2318
2607
  //#endregion
2319
2608
  //#region src/diagram.d.ts
2320
2609
  /**
@@ -2323,7 +2612,7 @@ declare function detectNonGeographicCoordinates(geojson: GeoJSON.FeatureCollecti
2323
2612
  * hang the UI; typical thematic layers (counties, districts) sit well below
2324
2613
  * this.
2325
2614
  */
2326
- declare const MAX_DIAGRAM_FEATURES = 2000;
2615
+ export declare const MAX_DIAGRAM_FEATURES = 2000;
2327
2616
  /**
2328
2617
  * Hard cap on how many raw features {@link collectDiagramData} visits while
2329
2618
  * looking for drawable diagrams. Without it, a layer whose drawable ratio is
@@ -2331,11 +2620,11 @@ declare const MAX_DIAGRAM_FEATURES = 2000;
2331
2620
  * an arbitrarily large collection on every rebuild. Features past this bound
2332
2621
  * are treated as truncation, which the Style Panel surfaces.
2333
2622
  */
2334
- declare const MAX_DIAGRAM_SCAN_FEATURES = 100000;
2623
+ export declare const MAX_DIAGRAM_SCAN_FEATURES = 100000;
2335
2624
  /** Smallest rendered diagram size in pixels under scaled sizing. */
2336
- declare const MIN_DIAGRAM_SIZE = 8;
2625
+ export declare const MIN_DIAGRAM_SIZE = 8;
2337
2626
  /** One feature's chart, ready for drawing. */
2338
- interface DiagramDatum {
2627
+ export interface DiagramDatum {
2339
2628
  /** Anchor position: the point location or polygon/line midpoint centroid. */
2340
2629
  position: [number, number];
2341
2630
  /** One value per configured diagram field (negatives clamped to 0). */
@@ -2346,7 +2635,7 @@ interface DiagramDatum {
2346
2635
  sizeValue: number;
2347
2636
  }
2348
2637
  /** The per-layer diagram dataset plus the maxima needed for scaling. */
2349
- interface DiagramData {
2638
+ export interface DiagramData {
2350
2639
  data: DiagramDatum[];
2351
2640
  /** Largest {@link DiagramDatum.sizeValue} (0 when there is no data). */
2352
2641
  maxSizeValue: number;
@@ -2363,7 +2652,7 @@ interface DiagramData {
2363
2652
  *
2364
2653
  * @param style - The layer style to test.
2365
2654
  */
2366
- declare function isDiagramStyleEnabled(style: LayerStyle): boolean;
2655
+ export declare function isDiagramStyleEnabled(style: LayerStyle): boolean;
2367
2656
  /**
2368
2657
  * Whether a heatmap/cluster point renderer suppresses the layer's diagrams.
2369
2658
  * The point renderer only applies (and is only user-editable) on point-only
@@ -2379,7 +2668,7 @@ declare function isDiagramStyleEnabled(style: LayerStyle): boolean;
2379
2668
  * @param geojson - The layer's feature collection (undefined suppresses nothing).
2380
2669
  * @param style - The layer style carrying `pointRenderer`.
2381
2670
  */
2382
- declare function diagramsSuppressedByPointRenderer(geojson: FeatureCollection | undefined, style: LayerStyle): boolean;
2671
+ export declare function diagramsSuppressedByPointRenderer(geojson: FeatureCollection | undefined, style: LayerStyle): boolean;
2383
2672
  /**
2384
2673
  * Where a feature's diagram is anchored: the point itself, a line's middle
2385
2674
  * vertex, or the polygon centroid (largest part of a multi-polygon). Returns
@@ -2387,7 +2676,7 @@ declare function diagramsSuppressedByPointRenderer(geojson: FeatureCollection |
2387
2676
  *
2388
2677
  * @param geometry - The feature geometry (may be null for null-geometry rows).
2389
2678
  */
2390
- declare function diagramAnchor(geometry: Geometry | null | undefined): [number, number] | null;
2679
+ export declare function diagramAnchor(geometry: Geometry | null | undefined): [number, number] | null;
2391
2680
  /**
2392
2681
  * Extract the per-feature diagram dataset from a layer's GeoJSON and style:
2393
2682
  * one {@link DiagramDatum} per feature that has an anchor and at least one
@@ -2397,7 +2686,7 @@ declare function diagramAnchor(geometry: Geometry | null | undefined): [number,
2397
2686
  * @param geojson - The layer's feature collection.
2398
2687
  * @param style - The layer style carrying the diagram configuration.
2399
2688
  */
2400
- declare function collectDiagramData(geojson: FeatureCollection, style: LayerStyle): DiagramData;
2689
+ export declare function collectDiagramData(geojson: FeatureCollection, style: LayerStyle): DiagramData;
2401
2690
  /**
2402
2691
  * The rendered size (diameter for pie/donut, box height/width for bars) of one
2403
2692
  * diagram in pixels. Fixed sizing returns the configured size; scaled sizing
@@ -2410,7 +2699,7 @@ declare function collectDiagramData(geojson: FeatureCollection, style: LayerStyl
2410
2699
  * @param maxSizeValue - The dataset's largest size value (from
2411
2700
  * {@link collectDiagramData}).
2412
2701
  */
2413
- declare function diagramPixelSize(datum: DiagramDatum, style: LayerStyle, maxSizeValue: number): number;
2702
+ export declare function diagramPixelSize(datum: DiagramDatum, style: LayerStyle, maxSizeValue: number): number;
2414
2703
  //#endregion
2415
2704
  //#region src/marker-shape.d.ts
2416
2705
  /**
@@ -2430,7 +2719,7 @@ declare function diagramPixelSize(datum: DiagramDatum, style: LayerStyle, maxSiz
2430
2719
  * @param size - The box edge length in pixels; the shape is inset slightly so a
2431
2720
  * stroke is not clipped at the edge.
2432
2721
  */
2433
- declare function drawMarkerPath(ctx: CanvasRenderingContext2D, shape: MarkerShape, size: number): void;
2722
+ export declare function drawMarkerPath(ctx: CanvasRenderingContext2D, shape: MarkerShape, size: number): void;
2434
2723
  /**
2435
2724
  * Resolve user-supplied SVG input to an `Image.src`: inline markup (starting
2436
2725
  * with `<`) is encoded as a data URL; otherwise only `data:` and `http(s):`
@@ -2453,7 +2742,7 @@ declare function drawMarkerPath(ctx: CanvasRenderingContext2D, shape: MarkerShap
2453
2742
  * @param markup - Raw SVG markup, a `data:` URL, or an `http(s)` URL.
2454
2743
  * @returns An `Image.src` value, or `null` when nothing loadable was given.
2455
2744
  */
2456
- declare function resolveSvgSource(markup: string): string | null;
2745
+ export declare function resolveSvgSource(markup: string): string | null;
2457
2746
  //#endregion
2458
2747
  //#region src/hyperlink.d.ts
2459
2748
  /**
@@ -2463,7 +2752,7 @@ declare function resolveSvgSource(markup: string): string | null;
2463
2752
  * are accepted. Substrings in prose and schemes such as `javascript:` and
2464
2753
  * `file:` remain plain text.
2465
2754
  */
2466
- declare function attributeLinkUrl(value: unknown): string | null;
2755
+ export declare function attributeLinkUrl(value: unknown): string | null;
2467
2756
  //#endregion
2468
2757
  //#region src/photo.d.ts
2469
2758
  /**
@@ -2473,7 +2762,7 @@ declare function attributeLinkUrl(value: unknown): string | null;
2473
2762
  * geotagged-photo or field-collection layer.
2474
2763
  */
2475
2764
  /** Property key under which a photo's downscaled thumbnail (data URL) is stored. */
2476
- declare const PHOTO_PROPERTY = "photo";
2765
+ export declare const PHOTO_PROPERTY = "photo";
2477
2766
  /**
2478
2767
  * Property key under which a geotagged photo's full-resolution image (a data URL
2479
2768
  * of the original, un-re-encoded bytes) is stored. {@link PHOTO_PROPERTY} holds
@@ -2482,7 +2771,7 @@ declare const PHOTO_PROPERTY = "photo";
2482
2771
  * image". Absent when the source is already at or below the thumbnail cap, or a
2483
2772
  * format a browser cannot display at native size (TIFF/HEIC).
2484
2773
  */
2485
- declare const PHOTO_FULL_PROPERTY = "photo_full";
2774
+ export declare const PHOTO_FULL_PROPERTY = "photo_full";
2486
2775
  //#endregion
2487
2776
  //#region src/ellipsoids.d.ts
2488
2777
  /**
@@ -2506,7 +2795,7 @@ declare const PHOTO_FULL_PROPERTY = "photo_full";
2506
2795
  * shortcut over a full CRS/context refactor.
2507
2796
  */
2508
2797
  /** A biaxial (rotational) ellipsoid describing a celestial body. */
2509
- interface Ellipsoid {
2798
+ export interface Ellipsoid {
2510
2799
  /** Stable id persisted in the project (`map.ellipsoidId`). */
2511
2800
  id: string;
2512
2801
  /** Human-readable name shown in the UI. */
@@ -2526,7 +2815,7 @@ interface Ellipsoid {
2526
2815
  * products treat them and is well within the accuracy MapLibre's unit-sphere
2527
2816
  * rendering can represent anyway.
2528
2817
  */
2529
- declare const ELLIPSOIDS: readonly [{
2818
+ export declare const ELLIPSOIDS: readonly [{
2530
2819
  readonly id: "earth";
2531
2820
  readonly name: "Earth (WGS 84)";
2532
2821
  readonly semiMajorAxisMeters: 6378137;
@@ -2587,29 +2876,29 @@ declare const ELLIPSOIDS: readonly [{
2587
2876
  readonly semiMajorAxisMeters: 606000;
2588
2877
  readonly inverseFlattening: 0;
2589
2878
  }];
2590
- type EllipsoidId = (typeof ELLIPSOIDS)[number]["id"];
2591
- declare const DEFAULT_ELLIPSOID_ID: EllipsoidId;
2879
+ export type EllipsoidId = (typeof ELLIPSOIDS)[number]["id"];
2880
+ export declare const DEFAULT_ELLIPSOID_ID: EllipsoidId;
2592
2881
  /** Look an ellipsoid up by id, falling back to Earth for unknown ids. */
2593
- declare function getEllipsoid(id: string | undefined): Ellipsoid;
2882
+ export declare function getEllipsoid(id: string | undefined): Ellipsoid;
2594
2883
  /**
2595
2884
  * Mean radius `R = (2a + b) / 3` in metres, where `b` is the polar radius
2596
2885
  * derived from the inverse flattening. This is the radius used for spherical
2597
2886
  * (haversine) distance and area math.
2598
2887
  */
2599
- declare function meanRadiusMeters(ellipsoid: Ellipsoid): number;
2888
+ export declare function meanRadiusMeters(ellipsoid: Ellipsoid): number;
2600
2889
  /** Earth's mean radius in metres — the radius Turf.js and MapLibre bake in. */
2601
- declare const EARTH_MEAN_RADIUS_METERS: number;
2890
+ export declare const EARTH_MEAN_RADIUS_METERS: number;
2602
2891
  /**
2603
2892
  * Point the measurement helpers at a body. Unknown ids fall back to Earth so a
2604
2893
  * malformed project can never break measurements. Safe to call on every
2605
2894
  * preferences change; it is a cheap assignment.
2606
2895
  */
2607
- declare function setActiveEllipsoidId(id: string | undefined): void;
2608
- declare function getActiveEllipsoid(): Ellipsoid;
2896
+ export declare function setActiveEllipsoidId(id: string | undefined): void;
2897
+ export declare function getActiveEllipsoid(): Ellipsoid;
2609
2898
  /** Mean radius (metres) of the active body — for haversine distance/area. */
2610
- declare function getActiveMeanRadiusMeters(): number;
2899
+ export declare function getActiveMeanRadiusMeters(): number;
2611
2900
  /** Semi-major axis (metres) of the active body — for its Web-Mercator scale. */
2612
- declare function getActiveSemiMajorAxisMeters(): number;
2901
+ export declare function getActiveSemiMajorAxisMeters(): number;
2613
2902
  /**
2614
2903
  * The active body's mean radius as a fraction of Earth's — `R_body / R_earth`,
2615
2904
  * and exactly `1` on Earth.
@@ -2625,7 +2914,7 @@ declare function getActiveSemiMajorAxisMeters(): number;
2625
2914
  * Suggested by @thareUSGS (USGS Astrogeology) on GeoLibre#1128 as the practical
2626
2915
  * workaround planetary web maps have long used on Earth-locked engines.
2627
2916
  */
2628
- declare function getActiveBodyRadiusRatio(): number;
2917
+ export declare function getActiveBodyRadiusRatio(): number;
2629
2918
  /**
2630
2919
  * Convert a length Turf.js measured on Earth into the active body's true ground
2631
2920
  * length. A no-op on Earth.
@@ -2636,7 +2925,7 @@ declare function getActiveBodyRadiusRatio(): number;
2636
2925
  * length in whatever unit Turf gave it back (metres, kilometres, miles) and the
2637
2926
  * result is in that same unit. There is no hidden unit conversion here.
2638
2927
  */
2639
- declare function earthLengthToBody(length: number): number;
2928
+ export declare function earthLengthToBody(length: number): number;
2640
2929
  /**
2641
2930
  * Convert a true ground length on the active body into the Earth-equivalent
2642
2931
  * length to hand Turf.js. A no-op on Earth.
@@ -2648,7 +2937,7 @@ declare function earthLengthToBody(length: number): number;
2648
2937
  * Unit-agnostic like {@link earthLengthToBody}: pass the length in whatever
2649
2938
  * unit you are about to hand Turf alongside it, and the result is in that unit.
2650
2939
  */
2651
- declare function bodyLengthToEarth(length: number): number;
2940
+ export declare function bodyLengthToEarth(length: number): number;
2652
2941
  /**
2653
2942
  * Convert an area Turf.js measured on Earth into the active body's true ground
2654
2943
  * area. A no-op on Earth.
@@ -2657,7 +2946,7 @@ declare function bodyLengthToEarth(length: number): number;
2657
2946
  * correction as {@link earthLengthToBody}. Unit-agnostic in the same way, for
2658
2947
  * whatever squared unit the area is expressed in.
2659
2948
  */
2660
- declare function earthAreaToBody(area: number): number;
2949
+ export declare function earthAreaToBody(area: number): number;
2661
2950
  /**
2662
2951
  * A raster basemap for a celestial body — the Moon and Mars mosaics, plus the
2663
2952
  * Earth satellite imagery the planet switcher pairs with Earth. The tiles are
@@ -2666,7 +2955,7 @@ declare function earthAreaToBody(area: number): number;
2666
2955
  * sentinel; the map controller expands it into a raster style at apply time (it
2667
2956
  * is not a fetchable URL).
2668
2957
  */
2669
- interface PlanetaryBasemap {
2958
+ export interface PlanetaryBasemap {
2670
2959
  id: string;
2671
2960
  name: string;
2672
2961
  /** Sentinel stored as the basemap style URL. */
@@ -2687,8 +2976,8 @@ interface PlanetaryBasemap {
2687
2976
  /** The body this basemap depicts, so selecting it can set the ellipsoid. */
2688
2977
  ellipsoidId: EllipsoidId;
2689
2978
  }
2690
- declare const PLANETARY_BASEMAP_SENTINEL_PREFIX = "geolibre://basemap/";
2691
- declare const PLANETARY_BASEMAPS: readonly PlanetaryBasemap[];
2979
+ export declare const PLANETARY_BASEMAP_SENTINEL_PREFIX = "geolibre://basemap/";
2980
+ export declare const PLANETARY_BASEMAPS: readonly PlanetaryBasemap[];
2692
2981
  /**
2693
2982
  * The section a planetary basemap is grouped under in the New Project and
2694
2983
  * Change Basemap pickers. The Moon and Mars keep dedicated sections (they are
@@ -2696,9 +2985,9 @@ declare const PLANETARY_BASEMAPS: readonly PlanetaryBasemap[];
2696
2985
  * collapsed into a single "other" section so the picker isn't a wall of
2697
2986
  * one-item headings.
2698
2987
  */
2699
- type PlanetaryBasemapSectionId = "moon" | "mars" | "other";
2988
+ export type PlanetaryBasemapSectionId = "moon" | "mars" | "other";
2700
2989
  /** A picker section paired with the planetary basemaps it lists. */
2701
- interface PlanetaryBasemapGroup {
2990
+ export interface PlanetaryBasemapGroup {
2702
2991
  id: PlanetaryBasemapSectionId;
2703
2992
  basemaps: readonly PlanetaryBasemap[];
2704
2993
  }
@@ -2708,11 +2997,11 @@ interface PlanetaryBasemapGroup {
2708
2997
  * in {@link PLANETARY_BASEMAPS} order (grouped by body). Empty sections are
2709
2998
  * dropped.
2710
2999
  */
2711
- declare const PLANETARY_BASEMAP_GROUPS: readonly PlanetaryBasemapGroup[];
3000
+ export declare const PLANETARY_BASEMAP_GROUPS: readonly PlanetaryBasemapGroup[];
2712
3001
  /** Resolve a `geolibre://basemap/<id>` sentinel to its planetary basemap. */
2713
- declare function getPlanetaryBasemapByStyleUrl(styleUrl: string | undefined): PlanetaryBasemap | undefined;
3002
+ export declare function getPlanetaryBasemapByStyleUrl(styleUrl: string | undefined): PlanetaryBasemap | undefined;
2714
3003
  /** Look a planetary basemap up by its stable id. */
2715
- declare function getPlanetaryBasemapById(id: string): PlanetaryBasemap | undefined;
3004
+ export declare function getPlanetaryBasemapById(id: string): PlanetaryBasemap | undefined;
2716
3005
  /**
2717
3006
  * The celestial bodies offered by the Layers-panel planet switcher, in menu
2718
3007
  * order (like Google Earth's planet dropdown). Each body is paired with the
@@ -2720,7 +3009,7 @@ declare function getPlanetaryBasemapById(id: string): PlanetaryBasemap | undefin
2720
3009
  * OpenPlanetaryMap Hillshaded Albedo mosaic for the Moon, and the OpenPlanetaryMap
2721
3010
  * Viking mosaic for Mars.
2722
3011
  */
2723
- declare const PLANET_SWITCHER_OPTIONS: readonly [{
3012
+ export declare const PLANET_SWITCHER_OPTIONS: readonly [{
2724
3013
  readonly ellipsoidId: "earth";
2725
3014
  readonly basemapId: "earth-usgs-imagery";
2726
3015
  }, {
@@ -2780,11 +3069,11 @@ declare const PLANET_SWITCHER_OPTIONS: readonly [{
2780
3069
  * heading and explanatory note inside the single "Regional" section, so a
2781
3070
  * future region slots in without the section itself becoming country-specific.
2782
3071
  */
2783
- type RegionalBasemapRegionId = "china";
3072
+ export type RegionalBasemapRegionId = "china";
2784
3073
  /**
2785
3074
  * A raster basemap for a region, rendered from XYZ (or TMS) tiles.
2786
3075
  */
2787
- interface RegionalBasemap {
3076
+ export interface RegionalBasemap {
2788
3077
  id: string;
2789
3078
  /** Which region heading this basemap sits under. */
2790
3079
  region: RegionalBasemapRegionId;
@@ -2824,7 +3113,7 @@ interface RegionalBasemap {
2824
3113
  */
2825
3114
  gcj02?: boolean;
2826
3115
  }
2827
- declare const REGIONAL_BASEMAP_SENTINEL_PREFIX = "geolibre://regional-basemap/";
3116
+ export declare const REGIONAL_BASEMAP_SENTINEL_PREFIX = "geolibre://regional-basemap/";
2828
3117
  /**
2829
3118
  * Basemaps served from inside mainland China.
2830
3119
  *
@@ -2833,117 +3122,53 @@ declare const REGIONAL_BASEMAP_SENTINEL_PREFIX = "geolibre://regional-basemap/";
2833
3122
  * tile rather than a 404 past zoom 18, and Tencent 400s past 19 with zoom 19
2834
3123
  * already blank.
2835
3124
  */
2836
- declare const CHINA_BASEMAPS: readonly RegionalBasemap[];
3125
+ export declare const CHINA_BASEMAPS: readonly RegionalBasemap[];
2837
3126
  /** Every regional basemap, across all regions. */
2838
- declare const REGIONAL_BASEMAPS: readonly RegionalBasemap[];
3127
+ export declare const REGIONAL_BASEMAPS: readonly RegionalBasemap[];
2839
3128
  /**
2840
3129
  * The regional basemaps grouped for display, one entry per region. Both the New
2841
3130
  * Project and Change Basemap panels render this inside a single collapsible
2842
3131
  * "Regional" section, so adding a region is a change here rather than in two
2843
3132
  * dialogs.
2844
3133
  */
2845
- declare const REGIONAL_BASEMAP_GROUPS: readonly {
3134
+ export declare const REGIONAL_BASEMAP_GROUPS: readonly {
2846
3135
  id: RegionalBasemapRegionId;
2847
3136
  basemaps: readonly RegionalBasemap[];
2848
3137
  }[];
2849
3138
  /** Look up a regional basemap by its `geolibre://regional-basemap/<id>` sentinel. */
2850
- declare function getRegionalBasemapByStyleUrl(styleUrl: string | undefined): RegionalBasemap | undefined;
3139
+ export declare function getRegionalBasemapByStyleUrl(styleUrl: string | undefined): RegionalBasemap | undefined;
2851
3140
  /** Look up a regional basemap by id. */
2852
- declare function getRegionalBasemapById(id: string | undefined): RegionalBasemap | undefined;
3141
+ export declare function getRegionalBasemapById(id: string | undefined): RegionalBasemap | undefined;
2853
3142
  /** Whether a style URL is a regional-basemap sentinel, resolvable or not. */
2854
- declare function isRegionalBasemapSentinel(styleUrl: string | undefined): boolean;
3143
+ export declare function isRegionalBasemapSentinel(styleUrl: string | undefined): boolean;
2855
3144
  //#endregion
2856
- //#region src/cesium-imagery.d.ts
2857
- /**
2858
- * Maps the project's basemap onto imagery the Cesium globe can render.
2859
- *
2860
- * The 2D panes render `basemapStyleUrl` through MapLibre, which understands
2861
- * vector GL styles and GeoLibre's `geolibre://` sentinels. Cesium understands
2862
- * neither: it draws imagery from tile providers only. So a globe pane that
2863
- * simply mounted the store basemap would show nothing, which is why the pane
2864
- * used to hardcode Ion World Imagery (with a token) or OpenStreetMap (without)
2865
- * and ignore the user's choice entirely — leaving a bright globe beside dark 2D
2866
- * panes and breaking the "same map, different projection" promise the multi-map
2867
- * grid makes.
2868
- *
2869
- * This module is the translation. It is deliberately **engine-free** — it
2870
- * returns a plain descriptor and never imports Cesium — so it lives in
2871
- * `@geolibre/core` beside the basemap catalogs it reads, the 2D and 3D
2872
- * renderers share one source of truth, and the Cesium chunk boundary in
2873
- * `vite.config.ts` stays intact.
2874
- *
2875
- * Three outcomes are possible, and the caller has to handle all three (see
2876
- * {@link CesiumBasemapImagery}): tiles to draw, nothing to draw, or "no raster
2877
- * equivalent exists — pick your own default".
2878
- */
2879
- /**
2880
- * What the globe should draw underneath the project's data layers.
2881
- *
2882
- * - `xyz` — a tile template to render, with the credit and zoom bounds that go
2883
- * with it.
2884
- * - `none` — the user chose the blank basemap; draw a bare ellipsoid.
2885
- * - `default` — this basemap has no raster equivalent (a custom style URL, a
2886
- * provider style, an offline archive). The renderer falls back to whatever it
2887
- * can offer, which is Ion World Imagery when a token is configured and
2888
- * OpenStreetMap otherwise.
2889
- */
2890
- type CesiumBasemapImagery = {
2891
- kind: "none";
2892
- } | {
2893
- kind: "default";
2894
- } | {
2895
- kind: "xyz";
2896
- /** Tile template with `{z}`/`{x}`/`{y}` placeholders. */
2897
- template: string;
2898
- /** Credit to show on the globe, as the HTML the 2D map already uses. */
2899
- attribution: string;
2900
- /** Max native zoom of the source, so the globe overzooms rather than 404s. */
2901
- maximumLevel?: number;
2902
- /**
2903
- * Tile row ordering. `"tms"` numbers rows from the bottom; absent means
2904
- * standard XYZ. Cesium has no `scheme` option, so a TMS template needs
2905
- * `{y}` swapped for its `{reverseY}` placeholder at render time.
2906
- */
2907
- scheme?: "tms";
2908
- /**
2909
- * A transparent overlay drawn directly above {@link template} — the
2910
- * roads-and-labels tiles a hybrid basemap (Amap Hybrid) bakes in, so one
2911
- * basemap selection still yields a labelled satellite globe.
2912
- */
2913
- overlayTemplate?: string;
2914
- };
3145
+ //#region src/geojson-z.d.ts
2915
3146
  /**
2916
- * Whether two descriptors would draw the same thing.
2917
- *
2918
- * Descriptors are built fresh on every call, so two basemaps resolving to the
2919
- * same analogue — OpenFreeMap `liberty` and `bright` are both the streets
2920
- * tone — yield equal but distinct objects. A renderer that remembers the
2921
- * descriptor it drew (to skip redundant work) must compare by value: a
2922
- * reference check would miss that case and tear down and re-add an identical
2923
- * tile provider, costing a flash and a round of re-requested tiles for no
2924
- * visible change.
3147
+ * Helpers for vector data whose coordinates carry a Z value (elevation), e.g.
3148
+ * GPX tracks with `<ele>` readings or LineStringZ/PointZ geometries. MapLibre's
3149
+ * 2D style layers ignore the third coordinate, so layers that want to render
3150
+ * their Z values use these helpers to detect and rescale elevations before
3151
+ * handing the data to a deck.gl overlay. The same data can carry its elevation
3152
+ * in a `bbox` member too, which `horizontalBbox` trims back to two dimensions.
2925
3153
  */
2926
- declare function sameCesiumImagery(a: CesiumBasemapImagery, b: CesiumBasemapImagery): boolean;
2927
3154
  /**
2928
- * Translate a basemap style URL into imagery for the Cesium globe.
3155
+ * Reduces a bounding box to its horizontal extent, `[west, south, east, north]`.
2929
3156
  *
2930
- * Planetary and regional basemaps are already raster tile sets, so they carry
2931
- * straight over — the globe shows the same Mars/Moon/Amap tiles the 2D panes
2932
- * do. GeoLibre's own vector styles map to a keyless raster basemap of matching
2933
- * tone, so switching the project to a dark basemap darkens the globe too.
2934
- * Everything else reports `default`, leaving the choice of fallback imagery to
2935
- * the renderer (which knows whether an Ion token is configured).
3157
+ * RFC 7946 §5 lets a `bbox` member carry elevation, in which case it holds six
3158
+ * values — `[west, south, minAltitude, east, north, maxAltitude]` — and
3159
+ * `@turf/bbox` returns a collection's own member verbatim rather than
3160
+ * recomputing it. A consumer reading such a box as four values takes the
3161
+ * altitude for a longitude and the east edge for a latitude; that is how a 3D
3162
+ * feed reached MapLibre as an out-of-range latitude (#2358).
2936
3163
  *
2937
- * A `geolibre://` sentinel that no longer resolves is treated as the default
2938
- * basemap, mirroring what `resolveMapStyle` does for the 2D map rather than
2939
- * handing the sentinel onward as if it were fetchable.
3164
+ * Returns null when there is no usable horizontal extent: a box of any other
3165
+ * length, or one carrying a non-finite value anywhere — an empty collection, or
3166
+ * one whose features all have a null geometry, bboxes to ±Infinity, and a box
3167
+ * whose altitudes are not finite is not one to trust the rest of.
2940
3168
  *
2941
- * @param styleUrl - The project's `basemapStyleUrl`.
2942
- * @returns What the globe should draw beneath the data layers.
3169
+ * @param box - A GeoJSON or Turf bounding box, of four or six values.
2943
3170
  */
2944
- declare function basemapToCesiumImagery(styleUrl: string | undefined): CesiumBasemapImagery;
2945
- //#endregion
2946
- //#region src/geojson-z.d.ts
3171
+ export declare function horizontalBbox(box: readonly number[] | null | undefined): [number, number, number, number] | null;
2947
3172
  /**
2948
3173
  * Returns true when any coordinate in the GeoJSON carries a finite, non-zero
2949
3174
  * Z value. All-zero Z arrays are treated as flat data because rendering them
@@ -2952,7 +3177,7 @@ declare function basemapToCesiumImagery(styleUrl: string | undefined): CesiumBas
2952
3177
  *
2953
3178
  * @param geojson - Any GeoJSON object (geometry, feature, or collection).
2954
3179
  */
2955
- declare function geojsonHasZCoordinates(geojson: GeoJSON$1 | null | undefined): boolean;
3180
+ export declare function geojsonHasZCoordinates(geojson: GeoJSON$1 | null | undefined): boolean;
2956
3181
  /**
2957
3182
  * Returns a copy of the GeoJSON with every coordinate's Z value mapped to
2958
3183
  * `z * verticalScale + offset` (missing or non-finite Z treated as 0). Used
@@ -2965,7 +3190,7 @@ declare function geojsonHasZCoordinates(geojson: GeoJSON$1 | null | undefined):
2965
3190
  * @param verticalScale - Multiplier applied to each Z value.
2966
3191
  * @param offset - Constant altitude in meters added after scaling.
2967
3192
  */
2968
- declare function transformGeojsonElevation(geojson: FeatureCollection, verticalScale: number, offset: number): FeatureCollection;
3193
+ export declare function transformGeojsonElevation(geojson: FeatureCollection, verticalScale: number, offset: number): FeatureCollection;
2969
3194
  //#endregion
2970
3195
  //#region src/color-ramp.d.ts
2971
3196
  /**
@@ -2977,13 +3202,13 @@ declare function transformGeojsonElevation(geojson: FeatureCollection, verticalS
2977
3202
  * (`COLORMAP_INDEX` keys) so a ramp choice maps 1:1 onto the raster render
2978
3203
  * path.
2979
3204
  */
2980
- type ColorRamp = {
3205
+ export type ColorRamp = {
2981
3206
  value: string;
2982
3207
  label: string;
2983
3208
  colors: readonly string[];
2984
3209
  };
2985
3210
  /** The built-in color ramps offered by the style panels. */
2986
- declare const VECTOR_COLOR_RAMPS: readonly ColorRamp[];
3211
+ export declare const VECTOR_COLOR_RAMPS: readonly ColorRamp[];
2987
3212
  /**
2988
3213
  * Resolves a ramp definition by name, falling back to the first ramp when the
2989
3214
  * name is unknown.
@@ -2991,7 +3216,7 @@ declare const VECTOR_COLOR_RAMPS: readonly ColorRamp[];
2991
3216
  * @param value - The ramp `value` (e.g. "viridis").
2992
3217
  * @returns The matching ramp, or the first ramp.
2993
3218
  */
2994
- declare function getVectorColorRamp(value: string): ColorRamp;
3219
+ export declare function getVectorColorRamp(value: string): ColorRamp;
2995
3220
  /**
2996
3221
  * Samples a ramp into `count` evenly spaced hex colors by linearly
2997
3222
  * interpolating between the ramp's anchor colors.
@@ -3000,7 +3225,7 @@ declare function getVectorColorRamp(value: string): ColorRamp;
3000
3225
  * @param count - Number of colors to produce.
3001
3226
  * @returns An array of `count` hex colors (a single end color when count <= 1).
3002
3227
  */
3003
- declare function interpolateRampColors(colorRamp: string, count: number): string[];
3228
+ export declare function interpolateRampColors(colorRamp: string, count: number): string[];
3004
3229
  /**
3005
3230
  * Samples an explicit list of anchor colors into `count` evenly spaced hex
3006
3231
  * colors by linear interpolation. Backs both the named ramps and user-defined
@@ -3010,7 +3235,7 @@ declare function interpolateRampColors(colorRamp: string, count: number): string
3010
3235
  * @param count - Number of colors to produce.
3011
3236
  * @returns An array of `count` hex colors (a single end color when count <= 1).
3012
3237
  */
3013
- declare function interpolateColors(colors: readonly string[], count: number): string[];
3238
+ export declare function interpolateColors(colors: readonly string[], count: number): string[];
3014
3239
  /**
3015
3240
  * Normalizes a single user-entered color token into a canonical `#rrggbb`
3016
3241
  * lowercase hex string, or null when it is not a valid 3- or 6-digit hex
@@ -3020,7 +3245,7 @@ declare function interpolateColors(colors: readonly string[], count: number): st
3020
3245
  * @param token - A raw color token (e.g. "FF0000", "#f00", " #AaBbCc ").
3021
3246
  * @returns The canonical `#rrggbb` color, or null when invalid.
3022
3247
  */
3023
- declare function normalizeHexColor(token: string): string | null;
3248
+ export declare function normalizeHexColor(token: string): string | null;
3024
3249
  /**
3025
3250
  * Parses a free-text list of hex color codes into canonical `#rrggbb` colors,
3026
3251
  * for the custom color-ramp inputs. Tokens may be separated by commas,
@@ -3030,7 +3255,7 @@ declare function normalizeHexColor(token: string): string | null;
3030
3255
  * @param input - The raw text the user entered.
3031
3256
  * @returns The valid, normalized colors in input order.
3032
3257
  */
3033
- declare function parseHexColorList(input: string): string[];
3258
+ export declare function parseHexColorList(input: string): string[];
3034
3259
  /**
3035
3260
  * Linearly interpolates between two hex colors.
3036
3261
  *
@@ -3039,14 +3264,14 @@ declare function parseHexColorList(input: string): string[];
3039
3264
  * @param ratio - Blend factor in [0, 1].
3040
3265
  * @returns The interpolated hex color.
3041
3266
  */
3042
- declare function interpolateHexColor(from: string, to: string, ratio: number): string;
3267
+ export declare function interpolateHexColor(from: string, to: string, ratio: number): string;
3043
3268
  /**
3044
3269
  * Parses a `#rrggbb` hex color into its RGB channels.
3045
3270
  *
3046
3271
  * @param value - A `#rrggbb` hex color.
3047
3272
  * @returns The red, green, and blue channels (0-255).
3048
3273
  */
3049
- declare function parseHexColor(value: string): {
3274
+ export declare function parseHexColor(value: string): {
3050
3275
  b: number;
3051
3276
  g: number;
3052
3277
  r: number;
@@ -3057,7 +3282,7 @@ declare function parseHexColor(value: string): {
3057
3282
  * @param color - The red, green, and blue channels (0-255).
3058
3283
  * @returns A `#rrggbb` hex color.
3059
3284
  */
3060
- declare function rgbToHex(color: {
3285
+ export declare function rgbToHex(color: {
3061
3286
  b: number;
3062
3287
  g: number;
3063
3288
  r: number;
@@ -3070,7 +3295,7 @@ declare function rgbToHex(color: {
3070
3295
  * @param count - Number of breaks to produce.
3071
3296
  * @returns The break values (min..max inclusive when count > 1).
3072
3297
  */
3073
- declare function createEqualIntervalBreaks(min: number, max: number, count: number): number[];
3298
+ export declare function createEqualIntervalBreaks(min: number, max: number, count: number): number[];
3074
3299
  /**
3075
3300
  * Builds `count` quantile break values from a sample of numeric values.
3076
3301
  *
@@ -3083,9 +3308,9 @@ declare function createEqualIntervalBreaks(min: number, max: number, count: numb
3083
3308
  * @param count - Number of breaks to produce.
3084
3309
  * @returns The quantile break values.
3085
3310
  */
3086
- declare function createQuantileBreaks(values: number[], count: number): number[];
3311
+ export declare function createQuantileBreaks(values: number[], count: number): number[];
3087
3312
  /** The classification schemes the graduated vector renderer offers. */
3088
- type GraduatedClassificationScheme = "equal-interval" | "quantile" | "natural-breaks";
3313
+ export type GraduatedClassificationScheme = "equal-interval" | "quantile" | "natural-breaks";
3089
3314
  /**
3090
3315
  * Builds the class *lower bounds* for a graduated vector renderer.
3091
3316
  *
@@ -3109,7 +3334,7 @@ type GraduatedClassificationScheme = "equal-interval" | "quantile" | "natural-br
3109
3334
  * @param scheme - The classification scheme.
3110
3335
  * @returns Up to `count` strictly ascending class lower bounds.
3111
3336
  */
3112
- declare function createGraduatedClassBreaks(values: number[], count: number, scheme: GraduatedClassificationScheme): number[];
3337
+ export declare function createGraduatedClassBreaks(values: number[], count: number, scheme: GraduatedClassificationScheme): number[];
3113
3338
  //#endregion
3114
3339
  //#region src/paths.d.ts
3115
3340
  /**
@@ -3119,7 +3344,7 @@ declare function createGraduatedClassBreaks(values: number[], count: number, sch
3119
3344
  * @param path - The path to check.
3120
3345
  * @returns True when the path contains a traversal segment.
3121
3346
  */
3122
- declare function hasPathTraversal(path: string): boolean;
3347
+ export declare function hasPathTraversal(path: string): boolean;
3123
3348
  /**
3124
3349
  * Whether a path is an absolute local filesystem path a host could read.
3125
3350
  *
@@ -3137,7 +3362,7 @@ declare function hasPathTraversal(path: string): boolean;
3137
3362
  * @param path - The path to check.
3138
3363
  * @returns True when the path is an absolute POSIX or Windows path.
3139
3364
  */
3140
- declare function isAbsoluteFilesystemPath(path: string): boolean;
3365
+ export declare function isAbsoluteFilesystemPath(path: string): boolean;
3141
3366
  //#endregion
3142
3367
  //#region src/routing.d.ts
3143
3368
  /**
@@ -3153,17 +3378,17 @@ declare function isAbsoluteFilesystemPath(path: string): boolean;
3153
3378
  * unit-tested without a browser or network.
3154
3379
  */
3155
3380
  /** Default public Valhalla server (FOSSGIS). CORS-enabled; usage limits apply. */
3156
- declare const DEFAULT_ROUTING_ENDPOINT = "https://valhalla1.openstreetmap.de";
3381
+ export declare const DEFAULT_ROUTING_ENDPOINT = "https://valhalla1.openstreetmap.de";
3157
3382
  /** Valhalla costing models exposed in the UI. */
3158
- type RoutingMode = "auto" | "pedestrian" | "bicycle";
3383
+ export type RoutingMode = "auto" | "pedestrian" | "bicycle";
3159
3384
  /** Isochrone contour metric: travel time (minutes) or distance (km). */
3160
- type RoutingMetric = "time" | "distance";
3161
- interface RoutingConfig {
3385
+ export type RoutingMetric = "time" | "distance";
3386
+ export interface RoutingConfig {
3162
3387
  /** Base URL of the Valhalla server (no trailing slash). */
3163
3388
  endpoint: string;
3164
3389
  }
3165
3390
  /** A point with a stable id, used as an isochrone origin or matrix source/target. */
3166
- interface RoutingPoint {
3391
+ export interface RoutingPoint {
3167
3392
  id: string | number;
3168
3393
  lon: number;
3169
3394
  lat: number;
@@ -3174,7 +3399,7 @@ interface RoutingPoint {
3174
3399
  *
3175
3400
  * @returns The resolved routing configuration.
3176
3401
  */
3177
- declare function getRoutingConfig(): RoutingConfig;
3402
+ export declare function getRoutingConfig(): RoutingConfig;
3178
3403
  /**
3179
3404
  * Parses a comma/space-separated contour string ("5, 10, 15") into a sorted,
3180
3405
  * de-duplicated list of positive numbers.
@@ -3182,8 +3407,8 @@ declare function getRoutingConfig(): RoutingConfig;
3182
3407
  * @param value - The raw contour string.
3183
3408
  * @returns Ascending unique positive contour values.
3184
3409
  */
3185
- declare function parseContours(value: string): number[];
3186
- interface IsochroneRequestBody {
3410
+ export declare function parseContours(value: string): number[];
3411
+ export interface IsochroneRequestBody {
3187
3412
  locations: {
3188
3413
  lon: number;
3189
3414
  lat: number;
@@ -3203,7 +3428,7 @@ interface IsochroneRequestBody {
3203
3428
  * @param opts - Travel mode, metric, and contour values (minutes for time, km for distance).
3204
3429
  * @returns The request body.
3205
3430
  */
3206
- declare function buildIsochroneRequest(point: [number, number], opts: {
3431
+ export declare function buildIsochroneRequest(point: [number, number], opts: {
3207
3432
  mode: RoutingMode;
3208
3433
  metric: RoutingMetric;
3209
3434
  contours: number[];
@@ -3223,12 +3448,12 @@ type IsochroneFeatureProps = {
3223
3448
  * @param ctx - Origin id, travel mode, and metric to tag onto each polygon.
3224
3449
  * @returns The tagged polygon features.
3225
3450
  */
3226
- declare function isochroneResponseToFeatures(response: unknown, ctx: {
3451
+ export declare function isochroneResponseToFeatures(response: unknown, ctx: {
3227
3452
  sourceId: string | number;
3228
3453
  mode: RoutingMode;
3229
3454
  metric: RoutingMetric;
3230
3455
  }): Feature<Polygon | MultiPolygon, IsochroneFeatureProps>[];
3231
- interface MatrixRequestBody {
3456
+ export interface MatrixRequestBody {
3232
3457
  sources: {
3233
3458
  lon: number;
3234
3459
  lat: number;
@@ -3247,7 +3472,7 @@ interface MatrixRequestBody {
3247
3472
  * @param mode - The travel mode.
3248
3473
  * @returns The request body.
3249
3474
  */
3250
- declare function buildMatrixRequest(origins: RoutingPoint[], targets: RoutingPoint[], mode: RoutingMode): MatrixRequestBody;
3475
+ export declare function buildMatrixRequest(origins: RoutingPoint[], targets: RoutingPoint[], mode: RoutingMode): MatrixRequestBody;
3251
3476
  type MatrixFeatureProps = {
3252
3477
  origin_id: string | number;
3253
3478
  dest_id: string | number;
@@ -3266,10 +3491,10 @@ type MatrixFeatureProps = {
3266
3491
  * @param ctx - The travel mode to tag onto each pair.
3267
3492
  * @returns The OD-pair LineString features.
3268
3493
  */
3269
- declare function matrixResponseToFeatures(response: unknown, origins: RoutingPoint[], targets: RoutingPoint[], ctx: {
3494
+ export declare function matrixResponseToFeatures(response: unknown, origins: RoutingPoint[], targets: RoutingPoint[], ctx: {
3270
3495
  mode: RoutingMode;
3271
3496
  }): Feature<LineString, MatrixFeatureProps>[];
3272
- interface RouteRequestBody {
3497
+ export interface RouteRequestBody {
3273
3498
  locations: {
3274
3499
  lon: number;
3275
3500
  lat: number;
@@ -3288,7 +3513,7 @@ interface RouteRequestBody {
3288
3513
  * @param mode - The travel mode (costing model).
3289
3514
  * @returns The request body.
3290
3515
  */
3291
- declare function buildRouteRequest(points: RoutingPoint[], mode: RoutingMode): RouteRequestBody;
3516
+ export declare function buildRouteRequest(points: RoutingPoint[], mode: RoutingMode): RouteRequestBody;
3292
3517
  type RouteFeatureProps = {
3293
3518
  leg_index: number;
3294
3519
  from_id: string | number;
@@ -3307,7 +3532,7 @@ type RouteFeatureProps = {
3307
3532
  * @param ctx - The travel mode to tag onto each leg.
3308
3533
  * @returns One LineString feature per routed leg.
3309
3534
  */
3310
- declare function routeResponseToFeatures(response: unknown, points: RoutingPoint[], ctx: {
3535
+ export declare function routeResponseToFeatures(response: unknown, points: RoutingPoint[], ctx: {
3311
3536
  mode: RoutingMode;
3312
3537
  }): Feature<LineString, RouteFeatureProps>[];
3313
3538
  /**
@@ -3327,13 +3552,13 @@ declare function routeResponseToFeatures(response: unknown, points: RoutingPoint
3327
3552
  * @param b - The second value.
3328
3553
  * @returns A negative, zero, or positive number for ascending order.
3329
3554
  */
3330
- declare function compareSequenceValues(a: unknown, b: unknown): number;
3555
+ export declare function compareSequenceValues(a: unknown, b: unknown): number;
3331
3556
  /**
3332
3557
  * Error thrown when a Valhalla request returns a non-2xx response. Carries the
3333
3558
  * HTTP status so callers can branch on it (e.g. a 4xx rejection) without
3334
3559
  * pattern-matching the message string.
3335
3560
  */
3336
- declare class RoutingRequestError extends Error {
3561
+ export declare class RoutingRequestError extends Error {
3337
3562
  readonly status: number;
3338
3563
  constructor(status: number, statusText: string);
3339
3564
  }
@@ -3345,7 +3570,7 @@ declare class RoutingRequestError extends Error {
3345
3570
  * @param signal - Optional abort signal.
3346
3571
  * @returns The Valhalla GeoJSON response.
3347
3572
  */
3348
- declare function requestIsochrone(endpoint: string, body: IsochroneRequestBody, signal?: AbortSignal): Promise<unknown>;
3573
+ export declare function requestIsochrone(endpoint: string, body: IsochroneRequestBody, signal?: AbortSignal): Promise<unknown>;
3349
3574
  /**
3350
3575
  * Requests an OD cost matrix from the Valhalla server.
3351
3576
  *
@@ -3354,7 +3579,7 @@ declare function requestIsochrone(endpoint: string, body: IsochroneRequestBody,
3354
3579
  * @param signal - Optional abort signal.
3355
3580
  * @returns The Valhalla matrix response.
3356
3581
  */
3357
- declare function requestMatrix(endpoint: string, body: MatrixRequestBody, signal?: AbortSignal): Promise<unknown>;
3582
+ export declare function requestMatrix(endpoint: string, body: MatrixRequestBody, signal?: AbortSignal): Promise<unknown>;
3358
3583
  /**
3359
3584
  * Requests a route through ordered waypoints from the Valhalla server.
3360
3585
  *
@@ -3363,7 +3588,7 @@ declare function requestMatrix(endpoint: string, body: MatrixRequestBody, signal
3363
3588
  * @param signal - Optional abort signal.
3364
3589
  * @returns The Valhalla `/route` response.
3365
3590
  */
3366
- declare function requestRoute(endpoint: string, body: RouteRequestBody, signal?: AbortSignal): Promise<unknown>;
3591
+ export declare function requestRoute(endpoint: string, body: RouteRequestBody, signal?: AbortSignal): Promise<unknown>;
3367
3592
  //#endregion
3368
3593
  //#region src/polyline.d.ts
3369
3594
  /**
@@ -3384,8 +3609,8 @@ declare function requestRoute(endpoint: string, body: RouteRequestBody, signal?:
3384
3609
  * @param str - Input string with potentially escaped backslashes.
3385
3610
  * @returns Cleaned polyline string.
3386
3611
  */
3387
- declare function unescapePolyline(str: string): string;
3388
- interface PolylineDecodeResult {
3612
+ export declare function unescapePolyline(str: string): string;
3613
+ export interface PolylineDecodeResult {
3389
3614
  coordinates: [number, number][];
3390
3615
  complete: boolean;
3391
3616
  }
@@ -3399,7 +3624,7 @@ interface PolylineDecodeResult {
3399
3624
  * @param unescape - Whether to unescape double-escaped backslashes before decoding (default: false).
3400
3625
  * @returns Object with decoded `coordinates` and `complete` boolean status.
3401
3626
  */
3402
- declare function decodePolylineDetailed(encoded: string, precision?: number, unescape?: boolean): PolylineDecodeResult;
3627
+ export declare function decodePolylineDetailed(encoded: string, precision?: number, unescape?: boolean): PolylineDecodeResult;
3403
3628
  /**
3404
3629
  * Decodes an encoded polyline string into an array of `[lon, lat]` coordinates.
3405
3630
  *
@@ -3408,7 +3633,7 @@ declare function decodePolylineDetailed(encoded: string, precision?: number, une
3408
3633
  * @param unescape - Whether to unescape double-escaped backslashes before decoding (default: false).
3409
3634
  * @returns Array of `[lon, lat]` coordinate pairs in GeoJSON order.
3410
3635
  */
3411
- declare function decodePolyline(encoded: string, precision?: number, unescape?: boolean): [number, number][];
3636
+ export declare function decodePolyline(encoded: string, precision?: number, unescape?: boolean): [number, number][];
3412
3637
  /**
3413
3638
  * Encodes an array of `[lon, lat]` coordinates into a Google Encoded Polyline string.
3414
3639
  *
@@ -3416,7 +3641,7 @@ declare function decodePolyline(encoded: string, precision?: number, unescape?:
3416
3641
  * @param precision - Number of decimal digits (default: 5).
3417
3642
  * @returns The encoded polyline string.
3418
3643
  */
3419
- declare function encodePolyline(coordinates: [number, number][], precision?: number): string;
3644
+ export declare function encodePolyline(coordinates: [number, number][], precision?: number): string;
3420
3645
  /**
3421
3646
  * Decodes an encoded polyline string into a GeoJSON `Feature<LineString>`.
3422
3647
  *
@@ -3425,7 +3650,7 @@ declare function encodePolyline(coordinates: [number, number][], precision?: num
3425
3650
  * @param properties - Optional feature properties.
3426
3651
  * @returns A GeoJSON LineString Feature.
3427
3652
  */
3428
- declare function polylineStrToGeoJSON(encoded: string, precision?: number, properties?: GeoJsonProperties): Feature<LineString>;
3653
+ export declare function polylineStrToGeoJSON(encoded: string, precision?: number, properties?: GeoJsonProperties): Feature<LineString>;
3429
3654
  /**
3430
3655
  * Encodes a GeoJSON LineString, MultiLineString, Feature, or FeatureCollection into encoded polyline string(s).
3431
3656
  *
@@ -3433,8 +3658,8 @@ declare function polylineStrToGeoJSON(encoded: string, precision?: number, prope
3433
3658
  * @param precision - Coordinate precision (default: 5).
3434
3659
  * @returns An encoded polyline string for LineString, or an array of strings for MultiLineString / FeatureCollection.
3435
3660
  */
3436
- declare function geoJSONToPolylineStr(geojson: LineString | MultiLineString | Feature<LineString | MultiLineString> | FeatureCollection<LineString | MultiLineString>, precision?: number): string | string[];
3437
- interface PolylineBatchOptions {
3661
+ export declare function geoJSONToPolylineStr(geojson: LineString | MultiLineString | Feature<LineString | MultiLineString> | FeatureCollection<LineString | MultiLineString>, precision?: number): string | string[];
3662
+ export interface PolylineBatchOptions {
3438
3663
  /** Coordinate precision (default: 5) */
3439
3664
  precision?: number;
3440
3665
  /** Whether to unescape `\\` backslashes (default: true) */
@@ -3453,7 +3678,7 @@ interface PolylineBatchOptions {
3453
3678
  * @param options - Decoding and parsing configuration.
3454
3679
  * @returns A FeatureCollection containing LineString (or MultiLineString) features.
3455
3680
  */
3456
- declare function batchDecodePolylines(input: string, options?: PolylineBatchOptions): FeatureCollection<LineString | MultiLineString>;
3681
+ export declare function batchDecodePolylines(input: string, options?: PolylineBatchOptions): FeatureCollection<LineString | MultiLineString>;
3457
3682
  //#endregion
3458
3683
  //#region src/vector-color.d.ts
3459
3684
  /**
@@ -3463,16 +3688,16 @@ declare function batchDecodePolylines(input: string, options?: PolylineBatchOpti
3463
3688
  * stays free of a maplibre-gl dependency; consumers cast to the concrete
3464
3689
  * `PropertyValueSpecification<string>` where the MapLibre types are in scope.
3465
3690
  */
3466
- type VectorColorValue = string | unknown[];
3691
+ export type VectorColorValue = string | unknown[];
3467
3692
  /** Whether a color value is a data-driven expression rather than a flat color. */
3468
- declare function isVectorColorExpression(value: VectorColorValue): value is unknown[];
3693
+ export declare function isVectorColorExpression(value: VectorColorValue): value is unknown[];
3469
3694
  /**
3470
3695
  * Whether a string is a 6-digit hex color (`#rrggbb`), the form the vector
3471
3696
  * renderer treats as valid. Exported so the symbology exporters can apply the
3472
3697
  * same validity check the live `match`/`case` expressions use rather than
3473
3698
  * re-deriving the regex.
3474
3699
  */
3475
- declare function isHexColor(value: unknown): boolean;
3700
+ export declare function isHexColor(value: unknown): boolean;
3476
3701
  declare const SIMPLE_STYLE_NUMBER_KEYS: readonly ["fill-opacity", "stroke-width", "stroke-opacity", "marker-opacity"];
3477
3702
  /**
3478
3703
  * Apply a per-feature transform to a value, descending into the outputs of a
@@ -3483,7 +3708,7 @@ declare const SIMPLE_STYLE_NUMBER_KEYS: readonly ["fill-opacity", "stroke-width"
3483
3708
  * must be pushed inside the step's outputs rather than wrapped around it.
3484
3709
  * Non-step values are transformed directly.
3485
3710
  */
3486
- declare function mapZoomStepOutputs(value: unknown, transform: (output: unknown) => unknown): unknown;
3711
+ export declare function mapZoomStepOutputs(value: unknown, transform: (output: unknown) => unknown): unknown;
3487
3712
  /**
3488
3713
  * Resolve a numeric paint value, letting a per-feature simplestyle property
3489
3714
  * override the layer value when {@link LayerStyle.simpleStyleEnabled} is set.
@@ -3502,7 +3727,7 @@ declare function mapZoomStepOutputs(value: unknown, transform: (output: unknown)
3502
3727
  * @param base - The layer-level fallback value.
3503
3728
  * @returns A `to-number` expression, or `base` when disabled.
3504
3729
  */
3505
- declare function simpleStyleNumberValue(style: LayerStyle, property: (typeof SIMPLE_STYLE_NUMBER_KEYS)[number], base: number): number | unknown[];
3730
+ export declare function simpleStyleNumberValue(style: LayerStyle, property: (typeof SIMPLE_STYLE_NUMBER_KEYS)[number], base: number): number | unknown[];
3506
3731
  /**
3507
3732
  * Ground resolution (meters per pixel) at MapLibre zoom 0 on the equator, for
3508
3733
  * the Web Mercator projection: earth circumference (2*pi*6378137) over the
@@ -3510,7 +3735,7 @@ declare function simpleStyleNumberValue(style: LayerStyle, property: (typeof SIM
3510
3735
  * the Mapbox-style importer can reverse {@link metersWidthExpression} without a
3511
3736
  * second copy of the magic number.
3512
3737
  */
3513
- declare const MERCATOR_METERS_PER_PIXEL_AT_ZOOM_0: number;
3738
+ export declare const MERCATOR_METERS_PER_PIXEL_AT_ZOOM_0: number;
3514
3739
  /**
3515
3740
  * Same ground resolution as {@link MERCATOR_METERS_PER_PIXEL_AT_ZOOM_0} but for
3516
3741
  * the project's active body: its circumference over the 512px zoom-0 world. On
@@ -3520,7 +3745,7 @@ declare const MERCATOR_METERS_PER_PIXEL_AT_ZOOM_0: number;
3520
3745
  * with the same ellipsoid-aware factor the exporter used (keeping the round trip
3521
3746
  * correct on non-Earth projects), rather than the Earth-only constant.
3522
3747
  */
3523
- declare function mercatorMetersPerPixelAtZoom0(): number;
3748
+ export declare function mercatorMetersPerPixelAtZoom0(): number;
3524
3749
  /**
3525
3750
  * Build a zoom-driven width expression that keeps a stroke proportional to the
3526
3751
  * map scale, so a width given in ground meters renders thicker when zoomed in
@@ -3539,7 +3764,7 @@ declare function mercatorMetersPerPixelAtZoom0(): number;
3539
3764
  * @param meters - The stroke width in ground meters.
3540
3765
  * @returns A MapLibre `interpolate` expression array.
3541
3766
  */
3542
- declare function metersWidthExpression(meters: number): unknown[];
3767
+ export declare function metersWidthExpression(meters: number): unknown[];
3543
3768
  /**
3544
3769
  * Resolve the `line-width` paint value for a layer style, honoring the
3545
3770
  * {@link LayerStyle.strokeWidthUnit}:
@@ -3557,7 +3782,7 @@ declare function metersWidthExpression(meters: number): unknown[];
3557
3782
  * @param style - The layer style.
3558
3783
  * @returns A number (constant pixels) or a MapLibre expression array.
3559
3784
  */
3560
- declare function lineWidthValue(style: LayerStyle): number | unknown[];
3785
+ export declare function lineWidthValue(style: LayerStyle): number | unknown[];
3561
3786
  /**
3562
3787
  * Whether a FeatureCollection carries per-feature simplestyle-spec properties
3563
3788
  * worth honoring: at least one feature with a valid hex color in a color key
@@ -3568,7 +3793,7 @@ declare function lineWidthValue(style: LayerStyle): number | unknown[];
3568
3793
  * @param geojson - The collection to inspect (may be undefined).
3569
3794
  * @returns `true` when simplestyle rendering should be enabled for the layer.
3570
3795
  */
3571
- declare function hasSimpleStyleProperties(geojson: {
3796
+ export declare function hasSimpleStyleProperties(geojson: {
3572
3797
  features?: {
3573
3798
  properties?: Record<string, unknown> | null;
3574
3799
  }[];
@@ -3578,7 +3803,7 @@ declare function hasSimpleStyleProperties(geojson: {
3578
3803
  * tolerating trailing commas. Returns null when the text is empty or not a
3579
3804
  * JSON array.
3580
3805
  */
3581
- declare function parseJsonExpression(expression: string): unknown[] | null;
3806
+ export declare function parseJsonExpression(expression: string): unknown[] | null;
3582
3807
  /**
3583
3808
  * Builds the data-driven color value for a vector layer's current style mode.
3584
3809
  * `single` (or any mode that cannot produce a valid expression) returns the
@@ -3597,7 +3822,7 @@ declare function parseJsonExpression(expression: string): unknown[] | null;
3597
3822
  * expression fallback.
3598
3823
  * @returns A flat color string or a MapLibre color expression.
3599
3824
  */
3600
- declare function vectorColorExpression(style: LayerStyle, fallbackColor: string): VectorColorValue;
3825
+ export declare function vectorColorExpression(style: LayerStyle, fallbackColor: string): VectorColorValue;
3601
3826
  /**
3602
3827
  * A rule-based renderer rule resolved for rendering: the rule tree walked down
3603
3828
  * to a drawable leaf, with the ancestors' filters ANDed in and zoom ranges
@@ -3607,7 +3832,7 @@ declare function vectorColorExpression(style: LayerStyle, fallbackColor: string)
3607
3832
  * emitted. Shared by the paint compilers, the legend, and the symbology
3608
3833
  * exporters so all of them agree on which rules actually draw.
3609
3834
  */
3610
- interface EffectiveVectorRule {
3835
+ export interface EffectiveVectorRule {
3611
3836
  id: string;
3612
3837
  /** The leaf rule's label (for the legend / exported rule titles). */
3613
3838
  label: string;
@@ -3635,7 +3860,7 @@ interface EffectiveVectorRule {
3635
3860
  * @param style - The layer style (reads {@link LayerStyle.vectorRules}).
3636
3861
  * @returns The ordered drawable rules and the enabled else rule, if any.
3637
3862
  */
3638
- declare function effectiveVectorRules(style: LayerStyle): {
3863
+ export declare function effectiveVectorRules(style: LayerStyle): {
3639
3864
  rules: EffectiveVectorRule[];
3640
3865
  elseRule: VectorRule | null;
3641
3866
  };
@@ -3657,7 +3882,7 @@ declare function effectiveVectorRules(style: LayerStyle): {
3657
3882
  * @param style - The layer style (reads {@link LayerStyle.vectorRules}).
3658
3883
  * @returns The filter to `["all", …]`-combine into each sub-layer, or `null`.
3659
3884
  */
3660
- declare function ruleBasedVisibilityFilter(style: LayerStyle): unknown[] | null;
3885
+ export declare function ruleBasedVisibilityFilter(style: LayerStyle): unknown[] | null;
3661
3886
  /**
3662
3887
  * Compiles the `"rule-based"` renderer's ordered rules into a MapLibre `case`
3663
3888
  * color expression: `["case", filter1, color1, filter2, color2, …, elseColor]`.
@@ -3674,27 +3899,40 @@ declare function ruleBasedVisibilityFilter(style: LayerStyle): unknown[] | null;
3674
3899
  * @param fallbackColor - The color used when no else rule defines one.
3675
3900
  * @returns A MapLibre expression, or a flat color when no rule applies.
3676
3901
  */
3677
- declare function ruleBasedColorExpression(style: LayerStyle, fallbackColor: string): VectorColorValue;
3902
+ export declare function ruleBasedColorExpression(style: LayerStyle, fallbackColor: string): VectorColorValue;
3678
3903
  /**
3679
3904
  * The stroke/outline color for polygon outlines and circle strokes, honoring
3680
3905
  * per-rule {@link VectorRule.strokeColor} overrides in rule-based mode.
3681
3906
  * Falls back to the flat layer stroke color.
3682
3907
  */
3683
- declare function vectorOutlineColorValue(style: LayerStyle): VectorColorValue;
3908
+ export declare function vectorOutlineColorValue(style: LayerStyle): VectorColorValue;
3684
3909
  /**
3685
3910
  * A stroke-width paint value honoring per-rule {@link VectorRule.strokeWidth}
3686
3911
  * overrides in rule-based mode; `fallback` is the layer-level width (a number
3687
3912
  * or an already-built expression such as the meters-based interpolation).
3688
3913
  */
3689
- declare function vectorStrokeWidthValue(style: LayerStyle, fallback: number | unknown[]): number | unknown[];
3914
+ export declare function vectorStrokeWidthValue(style: LayerStyle, fallback: number | unknown[]): number | unknown[];
3690
3915
  /**
3691
3916
  * A fill/circle opacity paint value honoring per-rule
3692
3917
  * {@link VectorRule.fillOpacity} overrides in rule-based mode; `fallback` is
3693
3918
  * the layer-level opacity value (number or expression).
3694
3919
  */
3695
- declare function vectorFillOpacityValue(style: LayerStyle, fallback: number | unknown[]): number | unknown[];
3920
+ export declare function vectorFillOpacityValue(style: LayerStyle, fallback: number | unknown[]): number | unknown[];
3921
+ /**
3922
+ * The color-ramp colors a density heatmap paints with.
3923
+ *
3924
+ * {@link getVectorColorRamp} falls back to the *first* ramp ("viridis") for an
3925
+ * unknown name, which is not the heatmap default ("turbo"). Both the map paint
3926
+ * (`heatmapPaint` in `@geolibre/map`) and the auto-legend gradient resolve the
3927
+ * ramp here so a stale or hand-edited `heatmapColorRamp` cannot make the legend
3928
+ * and the rendered heatmap disagree about which ramp is in use.
3929
+ *
3930
+ * @param style - The layer style.
3931
+ * @returns The ramp's colors, or the default ramp's colors for an unknown name.
3932
+ */
3933
+ export declare function heatmapRampColors(style: LayerStyle): readonly string[];
3696
3934
  /** The validated proportional (graduated) size configuration of a layer. */
3697
- interface ProportionalSizeRange {
3935
+ export interface ProportionalSizeRange {
3698
3936
  property: string;
3699
3937
  minValue: number;
3700
3938
  maxValue: number;
@@ -3712,7 +3950,7 @@ interface ProportionalSizeRange {
3712
3950
  * @param style - The layer style.
3713
3951
  * @returns The validated range, or `null` when proportional sizing is off.
3714
3952
  */
3715
- declare function proportionalSizeRange(style: LayerStyle): ProportionalSizeRange | null;
3953
+ export declare function proportionalSizeRange(style: LayerStyle): ProportionalSizeRange | null;
3716
3954
  /**
3717
3955
  * The proportional `interpolate` expression mapping
3718
3956
  * `proportionalSizeMinValue..proportionalSizeMaxValue` onto
@@ -3722,7 +3960,7 @@ declare function proportionalSizeRange(style: LayerStyle): ProportionalSizeRange
3722
3960
  * @param style - The layer style.
3723
3961
  * @returns The `interpolate` expression, or `null`.
3724
3962
  */
3725
- declare function proportionalRadiusExpression(style: LayerStyle): unknown[] | null;
3963
+ export declare function proportionalRadiusExpression(style: LayerStyle): unknown[] | null;
3726
3964
  /**
3727
3965
  * The geometry generator's centroid-size configuration, or `null` when the
3728
3966
  * generated points should all take the flat
@@ -3733,7 +3971,7 @@ declare function proportionalRadiusExpression(style: LayerStyle): unknown[] | nu
3733
3971
  * @param style - The layer style.
3734
3972
  * @returns The validated range, or `null` when field-driven sizing is off.
3735
3973
  */
3736
- declare function generatorSizeRange(style: LayerStyle): ProportionalSizeRange | null;
3974
+ export declare function generatorSizeRange(style: LayerStyle): ProportionalSizeRange | null;
3737
3975
  /**
3738
3976
  * Builds the `circle-radius` paint value for the geometry generator's derived
3739
3977
  * centroid points: an `interpolate` over
@@ -3748,7 +3986,7 @@ declare function generatorSizeRange(style: LayerStyle): ProportionalSizeRange |
3748
3986
  * @param style - The layer style.
3749
3987
  * @returns A constant radius (pixels) or a MapLibre `interpolate` expression.
3750
3988
  */
3751
- declare function generatorCircleRadiusValue(style: LayerStyle): number | unknown[];
3989
+ export declare function generatorCircleRadiusValue(style: LayerStyle): number | unknown[];
3752
3990
  /**
3753
3991
  * Builds the `circle-radius` paint value, honoring proportional (graduated)
3754
3992
  * symbol sizing. When {@link LayerStyle.proportionalSizeEnabled} is set with a
@@ -3760,9 +3998,9 @@ declare function generatorCircleRadiusValue(style: LayerStyle): number | unknown
3760
3998
  * @param style - The layer style.
3761
3999
  * @returns A constant radius (pixels) or a MapLibre `interpolate` expression.
3762
4000
  */
3763
- declare function circleRadiusValue(style: LayerStyle): number | unknown[];
4001
+ export declare function circleRadiusValue(style: LayerStyle): number | unknown[];
3764
4002
  /** Fill color value for a polygon layer (fallback: the layer fill color). */
3765
- declare function vectorFillColorValue(style: LayerStyle): VectorColorValue;
4003
+ export declare function vectorFillColorValue(style: LayerStyle): VectorColorValue;
3766
4004
  /**
3767
4005
  * Circle color value for a point layer. Intentionally identical to
3768
4006
  * `vectorFillColorValue`: GeoLibre has no separate point-fill color, so point
@@ -3770,7 +4008,7 @@ declare function vectorFillColorValue(style: LayerStyle): VectorColorValue;
3770
4008
  * package). Kept as its own function so the per-geometry callers read in
3771
4009
  * parallel and a future dedicated circle color stays a one-line change here.
3772
4010
  */
3773
- declare function vectorCircleColorValue(style: LayerStyle): VectorColorValue;
4011
+ export declare function vectorCircleColorValue(style: LayerStyle): VectorColorValue;
3774
4012
  /**
3775
4013
  * Line color value for line geometry and polygon outlines (fallback: the
3776
4014
  * layer stroke color). For non-`expression` modes the data-driven color is
@@ -3778,7 +4016,7 @@ declare function vectorCircleColorValue(style: LayerStyle): VectorColorValue;
3778
4016
  * color, matching the polygon-fill-only behavior of categorized/graduated
3779
4017
  * styling.
3780
4018
  */
3781
- declare function vectorLineColorValue(style: LayerStyle): VectorColorValue;
4019
+ export declare function vectorLineColorValue(style: LayerStyle): VectorColorValue;
3782
4020
  /**
3783
4021
  * Resolves the 3D-extrusion height for a layer style into a MapLibre value: a
3784
4022
  * plain meters number, or a data-driven expression. In advanced mode a valid
@@ -3791,7 +4029,7 @@ declare function vectorLineColorValue(style: LayerStyle): VectorColorValue;
3791
4029
  * @param style - The layer style.
3792
4030
  * @returns The extrusion height as a number or a MapLibre expression array.
3793
4031
  */
3794
- declare function extrusionHeightValue(style: LayerStyle): number | unknown[];
4032
+ export declare function extrusionHeightValue(style: LayerStyle): number | unknown[];
3795
4033
  /**
3796
4034
  * Resolves the 3D-extrusion color for a layer style: a data-driven expression
3797
4035
  * when the layer's symbology mode produces one (categorized/graduated/rule/
@@ -3802,7 +4040,7 @@ declare function extrusionHeightValue(style: LayerStyle): number | unknown[];
3802
4040
  * @param style - The layer style.
3803
4041
  * @returns A flat color string or a MapLibre color expression array.
3804
4042
  */
3805
- declare function extrusionColorValue(style: LayerStyle): VectorColorValue;
4043
+ export declare function extrusionColorValue(style: LayerStyle): VectorColorValue;
3806
4044
  //#endregion
3807
4045
  //#region src/expressions.d.ts
3808
4046
  /**
@@ -3815,7 +4053,7 @@ declare function extrusionColorValue(style: LayerStyle): VectorColorValue;
3815
4053
  * later the field calculator and atlas) share one implementation.
3816
4054
  */
3817
4055
  /** One documented function/operator the builder can insert. */
3818
- interface ExpressionFunctionDoc {
4056
+ export interface ExpressionFunctionDoc {
3819
4057
  /** The MapLibre operator name, e.g. `get` or `==`. */
3820
4058
  name: string;
3821
4059
  /** The snippet inserted into the expression text (valid JSON). */
@@ -3828,7 +4066,7 @@ interface ExpressionFunctionDoc {
3828
4066
  docKey: string;
3829
4067
  }
3830
4068
  /** A group of related functions shown as one section of the reference tree. */
3831
- interface ExpressionFunctionCategory {
4069
+ export interface ExpressionFunctionCategory {
3832
4070
  /** Stable key, also the i18n suffix under `style.expressionBuilder.categories`. */
3833
4071
  key: string;
3834
4072
  functions: ExpressionFunctionDoc[];
@@ -3838,17 +4076,17 @@ interface ExpressionFunctionCategory {
3838
4076
  * standalone-compilable MapLibre expressions (enforced by tests) so inserting
3839
4077
  * one into an empty editor always yields a working starting point.
3840
4078
  */
3841
- declare const EXPRESSION_FUNCTION_CATEGORIES: ExpressionFunctionCategory[];
4079
+ export declare const EXPRESSION_FUNCTION_CATEGORIES: ExpressionFunctionCategory[];
3842
4080
  /**
3843
4081
  * Strips commas that directly precede a closing bracket/brace outside of
3844
4082
  * strings, so user-typed expressions with trailing commas still parse.
3845
4083
  * Shared by {@link parseJsonExpression} (vector-color) and the builder.
3846
4084
  */
3847
- declare function removeTrailingJsonCommas(value: string): string;
4085
+ export declare function removeTrailingJsonCommas(value: string): string;
3848
4086
  /** Result types the builder can require of a whole expression. */
3849
- type ExpressionExpectedType = "boolean" | "color" | "string" | "number";
4087
+ export type ExpressionExpectedType = "boolean" | "color" | "string" | "number";
3850
4088
  /** Options for {@link validateMapExpression}. */
3851
- interface ValidateMapExpressionOptions {
4089
+ export interface ValidateMapExpressionOptions {
3852
4090
  /**
3853
4091
  * Variables substituted before compiling, so a numeric `@token` used in a
3854
4092
  * numeric slot type-checks against its value instead of the raw string.
@@ -3862,7 +4100,7 @@ interface ValidateMapExpressionOptions {
3862
4100
  expectedType?: ExpressionExpectedType;
3863
4101
  }
3864
4102
  /** Outcome of validating an expression source string. */
3865
- interface ExpressionValidation {
4103
+ export interface ExpressionValidation {
3866
4104
  ok: boolean;
3867
4105
  /**
3868
4106
  * Failure class, for callers that want to localize the shape errors:
@@ -3885,9 +4123,9 @@ interface ExpressionValidation {
3885
4123
  * returned `parsed` array is the raw, unsubstituted parse. An empty/blank
3886
4124
  * source is valid (surfaces treat it as "no expression").
3887
4125
  */
3888
- declare function validateMapExpression(source: string, options?: ValidateMapExpressionOptions): ExpressionValidation;
4126
+ export declare function validateMapExpression(source: string, options?: ValidateMapExpressionOptions): ExpressionValidation;
3889
4127
  /** A named `@` variable with its current value. */
3890
- interface ExpressionVariable {
4128
+ export interface ExpressionVariable {
3891
4129
  /** Token including the `@` prefix, e.g. `@project_name`. */
3892
4130
  token: string;
3893
4131
  value: string | number | boolean;
@@ -3898,9 +4136,9 @@ interface ExpressionVariable {
3898
4136
  * Unknown `@` strings are left untouched so field values that happen to start
3899
4137
  * with `@` never get mangled.
3900
4138
  */
3901
- declare function substituteExpressionVariables(node: unknown, variables: ExpressionVariable[]): unknown;
4139
+ export declare function substituteExpressionVariables(node: unknown, variables: ExpressionVariable[]): unknown;
3902
4140
  /** Result of a live preview evaluation. */
3903
- interface ExpressionPreview {
4141
+ export interface ExpressionPreview {
3904
4142
  kind: "empty" | "error" | "value";
3905
4143
  /** Problems when `kind` is "error" (parse or runtime). */
3906
4144
  errors?: string[];
@@ -3908,7 +4146,7 @@ interface ExpressionPreview {
3908
4146
  value?: unknown;
3909
4147
  }
3910
4148
  /** Options for {@link evaluateMapExpression}. */
3911
- interface EvaluateMapExpressionOptions {
4149
+ export interface EvaluateMapExpressionOptions {
3912
4150
  /** The sample feature the expression is evaluated against. */
3913
4151
  feature?: Feature | null;
3914
4152
  /** Map zoom used for `["zoom"]`; defaults to 0. */
@@ -3925,7 +4163,7 @@ interface EvaluateMapExpressionOptions {
3925
4163
  * Runtime failures (e.g. `to-color` on garbage) come back as errors instead
3926
4164
  * of throwing.
3927
4165
  */
3928
- declare function evaluateMapExpression(source: string, options?: EvaluateMapExpressionOptions): ExpressionPreview;
4166
+ export declare function evaluateMapExpression(source: string, options?: EvaluateMapExpressionOptions): ExpressionPreview;
3929
4167
  /**
3930
4168
  * A compiled per-feature evaluator: the expression is parsed and compiled
3931
4169
  * once, then `evaluate` runs it against each feature. `evaluate` is absent
@@ -3933,11 +4171,16 @@ declare function evaluateMapExpression(source: string, options?: EvaluateMapExpr
3933
4171
  * failures (same rationale as {@link evaluateMapExpression}: throwing keeps
3934
4172
  * errors out of console.warn) so callers decide per-feature error handling.
3935
4173
  */
3936
- interface CompiledFeatureExpression {
4174
+ export interface CompiledFeatureExpression {
3937
4175
  ok: boolean;
3938
4176
  /** Parse/compile problems when `ok` is false. */
3939
4177
  errors: string[];
3940
- evaluate?: (feature: Feature) => unknown;
4178
+ /**
4179
+ * Runs the expression against one feature. `zoom` overrides the zoom the
4180
+ * expression was compiled with, for callers that re-evaluate a
4181
+ * zoom-dependent expression as the camera moves.
4182
+ */
4183
+ evaluate?: (feature: Feature, zoom?: number) => unknown;
3941
4184
  }
3942
4185
  /**
3943
4186
  * Compiles an expression source once for bulk per-feature evaluation (virtual
@@ -3946,13 +4189,13 @@ interface CompiledFeatureExpression {
3946
4189
  * feature. An empty source is reported as a failure with no errors — there is
3947
4190
  * nothing to evaluate.
3948
4191
  */
3949
- declare function compileFeatureExpression(source: string, options?: {
4192
+ export declare function compileFeatureExpression(source: string, options?: {
3950
4193
  zoom?: number;
3951
4194
  variables?: ExpressionVariable[];
3952
4195
  expectedType?: ExpressionExpectedType;
3953
4196
  }): CompiledFeatureExpression;
3954
4197
  /** Result of matching a feature array against a boolean expression. */
3955
- interface FeatureExpressionMatches {
4198
+ export interface FeatureExpressionMatches {
3956
4199
  /** False when the expression failed to parse or compile. */
3957
4200
  ok: boolean;
3958
4201
  /** Parse/compile problems when `ok` is false. */
@@ -3974,7 +4217,7 @@ interface FeatureExpressionMatches {
3974
4217
  * layers. An empty source is reported as `ok: false` with no errors — there
3975
4218
  * is nothing to select by.
3976
4219
  */
3977
- declare function matchFeaturesByExpression(features: readonly Feature[], source: string, options?: {
4220
+ export declare function matchFeaturesByExpression(features: readonly Feature[], source: string, options?: {
3978
4221
  zoom?: number;
3979
4222
  variables?: ExpressionVariable[];
3980
4223
  }): FeatureExpressionMatches;
@@ -3986,7 +4229,7 @@ declare function matchFeaturesByExpression(features: readonly Feature[], source:
3986
4229
  * attribute data that happens to carry numeric r/g/b/a fields (e.g. via
3987
4230
  * `["properties"]`) is never misclassified as a color.
3988
4231
  */
3989
- declare function isStyleSpecColor(value: unknown): value is {
4232
+ export declare function isStyleSpecColor(value: unknown): value is {
3990
4233
  r: number;
3991
4234
  g: number;
3992
4235
  b: number;
@@ -3997,18 +4240,109 @@ declare function isStyleSpecColor(value: unknown): value is {
3997
4240
  * instances become rgba() strings, plain values render as JSON, and
3998
4241
  * `null`/`undefined` render as "null".
3999
4242
  */
4000
- declare function formatExpressionPreviewValue(value: unknown): string;
4243
+ export declare function formatExpressionPreviewValue(value: unknown): string;
4001
4244
  /** Attribute field types the builder badges fields with. */
4002
- type ExpressionFieldType = "string" | "number" | "boolean" | "mixed" | "unknown";
4245
+ export type ExpressionFieldType = "string" | "number" | "boolean" | "mixed" | "unknown";
4003
4246
  /**
4004
4247
  * Infers a display type for each named field by scanning feature properties:
4005
4248
  * a single consistent primitive type wins, disagreements become "mixed", and
4006
4249
  * fields with no non-null values are "unknown".
4007
4250
  */
4008
- declare function inferFieldTypes(features: ReadonlyArray<{
4251
+ export declare function inferFieldTypes(features: ReadonlyArray<{
4009
4252
  properties?: Record<string, unknown> | null;
4010
4253
  }>, names: string[]): Record<string, ExpressionFieldType>;
4011
4254
  //#endregion
4255
+ //#region src/document-locale.d.ts
4256
+ /**
4257
+ * The document language, so formatted numbers and dates follow the UI locale.
4258
+ *
4259
+ * Shared by the Identify popup's value formatting and by label number
4260
+ * formatting, which both fall back to it when the author has not pinned an
4261
+ * explicit locale. Returns `undefined` outside a browser (tests, the headless
4262
+ * project authoring paths), which leaves `Intl` on its own default.
4263
+ */
4264
+ export declare function documentLocale(): string | undefined;
4265
+ //#endregion
4266
+ //#region src/label-number-format.d.ts
4267
+ /**
4268
+ * Locale-aware number formatting for map labels (issue #2336).
4269
+ *
4270
+ * A numeric attribute rendered straight into a label reads as `1234567.5`,
4271
+ * which is hard to compare at a glance. QGIS solves this with
4272
+ * `format_number(field, places, language)`; the equivalent here is three
4273
+ * {@link LabelStyle} fields — {@link LabelStyle.numberFormatEnabled},
4274
+ * {@link LabelStyle.numberDecimals} and {@link LabelStyle.numberLocale} —
4275
+ * whose effect this module renders two ways:
4276
+ *
4277
+ * - {@link labelFieldTextField} builds the MapLibre `text-field` expression the
4278
+ * 2D map and the Mapbox/MapLibre style export both use, so the map and the
4279
+ * exported style agree.
4280
+ * - {@link formatLabelNumber} does the same in JavaScript for the paths that
4281
+ * resolve label text themselves: the Cesium globe and the duplicate-label
4282
+ * collapsing modes.
4283
+ *
4284
+ * Formatting applies to {@link LabelStyle.field} only. A label
4285
+ * {@link LabelStyle.expression} formats its own output (with `number-format`,
4286
+ * offered in the Expression Builder), so wrapping it here would fight the
4287
+ * author.
4288
+ */
4289
+ /**
4290
+ * Locales offered for {@link LabelStyle.numberLocale}, alongside the default
4291
+ * empty value that follows the app's own language.
4292
+ *
4293
+ * Deliberately short, and every entry groups with a character the map's glyph
4294
+ * stack can draw: ASCII `,`/`.` or U+00A0. Locales whose CLDR grouping uses
4295
+ * the narrow no-break space U+202F (`fr-FR`) or non-Latin digits (`ar-EG`)
4296
+ * are left out because a missing glyph renders as a blank box on the map
4297
+ * rather than as a separator. An author who needs one of those can still
4298
+ * write `["number-format", …]` in the label expression.
4299
+ */
4300
+ export declare const LABEL_NUMBER_LOCALES: readonly ["en-US", "de-DE", "ru-RU", "hi-IN"];
4301
+ /** Sample value used to preview a locale's separators in the Style panel. */
4302
+ export declare const LABEL_NUMBER_SAMPLE = 1234567.5;
4303
+ /** Clamp a decimal-places setting to the range the UI and `Intl` both accept. */
4304
+ export declare function clampLabelDecimals(decimals: number): number;
4305
+ /**
4306
+ * The first locale tag that both `Intl` accepts and the map can draw, or
4307
+ * `undefined` to leave `Intl` and MapLibre on the runtime default.
4308
+ *
4309
+ * Every path resolves its locale through here -- the JavaScript formatter, the
4310
+ * MapLibre expression, and the dedup cache key -- so all three agree on which
4311
+ * locale is actually in effect.
4312
+ */
4313
+ export declare function resolveLabelNumberLocale(...tags: (string | undefined)[]): string | undefined;
4314
+ /**
4315
+ * Format one label value as a number, or `null` when the setting is off or the
4316
+ * value is not a finite number (a text attribute keeps its own rendering).
4317
+ *
4318
+ * @param value - The raw attribute value.
4319
+ * @param labels - The layer's label configuration.
4320
+ * @param fallbackLocale - Locale used when {@link LabelStyle.numberLocale} is
4321
+ * empty; the caller passes the app's language. Omitted means the runtime
4322
+ * default, matching how popups format their numbers.
4323
+ */
4324
+ export declare function formatLabelNumber(value: unknown, labels: Pick<LabelStyle, "numberFormatEnabled" | "numberDecimals" | "numberLocale">, fallbackLocale?: string): string | null;
4325
+ /**
4326
+ * The MapLibre expression that renders {@link LabelStyle.field} as text, with
4327
+ * number formatting applied when it is on. Returns `""` when no field is set,
4328
+ * which callers treat as "no label text".
4329
+ *
4330
+ * Number formatting is guarded by a `typeof` test rather than applied blindly
4331
+ * so a mixed or text column still labels normally; only real numbers take the
4332
+ * `number-format` branch.
4333
+ */
4334
+ export declare function labelFieldTextField(labels: Pick<LabelStyle, "field" | "numberFormatEnabled" | "numberDecimals" | "numberLocale">, fallbackLocale?: string): unknown[] | "";
4335
+ /**
4336
+ * Render {@link LABEL_NUMBER_SAMPLE} the way a locale/decimals pair would, so
4337
+ * the Style panel can name each choice by the separators it actually produces
4338
+ * ("1,234,567.50") instead of by an opaque language tag.
4339
+ *
4340
+ * A tag `Intl` rejects (or one the map cannot draw) falls back to the runtime
4341
+ * locale's formatting rather than to an unformatted number, matching what
4342
+ * {@link formatLabelNumber} and the emitted expression do with the same tag.
4343
+ */
4344
+ export declare function formatLabelNumberSample(locale: string, decimals: number): string;
4345
+ //#endregion
4012
4346
  //#region src/external-native-paint.d.ts
4013
4347
  /**
4014
4348
  * Paint ownership for plugin-registered native layers.
@@ -4032,7 +4366,7 @@ declare function inferFieldTypes(features: ReadonlyArray<{
4032
4366
  * instead, keyed by layer id, and the layer record only carries the
4033
4367
  * serializable `paintMode` flag.
4034
4368
  */
4035
- interface ExternalNativePaintBridge {
4369
+ export interface ExternalNativePaintBridge {
4036
4370
  /**
4037
4371
  * Apply an opacity in [0, 1] to the plugin's layer (e.g.
4038
4372
  * `zarrLayer.setOpacity(value)`). When supplied, GeoLibre keeps its Opacity
@@ -4047,7 +4381,7 @@ interface ExternalNativePaintBridge {
4047
4381
  setVisibility?: (visible: boolean) => void;
4048
4382
  }
4049
4383
  /** Serializable paint-ownership marker stored in `GeoLibreLayer.metadata`. */
4050
- type ExternalNativePaintMode = "geolibre" | "plugin";
4384
+ export type ExternalNativePaintMode = "geolibre" | "plugin";
4051
4385
  /**
4052
4386
  * Whether a layer is drawn by a **custom render layer** its control created — a
4053
4387
  * deck.gl overlay, 3D Tiles, or Add Vector Layer's own MapLibre layers — rather
@@ -4066,33 +4400,33 @@ type ExternalNativePaintMode = "geolibre" | "plugin";
4066
4400
  * @param layer - A store layer (metadata only).
4067
4401
  * @returns True when only the owning control can create the layer's map output.
4068
4402
  */
4069
- declare function controlRendersLayer(layer: {
4403
+ export declare function controlRendersLayer(layer: {
4070
4404
  metadata: Record<string, unknown>;
4071
4405
  }): boolean;
4072
4406
  /**
4073
4407
  * True when the plugin that registered this layer paints it itself, so GeoLibre
4074
4408
  * must not offer (or apply) MapLibre paint properties for it.
4075
4409
  */
4076
- declare function pluginOwnsPaint(layer: {
4410
+ export declare function pluginOwnsPaint(layer: {
4077
4411
  metadata: Record<string, unknown>;
4078
4412
  }): boolean;
4079
4413
  /** Register (or replace) the paint bridge a plugin supplied for a layer. */
4080
- declare function setExternalNativePaintBridge(layerId: string, bridge: ExternalNativePaintBridge | undefined): void;
4414
+ export declare function setExternalNativePaintBridge(layerId: string, bridge: ExternalNativePaintBridge | undefined): void;
4081
4415
  /** Drop a layer's paint bridge (on unregister, or when the layer is removed). */
4082
- declare function clearExternalNativePaintBridge(layerId: string): void;
4416
+ export declare function clearExternalNativePaintBridge(layerId: string): void;
4083
4417
  /** The paint bridge for a layer, if its plugin supplied one. */
4084
- declare function getExternalNativePaintBridge(layerId: string): ExternalNativePaintBridge | undefined;
4418
+ export declare function getExternalNativePaintBridge(layerId: string): ExternalNativePaintBridge | undefined;
4085
4419
  /**
4086
4420
  * True when a plugin-painted layer bridged `setOpacity`, so an Opacity slider
4087
4421
  * would actually reach the renderer. It says nothing about GeoLibre-painted
4088
4422
  * layers, which have no bridge: the Style and Layers panels combine it with
4089
4423
  * `!pluginOwnsPaint(layer)` to decide whether to show the slider at all.
4090
4424
  */
4091
- declare function supportsBridgedOpacity(layerId: string): boolean;
4425
+ export declare function supportsBridgedOpacity(layerId: string): boolean;
4092
4426
  //#endregion
4093
4427
  //#region src/attribute-form.d.ts
4094
4428
  /** Options threaded to expression evaluation (constraints, visibility). */
4095
- interface AttributeFormEvalOptions {
4429
+ export interface AttributeFormEvalOptions {
4096
4430
  /** Map zoom for `["zoom"]` in expressions; defaults to 0. */
4097
4431
  zoom?: number;
4098
4432
  /**
@@ -4104,7 +4438,7 @@ interface AttributeFormEvalOptions {
4104
4438
  feature?: Feature;
4105
4439
  }
4106
4440
  /** Why a field's value was rejected; codes map to localized messages. */
4107
- interface AttributeFormFieldError {
4441
+ export interface AttributeFormFieldError {
4108
4442
  code: "required" | "number" | "range" | "valueMap" | "constraint";
4109
4443
  /**
4110
4444
  * For `constraint`: the author's `constraintDescription`, or the
@@ -4116,37 +4450,37 @@ interface AttributeFormFieldError {
4116
4450
  max?: number;
4117
4451
  }
4118
4452
  /** Outcome of validating a whole properties record against a form config. */
4119
- interface AttributeFormValidation {
4453
+ export interface AttributeFormValidation {
4120
4454
  ok: boolean;
4121
4455
  /** Field name → error for every failing, visible, configured field. */
4122
4456
  errors: Record<string, AttributeFormFieldError>;
4123
4457
  }
4124
4458
  /** Look up the configuration for a field, if any. */
4125
- declare function getAttributeFormField(form: AttributeFormConfig | undefined, field: string): AttributeFormFieldConfig | undefined;
4459
+ export declare function getAttributeFormField(form: AttributeFormConfig | undefined, field: string): AttributeFormFieldConfig | undefined;
4126
4460
  /** The label attribute forms should show for a configured field. */
4127
- declare function attributeFormFieldLabel(config: AttributeFormFieldConfig): string;
4461
+ export declare function attributeFormFieldLabel(config: AttributeFormFieldConfig): string;
4128
4462
  /**
4129
4463
  * Parse the designer's value-map text — one entry per line, `value=label` or
4130
4464
  * just `value` — into entries. Blank lines and duplicate values are dropped.
4131
4465
  */
4132
- declare function parseValueMapText(text: string): AttributeFormValueMapEntry[];
4466
+ export declare function parseValueMapText(text: string): AttributeFormValueMapEntry[];
4133
4467
  /** Serialize value-map entries back into the designer's editable text form. */
4134
- declare function valueMapToText(entries: readonly AttributeFormValueMapEntry[] | undefined): string;
4468
+ export declare function valueMapToText(entries: readonly AttributeFormValueMapEntry[] | undefined): string;
4135
4469
  /** Display label for a stored value under a value-map widget. */
4136
- declare function valueMapLabelFor(config: AttributeFormFieldConfig, value: unknown): string;
4470
+ export declare function valueMapLabelFor(config: AttributeFormFieldConfig, value: unknown): string;
4137
4471
  /**
4138
4472
  * Coerce a raw form string into the typed value the widget stores on the
4139
4473
  * feature. An empty/blank string means "no value" (`null`). A `number`/`range`
4140
4474
  * string that does not parse is returned verbatim so validation can flag it
4141
4475
  * instead of silently dropping the input.
4142
4476
  */
4143
- declare function coerceAttributeFormValue(config: AttributeFormFieldConfig, raw: string): unknown;
4477
+ export declare function coerceAttributeFormValue(config: AttributeFormFieldConfig, raw: string): unknown;
4144
4478
  /**
4145
4479
  * Whether a configured field is currently shown, given the form's candidate
4146
4480
  * properties. An empty, invalid, or erroring visibility expression fails open
4147
4481
  * (visible) so a typo cannot hide data entry.
4148
4482
  */
4149
- declare function isAttributeFormFieldVisible(config: AttributeFormFieldConfig, properties: Record<string, unknown>, options?: AttributeFormEvalOptions): boolean;
4483
+ export declare function isAttributeFormFieldVisible(config: AttributeFormFieldConfig, properties: Record<string, unknown>, options?: AttributeFormEvalOptions): boolean;
4150
4484
  /**
4151
4485
  * Validate one configured field against the candidate properties record (the
4152
4486
  * field's own candidate value lives at `properties[config.field]`). Returns
@@ -4154,17 +4488,17 @@ declare function isAttributeFormFieldVisible(config: AttributeFormFieldConfig, p
4154
4488
  * numeric bounds, value-map membership, then the constraint expression — the
4155
4489
  * constraint sees the whole record, so cross-field rules work.
4156
4490
  */
4157
- declare function validateAttributeFormField(config: AttributeFormFieldConfig, properties: Record<string, unknown>, options?: AttributeFormEvalOptions): AttributeFormFieldError | null;
4491
+ export declare function validateAttributeFormField(config: AttributeFormFieldConfig, properties: Record<string, unknown>, options?: AttributeFormEvalOptions): AttributeFormFieldError | null;
4158
4492
  /**
4159
4493
  * Validate a whole candidate properties record against a form config. Hidden
4160
4494
  * fields (visibility expression currently false) are skipped entirely — a
4161
4495
  * field the form does not show cannot block a save.
4162
4496
  */
4163
- declare function validateAttributeFormValues(form: AttributeFormConfig | undefined, properties: Record<string, unknown>, options?: AttributeFormEvalOptions): AttributeFormValidation;
4497
+ export declare function validateAttributeFormValues(form: AttributeFormConfig | undefined, properties: Record<string, unknown>, options?: AttributeFormEvalOptions): AttributeFormValidation;
4164
4498
  //#endregion
4165
4499
  //#region src/popup.d.ts
4166
4500
  /** One resolved popup row, ready for the renderer. */
4167
- interface PopupRow {
4501
+ export interface PopupRow {
4168
4502
  /** Feature property key. */
4169
4503
  field: string;
4170
4504
  /** Label to print in the key column. */
@@ -4179,25 +4513,25 @@ interface PopupRow {
4179
4513
  linkLabel?: string;
4180
4514
  }
4181
4515
  /** Whether the Identify popup should open for a layer. Default: yes. */
4182
- declare function isPopupClickEnabled(popup: LayerPopupConfig | undefined): boolean;
4516
+ export declare function isPopupClickEnabled(popup: LayerPopupConfig | undefined): boolean;
4183
4517
  /** Whether a hover tooltip should follow the pointer. Default: no. */
4184
- declare function isPopupHoverEnabled(popup: LayerPopupConfig | undefined): boolean;
4518
+ export declare function isPopupHoverEnabled(popup: LayerPopupConfig | undefined): boolean;
4185
4519
  /** The label a popup shows for a configured field. */
4186
- declare function popupFieldLabel(config: PopupFieldConfig): string;
4520
+ export declare function popupFieldLabel(config: PopupFieldConfig): string;
4187
4521
  /**
4188
4522
  * Property keys that never belong in a popup: GeoLibre's own internal columns
4189
4523
  * and the full-resolution companion of a photo thumbnail (an internal twin of
4190
4524
  * a value already shown, and often multiple megabytes of data URL).
4191
4525
  */
4192
- declare function isInternalPopupField(key: string): boolean;
4526
+ export declare function isInternalPopupField(key: string): boolean;
4193
4527
  /**
4194
4528
  * The property keys a popup may show, before any popup config narrows them:
4195
4529
  * the feature's own keys minus the internal ones and anything the author
4196
4530
  * marked `"hidden"` or `"excluded"`.
4197
4531
  */
4198
- declare function visiblePopupFields(properties: Record<string, unknown>, fieldVisibility?: Record<string, FieldVisibility>): string[];
4532
+ export declare function visiblePopupFields(properties: Record<string, unknown>, fieldVisibility?: Record<string, FieldVisibility>): string[];
4199
4533
  /** Options for {@link formatPopupValue} and {@link resolvePopupRows}. */
4200
- interface PopupFormatOptions {
4534
+ export interface PopupFormatOptions {
4201
4535
  /**
4202
4536
  * BCP 47 tag for number/date formatting. Omitted means the runtime default,
4203
4537
  * which is what the browser uses for every other locale-aware rendering.
@@ -4205,14 +4539,14 @@ interface PopupFormatOptions {
4205
4539
  locale?: string;
4206
4540
  }
4207
4541
  /** Stringify a value the way the untyped popup always has. */
4208
- declare function stringifyPopupValue(value: unknown): string;
4542
+ export declare function stringifyPopupValue(value: unknown): string;
4209
4543
  /**
4210
4544
  * Render one value as text under a field's kind and format. `"auto"` and
4211
4545
  * `"image"` values are returned verbatim (the renderer draws them itself);
4212
4546
  * every other kind is stringified, formatted, then wrapped in the configured
4213
4547
  * prefix/suffix.
4214
4548
  */
4215
- declare function formatPopupValue(value: unknown, config?: Pick<PopupFieldConfig, "kind" | "format">, options?: PopupFormatOptions): string;
4549
+ export declare function formatPopupValue(value: unknown, config?: Pick<PopupFieldConfig, "kind" | "format">, options?: PopupFormatOptions): string;
4216
4550
  /**
4217
4551
  * The properties a popup may read, with the author's hidden and excluded
4218
4552
  * fields and GeoLibre's internal columns removed.
@@ -4223,9 +4557,9 @@ declare function formatPopupValue(value: unknown, config?: Pick<PopupFieldConfig
4223
4557
  * this module already honors `fieldVisibility` field by field; an expression
4224
4558
  * has no field list to filter, so the filtering has to happen to its input.
4225
4559
  */
4226
- declare function visiblePopupProperties(properties: Record<string, unknown>, fieldVisibility?: Record<string, FieldVisibility>): Record<string, unknown>;
4560
+ export declare function visiblePopupProperties(properties: Record<string, unknown>, fieldVisibility?: Record<string, FieldVisibility>): Record<string, unknown>;
4227
4561
  /** Options for {@link resolvePopupRows}. */
4228
- interface ResolvePopupRowsOptions extends PopupFormatOptions {
4562
+ export interface ResolvePopupRowsOptions extends PopupFormatOptions {
4229
4563
  popup?: LayerPopupConfig;
4230
4564
  fieldVisibility?: Record<string, FieldVisibility>;
4231
4565
  /** Resolve the hover subset (fields flagged `hover`) instead of the full list. */
@@ -4247,9 +4581,9 @@ interface ResolvePopupRowsOptions extends PopupFormatOptions {
4247
4581
  * without choosing a field gets no tip rather than the whole table following
4248
4582
  * the pointer.
4249
4583
  */
4250
- declare function resolvePopupRows(properties: Record<string, unknown>, options?: ResolvePopupRowsOptions): PopupRow[];
4584
+ export declare function resolvePopupRows(properties: Record<string, unknown>, options?: ResolvePopupRowsOptions): PopupRow[];
4251
4585
  /** Options for {@link resolvePopupTitle} and {@link resolvePopupBody}. */
4252
- interface PopupExpressionOptions {
4586
+ export interface PopupExpressionOptions {
4253
4587
  /**
4254
4588
  * The author's field visibility, so an expression cannot read a hidden or
4255
4589
  * excluded column. Omitting it means nothing is hidden.
@@ -4266,7 +4600,7 @@ interface PopupExpressionOptions {
4266
4600
  * compile or evaluate, and a title field that is empty or hidden, both fall
4267
4601
  * back to the layer name rather than leaving the popup headless.
4268
4602
  */
4269
- declare function resolvePopupTitle(layerName: string, properties: Record<string, unknown>, popup: LayerPopupConfig | undefined, options?: PopupExpressionOptions): string;
4603
+ export declare function resolvePopupTitle(layerName: string, properties: Record<string, unknown>, popup: LayerPopupConfig | undefined, options?: PopupExpressionOptions): string;
4270
4604
  /**
4271
4605
  * The title the author's own configuration produced, or `null` when there is
4272
4606
  * none — no title field or expression, or one that evaluated to nothing, or a
@@ -4279,23 +4613,23 @@ declare function resolvePopupTitle(layerName: string, properties: Record<string,
4279
4613
  * resolved text happens to equal the layer name. A city layer named "Olympia"
4280
4614
  * whose feature is also called "Olympia" is a real title, not a fallback.
4281
4615
  */
4282
- declare function resolveConfiguredPopupTitle(properties: Record<string, unknown>, popup: LayerPopupConfig | undefined, options?: PopupExpressionOptions): string | null;
4616
+ export declare function resolveConfiguredPopupTitle(properties: Record<string, unknown>, popup: LayerPopupConfig | undefined, options?: PopupExpressionOptions): string | null;
4283
4617
  /**
4284
4618
  * The popup body text when the author supplied a body expression, or `null`
4285
4619
  * when there is none (or it failed) and the field rows should render instead.
4286
4620
  */
4287
- declare function resolvePopupBody(properties: Record<string, unknown>, popup: LayerPopupConfig | undefined, options?: PopupExpressionOptions): string | null;
4621
+ export declare function resolvePopupBody(properties: Record<string, unknown>, popup: LayerPopupConfig | undefined, options?: PopupExpressionOptions): string | null;
4288
4622
  /**
4289
4623
  * Whether a value should render as an inline image thumbnail under `"auto"`.
4290
4624
  * Kept here so the renderer and the designer's preview agree on what counts.
4291
4625
  */
4292
- declare function isInlineImageValue(value: unknown): value is string;
4626
+ export declare function isInlineImageValue(value: unknown): value is string;
4293
4627
  /**
4294
4628
  * Whether a URL is safe to put in a popup `href`/`src`. Only http(s) and
4295
4629
  * inline raster data URLs: a `javascript:` or `data:text/html` value coming
4296
4630
  * from an untrusted GeoJSON must never become a live link.
4297
4631
  */
4298
- declare function isSafePopupUrl(value: unknown, allowDataImage?: boolean): value is string;
4632
+ export declare function isSafePopupUrl(value: unknown, allowDataImage?: boolean): value is string;
4299
4633
  //#endregion
4300
4634
  //#region src/joins.d.ts
4301
4635
  /**
@@ -4305,15 +4639,15 @@ declare function isSafePopupUrl(value: unknown, allowDataImage?: boolean): value
4305
4639
  * join while a zero-padded code like `"01001"` only matches another `"01001"`.
4306
4640
  * Kept in sync with the Processing attribute join's `attributeJoinKey`.
4307
4641
  */
4308
- declare function layerJoinKey(value: unknown): string | null;
4642
+ export declare function layerJoinKey(value: unknown): string | null;
4309
4643
  /**
4310
4644
  * Remove every column previously added by `joins` (per their `addedFields`
4311
4645
  * bookkeeping) from a copy of `features`, restoring the pre-join properties.
4312
4646
  * Features without any tracked column are returned unchanged (same reference).
4313
4647
  */
4314
- declare function stripJoinFields(features: Feature[], joins: LayerJoin[] | undefined): Feature[];
4648
+ export declare function stripJoinFields(features: Feature[], joins: LayerJoin[] | undefined): Feature[];
4315
4649
  /** Result of {@link applyLayerJoins}: joined features plus refreshed join records. */
4316
- interface ApplyLayerJoinsResult {
4650
+ export interface ApplyLayerJoinsResult {
4317
4651
  features: Feature[];
4318
4652
  /** Input joins with `addedFields` and `stats` recomputed for this run. */
4319
4653
  joins: LayerJoin[];
@@ -4336,7 +4670,7 @@ interface ApplyLayerJoinsResult {
4336
4670
  * feature collection, or `undefined` when the layer is gone (or is the
4337
4671
  * target itself; self-joins are refused by the caller).
4338
4672
  */
4339
- declare function applyLayerJoins(features: Feature[], joins: LayerJoin[] | undefined, resolveSource: (joinLayerId: string) => FeatureCollection | undefined): ApplyLayerJoinsResult;
4673
+ export declare function applyLayerJoins(features: Feature[], joins: LayerJoin[] | undefined, resolveSource: (joinLayerId: string) => FeatureCollection | undefined): ApplyLayerJoinsResult;
4340
4674
  /**
4341
4675
  * Strip-and-reapply this layer's derived columns — persistent joins, then
4342
4676
  * virtual fields (so an expression can read joined columns) — resolving join
@@ -4346,7 +4680,7 @@ declare function applyLayerJoins(features: Feature[], joins: LayerJoin[] | undef
4346
4680
  * existing definitions against current data. Layers without a feature
4347
4681
  * collection are returned unchanged.
4348
4682
  */
4349
- declare function applyJoinsToLayer(layer: GeoLibreLayer, allLayers: GeoLibreLayer[], nextJoins?: LayerJoin[], nextVirtualFields?: LayerVirtualField[]): GeoLibreLayer;
4683
+ export declare function applyJoinsToLayer(layer: GeoLibreLayer, allLayers: GeoLibreLayer[], nextJoins?: LayerJoin[], nextVirtualFields?: LayerVirtualField[]): GeoLibreLayer;
4350
4684
  /**
4351
4685
  * Ids of every layer whose data (directly or transitively) feeds `layerId`'s
4352
4686
  * joins, following `joinLayerId` edges through each source's own joins.
@@ -4356,7 +4690,7 @@ declare function applyJoinsToLayer(layer: GeoLibreLayer, allLayers: GeoLibreLaye
4356
4690
  * authored (the refresh cascade still breaks them defensively for hand-edited
4357
4691
  * projects).
4358
4692
  */
4359
- declare function collectTransitiveJoinSourceIds(layers: GeoLibreLayer[], layerId: string): Set<string>;
4693
+ export declare function collectTransitiveJoinSourceIds(layers: GeoLibreLayer[], layerId: string): Set<string>;
4360
4694
  /**
4361
4695
  * Refresh every layer whose joins (directly or transitively) consume the
4362
4696
  * layer identified by `seedId`, after that layer's data changed — or after it
@@ -4365,7 +4699,7 @@ declare function collectTransitiveJoinSourceIds(layers: GeoLibreLayer[], layerId
4365
4699
  * layer joining two other affected layers sees both of them fresh regardless
4366
4700
  * of their positions in the layer panel. The seed itself is not touched.
4367
4701
  */
4368
- declare function cascadeLayerJoinRefresh(layers: GeoLibreLayer[], seedId: string): GeoLibreLayer[];
4702
+ export declare function cascadeLayerJoinRefresh(layers: GeoLibreLayer[], seedId: string): GeoLibreLayer[];
4369
4703
  /**
4370
4704
  * Re-resolve every layer's persistent joins against the freshly loaded layer
4371
4705
  * set (project open). Layers re-derive in topological order of their join
@@ -4376,7 +4710,7 @@ declare function cascadeLayerJoinRefresh(layers: GeoLibreLayer[], seedId: string
4376
4710
  * too (their expressions run against the freshly loaded features). Layer sets
4377
4711
  * without joins or virtual fields pass through by reference.
4378
4712
  */
4379
- declare function reapplyLayerJoins(layers: GeoLibreLayer[]): GeoLibreLayer[];
4713
+ export declare function reapplyLayerJoins(layers: GeoLibreLayer[]): GeoLibreLayer[];
4380
4714
  //#endregion
4381
4715
  //#region src/virtual-fields.d.ts
4382
4716
  /**
@@ -4420,9 +4754,9 @@ declare function reapplyLayerJoins(layers: GeoLibreLayer[]): GeoLibreLayer[];
4420
4754
  * Features without any tracked column are returned unchanged (same
4421
4755
  * reference).
4422
4756
  */
4423
- declare function stripVirtualFieldColumns(features: Feature[], fields: LayerVirtualField[] | undefined): Feature[];
4757
+ export declare function stripVirtualFieldColumns(features: Feature[], fields: LayerVirtualField[] | undefined): Feature[];
4424
4758
  /** Result of {@link applyLayerVirtualFields}: features plus refreshed bookkeeping. */
4425
- interface ApplyVirtualFieldsResult {
4759
+ export interface ApplyVirtualFieldsResult {
4426
4760
  features: Feature[];
4427
4761
  /** Input fields with `addedField`/`error`/`errorCount` recomputed for this run. */
4428
4762
  fields: LayerVirtualField[];
@@ -4438,7 +4772,7 @@ interface ApplyVirtualFieldsResult {
4438
4772
  * the column. Fields evaluate sequentially, so a later field's expression
4439
4773
  * can `["get", ...]` an earlier field's column.
4440
4774
  */
4441
- declare function applyLayerVirtualFields(features: Feature[], fields: LayerVirtualField[] | undefined): ApplyVirtualFieldsResult;
4775
+ export declare function applyLayerVirtualFields(features: Feature[], fields: LayerVirtualField[] | undefined): ApplyVirtualFieldsResult;
4442
4776
  //#endregion
4443
4777
  //#region src/quick-filters.d.ts
4444
4778
  /**
@@ -4449,7 +4783,7 @@ declare function applyLayerVirtualFields(features: Feature[], fields: LayerVirtu
4449
4783
  * @param filter - The persisted control state.
4450
4784
  * @returns A MapLibre filter expression, or `null`.
4451
4785
  */
4452
- declare function compileQuickFilter(filter: LayerQuickFilter): unknown[] | null;
4786
+ export declare function compileQuickFilter(filter: LayerQuickFilter): unknown[] | null;
4453
4787
  /**
4454
4788
  * Compile a layer's quick filters into a single MapLibre filter expression.
4455
4789
  * Multiple controls narrow the data together (`["all", …]`), matching how a
@@ -4459,7 +4793,7 @@ declare function compileQuickFilter(filter: LayerQuickFilter): unknown[] | null;
4459
4793
  * @param filters - The layer's persisted quick filters.
4460
4794
  * @returns A MapLibre filter expression, or `null`.
4461
4795
  */
4462
- declare function compileQuickFilters(filters: readonly LayerQuickFilter[] | undefined): unknown[] | null;
4796
+ export declare function compileQuickFilters(filters: readonly LayerQuickFilter[] | undefined): unknown[] | null;
4463
4797
  /**
4464
4798
  * The quick filters that actually constrain the layer right now. Drives the
4465
4799
  * "filtered" badge on the layer row and its count, so an active filter is
@@ -4468,14 +4802,14 @@ declare function compileQuickFilters(filters: readonly LayerQuickFilter[] | unde
4468
4802
  * @param layer - The layer to inspect.
4469
4803
  * @returns The constraining filters, in their configured order.
4470
4804
  */
4471
- declare function activeQuickFilters(layer: GeoLibreLayer): LayerQuickFilter[];
4805
+ export declare function activeQuickFilters(layer: GeoLibreLayer): LayerQuickFilter[];
4472
4806
  /**
4473
4807
  * Whether the layer is currently narrowed by at least one quick filter.
4474
4808
  *
4475
4809
  * @param layer - The layer to inspect.
4476
4810
  * @returns `true` when a quick filter constrains the rendered features.
4477
4811
  */
4478
- declare function hasActiveQuickFilter(layer: GeoLibreLayer): boolean;
4812
+ export declare function hasActiveQuickFilter(layer: GeoLibreLayer): boolean;
4479
4813
  /**
4480
4814
  * Clear every chosen value while keeping the controls themselves, so "Clear
4481
4815
  * filters" is one action that leaves the layer's configured controls in place
@@ -4484,7 +4818,36 @@ declare function hasActiveQuickFilter(layer: GeoLibreLayer): boolean;
4484
4818
  * @param filters - The layer's persisted quick filters.
4485
4819
  * @returns The same controls with their selections emptied.
4486
4820
  */
4487
- declare function clearQuickFilterValues(filters: readonly LayerQuickFilter[] | undefined): LayerQuickFilter[];
4821
+ export declare function clearQuickFilterValues(filters: readonly LayerQuickFilter[] | undefined): LayerQuickFilter[];
4822
+ //#endregion
4823
+ //#region src/layer-filters.d.ts
4824
+ /** The layer fields needed to inspect project-authored feature filters. */
4825
+ type LayerFilterSource = Pick<GeoLibreLayer, "filterExpression" | "quickFilters">;
4826
+ /**
4827
+ * Return a layer's persisted expression filter when it has a usable array
4828
+ * shape, otherwise return null.
4829
+ *
4830
+ * @param layer - The layer whose expression filter should be read.
4831
+ * @returns The active expression filter, or null when none is configured.
4832
+ */
4833
+ export declare function activeLayerFilterExpression(layer: LayerFilterSource): unknown[] | null;
4834
+ /**
4835
+ * Compile all project-authored filters for a layer into one MapLibre boolean
4836
+ * expression. An explicit expression and Quick Filter controls narrow the
4837
+ * layer together.
4838
+ *
4839
+ * @param layer - The layer whose authored filters should be composed.
4840
+ * @returns A MapLibre filter expression, or null when no authored filter is active.
4841
+ */
4842
+ export declare function compileLayerFilters(layer: LayerFilterSource): unknown[] | null;
4843
+ /**
4844
+ * Whether a project-authored expression or Quick Filter currently narrows a
4845
+ * layer. This drives the filtered indicator and clear action in the layer UI.
4846
+ *
4847
+ * @param layer - The layer to inspect.
4848
+ * @returns True when at least one persisted filter is active.
4849
+ */
4850
+ export declare function hasActiveLayerFilter(layer: LayerFilterSource): boolean;
4488
4851
  //#endregion
4489
4852
  //#region src/capabilities.d.ts
4490
4853
  /**
@@ -4496,37 +4859,37 @@ declare function clearQuickFilterValues(filters: readonly LayerQuickFilter[] | u
4496
4859
  * false for derived queries (DuckDB/SQL), read-only vector tiles, and raster layers.
4497
4860
  * - `export`: true by default.
4498
4861
  */
4499
- declare function inferLayerCapabilities(layer: GeoLibreLayer): Required<LayerCapabilities>;
4862
+ export declare function inferLayerCapabilities(layer: GeoLibreLayer): Required<LayerCapabilities>;
4500
4863
  /**
4501
4864
  * Resolves the effective capabilities for a layer by overlaying any explicit
4502
4865
  * capability overrides on top of inferred defaults.
4503
4866
  */
4504
- declare function resolveLayerCapabilities(layer: GeoLibreLayer | undefined): Required<LayerCapabilities>;
4867
+ export declare function resolveLayerCapabilities(layer: GeoLibreLayer | undefined): Required<LayerCapabilities>;
4505
4868
  /**
4506
4869
  * Normalizes an untrusted capabilities value from JSON/project data.
4507
4870
  */
4508
- declare function normalizeLayerCapabilities(raw: unknown): LayerCapabilities | undefined;
4871
+ export declare function normalizeLayerCapabilities(raw: unknown): LayerCapabilities | undefined;
4509
4872
  /**
4510
4873
  * All supported application privilege identifiers in GeoLibre.
4511
4874
  */
4512
- declare const ALL_APP_PRIVILEGES: readonly AppPrivilege[];
4875
+ export declare const ALL_APP_PRIVILEGES: readonly AppPrivilege[];
4513
4876
  /**
4514
4877
  * Standard privilege bundles for named application roles.
4515
4878
  */
4516
- declare const ROLE_PRIVILEGES: Record<Exclude<AppRole, "custom">, readonly AppPrivilege[]>;
4879
+ export declare const ROLE_PRIVILEGES: Record<Exclude<AppRole, "custom">, readonly AppPrivilege[]>;
4517
4880
  /**
4518
4881
  * Resolves the effective privilege list for a given role, applying custom overrides if specified.
4519
4882
  */
4520
- declare function resolveRolePrivileges(role: AppRole, customPrivileges?: readonly AppPrivilege[]): AppPrivilege[];
4883
+ export declare function resolveRolePrivileges(role: AppRole, customPrivileges?: readonly AppPrivilege[]): AppPrivilege[];
4521
4884
  /**
4522
4885
  * Intersects multiple sets of privileges to derive the effective permissions when multiple
4523
4886
  * policies (e.g. deployment, organization, and share link) apply simultaneously.
4524
4887
  */
4525
- declare function intersectPrivileges(...privilegeSets: (readonly AppPrivilege[])[]): AppPrivilege[];
4888
+ export declare function intersectPrivileges(...privilegeSets: (readonly AppPrivilege[])[]): AppPrivilege[];
4526
4889
  /**
4527
4890
  * Evaluates whether an application capability set grants a specific privilege.
4528
4891
  */
4529
- declare function hasAppPrivilege(capabilities: AppCapabilities | undefined, privilege: AppPrivilege): boolean;
4892
+ export declare function hasAppPrivilege(capabilities: AppCapabilities | undefined, privilege: AppPrivilege): boolean;
4530
4893
  /**
4531
4894
  * Resolves why a privilege is withheld: its own reason if it has one, otherwise
4532
4895
  * the reason recorded for the capability set as a whole.
@@ -4535,19 +4898,19 @@ declare function hasAppPrivilege(capabilities: AppCapabilities | undefined, priv
4535
4898
  * @param privilege - The privilege being explained.
4536
4899
  * @returns The reason, or undefined when none was recorded.
4537
4900
  */
4538
- declare function appPrivilegeReason(capabilities: AppCapabilities | undefined, privilege: AppPrivilege): string | undefined;
4901
+ export declare function appPrivilegeReason(capabilities: AppCapabilities | undefined, privilege: AppPrivilege): string | undefined;
4539
4902
  /**
4540
4903
  * Creates the default unconstrained application capabilities (Administrator role).
4541
4904
  */
4542
- declare function createDefaultAppCapabilities(): AppCapabilities;
4905
+ export declare function createDefaultAppCapabilities(): AppCapabilities;
4543
4906
  /**
4544
4907
  * Normalizes an untrusted array of privilege strings.
4545
4908
  */
4546
- declare function normalizeAppPrivileges(raw: unknown): AppPrivilege[] | undefined;
4909
+ export declare function normalizeAppPrivileges(raw: unknown): AppPrivilege[] | undefined;
4547
4910
  //#endregion
4548
4911
  //#region src/deployment-capabilities.d.ts
4549
4912
  /** A privileged action a deployment can grant or withhold. */
4550
- type DeploymentCapability =
4913
+ export type DeploymentCapability =
4551
4914
  /** Create, save, or otherwise author the project itself. */
4552
4915
  "project:edit" |
4553
4916
  /** Bring new data into the map from files, URLs, or services. */
@@ -4561,14 +4924,14 @@ type DeploymentCapability =
4561
4924
  /** Reach the application settings. */
4562
4925
  "settings:manage";
4563
4926
  /** Every capability, in a stable order for docs and tests. */
4564
- declare const DEPLOYMENT_CAPABILITIES: readonly DeploymentCapability[];
4927
+ export declare const DEPLOYMENT_CAPABILITIES: readonly DeploymentCapability[];
4565
4928
  /**
4566
4929
  * The default grant: everything. `full` must stay the default so an existing
4567
4930
  * deployment that configures nothing behaves exactly as it did before.
4568
4931
  */
4569
- declare const ALL_DEPLOYMENT_CAPABILITIES: ReadonlySet<DeploymentCapability>;
4932
+ export declare const ALL_DEPLOYMENT_CAPABILITIES: ReadonlySet<DeploymentCapability>;
4570
4933
  /** Whether an arbitrary string names a capability we know how to enforce. */
4571
- declare function isDeploymentCapability(value: string): value is DeploymentCapability;
4934
+ export declare function isDeploymentCapability(value: string): value is DeploymentCapability;
4572
4935
  /**
4573
4936
  * The reserved token that grants nothing, for a deployment that wants the map
4574
4937
  * and nothing else.
@@ -4578,7 +4941,7 @@ declare function isDeploymentCapability(value: string): value is DeploymentCapab
4578
4941
  * meaning "full" so existing deployments are unchanged. Without a spelling for
4579
4942
  * "none", the most locked-down configuration would be the one you cannot write.
4580
4943
  */
4581
- declare const NO_DEPLOYMENT_CAPABILITIES = "none";
4944
+ export declare const NO_DEPLOYMENT_CAPABILITIES = "none";
4582
4945
  /**
4583
4946
  * Parse a comma-separated capability list from deployment configuration.
4584
4947
  *
@@ -4594,7 +4957,7 @@ declare const NO_DEPLOYMENT_CAPABILITIES = "none";
4594
4957
  * @param raw - The configured value, e.g. `"data:add, export:data"`.
4595
4958
  * @returns The granted capabilities, with duplicates and unknown names removed.
4596
4959
  */
4597
- declare function parseDeploymentCapabilities(raw: string): ReadonlySet<DeploymentCapability>;
4960
+ export declare function parseDeploymentCapabilities(raw: string): ReadonlySet<DeploymentCapability>;
4598
4961
  //#endregion
4599
4962
  //#region src/selection.d.ts
4600
4963
  /**
@@ -4602,29 +4965,29 @@ declare function parseDeploymentCapabilities(raw: string): ReadonlySet<Deploymen
4602
4965
  * mirroring QGIS's four selection behaviors: replace the selection, add to
4603
4966
  * it, remove from it, or keep only features in both.
4604
4967
  */
4605
- type SelectionMode = "new" | "add" | "remove" | "intersect";
4968
+ export type SelectionMode = "new" | "add" | "remove" | "intersect";
4606
4969
  /** Selection modes in display order. */
4607
- declare const SELECTION_MODES: readonly SelectionMode[];
4970
+ export declare const SELECTION_MODES: readonly SelectionMode[];
4608
4971
  /**
4609
4972
  * The id under which a feature participates in the selection model. Mirrors
4610
4973
  * the convention shared by the attribute table and the map highlight
4611
4974
  * (`String(feature.id ?? index)`): the feature's own `id` when present,
4612
4975
  * otherwise its index in the layer's feature array.
4613
4976
  */
4614
- declare function featureSelectionId(feature: Feature, index: number): string;
4977
+ export declare function featureSelectionId(feature: Feature, index: number): string;
4615
4978
  /**
4616
4979
  * Combines the current selection with a freshly matched id set according to
4617
4980
  * `mode`. The result is deduplicated and order-stable: "new" follows the
4618
4981
  * matched order, "add" appends unseen matches after the current ids, and
4619
4982
  * "remove"/"intersect" preserve the current selection's order.
4620
4983
  */
4621
- declare function applySelectionMode(current: readonly string[], matched: readonly string[], mode: SelectionMode): string[];
4984
+ export declare function applySelectionMode(current: readonly string[], matched: readonly string[], mode: SelectionMode): string[];
4622
4985
  /**
4623
4986
  * The complement of `current` within `allIds` (QGIS "Invert selection"):
4624
4987
  * every feature id not currently selected, in layer order. With an empty
4625
4988
  * selection this selects everything.
4626
4989
  */
4627
- declare function invertSelection(allIds: readonly string[], current: readonly string[]): string[];
4990
+ export declare function invertSelection(allIds: readonly string[], current: readonly string[]): string[];
4628
4991
  //#endregion
4629
4992
  //#region src/selection-actions.d.ts
4630
4993
  /**
@@ -4646,15 +5009,15 @@ declare function invertSelection(allIds: readonly string[], current: readonly st
4646
5009
  * the map's drawing gestures (`@geolibre/map`) share one copy of this rule
4647
5010
  * instead of two that can drift apart.
4648
5011
  */
4649
- declare function applyMatchedSelection(targetLayerId: string, matchedIds: string[], mode: SelectionMode): number;
5012
+ export declare function applyMatchedSelection(targetLayerId: string, matchedIds: string[], mode: SelectionMode): number;
4650
5013
  //#endregion
4651
5014
  //#region src/scale-units.d.ts
4652
5015
  /** Conversion constants shared by every scale-bar denomination. */
4653
- declare const FEET_PER_METER = 3.2808398950131235;
4654
- declare const METERS_PER_FOOT = 0.3048;
4655
- declare const FEET_PER_MILE = 5280;
4656
- declare const METERS_PER_MILE = 1609.344;
4657
- declare const METERS_PER_NAUTICAL_MILE = 1852;
5016
+ export declare const FEET_PER_METER = 3.2808398950131235;
5017
+ export declare const METERS_PER_FOOT = 0.3048;
5018
+ export declare const FEET_PER_MILE = 5280;
5019
+ export declare const METERS_PER_MILE = 1609.344;
5020
+ export declare const METERS_PER_NAUTICAL_MILE = 1852;
4658
5021
  /**
4659
5022
  * The largest `1 / 2 / 3 / 5 / 10 × 10ⁿ` number that does not exceed `num`, so
4660
5023
  * the bar lands on a readable round value. Uses log10 for the magnitude (unlike
@@ -4662,9 +5025,9 @@ declare const METERS_PER_NAUTICAL_MILE = 1852;
4662
5025
  * rounds *up* — producing a bar wider than the max width for sub-unit spans).
4663
5026
  * Returns 0 for a non-positive input so callers can clamp or fall back.
4664
5027
  */
4665
- declare function getRoundNum(num: number): number;
5028
+ export declare function getRoundNum(num: number): number;
4666
5029
  /** Trim trailing-zero noise from a rounded value (e.g. 0.5, 2, 300). */
4667
- declare function formatRoundNum(value: number): string;
5030
+ export declare function formatRoundNum(value: number): string;
4668
5031
  /**
4669
5032
  * The denomination a scale bar rounds and labels distances with for a ground
4670
5033
  * span of `maxMeters` in the requested unit system: km/m for metric, mi/ft for
@@ -4673,7 +5036,7 @@ declare function formatRoundNum(value: number): string;
4673
5036
  * one unit of that denomination in metres, so a caller can round the span in
4674
5037
  * unit space and convert the result back to metres (and thus pixels).
4675
5038
  */
4676
- declare function scaleDenomination(maxMeters: number, unit: MapScaleUnit): {
5039
+ export declare function scaleDenomination(maxMeters: number, unit: MapScaleUnit): {
4677
5040
  metersPerUnit: number;
4678
5041
  label: string;
4679
5042
  };
@@ -4682,7 +5045,7 @@ declare function scaleDenomination(maxMeters: number, unit: MapScaleUnit): {
4682
5045
  * bar's denomination) and its label — the shape the on-screen control consumes.
4683
5046
  * Derived from {@link scaleDenomination} so the two never diverge.
4684
5047
  */
4685
- declare function scaleSpan(maxMeters: number, unit: MapScaleUnit): {
5048
+ export declare function scaleSpan(maxMeters: number, unit: MapScaleUnit): {
4686
5049
  span: number;
4687
5050
  label: string;
4688
5051
  };
@@ -4713,17 +5076,17 @@ declare function scaleSpan(maxMeters: number, unit: MapScaleUnit): {
4713
5076
  * callers must not reach for it when the active body is not Earth.
4714
5077
  */
4715
5078
  /** A coordinate as `[longitude, latitude]` in degrees. */
4716
- type LngLat = [number, number];
5079
+ export type LngLat = [number, number];
4717
5080
  /** Open-Meteo accepts at most 100 coordinates per elevation request. */
4718
- declare const MAX_POINTS_PER_REQUEST = 100;
5081
+ export declare const MAX_POINTS_PER_REQUEST = 100;
4719
5082
  /** Abort an elevation request that has not responded within this window. */
4720
- declare const ELEVATION_REQUEST_TIMEOUT_MS = 15000;
5083
+ export declare const ELEVATION_REQUEST_TIMEOUT_MS = 15000;
4721
5084
  /** Error thrown when an elevation request cannot be completed or parsed. */
4722
- declare class ElevationFetchError extends Error {
5085
+ export declare class ElevationFetchError extends Error {
4723
5086
  constructor(message: string);
4724
5087
  }
4725
5088
  /** A `fetch`-compatible function, so tests can inject a stub. */
4726
- type FetchLike = (url: string, init?: RequestInit) => Promise<Response>;
5089
+ export type FetchLike = (url: string, init?: RequestInit) => Promise<Response>;
4727
5090
  /**
4728
5091
  * Fetch elevations (in meters) for an ordered list of coordinates.
4729
5092
  *
@@ -4733,9 +5096,9 @@ type FetchLike = (url: string, init?: RequestInit) => Promise<Response>;
4733
5096
  * @throws {ElevationFetchError} On too many points, a network error, a non-2xx
4734
5097
  * response, a malformed body, or a length mismatch
4735
5098
  */
4736
- declare function fetchElevations(points: LngLat[], fetchImpl?: FetchLike): Promise<number[]>;
5099
+ export declare function fetchElevations(points: LngLat[], fetchImpl?: FetchLike): Promise<number[]>;
4737
5100
  /** The slice of the MapLibre map the terrain sampler needs (stubbed in tests). */
4738
- interface TerrainMapLike {
5101
+ export interface TerrainMapLike {
4739
5102
  getTerrain?: () => {
4740
5103
  exaggeration?: number;
4741
5104
  } | null | undefined;
@@ -4746,24 +5109,24 @@ interface TerrainMapLike {
4746
5109
  * (MapLibre's `queryTerrainElevation` bakes the exaggeration in, so it is
4747
5110
  * divided back out). Returns null when terrain is not enabled.
4748
5111
  */
4749
- declare function sampleMapTerrain(map: TerrainMapLike | null | undefined, points: LngLat[]): (number | null)[] | null;
5112
+ export declare function sampleMapTerrain(map: TerrainMapLike | null | undefined, points: LngLat[]): (number | null)[] | null;
4750
5113
  /**
4751
5114
  * Sample a single point's elevation from enabled 3D terrain, in true meters.
4752
5115
  * Returns null when terrain is off or the DEM tile under the point has not
4753
5116
  * loaded — the caller decides whether that is worth a network round-trip.
4754
5117
  */
4755
- declare function sampleMapTerrainPoint(map: TerrainMapLike | null | undefined, point: LngLat): number | null;
5118
+ export declare function sampleMapTerrainPoint(map: TerrainMapLike | null | undefined, point: LngLat): number | null;
4756
5119
  /**
4757
5120
  * Sample elevations from the Open-Meteo API, chunked to its 100-point request
4758
5121
  * limit. A failed chunk yields nulls for its points rather than throwing, so a
4759
5122
  * flaky network degrades the readout instead of breaking the caller.
4760
5123
  */
4761
- declare function sampleRemoteElevations(points: LngLat[], fetchImpl?: FetchLike): Promise<(number | null)[]>;
5124
+ export declare function sampleRemoteElevations(points: LngLat[], fetchImpl?: FetchLike): Promise<(number | null)[]>;
4762
5125
  /** How long the pointer must sit still before a remote lookup is worth it. */
4763
- declare const POINTER_ELEVATION_DEBOUNCE_MS = 500;
5126
+ export declare const POINTER_ELEVATION_DEBOUNCE_MS = 500;
4764
5127
  /** Remote results kept per resolver; bounded so a long session cannot grow it without limit. */
4765
- declare const POINTER_ELEVATION_CACHE_LIMIT = 500;
4766
- interface PointerElevationResolverOptions {
5128
+ export declare const POINTER_ELEVATION_CACHE_LIMIT = 500;
5129
+ export interface PointerElevationResolverOptions {
4767
5130
  /** The live map, for the terrain sample. May return null before init. */
4768
5131
  getMap: () => TerrainMapLike | null | undefined;
4769
5132
  /**
@@ -4787,7 +5150,7 @@ interface PointerElevationResolverOptions {
4787
5150
  fetchImpl?: FetchLike;
4788
5151
  debounceMs?: number;
4789
5152
  }
4790
- interface PointerElevationResolver {
5153
+ export interface PointerElevationResolver {
4791
5154
  /** Report a new pointer position, or null when the pointer leaves the map. */
4792
5155
  update: (point: LngLat | null) => void;
4793
5156
  /**
@@ -4817,7 +5180,7 @@ interface PointerElevationResolver {
4817
5180
  * previous point's value: showing a stale height next to fresh coordinates
4818
5181
  * would be worse than showing nothing.
4819
5182
  */
4820
- declare function createPointerElevationResolver(options: PointerElevationResolverOptions): PointerElevationResolver;
5183
+ export declare function createPointerElevationResolver(options: PointerElevationResolverOptions): PointerElevationResolver;
4821
5184
  //#endregion
4822
5185
  //#region src/camera-altitude.d.ts
4823
5186
  /**
@@ -4828,7 +5191,7 @@ declare function createPointerElevationResolver(options: PointerElevationResolve
4828
5191
  * @returns Altitude in metres above the active body's datum, or null when the
4829
5192
  * input is not a usable number (no map, degenerate transform, globe edge case)
4830
5193
  */
4831
- declare function scaleAltitudeToActiveBody(earthAltitudeMeters: number | null): number | null;
5194
+ export declare function scaleAltitudeToActiveBody(earthAltitudeMeters: number | null): number | null;
4832
5195
  /**
4833
5196
  * Format a camera altitude for the status bar.
4834
5197
  *
@@ -4839,20 +5202,20 @@ declare function scaleAltitudeToActiveBody(earthAltitudeMeters: number | null):
4839
5202
  * the same thresholds {@link scaleDenomination} gives the scale bar, so the two
4840
5203
  * always agree about which unit this view is being described in.
4841
5204
  */
4842
- declare function formatCameraAltitude(meters: number, unit: MapScaleUnit): string;
5205
+ export declare function formatCameraAltitude(meters: number, unit: MapScaleUnit): string;
4843
5206
  //#endregion
4844
5207
  //#region src/project.d.ts
4845
5208
  /** Placeholder name a project carries before the user names it. */
4846
- declare const DEFAULT_PROJECT_NAME = "Untitled Project";
4847
- interface CreateProjectOptions {
5209
+ export declare const DEFAULT_PROJECT_NAME = "Untitled Project";
5210
+ export interface CreateProjectOptions {
4848
5211
  basemapStyleUrl?: string;
4849
5212
  mapView?: MapViewState;
4850
5213
  /** Celestial body the project describes; defaults to Earth when omitted. */
4851
5214
  ellipsoidId?: string;
4852
5215
  }
4853
- declare function normalizeBlankBackgroundColor(value: unknown): string | null;
4854
- declare function createDefaultMapView(): MapViewState;
4855
- declare function createEmptyProject(name?: string, options?: CreateProjectOptions): GeoLibreProject;
5216
+ export declare function normalizeBlankBackgroundColor(value: unknown): string | null;
5217
+ export declare function createDefaultMapView(): MapViewState;
5218
+ export declare function createEmptyProject(name?: string, options?: CreateProjectOptions): GeoLibreProject;
4856
5219
  /**
4857
5220
  * Serialize a project to `.geolibre.json` text: indented project structure with
4858
5221
  * compact (unindented) embedded GeoJSON. See {@link serializeProjectValue} for
@@ -4861,8 +5224,8 @@ declare function createEmptyProject(name?: string, options?: CreateProjectOption
4861
5224
  * @param project Project to serialize.
4862
5225
  * @returns The file contents to write.
4863
5226
  */
4864
- declare function serializeProject(project: GeoLibreProject): string;
4865
- declare function parseProject(json: string): GeoLibreProject;
5227
+ export declare function serializeProject(project: GeoLibreProject): string;
5228
+ export declare function parseProject(json: string): GeoLibreProject;
4866
5229
  /**
4867
5230
  * Validate and coerce a story map loaded from an untrusted project file.
4868
5231
  *
@@ -4872,9 +5235,9 @@ declare function parseProject(json: string): GeoLibreProject;
4872
5235
  * @param storymap Raw value read from the project JSON.
4873
5236
  * @returns A normalized story map, or null when there is nothing to keep.
4874
5237
  */
4875
- declare function normalizeStoryMap(storymap: unknown): StoryMap | null;
5238
+ export declare function normalizeStoryMap(storymap: unknown): StoryMap | null;
4876
5239
  /** Whether a story map carries chapters or any non-default setting. */
4877
- declare function storyMapHasContent(story: StoryMap): boolean;
5240
+ export declare function storyMapHasContent(story: StoryMap): boolean;
4878
5241
  /**
4879
5242
  * Coerce an untrusted (possibly hand-edited) `models` array into valid
4880
5243
  * {@link ProcessingModel} records. Drops models and steps without a usable id or
@@ -4886,7 +5249,7 @@ declare function storyMapHasContent(story: StoryMap): boolean;
4886
5249
  * @param value Raw `models` value from the project JSON.
4887
5250
  * @returns Normalized models, or `null` when none survive.
4888
5251
  */
4889
- declare function normalizeModels(value: unknown): ProcessingModel[] | null;
5252
+ export declare function normalizeModels(value: unknown): ProcessingModel[] | null;
4890
5253
  /**
4891
5254
  * Coerce an untrusted `graph` value into a {@link ProcessingModelGraph}. Drops
4892
5255
  * nodes without a usable id or an unknown kind, de-duplicates node ids, and
@@ -4900,7 +5263,7 @@ declare function normalizeModels(value: unknown): ProcessingModel[] | null;
4900
5263
  * @param value Raw `graph` value from the project JSON.
4901
5264
  * @returns The normalized graph, or `null` when it has no usable nodes.
4902
5265
  */
4903
- declare function normalizeModelGraph(value: unknown): ProcessingModelGraph | null;
5266
+ export declare function normalizeModelGraph(value: unknown): ProcessingModelGraph | null;
4904
5267
  /**
4905
5268
  * Coerce an untrusted (possibly hand-edited) `processingHistory` array into
4906
5269
  * valid {@link ProcessingRun} records. Drops entries without a usable id, tool
@@ -4912,31 +5275,41 @@ declare function normalizeModelGraph(value: unknown): ProcessingModelGraph | nul
4912
5275
  * @param value Raw `processingHistory` value from the project JSON.
4913
5276
  * @returns Normalized runs, or `null` when none survive.
4914
5277
  */
4915
- declare function normalizeProcessingHistory(value: unknown): ProcessingRun[] | null;
5278
+ export declare function normalizeProcessingHistory(value: unknown): ProcessingRun[] | null;
4916
5279
  /**
4917
5280
  * Coerce an untrusted (possibly hand-edited) camera object into a valid
4918
5281
  * {@link MapViewState}, falling back to the default view for missing parts.
4919
5282
  */
4920
- declare function normalizeMapViewState(value: unknown): MapViewState;
5283
+ export declare function normalizeMapViewState(value: unknown): MapViewState;
4921
5284
  /**
4922
5285
  * Coerce an untrusted `mapLayout` into a valid {@link MapGridLayout}. Returns
4923
5286
  * null when absent or effectively single-pane so default projects stay
4924
5287
  * byte-identical (the field is only written when the grid is larger than 1x1).
4925
5288
  */
4926
- declare function normalizeMapLayout(value: unknown): MapGridLayout | null;
5289
+ export declare function normalizeMapLayout(value: unknown): MapGridLayout | null;
5290
+ /**
5291
+ * Coerce an untrusted `primaryRenderer` into a known engine id (issue #2217).
5292
+ *
5293
+ * Returns null for the default 2D map — absent, unknown, or an explicit
5294
+ * `"maplibre"` — because the field is only written when it is not the default,
5295
+ * so a MapLibre project serializes byte-identically to before this existed.
5296
+ * The return type is narrowed to `"cesium" | null` rather than the full
5297
+ * {@link MapRendererKind} for that reason: `"maplibre"` is never a result.
5298
+ */
5299
+ export declare function normalizePrimaryRenderer(value: unknown): "cesium" | null;
4927
5300
  /**
4928
5301
  * Coerce an untrusted `secondaryMapViews` array into valid
4929
5302
  * {@link SecondaryMapView} records, dropping entries without a usable id and
4930
5303
  * de-duplicating by id. Returns null when none are valid.
4931
5304
  */
4932
- declare function normalizeSecondaryMapViews(value: unknown): SecondaryMapView[] | null;
5305
+ export declare function normalizeSecondaryMapViews(value: unknown): SecondaryMapView[] | null;
4933
5306
  /**
4934
5307
  * Reconcile a parsed grid layout with its secondary panes so the store invariant
4935
5308
  * holds: `secondaryMapViews.length === rows * cols - 1`. Surplus panes are
4936
5309
  * dropped; missing panes are filled by cloning the primary map. A null/absent
4937
5310
  * layout (or a 1x1 grid) collapses to the single-map default.
4938
5311
  */
4939
- declare function resolveMapGrid(layout: MapGridLayout | null, secondaryViews: SecondaryMapView[] | null, primary: {
5312
+ export declare function resolveMapGrid(layout: MapGridLayout | null, secondaryViews: SecondaryMapView[] | null, primary: {
4940
5313
  mapView: MapViewState;
4941
5314
  }): {
4942
5315
  mapLayout: MapGridLayout;
@@ -4953,7 +5326,7 @@ declare function resolveMapGrid(layout: MapGridLayout | null, secondaryViews: Se
4953
5326
  * @param value Raw `widgets` value from the project JSON.
4954
5327
  * @returns Normalized widgets, or `null` when none survive.
4955
5328
  */
4956
- declare function normalizeWidgets(value: unknown): DashboardWidget[] | null;
5329
+ export declare function normalizeWidgets(value: unknown): DashboardWidget[] | null;
4957
5330
  /**
4958
5331
  * Clamp an untrusted dashboard column count into the supported range, falling
4959
5332
  * back to the default for a missing or non-finite value.
@@ -4961,10 +5334,10 @@ declare function normalizeWidgets(value: unknown): DashboardWidget[] | null;
4961
5334
  * @param value Raw `dashboardColumns` value from the project JSON.
4962
5335
  * @returns An integer column count within [MIN, MAX].
4963
5336
  */
4964
- declare function normalizeDashboardColumns(value: unknown): number;
4965
- declare function isAllowedPluginManifestUrl(url: string): boolean;
4966
- declare function normalizeProjectComments(rawComments: unknown): ProjectComment[];
4967
- declare function projectFromStore(state: {
5337
+ export declare function normalizeDashboardColumns(value: unknown): number;
5338
+ export declare function isAllowedPluginManifestUrl(url: string): boolean;
5339
+ export declare function normalizeProjectComments(rawComments: unknown): ProjectComment[];
5340
+ export declare function projectFromStore(state: {
4968
5341
  projectName: string;
4969
5342
  mapView: MapViewState;
4970
5343
  basemapStyleUrl: string;
@@ -4986,12 +5359,13 @@ declare function projectFromStore(state: {
4986
5359
  mapLayout?: MapGridLayout;
4987
5360
  secondaryMapViews?: SecondaryMapView[];
4988
5361
  primaryMapLabel?: string;
5362
+ primaryRenderer?: MapRendererKind;
4989
5363
  /** Project-scoped Style Manager entries (the store's `projectStyleLibrary`). */
4990
5364
  styleLibrary?: StyleLibraryEntry[] | null;
4991
5365
  comments?: ProjectComment[] | null;
4992
5366
  metadata: Record<string, unknown>;
4993
5367
  }): GeoLibreProject;
4994
- declare function applyProjectToStore(project: GeoLibreProject): {
5368
+ export declare function applyProjectToStore(project: GeoLibreProject): {
4995
5369
  projectName: string;
4996
5370
  mapView: MapViewState;
4997
5371
  basemapStyleUrl: string;
@@ -5012,6 +5386,7 @@ declare function applyProjectToStore(project: GeoLibreProject): {
5012
5386
  mapLayout: MapGridLayout;
5013
5387
  secondaryMapViews: SecondaryMapView[];
5014
5388
  primaryMapLabel: string;
5389
+ primaryRenderer: MapRendererKind;
5015
5390
  projectStyleLibrary: StyleLibraryEntry[];
5016
5391
  comments: ProjectComment[];
5017
5392
  metadata: Record<string, unknown>;
@@ -5020,7 +5395,7 @@ declare function applyProjectToStore(project: GeoLibreProject): {
5020
5395
  * Create an unlinked copy of a project, suffixed with "(copy)" by default and
5021
5396
  * stripped of share-specific metadata (shareId, shareUrl, etc.).
5022
5397
  */
5023
- declare function detachProjectCopy(project: GeoLibreProject, options?: {
5398
+ export declare function detachProjectCopy(project: GeoLibreProject, options?: {
5024
5399
  nameSuffix?: string;
5025
5400
  }): GeoLibreProject;
5026
5401
  /**
@@ -5028,7 +5403,7 @@ declare function detachProjectCopy(project: GeoLibreProject, options?: {
5028
5403
  * keeping basemap, layer groups, styles, legend config, preferences, widgets, and
5029
5404
  * print layout.
5030
5405
  */
5031
- declare function createProjectTemplate(project: GeoLibreProject, options?: {
5406
+ export declare function createProjectTemplate(project: GeoLibreProject, options?: {
5032
5407
  name?: string;
5033
5408
  stripDataLayers?: boolean;
5034
5409
  }): GeoLibreProject;
@@ -5042,11 +5417,11 @@ declare function createProjectTemplate(project: GeoLibreProject, options?: {
5042
5417
  * so a future vector-stylable type cannot be added to one gate and missed in
5043
5418
  * another, leaving a dead-end entry point.
5044
5419
  */
5045
- declare function isStyleLibraryTargetLayer(type: LayerType): boolean;
5420
+ export declare function isStyleLibraryTargetLayer(type: LayerType): boolean;
5046
5421
  /** `type` discriminator of an exported Style Manager bundle file. */
5047
- declare const STYLE_LIBRARY_BUNDLE_TYPE = "geolibre-style-library";
5422
+ export declare const STYLE_LIBRARY_BUNDLE_TYPE = "geolibre-style-library";
5048
5423
  /** Current bundle format version, for forward-compatible readers. */
5049
- declare const STYLE_LIBRARY_BUNDLE_VERSION = 1;
5424
+ export declare const STYLE_LIBRARY_BUNDLE_VERSION = 1;
5050
5425
  /**
5051
5426
  * The {@link LayerStyle} keys a `"symbol"` entry captures: fill, stroke,
5052
5427
  * point/circle, marker, and fill-pattern symbology. Deliberately excludes the
@@ -5054,14 +5429,14 @@ declare const STYLE_LIBRARY_BUNDLE_VERSION = 1;
5054
5429
  * adjustments so a symbol preset restyles a layer without dismantling its
5055
5430
  * classification or labeling.
5056
5431
  */
5057
- declare const SYMBOL_STYLE_KEYS: readonly ["fillColor", "strokeColor", "strokeWidth", "strokeWidthUnit", "fillOpacity", "circleRadius", "fillPattern", "fillPatternColor", "fillPatternSvg", "markerEnabled", "markerShape", "markerColor", "markerSize", "markerSvg"];
5432
+ export declare const SYMBOL_STYLE_KEYS: readonly ["fillColor", "strokeColor", "strokeWidth", "strokeWidthUnit", "fillOpacity", "circleRadius", "fillPattern", "fillPatternColor", "fillPatternSvg", "markerEnabled", "markerShape", "markerColor", "markerSize", "markerSvg"];
5058
5433
  /**
5059
5434
  * The {@link LayerStyle} keys a `"ramp"` entry captures. The classified
5060
5435
  * attribute (`vectorStyleProperty`) and the concrete stops are deliberately
5061
5436
  * excluded: they are data-specific, so a ramp preset stays reusable across
5062
5437
  * layers with different attributes and value ranges.
5063
5438
  */
5064
- declare const RAMP_STYLE_KEYS: readonly ["vectorStyleColorRamp", "vectorStyleClassCount", "vectorStyleClassificationScheme"];
5439
+ export declare const RAMP_STYLE_KEYS: readonly ["vectorStyleColorRamp", "vectorStyleClassCount", "vectorStyleClassificationScheme"];
5065
5440
  /**
5066
5441
  * Extract the {@link LayerStyle} subset a Style Manager entry of `kind`
5067
5442
  * stores, deep-cloned so later edits to the live layer cannot mutate the
@@ -5071,7 +5446,7 @@ declare const RAMP_STYLE_KEYS: readonly ["vectorStyleColorRamp", "vectorStyleCla
5071
5446
  * @param kind - Which subset to capture.
5072
5447
  * @returns The cloned subset to store in a {@link StyleLibraryEntry}.
5073
5448
  */
5074
- declare function extractStyleLibraryStyle(style: LayerStyle, kind: StyleLibraryEntryKind): Partial<LayerStyle>;
5449
+ export declare function extractStyleLibraryStyle(style: LayerStyle, kind: StyleLibraryEntryKind): Partial<LayerStyle>;
5075
5450
  /**
5076
5451
  * Coerce an untrusted style patch (from a hand-edited project file or an
5077
5452
  * imported bundle) into a safe {@link LayerStyle} subset: unknown keys are
@@ -5084,7 +5459,7 @@ declare function extractStyleLibraryStyle(style: LayerStyle, kind: StyleLibraryE
5084
5459
  * @param value - The raw `style` value from JSON.
5085
5460
  * @returns The sanitized subset (empty when nothing usable survives).
5086
5461
  */
5087
- declare function sanitizeLayerStylePatch(value: unknown): Partial<LayerStyle>;
5462
+ export declare function sanitizeLayerStylePatch(value: unknown): Partial<LayerStyle>;
5088
5463
  /**
5089
5464
  * Coerce an untrusted (hand-edited project file or imported bundle) entries
5090
5465
  * array into valid {@link StyleLibraryEntry} records. Drops entries without a
@@ -5095,7 +5470,7 @@ declare function sanitizeLayerStylePatch(value: unknown): Partial<LayerStyle>;
5095
5470
  * @param value - The raw `styleLibrary` / bundle `entries` value.
5096
5471
  * @returns Normalized, de-duplicated entries (empty when none survive).
5097
5472
  */
5098
- declare function normalizeStyleLibraryEntries(value: unknown): StyleLibraryEntry[];
5473
+ export declare function normalizeStyleLibraryEntries(value: unknown): StyleLibraryEntry[];
5099
5474
  /**
5100
5475
  * Serialize Style Manager entries into the shareable bundle JSON written by
5101
5476
  * the Export action and read back by {@link parseStyleLibrary}.
@@ -5103,7 +5478,7 @@ declare function normalizeStyleLibraryEntries(value: unknown): StyleLibraryEntry
5103
5478
  * @param entries - The entries to export.
5104
5479
  * @returns Pretty-printed bundle JSON.
5105
5480
  */
5106
- declare function serializeStyleLibrary(entries: StyleLibraryEntry[]): string;
5481
+ export declare function serializeStyleLibrary(entries: StyleLibraryEntry[]): string;
5107
5482
  /**
5108
5483
  * Parse a Style Manager bundle produced by {@link serializeStyleLibrary} (a
5109
5484
  * bare entries array is also accepted, so hand-authored files work). Entries
@@ -5114,13 +5489,13 @@ declare function serializeStyleLibrary(entries: StyleLibraryEntry[]): string;
5114
5489
  * @throws Error when the JSON is not a style-library bundle or holds no
5115
5490
  * usable entries.
5116
5491
  */
5117
- declare function parseStyleLibrary(json: string): StyleLibraryEntry[];
5492
+ export declare function parseStyleLibrary(json: string): StyleLibraryEntry[];
5118
5493
  /**
5119
5494
  * Create a fresh unique id for a new library entry.
5120
5495
  *
5121
5496
  * @returns A random id (UUID when available).
5122
5497
  */
5123
- declare function createStyleLibraryEntryId(): string;
5498
+ export declare function createStyleLibraryEntryId(): string;
5124
5499
  /**
5125
5500
  * Built-in presets shown in the Style Manager so the library is not empty on
5126
5501
  * first open (issue #1294). Read-only: they are not persisted, cannot be
@@ -5128,13 +5503,13 @@ declare function createStyleLibraryEntryId(): string;
5128
5503
  * collide. Names are plain English by the same convention as the ramp labels
5129
5504
  * in `color-ramp.ts`.
5130
5505
  */
5131
- declare const BUILT_IN_STYLE_PRESETS: readonly StyleLibraryEntry[];
5506
+ export declare const BUILT_IN_STYLE_PRESETS: readonly StyleLibraryEntry[];
5132
5507
  //#endregion
5133
5508
  //#region src/layer-library.d.ts
5134
5509
  /** `type` discriminator of an exported Layer Library bundle file. */
5135
- declare const LAYER_LIBRARY_BUNDLE_TYPE = "geolibre-layer-library";
5510
+ export declare const LAYER_LIBRARY_BUNDLE_TYPE = "geolibre-layer-library";
5136
5511
  /** Current bundle format version, for forward-compatible readers. */
5137
- declare const LAYER_LIBRARY_BUNDLE_VERSION = 1;
5512
+ export declare const LAYER_LIBRARY_BUNDLE_VERSION = 1;
5138
5513
  /**
5139
5514
  * Size ceiling for one library entry's serialized JSON, in bytes. The library
5140
5515
  * lives in IndexedDB and is meant to be a small, shareable index of *sources*,
@@ -5144,7 +5519,7 @@ declare const LAYER_LIBRARY_BUNDLE_VERSION = 1;
5144
5519
  * Applied to the whole entry (not just `geojson`), because an Add Vector Layer
5145
5520
  * entry can also carry a `metadata.embeddedGeoJSON` copy of its features.
5146
5521
  */
5147
- declare const MAX_LAYER_LIBRARY_ENTRY_BYTES: number;
5522
+ export declare const MAX_LAYER_LIBRARY_ENTRY_BYTES: number;
5148
5523
  /**
5149
5524
  * Cap on how many entries a single normalization pass keeps. Enforced on the way
5150
5525
  * *in* — an imported bundle or a hand-edited database is untrusted, and without
@@ -5152,7 +5527,7 @@ declare const MAX_LAYER_LIBRARY_ENTRY_BYTES: number;
5152
5527
  * synchronous pass and into IndexedDB. Mirrors `MAX_FAVORITES`, which caps the
5153
5528
  * Browser panel's other user-grown list on read as well as write.
5154
5529
  */
5155
- declare const MAX_LAYER_LIBRARY_ENTRIES = 500;
5530
+ export declare const MAX_LAYER_LIBRARY_ENTRIES = 500;
5156
5531
  /**
5157
5532
  * Whether a layer's features can be re-fetched from its source specification
5158
5533
  * alone, so an entry need not embed them: a tile/service template, a remote
@@ -5163,7 +5538,7 @@ declare const MAX_LAYER_LIBRARY_ENTRIES = 500;
5163
5538
  * @param layer - The layer to inspect (source + metadata only).
5164
5539
  * @returns True when the source alone is enough to recreate the layer's data.
5165
5540
  */
5166
- declare function hasRestorableLayerSource(layer: Pick<GeoLibreLayer, "source" | "metadata">): boolean;
5541
+ export declare function hasRestorableLayerSource(layer: Pick<GeoLibreLayer, "source" | "metadata">): boolean;
5167
5542
  /**
5168
5543
  * Whether "Save to library" applies to a layer at all — the cheap predicate the
5169
5544
  * layer actions menu gates on. Two things have to hold:
@@ -5194,12 +5569,12 @@ declare function hasRestorableLayerSource(layer: Pick<GeoLibreLayer, "source" |
5194
5569
  * `isEmbeddableLocalVectorLayer`, the same predicate its save handler uses).
5195
5570
  * @returns Whether the layer can be offered to the library.
5196
5571
  */
5197
- declare function canSaveLayerToLibrary(layer: GeoLibreLayer, options?: {
5572
+ export declare function canSaveLayerToLibrary(layer: GeoLibreLayer, options?: {
5198
5573
  canRestoreControlPainted?: (layer: GeoLibreLayer) => boolean;
5199
5574
  hasMaterializableFeatures?: (layer: GeoLibreLayer) => boolean;
5200
5575
  }): boolean;
5201
5576
  /** Why a layer could not be captured into the library. */
5202
- type LayerLibraryCaptureFailure =
5577
+ export type LayerLibraryCaptureFailure =
5203
5578
  /** Nothing to re-add from: no source URL, no local path, no features. */
5204
5579
  "no-source" |
5205
5580
  /** Its features are the only copy, and they exceed the per-entry size cap. */
@@ -5211,7 +5586,7 @@ type LayerLibraryCaptureFailure =
5211
5586
  */
5212
5587
  "config-too-large";
5213
5588
  /** Outcome of {@link captureLayerLibraryEntry}. */
5214
- type LayerLibraryCaptureResult = {
5589
+ export type LayerLibraryCaptureResult = {
5215
5590
  ok: true;
5216
5591
  entry: LayerLibraryEntry;
5217
5592
  } | {
@@ -5228,7 +5603,7 @@ type LayerLibraryCaptureResult = {
5228
5603
  * @param layer - The layer to test (metadata only).
5229
5604
  * @returns True when a plugin control owns the layer's rendering.
5230
5605
  */
5231
- declare function isExternalNativeLayerRecord(layer: Pick<GeoLibreLayer, "metadata">): boolean;
5606
+ export declare function isExternalNativeLayerRecord(layer: Pick<GeoLibreLayer, "metadata">): boolean;
5232
5607
  /**
5233
5608
  * Capture a configured layer as a reusable Layer Library entry: its source
5234
5609
  * spec, layer type, full style (labels included), opacity, metadata, and the
@@ -5254,7 +5629,7 @@ declare function isExternalNativeLayerRecord(layer: Pick<GeoLibreLayer, "metadat
5254
5629
  * current data from its control).
5255
5630
  * @returns The entry, or the reason it could not be captured.
5256
5631
  */
5257
- declare function captureLayerLibraryEntry(layer: GeoLibreLayer, options: {
5632
+ export declare function captureLayerLibraryEntry(layer: GeoLibreLayer, options: {
5258
5633
  id: string;
5259
5634
  addedAt: string;
5260
5635
  name?: string;
@@ -5266,7 +5641,7 @@ declare function captureLayerLibraryEntry(layer: GeoLibreLayer, options: {
5266
5641
  * layer) and then applies this patch, so a degraded entry still comes back
5267
5642
  * "fully configured" rather than losing the styling the entry preserved.
5268
5643
  */
5269
- interface LayerLibraryConfigPatch {
5644
+ export interface LayerLibraryConfigPatch {
5270
5645
  name: string;
5271
5646
  style: LayerStyle;
5272
5647
  opacity: number;
@@ -5276,7 +5651,7 @@ interface LayerLibraryConfigPatch {
5276
5651
  popup?: LayerPopupConfig;
5277
5652
  }
5278
5653
  /** How an entry should be re-added to the current project. */
5279
- type LayerLibraryAddPlan =
5654
+ export type LayerLibraryAddPlan =
5280
5655
  /** Add this layer record to the store; the map sync renders it. */
5281
5656
  {
5282
5657
  kind: "layer";
@@ -5300,7 +5675,7 @@ type LayerLibraryAddPlan =
5300
5675
  * @param options - The fresh layer `id` to create it under.
5301
5676
  * @returns Either the layer record to add, or the local file to re-read.
5302
5677
  */
5303
- declare function planLayerLibraryAdd(entry: LayerLibraryEntry, options: {
5678
+ export declare function planLayerLibraryAdd(entry: LayerLibraryEntry, options: {
5304
5679
  id: string;
5305
5680
  }): LayerLibraryAddPlan;
5306
5681
  /**
@@ -5310,7 +5685,7 @@ declare function planLayerLibraryAdd(entry: LayerLibraryEntry, options: {
5310
5685
  * @param entry - The entry being re-added.
5311
5686
  * @returns The patch to merge onto the imported layer.
5312
5687
  */
5313
- declare function layerLibraryConfigPatch(entry: LayerLibraryEntry): LayerLibraryConfigPatch;
5688
+ export declare function layerLibraryConfigPatch(entry: LayerLibraryEntry): LayerLibraryConfigPatch;
5314
5689
  /**
5315
5690
  * The saved joins whose source layer is not present in the target project.
5316
5691
  *
@@ -5331,7 +5706,7 @@ declare function layerLibraryConfigPatch(entry: LayerLibraryEntry): LayerLibrary
5331
5706
  * @returns Ids of the join-target layers that cannot resolve ({@link LayerJoin}
5332
5707
  * has no display name).
5333
5708
  */
5334
- declare function unresolvedLayerLibraryJoins(entry: Pick<LayerLibraryEntry, "joins">, presentLayerIds: Iterable<string>): string[];
5709
+ export declare function unresolvedLayerLibraryJoins(entry: Pick<LayerLibraryEntry, "joins">, presentLayerIds: Iterable<string>): string[];
5335
5710
  /**
5336
5711
  * Whether re-adding an entry needs a host that can read local files — used to
5337
5712
  * badge the entry in the Browser panel and to explain the failure in the
@@ -5340,7 +5715,7 @@ declare function unresolvedLayerLibraryJoins(entry: Pick<LayerLibraryEntry, "joi
5340
5715
  * @param entry - The entry to test.
5341
5716
  * @returns True when only a filesystem-capable host can add it.
5342
5717
  */
5343
- declare function layerLibraryEntryNeedsLocalFile(entry: LayerLibraryEntry): boolean;
5718
+ export declare function layerLibraryEntryNeedsLocalFile(entry: LayerLibraryEntry): boolean;
5344
5719
  /**
5345
5720
  * Coerce an untrusted entries array (an imported bundle, or a record written by
5346
5721
  * an older version) into valid {@link LayerLibraryEntry} records. Entries
@@ -5355,7 +5730,7 @@ declare function layerLibraryEntryNeedsLocalFile(entry: LayerLibraryEntry): bool
5355
5730
  * @param value - The raw entries value.
5356
5731
  * @returns Normalized, de-duplicated entries (empty when none survive).
5357
5732
  */
5358
- declare function normalizeLayerLibraryEntries(value: unknown): LayerLibraryEntry[];
5733
+ export declare function normalizeLayerLibraryEntries(value: unknown): LayerLibraryEntry[];
5359
5734
  /**
5360
5735
  * Serialize Layer Library entries into the shareable bundle JSON written by the
5361
5736
  * Export action and read back by {@link parseLayerLibrary}. Per-user credentials
@@ -5364,7 +5739,7 @@ declare function normalizeLayerLibraryEntries(value: unknown): LayerLibraryEntry
5364
5739
  * @param entries - The entries to export.
5365
5740
  * @returns Pretty-printed bundle JSON.
5366
5741
  */
5367
- declare function serializeLayerLibrary(entries: LayerLibraryEntry[]): string;
5742
+ export declare function serializeLayerLibrary(entries: LayerLibraryEntry[]): string;
5368
5743
  /**
5369
5744
  * Parse a Layer Library bundle produced by {@link serializeLayerLibrary} (a
5370
5745
  * bare entries array is also accepted, so hand-authored files work). Entries
@@ -5375,13 +5750,13 @@ declare function serializeLayerLibrary(entries: LayerLibraryEntry[]): string;
5375
5750
  * @throws Error when the JSON is not a layer-library bundle or holds no usable
5376
5751
  * entries.
5377
5752
  */
5378
- declare function parseLayerLibrary(json: string): LayerLibraryEntry[];
5753
+ export declare function parseLayerLibrary(json: string): LayerLibraryEntry[];
5379
5754
  /**
5380
5755
  * Create a fresh unique id for a new library entry.
5381
5756
  *
5382
5757
  * @returns A random id (UUID when available).
5383
5758
  */
5384
- declare function createLayerLibraryEntryId(): string;
5759
+ export declare function createLayerLibraryEntryId(): string;
5385
5760
  //#endregion
5386
5761
  //#region src/layer-defaults.d.ts
5387
5762
  /**
@@ -5405,9 +5780,9 @@ declare function createLayerLibraryEntryId(): string;
5405
5780
  * *within* one layer: this one separates layers from each other, and the two
5406
5781
  * are free to diverge.
5407
5782
  */
5408
- declare const LAYER_PALETTE: readonly ["#3b82f6", "#ef4444", "#22c55e", "#a855f7", "#f97316", "#06b6d4", "#ec4899", "#84cc16"];
5783
+ export declare const LAYER_PALETTE: readonly ["#3b82f6", "#ef4444", "#22c55e", "#a855f7", "#f97316", "#06b6d4", "#ec4899", "#84cc16"];
5409
5784
  /** Darken a `#rrggbb` color toward black by `factor`. */
5410
- declare function darkenHex(hex: string, factor: number): string;
5785
+ export declare function darkenHex(hex: string, factor: number): string;
5411
5786
  /**
5412
5787
  * Pick the next layer color: the first palette entry no current layer is
5413
5788
  * already using, so deleting a layer frees its color back up rather than
@@ -5418,9 +5793,9 @@ declare function darkenHex(hex: string, factor: number): string;
5418
5793
  * palette assignment count; see {@link wearsPaletteColor}.
5419
5794
  * @returns A `#rrggbb` color from {@link LAYER_PALETTE}.
5420
5795
  */
5421
- declare function nextLayerPaletteColor(layers: readonly GeoLibreLayer[]): string;
5796
+ export declare function nextLayerPaletteColor(layers: readonly GeoLibreLayer[]): string;
5422
5797
  /** The geometry family a layer is mostly made of. */
5423
- type DominantGeometry = "point" | "line" | "polygon" | "mixed";
5798
+ export type DominantGeometry = "point" | "line" | "polygon" | "mixed";
5424
5799
  /**
5425
5800
  * Classify a collection by the geometry family most of its features carry,
5426
5801
  * reading at most {@link GEOMETRY_SAMPLE_SIZE} features so a very large layer
@@ -5430,8 +5805,8 @@ type DominantGeometry = "point" | "line" | "polygon" | "mixed";
5430
5805
  * @returns The dominant family, or `"mixed"` when nothing has a clear majority
5431
5806
  * (or the collection is empty).
5432
5807
  */
5433
- declare function dominantGeometry(geojson: FeatureCollection | undefined): DominantGeometry;
5434
- interface InitialLayerStyleOptions {
5808
+ export declare function dominantGeometry(geojson: FeatureCollection | undefined): DominantGeometry;
5809
+ export interface InitialLayerStyleOptions {
5435
5810
  /** The layer's data, used to pick geometry-appropriate sizes. */
5436
5811
  geojson?: FeatureCollection;
5437
5812
  /** Current project layers, so the new layer gets an unused palette color. */
@@ -5446,7 +5821,7 @@ interface InitialLayerStyleOptions {
5446
5821
  * @param options - Data and project context to derive the style from.
5447
5822
  * @returns A complete {@link LayerStyle}.
5448
5823
  */
5449
- declare function initialLayerStyle(options?: InitialLayerStyleOptions): LayerStyle;
5824
+ export declare function initialLayerStyle(options?: InitialLayerStyleOptions): LayerStyle;
5450
5825
  /**
5451
5826
  * True when a layer still wears exactly what {@link initialLayerStyle} gave it.
5452
5827
  *
@@ -5464,7 +5839,7 @@ declare function initialLayerStyle(options?: InitialLayerStyleOptions): LayerSty
5464
5839
  * @param geojson - Its data, so the geometry-derived sizes can be recomputed.
5465
5840
  * @returns `true` when nothing about the as-added look has been changed.
5466
5841
  */
5467
- declare function isInitialLayerStyle(style: LayerStyle, geojson?: FeatureCollection): boolean;
5842
+ export declare function isInitialLayerStyle(style: LayerStyle, geojson?: FeatureCollection): boolean;
5468
5843
  //#endregion
5469
5844
  //#region src/layer-style-clipboard.d.ts
5470
5845
  /**
@@ -5473,14 +5848,14 @@ declare function isInitialLayerStyle(style: LayerStyle, geojson?: FeatureCollect
5473
5848
  * LayerStyle} bag vs `metadata.rasterState`), so a paste only applies between
5474
5849
  * layers of the same family.
5475
5850
  */
5476
- type LayerStyleClipboardKind = "vector" | "raster";
5851
+ export type LayerStyleClipboardKind = "vector" | "raster";
5477
5852
  /**
5478
5853
  * The `metadata.rasterState` keys a raster style paste carries over: the
5479
5854
  * appearance of the render (colormap, stretch range, gamma, nodata), but not
5480
5855
  * the data selection (`mode`/`bands`/`index`), which stays with the target so
5481
5856
  * pasting a style never points a raster at a band it does not have.
5482
5857
  */
5483
- declare const RASTER_APPEARANCE_STATE_KEYS: readonly ["colormap", "reversed", "rescale", "nodata", "stretch", "gamma"];
5858
+ export declare const RASTER_APPEARANCE_STATE_KEYS: readonly ["colormap", "reversed", "rescale", "nodata", "stretch", "gamma"];
5484
5859
  /**
5485
5860
  * Fields every clipboard entry carries, regardless of style family. Layer
5486
5861
  * `opacity` is deliberately excluded: like QGIS "Paste Style" and GeoLibre's
@@ -5501,7 +5876,7 @@ interface CopiedLayerStyleBase {
5501
5876
  sourceName: string;
5502
5877
  }
5503
5878
  /** A copied vector layer style: the whole {@link LayerStyle} bag. */
5504
- interface CopiedVectorStyle extends CopiedLayerStyleBase {
5879
+ export interface CopiedVectorStyle extends CopiedLayerStyleBase {
5505
5880
  kind: "vector";
5506
5881
  /** Deep-cloned full vector layer style. */
5507
5882
  style: LayerStyle;
@@ -5511,7 +5886,7 @@ interface CopiedVectorStyle extends CopiedLayerStyleBase {
5511
5886
  * classification symbology. There is no `style` field — the vector
5512
5887
  * {@link LayerStyle} bag holds nothing a deck.gl raster renders from.
5513
5888
  */
5514
- interface CopiedRasterStyle extends CopiedLayerStyleBase {
5889
+ export interface CopiedRasterStyle extends CopiedLayerStyleBase {
5515
5890
  kind: "raster";
5516
5891
  /** Raster visualization state (`metadata.rasterState`). */
5517
5892
  rasterState?: Record<string, unknown>;
@@ -5526,7 +5901,7 @@ interface CopiedRasterStyle extends CopiedLayerStyleBase {
5526
5901
  * vector entry (or vice versa); a paste only applies between layers of the same
5527
5902
  * family.
5528
5903
  */
5529
- type CopiedLayerStyle = CopiedVectorStyle | CopiedRasterStyle;
5904
+ export type CopiedLayerStyle = CopiedVectorStyle | CopiedRasterStyle;
5530
5905
  /**
5531
5906
  * The copy/paste style family of a layer, or `null` when the layer has no
5532
5907
  * copyable symbology. Deck.gl rasters are `"raster"`; the vector-styled layers
@@ -5535,7 +5910,7 @@ type CopiedLayerStyle = CopiedVectorStyle | CopiedRasterStyle;
5535
5910
  * @param layer - The layer to classify.
5536
5911
  * @returns The style family, or `null`.
5537
5912
  */
5538
- declare function copyableLayerStyleKind(layer: GeoLibreLayer): LayerStyleClipboardKind | null;
5913
+ export declare function copyableLayerStyleKind(layer: GeoLibreLayer): LayerStyleClipboardKind | null;
5539
5914
  /**
5540
5915
  * Snapshot a layer's style for the clipboard, deep-cloned so later edits to the
5541
5916
  * live layer cannot mutate the copied entry.
@@ -5544,7 +5919,7 @@ declare function copyableLayerStyleKind(layer: GeoLibreLayer): LayerStyleClipboa
5544
5919
  * @returns The clipboard entry, or `null` when the layer has no copyable
5545
5920
  * symbology.
5546
5921
  */
5547
- declare function extractCopiedLayerStyle(layer: GeoLibreLayer): CopiedLayerStyle | null;
5922
+ export declare function extractCopiedLayerStyle(layer: GeoLibreLayer): CopiedLayerStyle | null;
5548
5923
  /**
5549
5924
  * Build the {@link GeoLibreLayer} patch that pastes a copied style onto a
5550
5925
  * target layer, or `null` when the target's style family does not match the
@@ -5554,16 +5929,16 @@ declare function extractCopiedLayerStyle(layer: GeoLibreLayer): CopiedLayerStyle
5554
5929
  * @param copied - The clipboard entry.
5555
5930
  * @returns A partial layer patch to merge, or `null` when incompatible.
5556
5931
  */
5557
- declare function applyCopiedLayerStyle(target: GeoLibreLayer, copied: CopiedLayerStyle): Partial<GeoLibreLayer> | null;
5932
+ export declare function applyCopiedLayerStyle(target: GeoLibreLayer, copied: CopiedLayerStyle): Partial<GeoLibreLayer> | null;
5558
5933
  //#endregion
5559
5934
  //#region src/layer-groups.d.ts
5560
5935
  /** Opacity a freshly created {@link LayerGroup} starts at (fully opaque). */
5561
- declare const DEFAULT_LAYER_GROUP_OPACITY = 1;
5936
+ export declare const DEFAULT_LAYER_GROUP_OPACITY = 1;
5562
5937
  /**
5563
5938
  * One row in the layer panel: either a top-level (ungrouped) layer or a group
5564
5939
  * header together with its child layers.
5565
5940
  */
5566
- type LayerTreeItem = {
5941
+ export type LayerTreeItem = {
5567
5942
  kind: "layer";
5568
5943
  layer: GeoLibreLayer;
5569
5944
  } | {
@@ -5579,7 +5954,7 @@ type LayerTreeItem = {
5579
5954
  * empty `layers` array, so that empty folders have a position in the panel and
5580
5955
  * can be reordered like any other row.
5581
5956
  */
5582
- type LayerPanelUnit = {
5957
+ export type LayerPanelUnit = {
5583
5958
  /** Group the block belongs to, or `null` for a lone ungrouped layer. */
5584
5959
  groupId: string | null;
5585
5960
  /** Member layers, top-first. Empty for a group with no layers under it. */
@@ -5617,12 +5992,12 @@ type LayerPanelUnit = {
5617
5992
  * @param groups Group definitions.
5618
5993
  * @returns Panel blocks in top-to-bottom display order.
5619
5994
  */
5620
- declare function buildLayerPanelUnits(layers: GeoLibreLayer[], groups: LayerGroup[]): LayerPanelUnit[];
5995
+ export declare function buildLayerPanelUnits(layers: GeoLibreLayer[], groups: LayerGroup[]): LayerPanelUnit[];
5621
5996
  /**
5622
5997
  * Where the layer panel should draw every group header, expressed against the
5623
5998
  * layer rows the panel already renders.
5624
5999
  */
5625
- type LayerPanelGroupHeaders = {
6000
+ export type LayerPanelGroupHeaders = {
5626
6001
  /** Headers drawn immediately above the keyed layer's row, in panel order. */
5627
6002
  aboveLayer: Map<string, LayerGroup[]>;
5628
6003
  /** Headers drawn below every layer row, in panel order. */
@@ -5647,7 +6022,7 @@ type LayerPanelGroupHeaders = {
5647
6022
  * @param groups Group definitions.
5648
6023
  * @returns The anchor layer (or the panel bottom) each header sits above.
5649
6024
  */
5650
- declare function layerPanelGroupHeaders(layers: GeoLibreLayer[], groups: LayerGroup[]): LayerPanelGroupHeaders;
6025
+ export declare function layerPanelGroupHeaders(layers: GeoLibreLayer[], groups: LayerGroup[]): LayerPanelGroupHeaders;
5651
6026
  /**
5652
6027
  * Derive the layer-panel tree from the flat `layers` array and the group
5653
6028
  * definitions.
@@ -5667,7 +6042,7 @@ declare function layerPanelGroupHeaders(layers: GeoLibreLayer[], groups: LayerGr
5667
6042
  * @param groups Group definitions.
5668
6043
  * @returns Panel rows in top-to-bottom display order.
5669
6044
  */
5670
- declare function buildLayerTree(layers: GeoLibreLayer[], groups: LayerGroup[]): LayerTreeItem[];
6045
+ export declare function buildLayerTree(layers: GeoLibreLayer[], groups: LayerGroup[]): LayerTreeItem[];
5671
6046
  /**
5672
6047
  * Fold each group's visibility and opacity into its child layers so the map
5673
6048
  * sync can keep treating every layer independently.
@@ -5682,7 +6057,7 @@ declare function buildLayerTree(layers: GeoLibreLayer[], groups: LayerGroup[]):
5682
6057
  * @param groups Group definitions.
5683
6058
  * @returns Layers with group effects applied.
5684
6059
  */
5685
- declare function applyGroupEffects(layers: GeoLibreLayer[], groups: LayerGroup[]): GeoLibreLayer[];
6060
+ export declare function applyGroupEffects(layers: GeoLibreLayer[], groups: LayerGroup[]): GeoLibreLayer[];
5686
6061
  /**
5687
6062
  * The single layer form of {@link applyGroupEffects}: the visibility and
5688
6063
  * opacity a layer should actually render at once its (possibly nested) parent
@@ -5701,7 +6076,7 @@ declare function applyGroupEffects(layers: GeoLibreLayer[], groups: LayerGroup[]
5701
6076
  * @returns The effective render state (the layer's own values when it is
5702
6077
  * ungrouped or its `groupId` is dangling).
5703
6078
  */
5704
- declare function effectiveLayerRenderState(layer: GeoLibreLayer, groups: LayerGroup[] | ReadonlyMap<string, LayerGroup>): {
6079
+ export declare function effectiveLayerRenderState(layer: GeoLibreLayer, groups: LayerGroup[] | ReadonlyMap<string, LayerGroup>): {
5705
6080
  visible: boolean;
5706
6081
  opacity: number;
5707
6082
  };
@@ -5712,7 +6087,7 @@ declare function effectiveLayerRenderState(layer: GeoLibreLayer, groups: LayerGr
5712
6087
  * @param groupId Group whose members to locate.
5713
6088
  * @returns Ascending list of member indices (empty when the group has none).
5714
6089
  */
5715
- declare function groupMemberIndices(layers: GeoLibreLayer[], groupId: string): number[];
6090
+ export declare function groupMemberIndices(layers: GeoLibreLayer[], groupId: string): number[];
5716
6091
  /**
5717
6092
  * Reorder `layers` so that every group's members form a single contiguous block,
5718
6093
  * preserving the relative order of layers within each group and of the
@@ -5726,7 +6101,7 @@ declare function groupMemberIndices(layers: GeoLibreLayer[], groupId: string): n
5726
6101
  * @param layers Flat layer list, possibly with interleaved group members.
5727
6102
  * @returns A new array with grouped layers made contiguous.
5728
6103
  */
5729
- declare function normalizeGroupContiguity(layers: GeoLibreLayer[]): GeoLibreLayer[];
6104
+ export declare function normalizeGroupContiguity(layers: GeoLibreLayer[]): GeoLibreLayer[];
5730
6105
  /**
5731
6106
  * How deeply a group is nested: 0 for a top-level folder, 1 for a child of one,
5732
6107
  * and so on. Drives the layer panel's indentation and keeps a parent ahead of
@@ -5738,7 +6113,7 @@ declare function normalizeGroupContiguity(layers: GeoLibreLayer[]): GeoLibreLaye
5738
6113
  * same set can pass a memoized map rather than rebuild one per call.
5739
6114
  * @returns The nesting depth.
5740
6115
  */
5741
- declare function layerGroupDepth(group: LayerGroup, groupById: ReadonlyMap<string, LayerGroup>): number;
6116
+ export declare function layerGroupDepth(group: LayerGroup, groupById: ReadonlyMap<string, LayerGroup>): number;
5742
6117
  /**
5743
6118
  * Move a group — with everything nested inside it — one block up or down among
5744
6119
  * its siblings, the groups sharing its parent.
@@ -5778,7 +6153,7 @@ declare function layerGroupDepth(group: LayerGroup, groupById: ReadonlyMap<strin
5778
6153
  * @returns The new arrays, or `null` when the group is already at that end of
5779
6154
  * the panel and nothing would change.
5780
6155
  */
5781
- declare function reorderLayerGroupInPanel(layers: GeoLibreLayer[], groups: LayerGroup[], id: string, direction: "up" | "down"): {
6156
+ export declare function reorderLayerGroupInPanel(layers: GeoLibreLayer[], groups: LayerGroup[], id: string, direction: "up" | "down"): {
5782
6157
  layers: GeoLibreLayer[];
5783
6158
  groups: LayerGroup[];
5784
6159
  } | null;
@@ -5790,7 +6165,7 @@ declare function reorderLayerGroupInPanel(layers: GeoLibreLayer[], groups: Layer
5790
6165
  * @param groups Group definitions.
5791
6166
  * @returns Per-group flags, keyed by group id.
5792
6167
  */
5793
- declare function layerGroupMoveability(layers: GeoLibreLayer[], groups: LayerGroup[]): Map<string, {
6168
+ export declare function layerGroupMoveability(layers: GeoLibreLayer[], groups: LayerGroup[]): Map<string, {
5794
6169
  up: boolean;
5795
6170
  down: boolean;
5796
6171
  }>;
@@ -5806,7 +6181,7 @@ declare function layerGroupMoveability(layers: GeoLibreLayer[], groups: LayerGro
5806
6181
  * @param value A decoded raster sample.
5807
6182
  * @returns The sample rendered for display.
5808
6183
  */
5809
- declare function formatPixelValue(value: number): string;
6184
+ export declare function formatPixelValue(value: number): string;
5810
6185
  //#endregion
5811
6186
  //#region src/storymap-sample.d.ts
5812
6187
  /**
@@ -5818,20 +6193,65 @@ declare function formatPixelValue(value: number): string;
5818
6193
  *
5819
6194
  * @returns A populated {@link StoryMap} with five sample chapters.
5820
6195
  */
5821
- declare function createSampleStoryMap(): StoryMap;
6196
+ export declare function createSampleStoryMap(): StoryMap;
6197
+ //#endregion
6198
+ //#region src/storymap-playback.d.ts
6199
+ /**
6200
+ * The opacity a story presentation has applied to a layer.
6201
+ *
6202
+ * @param opacities The store's `ui.storymapLayerOpacity` record.
6203
+ * @param layerId Store layer id.
6204
+ * @returns The recorded opacity in `[0, 1]`, or `1` when the presentation has
6205
+ * not touched the layer (or nothing is presenting).
6206
+ */
6207
+ export declare function storyLayerOpacityFactor(opacities: Record<string, number> | undefined, layerId: string): number;
6208
+ /**
6209
+ * A layer whose opacity reflects the story presentation's fade.
6210
+ *
6211
+ * A chapter's opacity *replaces* the layer's own opacity rather than scaling
6212
+ * it, matching `MapController.setStoryLayerOpacity`, which writes the chapter
6213
+ * value as the absolute paint opacity; otherwise a layer set to 0.7 in the
6214
+ * Layers panel and faded to 0.4 by a chapter would draw its diagrams at 0.28
6215
+ * while its MapLibre layers draw at 0.4.
6216
+ *
6217
+ * Returns the same object when the presentation has not touched the layer (or
6218
+ * recorded the opacity it already has), so identity-keyed caches downstream
6219
+ * keep hitting.
6220
+ *
6221
+ * @param layer Store layer.
6222
+ * @param opacities The store's `ui.storymapLayerOpacity` record.
6223
+ */
6224
+ export declare function applyStoryLayerOpacity(layer: GeoLibreLayer, opacities: Record<string, number> | undefined): GeoLibreLayer;
6225
+ /**
6226
+ * Whether a story presentation has faded a layer fully out.
6227
+ *
6228
+ * @param opacities The store's `ui.storymapLayerOpacity` record.
6229
+ * @param layerId Store layer id.
6230
+ */
6231
+ export declare function isStoryHiddenLayer(opacities: Record<string, number> | undefined, layerId: string): boolean;
6232
+ /**
6233
+ * The layers a reader can currently see during a story presentation: the
6234
+ * input minus those the active chapter has faded fully out. Outside a
6235
+ * presentation the input is returned as-is (same array identity).
6236
+ *
6237
+ * @param layers Store layers in panel order.
6238
+ * @param presenting The store's `ui.storymapPresenting` flag.
6239
+ * @param opacities The store's `ui.storymapLayerOpacity` record.
6240
+ */
6241
+ export declare function storyVisibleLayers(layers: GeoLibreLayer[], presenting: boolean, opacities: Record<string, number> | undefined): GeoLibreLayer[];
5822
6242
  //#endregion
5823
6243
  //#region src/layer-ref-scrub.d.ts
5824
6244
  /**
5825
6245
  * Filter out dashboard widgets whose `layerId` references a removed layer.
5826
6246
  * Returns the same array reference when nothing changes.
5827
6247
  */
5828
- declare function scrubWidgetsForRemovedLayers(widgets: DashboardWidget[], layerIds: string | Iterable<string>): DashboardWidget[];
6248
+ export declare function scrubWidgetsForRemovedLayers(widgets: DashboardWidget[], layerIds: string | Iterable<string>): DashboardWidget[];
5829
6249
  /**
5830
6250
  * Drop comments whose anchor is a feature on a removed layer.
5831
6251
  * Point-anchored comments are always kept.
5832
6252
  * Returns the same array reference when nothing changes.
5833
6253
  */
5834
- declare function scrubCommentsForRemovedLayers(comments: ProjectComment[], layerIds: string | Iterable<string>): ProjectComment[];
6254
+ export declare function scrubCommentsForRemovedLayers(comments: ProjectComment[], layerIds: string | Iterable<string>): ProjectComment[];
5835
6255
  /**
5836
6256
  * Scrub legend config of references to removed layers:
5837
6257
  * - `order`: filter out removed layer ids
@@ -5841,7 +6261,7 @@ declare function scrubCommentsForRemovedLayers(comments: ProjectComment[], layer
5841
6261
  *
5842
6262
  * Returns the same reference when nothing changes.
5843
6263
  */
5844
- declare function scrubLegendForRemovedLayers(legend: LegendConfig, layerIds: string | Iterable<string>): LegendConfig;
6264
+ export declare function scrubLegendForRemovedLayers(legend: LegendConfig, layerIds: string | Iterable<string>): LegendConfig;
5845
6265
  //#endregion
5846
6266
  //#region src/storymap-io.d.ts
5847
6267
  /**
@@ -5850,7 +6270,7 @@ declare function scrubLegendForRemovedLayers(legend: LegendConfig, layerIds: str
5850
6270
  * @param storymap The story map to serialize.
5851
6271
  * @returns A JSON string (settings and chapters).
5852
6272
  */
5853
- declare function serializeStoryMapJson(storymap: StoryMap): string;
6273
+ export declare function serializeStoryMapJson(storymap: StoryMap): string;
5854
6274
  /**
5855
6275
  * Parse a story map from JSON authored outside GeoLibre.
5856
6276
  *
@@ -5862,7 +6282,7 @@ declare function serializeStoryMapJson(storymap: StoryMap): string;
5862
6282
  * @returns A normalized story map.
5863
6283
  * @throws If the JSON is invalid or contains no usable chapters.
5864
6284
  */
5865
- declare function parseStoryMapJson(text: string): StoryMap;
6285
+ export declare function parseStoryMapJson(text: string): StoryMap;
5866
6286
  /**
5867
6287
  * Serialize a story map's chapters to CSV (one row per chapter).
5868
6288
  *
@@ -5872,7 +6292,7 @@ declare function parseStoryMapJson(text: string): StoryMap;
5872
6292
  * @param storymap The story map whose chapters to serialize.
5873
6293
  * @returns A CSV string with a header row.
5874
6294
  */
5875
- declare function serializeStoryMapCsv(storymap: StoryMap): string;
6295
+ export declare function serializeStoryMapCsv(storymap: StoryMap): string;
5876
6296
  /**
5877
6297
  * Parse chapters from a CSV authored outside GeoLibre.
5878
6298
  *
@@ -5886,7 +6306,7 @@ declare function serializeStoryMapCsv(storymap: StoryMap): string;
5886
6306
  * @returns A normalized story map.
5887
6307
  * @throws If the CSV has no data rows or no valid chapters.
5888
6308
  */
5889
- declare function parseStoryMapCsv(text: string, base?: StoryMap | null): StoryMap;
6309
+ export declare function parseStoryMapCsv(text: string, base?: StoryMap | null): StoryMap;
5890
6310
  //#endregion
5891
6311
  //#region src/store.d.ts
5892
6312
  type ConversionToolKind = "vector-to-vector" | "vector-to-geoparquet" | "vector-to-flatgeobuf" | "vector-to-shapefile" | "vector-to-geopackage" | "csv-to-geoparquet" | "vector-to-pmtiles" | "raster-to-pmtiles" | "raster-to-cog";
@@ -5985,6 +6405,14 @@ interface AppState {
5985
6405
  secondaryMapViews: SecondaryMapView[];
5986
6406
  /** User-entered label for the primary pane (shown only in multi-map mode). */
5987
6407
  primaryMapLabel: string;
6408
+ /**
6409
+ * Which engine draws the primary map area (issue #2217): the 2D MapLibre map
6410
+ * or the 3D Cesium globe. Both render the same store state, so switching
6411
+ * keeps the camera, basemap, layers, groups, visibility, and opacity — it
6412
+ * only changes what draws them. Independent of `mapLayout`: switching never
6413
+ * adds or removes panes.
6414
+ */
6415
+ primaryRenderer: MapRendererKind;
5988
6416
  selectedLayerId: string | null;
5989
6417
  selectedFeatureId: string | null;
5990
6418
  /**
@@ -6072,6 +6500,15 @@ interface AppState {
6072
6500
  storymapPanelOpen: boolean;
6073
6501
  storymapPresenting: boolean;
6074
6502
  storymapReturnToEditor: boolean;
6503
+ /**
6504
+ * Layer opacities the active story presentation has applied so far, keyed
6505
+ * by store layer id. Playback fades layers by writing MapLibre paint
6506
+ * properties directly (never the persisted `layers[].opacity`), so this is
6507
+ * how renderers outside MapLibre's paint model (deck.gl diagrams, 3D
6508
+ * Z-value geometry) and the on-map Legend follow a chapter's fades. Empty
6509
+ * while not presenting; never saved with the project.
6510
+ */
6511
+ storymapLayerOpacity: Record<string, number>;
6075
6512
  storymapComposingId: string | null;
6076
6513
  /** The Batch tools dialog (run one tool across many layers). */
6077
6514
  batchToolsOpen: boolean;
@@ -6127,6 +6564,12 @@ interface AppState {
6127
6564
  setSecondaryLayerVisibility: (id: string, layerId: string, visible: boolean) => void;
6128
6565
  /** Set the primary pane's custom label. */
6129
6566
  setPrimaryMapLabel: (label: string) => void;
6567
+ /**
6568
+ * Switch the primary map area between the 2D map and the 3D globe (no-op if
6569
+ * unchanged). Touches nothing else in the store, so the shared camera, layer,
6570
+ * and basemap state carries straight across the swap.
6571
+ */
6572
+ setPrimaryRenderer: (renderer: MapRendererKind) => void;
6130
6573
  /** Set one secondary pane's custom label (no-op if the id is unknown). */
6131
6574
  setSecondaryMapLabel: (id: string, label: string) => void;
6132
6575
  /**
@@ -6192,6 +6635,11 @@ interface AppState {
6192
6635
  setDashboardOpen: (open: boolean) => void;
6193
6636
  setStorymapPanelOpen: (open: boolean) => void;
6194
6637
  setStorymapPresenting: (presenting: boolean, returnToEditor?: boolean) => void;
6638
+ /**
6639
+ * Record the layer opacities a story chapter applied, merging into the
6640
+ * presentation's running map (see `ui.storymapLayerOpacity`).
6641
+ */
6642
+ setStorymapLayerOpacity: (changes: Record<string, number>) => void;
6195
6643
  setStorymapComposing: (chapterId: string | null) => void;
6196
6644
  setBatchToolsOpen: (open: boolean) => void;
6197
6645
  setModelBuilderOpen: (open: boolean) => void;
@@ -6385,6 +6833,8 @@ interface AppState {
6385
6833
  * array to remove every control.
6386
6834
  */
6387
6835
  setLayerQuickFilters: (id: string, filters: LayerQuickFilter[]) => void;
6836
+ /** Set or clear the project-persisted expression filter for a layer. */
6837
+ setLayerFilterExpression: (id: string, expression: unknown[] | null) => void;
6388
6838
  reorderLayer: (id: string, direction: "up" | "down") => void;
6389
6839
  moveLayer: (id: string, targetIndex: number) => void;
6390
6840
  moveLayersRelative: (layerIds: string[], targetLayerId: string, position: "above" | "below") => void;
@@ -6448,27 +6898,27 @@ interface AppState {
6448
6898
  setComments: (comments: ProjectComment[]) => void;
6449
6899
  }
6450
6900
  /** Reserved Identify target for querying every visible queryable layer at once. */
6451
- declare const IDENTIFY_ALL_LAYERS_ID = "__geolibre_identify_all_layers__";
6901
+ export declare const IDENTIFY_ALL_LAYERS_ID = "__geolibre_identify_all_layers__";
6452
6902
  /**
6453
6903
  * A fresh, inactive collaboration slice (no live session). Frozen (like
6454
6904
  * DEFAULT_LEGEND_CONFIG) to guard against accidental in-place mutation; store
6455
6905
  * actions always produce new objects via spread, so the frozen default is only
6456
6906
  * ever read.
6457
6907
  */
6458
- declare const DEFAULT_COLLABORATION_STATE: CollaborationState;
6908
+ export declare const DEFAULT_COLLABORATION_STATE: CollaborationState;
6459
6909
  /** Derive a human-friendly display name from a file path or URL. */
6460
- declare function projectPathLabel(path: string): string;
6461
- declare function subscribeProjectRestoreHistory(listener: () => void): () => void;
6462
- declare function canUndoProjectRestore(): boolean;
6463
- declare function canRedoProjectRestore(): boolean;
6910
+ export declare function projectPathLabel(path: string): string;
6911
+ export declare function subscribeProjectRestoreHistory(listener: () => void): () => void;
6912
+ export declare function canUndoProjectRestore(): boolean;
6913
+ export declare function canRedoProjectRestore(): boolean;
6464
6914
  /**
6465
6915
  * Register a whole-project restore as one undoable operation. The regular
6466
6916
  * temporal history intentionally tracks only editing fields, while restoring a
6467
6917
  * history snapshot also changes project metadata, camera, plugins, and other
6468
6918
  * serialized state, so it needs a full canonical project pair.
6469
6919
  */
6470
- declare function registerProjectRestoreHistory(before: GeoLibreProject, beforePath: string | null, after: GeoLibreProject, afterPath?: string | null): void;
6471
- declare const useAppStore: import("zustand").UseBoundStore<Omit<import("zustand").StoreApi<AppState>, "temporal"> & {
6920
+ export declare function registerProjectRestoreHistory(before: GeoLibreProject, beforePath: string | null, after: GeoLibreProject, afterPath?: string | null): void;
6921
+ export declare const useAppStore: import("zustand").UseBoundStore<Omit<import("zustand").StoreApi<AppState>, "temporal"> & {
6472
6922
  temporal: import("zustand").StoreApi<import("zundo").TemporalState<{
6473
6923
  layers: GeoLibreLayer[];
6474
6924
  layerGroups: LayerGroup[];
@@ -6486,27 +6936,27 @@ declare const useAppStore: import("zustand").UseBoundStore<Omit<import("zustand"
6486
6936
  * `layers`/basemap refs drive MapCanvas's existing effects, so the map
6487
6937
  * reconciles through MapController.syncLayers (never mutated directly here).
6488
6938
  */
6489
- declare function undo(): void;
6939
+ export declare function undo(): void;
6490
6940
  /** Step the history forward one entry and mark the project dirty. */
6491
- declare function redo(): void;
6941
+ export declare function redo(): void;
6492
6942
  /** Empty both the undo and redo stacks (e.g. on new/loaded project). */
6493
- declare function clearHistory(): void;
6943
+ export declare function clearHistory(): void;
6494
6944
  /**
6495
6945
  * React hook for consuming application capability state for a specific privilege.
6496
6946
  *
6497
6947
  * @param privilege - The privilege to check.
6498
6948
  * @returns `{ granted: boolean, reason?: string }`
6499
6949
  */
6500
- declare function useAppCapability(privilege: AppPrivilege): {
6950
+ export declare function useAppCapability(privilege: AppPrivilege): {
6501
6951
  granted: boolean;
6502
6952
  reason?: string;
6503
6953
  };
6504
6954
  //#endregion
6505
6955
  //#region src/history.d.ts
6506
- declare function setHistoryCoalesceMs(ms: number): void;
6507
- declare function getHistoryCoalesceMs(): number;
6508
- declare function setMaxHistoryFeatureCount(count: number): void;
6509
- declare function getMaxHistoryFeatureCount(): number;
6956
+ export declare function setHistoryCoalesceMs(ms: number): void;
6957
+ export declare function getHistoryCoalesceMs(): number;
6958
+ export declare function setMaxHistoryFeatureCount(count: number): void;
6959
+ export declare function getMaxHistoryFeatureCount(): number;
6510
6960
  /** Structural shape of a partialized undo snapshot, for size accounting. */
6511
6961
  interface HistorySnapshot {
6512
6962
  layers?: {
@@ -6531,7 +6981,7 @@ interface HistorySnapshot {
6531
6981
  * Returns the original array when nothing needs trimming, or a trimmed slice
6532
6982
  * (oldest entries removed) otherwise. Pure: never mutates its input.
6533
6983
  */
6534
- declare function trimHistoryBySize<T extends HistorySnapshot>(pastStates: T[], maxFeatures: number): T[];
6984
+ export declare function trimHistoryBySize<T extends HistorySnapshot>(pastStates: T[], maxFeatures: number): T[];
6535
6985
  //#endregion
6536
6986
  //#region src/geocoding.d.ts
6537
6987
  /**
@@ -6562,14 +7012,14 @@ declare function trimHistoryBySize<T extends HistorySnapshot>(pastStates: T[], m
6562
7012
  * via {@link setGeocodingFetch} — see the note there. See
6563
7013
  * docs/user-guide/data-integrations.md#geocoding.
6564
7014
  */
6565
- declare const DEFAULT_FORWARD_GEOCODE_ENDPOINT = "https://nominatim.openstreetmap.org/search";
6566
- declare const DEFAULT_REVERSE_GEOCODE_ENDPOINT = "https://nominatim.openstreetmap.org/reverse";
7015
+ export declare const DEFAULT_FORWARD_GEOCODE_ENDPOINT = "https://nominatim.openstreetmap.org/search";
7016
+ export declare const DEFAULT_REVERSE_GEOCODE_ENDPOINT = "https://nominatim.openstreetmap.org/reverse";
6567
7017
  /** Host whose public usage policy (1 req/sec, bulk limits) we must respect. */
6568
- declare const NOMINATIM_PUBLIC_HOST = "nominatim.openstreetmap.org";
7018
+ export declare const NOMINATIM_PUBLIC_HOST = "nominatim.openstreetmap.org";
6569
7019
  /** Minimum spacing between requests to the public Nominatim endpoint. */
6570
- declare const NOMINATIM_MIN_INTERVAL_MS = 1100;
7020
+ export declare const NOMINATIM_MIN_INTERVAL_MS = 1100;
6571
7021
  /** Host of the free, unkeyed public CartoCiudad geocoder (IGN/CNIG). */
6572
- declare const CARTOCIUDAD_PUBLIC_HOST = "cartociudad.es";
7022
+ export declare const CARTOCIUDAD_PUBLIC_HOST = "cartociudad.es";
6573
7023
  /**
6574
7024
  * Courtesy spacing (~5 req/sec) between requests to the public CartoCiudad
6575
7025
  * endpoint. Unlike {@link NOMINATIM_MIN_INTERVAL_MS} this is not a published
@@ -6577,22 +7027,22 @@ declare const CARTOCIUDAD_PUBLIC_HOST = "cartociudad.es";
6577
7027
  * a large batch does not burst at a free public government service. See
6578
7028
  * {@link geocoderMinIntervalMs}.
6579
7029
  */
6580
- declare const CARTOCIUDAD_MIN_INTERVAL_MS = 200;
7030
+ export declare const CARTOCIUDAD_MIN_INTERVAL_MS = 200;
6581
7031
  /** Max rows a single batch run will geocode against the public endpoint. */
6582
- declare const PUBLIC_GEOCODE_ROW_CAP = 1000;
7032
+ export declare const PUBLIC_GEOCODE_ROW_CAP = 1000;
6583
7033
  /** Property keys added to each geocoded feature. */
6584
- declare const GEOCODE_LAT_KEY = "geocode_lat";
6585
- declare const GEOCODE_LON_KEY = "geocode_lon";
6586
- declare const GEOCODE_DISPLAY_NAME_KEY = "geocode_display_name";
6587
- declare const GEOCODE_SCORE_KEY = "geocode_importance";
7034
+ export declare const GEOCODE_LAT_KEY = "geocode_lat";
7035
+ export declare const GEOCODE_LON_KEY = "geocode_lon";
7036
+ export declare const GEOCODE_DISPLAY_NAME_KEY = "geocode_display_name";
7037
+ export declare const GEOCODE_SCORE_KEY = "geocode_importance";
6588
7038
  /** Provider id that produced (or failed to produce) a match, when stamped. */
6589
- declare const GEOCODE_PROVIDER_KEY = "geocode_provider";
7039
+ export declare const GEOCODE_PROVIDER_KEY = "geocode_provider";
6590
7040
  /** Whether a row matched, when stamped. See {@link GeocodeStatus}. */
6591
- declare const GEOCODE_STATUS_KEY = "geocode_status";
7041
+ export declare const GEOCODE_STATUS_KEY = "geocode_status";
6592
7042
  /** Identifier of a selectable geocoding backend. */
6593
7043
  type GeocodingProviderId = "nominatim" | "pelias" | "arcgis" | "mapbox" | "google" | "cartociudad";
6594
7044
  /** The provider used when none is configured. */
6595
- declare const DEFAULT_GEOCODING_PROVIDER_ID: GeocodingProviderId;
7045
+ export declare const DEFAULT_GEOCODING_PROVIDER_ID: GeocodingProviderId;
6596
7046
  interface GeocoderConfig {
6597
7047
  /** Which backend to dispatch through. */
6598
7048
  providerId: GeocodingProviderId;
@@ -6703,12 +7153,12 @@ interface ReverseGeocodeDisplay {
6703
7153
  /** Whether a row matched during batch geocoding, stamped as {@link GEOCODE_STATUS_KEY}. */
6704
7154
  type GeocodeStatus = "matched" | "unmatched";
6705
7155
  /** Build a Nominatim forward-geocoding URL (jsonv2, address details on). */
6706
- declare function buildForwardGeocodeUrl(endpoint: string, query: string, options?: {
7156
+ export declare function buildForwardGeocodeUrl(endpoint: string, query: string, options?: {
6707
7157
  email?: string;
6708
7158
  limit?: number;
6709
7159
  }): string;
6710
7160
  /** Build a Nominatim reverse-geocoding URL (jsonv2, address details on). */
6711
- declare function buildReverseGeocodeUrl(endpoint: string, lon: number, lat: number, options?: {
7161
+ export declare function buildReverseGeocodeUrl(endpoint: string, lon: number, lat: number, options?: {
6712
7162
  email?: string;
6713
7163
  zoom?: number;
6714
7164
  }): string;
@@ -6724,7 +7174,7 @@ declare function buildReverseGeocodeUrl(endpoint: string, lon: number, lat: numb
6724
7174
  * `geocode_status: "matched"` (dropped when omitted, so the existing
6725
7175
  * `GeocodeDialog` call site keeps its current output unchanged).
6726
7176
  */
6727
- declare function geocodeMatchToFeature(match: GeocodeMatch, originalRow?: Record<string, string>, extra?: {
7177
+ export declare function geocodeMatchToFeature(match: GeocodeMatch, originalRow?: Record<string, string>, extra?: {
6728
7178
  providerId?: GeocodingProviderId;
6729
7179
  }): Feature<Point> | null;
6730
7180
  /**
@@ -6735,25 +7185,25 @@ declare function geocodeMatchToFeature(match: GeocodeMatch, originalRow?: Record
6735
7185
  * `geocode_provider`, de-duplicated against the original columns the same way
6736
7186
  * {@link geocodeMatchToFeature} does.
6737
7187
  */
6738
- declare function unmatchedGeocodeFeature(originalRow: Record<string, string>, providerId: GeocodingProviderId): Feature<null>;
7188
+ export declare function unmatchedGeocodeFeature(originalRow: Record<string, string>, providerId: GeocodingProviderId): Feature<null>;
6739
7189
  /**
6740
7190
  * Convert a Nominatim forward result into a point Feature. Retained as a thin
6741
7191
  * wrapper over {@link geocodeMatchToFeature} for callers and tests that work
6742
7192
  * directly with Nominatim results. Returns null when the result has no finite
6743
7193
  * coordinates.
6744
7194
  */
6745
- declare function nominatimResultToFeature(result: NominatimForwardResult, originalRow?: Record<string, string>): Feature<Point> | null;
7195
+ export declare function nominatimResultToFeature(result: NominatimForwardResult, originalRow?: Record<string, string>): Feature<Point> | null;
6746
7196
  /**
6747
7197
  * Resolve a Nominatim reverse result to a display string and address parts, or
6748
7198
  * null when the point could not be reverse-geocoded.
6749
7199
  */
6750
- declare function nominatimReverseResultToDisplay(result: NominatimReverseResult | null): ReverseGeocodeDisplay | null;
7200
+ export declare function nominatimReverseResultToDisplay(result: NominatimReverseResult | null): ReverseGeocodeDisplay | null;
6751
7201
  /** All selectable geocoding providers, Nominatim first (the default). */
6752
- declare const GEOCODING_PROVIDERS: readonly GeocodingProvider[];
7202
+ export declare const GEOCODING_PROVIDERS: readonly GeocodingProvider[];
6753
7203
  /** Coerce an arbitrary string to a known provider id, defaulting to Nominatim. */
6754
- declare function normalizeGeocodingProviderId(value: string | undefined | null): GeocodingProviderId;
7204
+ export declare function normalizeGeocodingProviderId(value: string | undefined | null): GeocodingProviderId;
6755
7205
  /** Look up a provider by id, falling back to Nominatim for unknown ids. */
6756
- declare function getGeocodingProvider(id: string | undefined | null): GeocodingProvider;
7206
+ export declare function getGeocodingProvider(id: string | undefined | null): GeocodingProvider;
6757
7207
  /**
6758
7208
  * Resolve the geocoder configuration from runtime env, falling back to the
6759
7209
  * selected provider's default endpoints. `VITE_GEOCODER_PROVIDER` selects the
@@ -6761,7 +7211,7 @@ declare function getGeocodingProvider(id: string | undefined | null): GeocodingP
6761
7211
  * the endpoints; `VITE_GEOCODER_EMAIL` supplies the contact email; and
6762
7212
  * `VITE_GEOCODER_API_KEY` supplies the API key for keyed providers.
6763
7213
  */
6764
- declare function getGeocoderConfig(): GeocoderConfig;
7214
+ export declare function getGeocoderConfig(): GeocoderConfig;
6765
7215
  /** Inputs to {@link resolveGeocoderConfig}, mirroring the project preference. */
6766
7216
  interface GeocodingPreferenceInput {
6767
7217
  providerId?: string;
@@ -6778,7 +7228,7 @@ interface GeocodingPreferenceInput {
6778
7228
  * the geocode dialog so a per-run provider choice resolves the right endpoints
6779
7229
  * and API key without round-tripping through runtime env.
6780
7230
  */
6781
- declare function resolveGeocoderConfig(input: GeocodingPreferenceInput): GeocoderConfig;
7231
+ export declare function resolveGeocoderConfig(input: GeocodingPreferenceInput): GeocoderConfig;
6782
7232
  /**
6783
7233
  * Whether requests to `endpoint` must be throttled AND row-capped. True for the
6784
7234
  * public Nominatim host (its usage policy applies) and, defensively, for any
@@ -6789,7 +7239,7 @@ declare function resolveGeocoderConfig(input: GeocodingPreferenceInput): Geocode
6789
7239
  * see {@link geocoderMinIntervalMs}, which paces CartoCiudad more gently
6790
7240
  * without capping its row count.
6791
7241
  */
6792
- declare function shouldThrottle(endpoint: string): boolean;
7242
+ export declare function shouldThrottle(endpoint: string): boolean;
6793
7243
  /**
6794
7244
  * The row cap to apply for `endpoint`: a finite cap for the public Nominatim
6795
7245
  * host, else Infinity. CartoCiudad is uncapped — IGN publishes no row limit and
@@ -6797,7 +7247,7 @@ declare function shouldThrottle(endpoint: string): boolean;
6797
7247
  * cap here would be an invented constraint. It is still paced; see
6798
7248
  * {@link geocoderMinIntervalMs}.
6799
7249
  */
6800
- declare function rowCap(endpoint: string): number;
7250
+ export declare function rowCap(endpoint: string): number;
6801
7251
  /**
6802
7252
  * Minimum spacing (ms) between requests for `endpoint`. Gated on the hostname,
6803
7253
  * not the selected provider, so pointing any provider at the public Nominatim
@@ -6812,28 +7262,28 @@ declare function rowCap(endpoint: string): number;
6812
7262
  * not borrowed here. Keyed providers and self-hosted endpoints are paced by
6813
7263
  * their own quotas, not by us.
6814
7264
  */
6815
- declare function geocoderMinIntervalMs(endpoint: string): number;
7265
+ export declare function geocoderMinIntervalMs(endpoint: string): number;
6816
7266
  /**
6817
7267
  * Whether `config` cannot geocode without an API key. True for the keyed
6818
7268
  * providers (ArcGIS, Mapbox, Google) and for Pelias only when it targets the
6819
7269
  * hosted geocode.earth endpoint (a self-hosted Pelias needs no key). Drives the
6820
7270
  * batch dialog's "missing key" warning and disabled run.
6821
7271
  */
6822
- declare function geocoderNeedsApiKey(config: GeocoderConfig): boolean;
7272
+ export declare function geocoderNeedsApiKey(config: GeocoderConfig): boolean;
6823
7273
  /**
6824
7274
  * Milliseconds to wait before starting the next request so consecutive
6825
7275
  * requests are spaced at least `intervalMs` apart, measured from the previous
6826
7276
  * request's start time (not its completion) so a slow network does not double
6827
7277
  * the wait. Returns 0 for the first request or when enough time has elapsed.
6828
7278
  */
6829
- declare function nextDelayMs(lastStartedAt: number | null, now: number, intervalMs: number): number;
7279
+ export declare function nextDelayMs(lastStartedAt: number | null, now: number, intervalMs: number): number;
6830
7280
  /**
6831
7281
  * Build geocoding requests from parsed CSV rows. The address for each row is
6832
7282
  * the selected columns trimmed and joined with ", " (so multi-part addresses
6833
7283
  * like street/city/country can be combined). Rows whose composed address is
6834
7284
  * empty are skipped.
6835
7285
  */
6836
- declare function csvRowsToGeocodeRequests(rows: Record<string, string>[], addressColumns: string[]): GeocodeRequest[];
7286
+ export declare function csvRowsToGeocodeRequests(rows: Record<string, string>[], addressColumns: string[]): GeocodeRequest[];
6837
7287
  /**
6838
7288
  * Override the fetch used for geocoding requests, or pass null to restore the
6839
7289
  * global browser `fetch`.
@@ -6850,12 +7300,12 @@ declare function csvRowsToGeocodeRequests(rows: Record<string, string>[], addres
6850
7300
  *
6851
7301
  * Safe to call multiple times; only the most recent implementation is used.
6852
7302
  */
6853
- declare function setGeocodingFetch(fetchImpl: typeof globalThis.fetch | null): void;
7303
+ export declare function setGeocodingFetch(fetchImpl: typeof globalThis.fetch | null): void;
6854
7304
  /**
6855
7305
  * Forward-geocode a single query through the configured provider, returning
6856
7306
  * normalized matches.
6857
7307
  */
6858
- declare function geocodeForward(query: string, options?: {
7308
+ export declare function geocodeForward(query: string, options?: {
6859
7309
  signal?: AbortSignal;
6860
7310
  config?: GeocoderConfig;
6861
7311
  limit?: number;
@@ -6864,7 +7314,7 @@ declare function geocodeForward(query: string, options?: {
6864
7314
  * Reverse-geocode a single point ([lon, lat]) through the configured provider,
6865
7315
  * returning a normalized display result or null when no address was found.
6866
7316
  */
6867
- declare function geocodeReverse(lon: number, lat: number, options?: {
7317
+ export declare function geocodeReverse(lon: number, lat: number, options?: {
6868
7318
  signal?: AbortSignal;
6869
7319
  config?: GeocoderConfig;
6870
7320
  zoom?: number;
@@ -6893,14 +7343,14 @@ declare function geocodeReverse(lon: number, lat: number, options?: {
6893
7343
  *
6894
7344
  * @returns The build-time environment record.
6895
7345
  */
6896
- declare function getBuildEnvironment(): Record<string, string | undefined>;
7346
+ export declare function getBuildEnvironment(): Record<string, string | undefined>;
6897
7347
  /**
6898
7348
  * Merges build-time env with project runtime env (the latter wins). Falls back
6899
7349
  * to build-time env alone outside a browser (e.g. in tests).
6900
7350
  *
6901
7351
  * @returns The resolved environment variables.
6902
7352
  */
6903
- declare function getRuntimeEnvironment(): Record<string, string | undefined>;
7353
+ export declare function getRuntimeEnvironment(): Record<string, string | undefined>;
6904
7354
  /**
6905
7355
  * Resolves a local DuckDB spatial extension path from the runtime environment.
6906
7356
  *
@@ -6915,7 +7365,7 @@ declare function getRuntimeEnvironment(): Record<string, string | undefined>;
6915
7365
  * injectable for testing.
6916
7366
  * @returns The trimmed extension path, or undefined when unset.
6917
7367
  */
6918
- declare function getSpatialExtensionPath(env?: Record<string, string | undefined>): string | undefined;
7368
+ export declare function getSpatialExtensionPath(env?: Record<string, string | undefined>): string | undefined;
6919
7369
  /**
6920
7370
  * Resolves the Protomaps API key from the runtime environment.
6921
7371
  *
@@ -6928,7 +7378,7 @@ declare function getSpatialExtensionPath(env?: Record<string, string | undefined
6928
7378
  * injectable for testing.
6929
7379
  * @returns The trimmed API key, or undefined when unset.
6930
7380
  */
6931
- declare function getProtomapsApiKey(env?: Record<string, string | undefined>): string | undefined;
7381
+ export declare function getProtomapsApiKey(env?: Record<string, string | undefined>): string | undefined;
6932
7382
  /**
6933
7383
  * Resolves the Google Maps API key from the runtime environment.
6934
7384
  *
@@ -6944,7 +7394,7 @@ declare function getProtomapsApiKey(env?: Record<string, string | undefined>): s
6944
7394
  * injectable for testing.
6945
7395
  * @returns The trimmed API key, or undefined when unset.
6946
7396
  */
6947
- declare function getGoogleMapsApiKey(env?: Record<string, string | undefined>): string | undefined;
7397
+ export declare function getGoogleMapsApiKey(env?: Record<string, string | undefined>): string | undefined;
6948
7398
  /**
6949
7399
  * Resolves the Mapbox access token from the runtime environment.
6950
7400
  *
@@ -6969,7 +7419,7 @@ declare function getGoogleMapsApiKey(env?: Record<string, string | undefined>):
6969
7419
  * injectable for testing.
6970
7420
  * @returns The trimmed token, or undefined when unset.
6971
7421
  */
6972
- declare function getMapboxAccessToken(env?: Record<string, string | undefined>): string | undefined;
7422
+ export declare function getMapboxAccessToken(env?: Record<string, string | undefined>): string | undefined;
6973
7423
  /**
6974
7424
  * Resolves the Cesium Ion access token from the runtime environment.
6975
7425
  *
@@ -6990,7 +7440,7 @@ declare function getMapboxAccessToken(env?: Record<string, string | undefined>):
6990
7440
  * injectable for testing.
6991
7441
  * @returns The trimmed token, or undefined when unset.
6992
7442
  */
6993
- declare function getCesiumIonToken(env?: Record<string, string | undefined>): string | undefined;
7443
+ export declare function getCesiumIonToken(env?: Record<string, string | undefined>): string | undefined;
6994
7444
  /**
6995
7445
  * Builds a full Protomaps v5 style URL for a flavor, injecting the API key.
6996
7446
  *
@@ -7000,7 +7450,7 @@ declare function getCesiumIonToken(env?: Record<string, string | undefined>): st
7000
7450
  * injectable for testing.
7001
7451
  * @returns The resolved style URL, or undefined when no API key is configured.
7002
7452
  */
7003
- declare function getProtomapsStyleUrl(flavor: string, env?: Record<string, string | undefined>): string | undefined;
7453
+ export declare function getProtomapsStyleUrl(flavor: string, env?: Record<string, string | undefined>): string | undefined;
7004
7454
  //#endregion
7005
7455
  //#region src/platform.d.ts
7006
7456
  /**
@@ -7025,22 +7475,128 @@ declare function getProtomapsStyleUrl(flavor: string, env?: Record<string, strin
7025
7475
  * runtime does not provide it (Node exposes a `navigator` without it).
7026
7476
  * @returns True when the UA claims macOS but the device reports multi-touch.
7027
7477
  */
7028
- declare function isIpadDesktopUserAgent(userAgent: string, maxTouchPoints: number | undefined): boolean;
7478
+ export declare function isIpadDesktopUserAgent(userAgent: string, maxTouchPoints: number | undefined): boolean;
7479
+ //#endregion
7480
+ //#region src/cesium-ion.d.ts
7481
+ /** `metadata.sourceKind` of a layer that references a Cesium Ion asset. */
7482
+ export declare const CESIUM_ION_SOURCE_KIND = "cesium-ion";
7483
+ /** What an Ion asset id resolves to on the globe. */
7484
+ type CesiumIonAssetKind = "3d-tiles" | "imagery";
7485
+ /** Cesium OSM Buildings, the one-click 3D Tiles asset every Ion account can use. */
7486
+ export declare const CESIUM_OSM_BUILDINGS_ASSET_ID = 96188;
7487
+ /** Bing Maps Aerial through Ion, the imagery asset every Ion account can use. */
7488
+ export declare const CESIUM_BING_AERIAL_ASSET_ID = 2;
7489
+ /** Ion assets offered as one-click picks in the Add Data dialog. */
7490
+ export declare const CESIUM_ION_QUICK_PICKS: ReadonlyArray<{
7491
+ assetId: number;
7492
+ kind: CesiumIonAssetKind;
7493
+ name: string;
7494
+ }>;
7495
+ /** Parse an Ion asset id the way the Add Data form and the project file carry it. */
7496
+ export declare function parseCesiumIonAssetId(value: unknown): number | null;
7497
+ /**
7498
+ * The Ion asset id a layer references, or null when the layer is not an Ion
7499
+ * asset layer (or carries no usable id).
7500
+ */
7501
+ export declare function cesiumIonAssetId(layer: Pick<GeoLibreLayer, "source" | "metadata">): number | null;
7502
+ /** Whether `layer` references a Cesium Ion asset. */
7503
+ export declare function isCesiumIonLayer(layer: Pick<GeoLibreLayer, "source" | "metadata">): boolean;
7504
+ /** What the Ion asset draws as: a tileset primitive or an imagery layer. */
7505
+ export declare function cesiumIonAssetKind(layer: Pick<GeoLibreLayer, "type">): CesiumIonAssetKind;
7506
+ /**
7507
+ * Whether only the 3D globe can render `layer`: the mirror of the globe's
7508
+ * `isCesiumSupportedLayerType`, for the Layers panel to badge on the 2D map.
7509
+ */
7510
+ export declare function isCesiumOnlyLayer(layer: Pick<GeoLibreLayer, "source" | "metadata">): boolean;
7511
+ interface CesiumIonLayerOptions {
7512
+ id?: string;
7513
+ name: string;
7514
+ assetId: number;
7515
+ kind: CesiumIonAssetKind;
7516
+ /** Metres to shift a tileset vertically; ignored for imagery. */
7517
+ altitudeOffset?: number;
7518
+ }
7519
+ /**
7520
+ * Build the store layer for a Cesium Ion asset. A tileset is a `3d-tiles`
7521
+ * layer whose `sourceKind` keeps it out of the 2D deck.gl control; imagery is
7522
+ * a `raster` layer with no tiles, marked external so the 2D sync leaves it
7523
+ * alone. Both persist only the asset id: the token is runtime configuration.
7524
+ */
7525
+ export declare function createCesiumIonLayer(options: CesiumIonLayerOptions): GeoLibreLayer;
7526
+ //#endregion
7527
+ //#region src/czml.d.ts
7528
+ /**
7529
+ * CZML (Cesium Language) domain models and layer authoring (issue #2290).
7530
+ *
7531
+ * CZML is a JSON-based format for describing dynamic, time-varying 3D geospatial
7532
+ * scenes on the Cesium globe (trajectories, satellites, vehicles, sensor
7533
+ * networks, moving entities with orientations and paths). The globe loads CZML
7534
+ * natively through `CzmlDataSource`; the 2D map has no equivalent, so CZML
7535
+ * layers are badged "3D only" there.
7536
+ */
7537
+ /** `metadata.sourceKind` of a layer that carries or references CZML data. */
7538
+ export declare const CZML_SOURCE_KIND = "czml";
7539
+ /** One CZML packet in a document stream. */
7540
+ type CzmlPacket = Record<string, unknown>;
7541
+ /** A CZML document represented as an array of packets. */
7542
+ type CzmlDocument = CzmlPacket[];
7543
+ /** One-click CZML samples offered in the Add Data dialog. */
7544
+ export declare const CZML_QUICK_PICKS: ReadonlyArray<{
7545
+ name: string;
7546
+ data: CzmlPacket[];
7547
+ }>;
7548
+ /**
7549
+ * Parse and validate a CZML payload from a JSON string or raw object.
7550
+ * Returns an array of CZML packets or null when the input is malformed.
7551
+ */
7552
+ export declare function parseCzml(value: unknown): CzmlPacket[] | null;
7553
+ /**
7554
+ * Whether `layer` represents a CZML dynamic 3D scene.
7555
+ */
7556
+ export declare function isCzmlLayer(layer: Pick<GeoLibreLayer, "source" | "metadata">): boolean;
7557
+ /** Extracted CZML source definition for a layer. */
7558
+ interface CzmlSource {
7559
+ url?: string;
7560
+ data?: CzmlPacket[] | string;
7561
+ }
7562
+ /**
7563
+ * Extract the CZML content and/or URL from a layer, or null if not a CZML layer.
7564
+ */
7565
+ export declare function czmlSource(layer: Pick<GeoLibreLayer, "source" | "metadata">): CzmlSource | null;
7566
+ /**
7567
+ * Options for constructing a CZML layer.
7568
+ */
7569
+ interface CzmlLayerOptions {
7570
+ /** Optional layer id; defaults to a new UUID. */
7571
+ id?: string;
7572
+ /** Display name of the layer in the Layers panel. */
7573
+ name: string;
7574
+ /** Inlined CZML packet array or serialized JSON string. */
7575
+ data?: CzmlPacket[] | string;
7576
+ /** Remote URL pointing to a .czml document. */
7577
+ url?: string;
7578
+ /** Local path when loaded from disk. */
7579
+ sourcePath?: string;
7580
+ }
7581
+ /**
7582
+ * Build a typed GeoLibreLayer representing a CZML dynamic scene on the Cesium globe.
7583
+ */
7584
+ export declare function createCzmlLayer(options: CzmlLayerOptions): GeoLibreLayer;
7029
7585
  //#endregion
7030
7586
  //#region src/three-d-tiles.d.ts
7031
7587
  /** Header Google's tile server expects the Maps API key in. */
7032
- declare const GOOGLE_MAPS_API_KEY_HEADER = "X-GOOG-API-KEY";
7588
+ export declare const GOOGLE_MAPS_API_KEY_HEADER = "X-GOOG-API-KEY";
7033
7589
  /** Whether `url` points at Google's Photorealistic 3D Tiles root tileset. */
7034
- declare function isGooglePhotorealisticTilesetUrl(url: string): boolean;
7590
+ export declare function isGooglePhotorealisticTilesetUrl(url: string): boolean;
7035
7591
  /** Drop the `X-GOOG-API-KEY` header (case-insensitive), keeping the rest. */
7036
- declare function stripGoogleMapsApiKeyHeader(headers: Record<string, string> | undefined): Record<string, string> | undefined;
7592
+ export declare function stripGoogleMapsApiKeyHeader(headers: Record<string, string> | undefined): Record<string, string> | undefined;
7037
7593
  /**
7038
7594
  * The real `X-GOOG-API-KEY` value from `headers`, or `undefined` when absent,
7039
7595
  * blank, or a masked placeholder.
7040
7596
  */
7041
- declare function googleMapsApiKeyHeaderValue(headers: Record<string, string> | undefined): string | undefined;
7597
+ export declare function googleMapsApiKeyHeaderValue(headers: Record<string, string> | undefined): string | undefined;
7042
7598
  /** Collapse an empty record to `undefined`, otherwise pass it through. */
7043
- declare function nonEmptyRecord(value: Record<string, string> | undefined): Record<string, string> | undefined;
7599
+ export declare function nonEmptyRecord(value: Record<string, string> | undefined): Record<string, string> | undefined;
7044
7600
  /**
7045
7601
  * Resolve the request headers a 3D Tiles layer should load with. For non-Google
7046
7602
  * tilesets the headers pass through unchanged. For Google Photorealistic tiles
@@ -7048,7 +7604,7 @@ declare function nonEmptyRecord(value: Record<string, string> | undefined): Reco
7048
7604
  * the given headers, the `googleMapsApiKey` argument, then `getGoogleMapsApiKey()`
7049
7605
  * (runtime env). Returns `undefined` when there is nothing to send.
7050
7606
  */
7051
- declare function resolveThreeDTilesRequestHeaders(url: string, headers: Record<string, string> | undefined, googleMapsApiKey?: string): Record<string, string> | undefined;
7607
+ export declare function resolveThreeDTilesRequestHeaders(url: string, headers: Record<string, string> | undefined, googleMapsApiKey?: string): Record<string, string> | undefined;
7052
7608
  /**
7053
7609
  * The request headers to persist on a 3D Tiles layer record. Non-Google
7054
7610
  * tilesets keep their headers; Google Photorealistic tiles keep any non-key
@@ -7056,7 +7612,7 @@ declare function resolveThreeDTilesRequestHeaders(url: string, headers: Record<s
7056
7612
  * projects do not carry the key in plain text (it is re-injected at render
7057
7613
  * time by `resolveThreeDTilesRequestHeaders`).
7058
7614
  */
7059
- declare function persistedThreeDTilesRequestHeaders(url: string, headers: Record<string, string> | undefined): Record<string, string> | undefined;
7615
+ export declare function persistedThreeDTilesRequestHeaders(url: string, headers: Record<string, string> | undefined): Record<string, string> | undefined;
7060
7616
  //#endregion
7061
7617
  //#region src/credentials.d.ts
7062
7618
  /**
@@ -7064,7 +7620,7 @@ declare function persistedThreeDTilesRequestHeaders(url: string, headers: Record
7064
7620
  * schema-level inventory. Keep the explicit preference/plugin handling in
7065
7621
  * redactProjectCredentials in sync when adding entries outside layer config.
7066
7622
  */
7067
- declare const PROJECT_CREDENTIAL_FIELDS: {
7623
+ export declare const PROJECT_CREDENTIAL_FIELDS: {
7068
7624
  readonly preferences: readonly ["environmentVariables", "geocoding.apiKeys"];
7069
7625
  readonly layerConfiguration: readonly ["requestHeaders", "headers", "authorization", "apiKey", "apiKeys", "accessToken", "token", "password", "clientSecret", "connectionString", "secret", "bearer", "auth", "authKey", "sasToken", "subscriptionKey", "signature", "pwd"];
7070
7626
  readonly pluginState: readonly ["plugins.settings"];
@@ -7087,7 +7643,7 @@ declare const PROJECT_CREDENTIAL_FIELDS: {
7087
7643
  * like any unknown blob. Mirrored by `PUBLISHABLE_PLUGIN_SETTINGS` in
7088
7644
  * `python/src/geolibre/project.py`; the two must agree.
7089
7645
  */
7090
- declare const PUBLISHABLE_PLUGIN_SETTINGS: Readonly<Record<string, readonly string[] | null>>;
7646
+ export declare const PUBLISHABLE_PLUGIN_SETTINGS: Readonly<Record<string, readonly string[] | null>>;
7091
7647
  interface CredentialRedactionResult {
7092
7648
  project: GeoLibreProject;
7093
7649
  /** Stable project paths removed or rewritten by the redaction pass. */
@@ -7118,14 +7674,14 @@ interface CredentialRedactionResult {
7118
7674
  * dialog's readiness check) scans exactly as deep as this pass does, instead of
7119
7675
  * keeping a second, shallower cap that would silently disagree.
7120
7676
  */
7121
- declare const MAX_REDACT_DEPTH = 12;
7677
+ export declare const MAX_REDACT_DEPTH = 12;
7122
7678
  /** Whether an object key in layer/plugin configuration holds a credential. */
7123
- declare function isCredentialFieldName(name: string): boolean;
7679
+ export declare function isCredentialFieldName(name: string): boolean;
7124
7680
  /**
7125
7681
  * Remove credentials from URL-shaped values without encoding tile-template
7126
7682
  * placeholders such as `{z}/{x}/{y}`.
7127
7683
  */
7128
- declare function redactUrlCredentials(value: string): string;
7684
+ export declare function redactUrlCredentials(value: string): string;
7129
7685
  /**
7130
7686
  * Return a detached project safe for any external egress.
7131
7687
  *
@@ -7140,24 +7696,24 @@ declare function redactUrlCredentials(value: string): string;
7140
7696
  * positions stay intact so recipients can still load and configure the plugin
7141
7697
  * themselves.
7142
7698
  */
7143
- declare function redactProjectCredentials(project: GeoLibreProject): CredentialRedactionResult;
7699
+ export declare function redactProjectCredentials(project: GeoLibreProject): CredentialRedactionResult;
7144
7700
  /** Convenience wrapper for callers that only need the safe project. */
7145
- declare function redactCredentials(project: GeoLibreProject): GeoLibreProject;
7701
+ export declare function redactCredentials(project: GeoLibreProject): GeoLibreProject;
7146
7702
  //#endregion
7147
7703
  //#region src/visibility.d.ts
7148
7704
  /**
7149
7705
  * Returns a new FeatureCollection with properties marked as "excluded" removed.
7150
7706
  */
7151
- declare function excludeHiddenFieldsFromGeojson(geojson: FeatureCollection, fieldVisibility?: Record<string, FieldVisibility>): FeatureCollection;
7707
+ export declare function excludeHiddenFieldsFromGeojson(geojson: FeatureCollection, fieldVisibility?: Record<string, FieldVisibility>): FeatureCollection;
7152
7708
  /**
7153
7709
  * Returns a new GeoLibreProject where all layers have their excluded fields
7154
7710
  * physically removed from their inline GeoJSON.
7155
7711
  */
7156
- declare function excludeHiddenFieldsFromProject(project: GeoLibreProject): GeoLibreProject;
7712
+ export declare function excludeHiddenFieldsFromProject(project: GeoLibreProject): GeoLibreProject;
7157
7713
  //#endregion
7158
7714
  //#region src/editor-tracking.d.ts
7159
7715
  /** Default field names for maintained editor tracking columns. */
7160
- declare const DEFAULT_EDITOR_TRACKING_CONFIG: Required<EditorTrackingConfig>;
7716
+ export declare const DEFAULT_EDITOR_TRACKING_CONFIG: Required<EditorTrackingConfig>;
7161
7717
  /**
7162
7718
  * Identity written to the author fields when nothing better is known.
7163
7719
  *
@@ -7165,7 +7721,7 @@ declare const DEFAULT_EDITOR_TRACKING_CONFIG: Required<EditorTrackingConfig>;
7165
7721
  * value that changes with the UI language would make the same editor appear as
7166
7722
  * several different people across a project's history.
7167
7723
  */
7168
- declare const DEFAULT_EDITOR_IDENTITY = "local-user";
7724
+ export declare const DEFAULT_EDITOR_IDENTITY = "local-user";
7169
7725
  /**
7170
7726
  * `localStorage` key holding the display name this browser edits under.
7171
7727
  *
@@ -7173,7 +7729,7 @@ declare const DEFAULT_EDITOR_IDENTITY = "local-user";
7173
7729
  * here, so a user who has introduced themselves once is recognized by both
7174
7730
  * features instead of being prompted twice.
7175
7731
  */
7176
- declare const EDITOR_IDENTITY_STORAGE_KEY = "geolibre_author_name";
7732
+ export declare const EDITOR_IDENTITY_STORAGE_KEY = "geolibre_author_name";
7177
7733
  /**
7178
7734
  * Choose the identity to stamp, most authoritative source first.
7179
7735
  *
@@ -7186,17 +7742,17 @@ declare const EDITOR_IDENTITY_STORAGE_KEY = "geolibre_author_name";
7186
7742
  * @param storedName Locally configured display name.
7187
7743
  * @returns A non-empty identity string.
7188
7744
  */
7189
- declare function pickEditorIdentity(collabName?: string | null, storedName?: string | null): string;
7745
+ export declare function pickEditorIdentity(collabName?: string | null, storedName?: string | null): string;
7190
7746
  /**
7191
7747
  * The four maintained column names, or `null` when tracking is off or the
7192
7748
  * configuration is unusable. Ordered created-then-edited so callers that render
7193
7749
  * the columns get a stable, meaningful order.
7194
7750
  */
7195
- declare function editorTrackingFieldNames(config?: EditorTrackingConfig): string[] | null;
7751
+ export declare function editorTrackingFieldNames(config?: EditorTrackingConfig): string[] | null;
7196
7752
  /**
7197
7753
  * Options for editor tracking stamping functions.
7198
7754
  */
7199
- interface EditorTrackingStampOptions {
7755
+ export interface EditorTrackingStampOptions {
7200
7756
  /** Optional custom editor tracking field configuration. */
7201
7757
  config?: EditorTrackingConfig;
7202
7758
  /**
@@ -7210,20 +7766,20 @@ interface EditorTrackingStampOptions {
7210
7766
  /**
7211
7767
  * Fully resolve an {@link EditorTrackingConfig} with fallback default field names.
7212
7768
  */
7213
- declare function resolveEditorTrackingConfig(config?: EditorTrackingConfig): Required<EditorTrackingConfig>;
7769
+ export declare function resolveEditorTrackingConfig(config?: EditorTrackingConfig): Required<EditorTrackingConfig>;
7214
7770
  /**
7215
7771
  * Check whether a field name corresponds to one of the maintained editor tracking columns.
7216
7772
  *
7217
7773
  * Returns `false` for an invalid config, so callers can use this as a plain predicate.
7218
7774
  */
7219
- declare function isMaintainedEditorTrackingField(fieldName: string, config?: EditorTrackingConfig): boolean;
7775
+ export declare function isMaintainedEditorTrackingField(fieldName: string, config?: EditorTrackingConfig): boolean;
7220
7776
  /**
7221
7777
  * Ensure all configured editor tracking field names are included in a field list.
7222
7778
  *
7223
7779
  * Returns the list unchanged for an invalid config, matching
7224
7780
  * {@link isMaintainedEditorTrackingField}.
7225
7781
  */
7226
- declare function ensureEditorTrackingFields(fields: string[], config?: EditorTrackingConfig): string[];
7782
+ export declare function ensureEditorTrackingFields(fields: string[], config?: EditorTrackingConfig): string[];
7227
7783
  /**
7228
7784
  * Stamp editor tracking metadata onto a feature's properties object.
7229
7785
  *
@@ -7239,15 +7795,15 @@ declare function ensureEditorTrackingFields(fields: string[], config?: EditorTra
7239
7795
  * On `"update"`: sets `edited_by`/`edited_at` and preserves `created_by` /
7240
7796
  * `created_at`, which record something this edit did not change.
7241
7797
  */
7242
- declare function stampFeaturePropertiesEditorTracking(properties: Record<string, unknown> | null | undefined, action: "create" | "update", options?: EditorTrackingStampOptions): Record<string, unknown>;
7798
+ export declare function stampFeaturePropertiesEditorTracking(properties: Record<string, unknown> | null | undefined, action: "create" | "update", options?: EditorTrackingStampOptions): Record<string, unknown>;
7243
7799
  /**
7244
7800
  * Stamp editor tracking metadata onto a GeoJSON {@link Feature}.
7245
7801
  */
7246
- declare function stampFeatureEditorTracking<T extends Feature>(feature: T, action: "create" | "update", options?: EditorTrackingStampOptions): T;
7802
+ export declare function stampFeatureEditorTracking<T extends Feature>(feature: T, action: "create" | "update", options?: EditorTrackingStampOptions): T;
7247
7803
  /**
7248
7804
  * Stamp editor tracking metadata onto all features in a {@link FeatureCollection}.
7249
7805
  */
7250
- declare function stampFeatureCollectionEditorTracking(collection: FeatureCollection, action: "create" | "update", options?: EditorTrackingStampOptions): FeatureCollection;
7806
+ export declare function stampFeatureCollectionEditorTracking(collection: FeatureCollection, action: "create" | "update", options?: EditorTrackingStampOptions): FeatureCollection;
7251
7807
  //#endregion
7252
7808
  //#region src/editor-identity.d.ts
7253
7809
  /**
@@ -7266,12 +7822,12 @@ declare function stampFeatureCollectionEditorTracking(collection: FeatureCollect
7266
7822
  * iframe), so a failure here has to read as "no name set" — an editor whose
7267
7823
  * browser refuses storage must still be able to edit.
7268
7824
  */
7269
- declare function readStoredAuthorName(): string;
7825
+ export declare function readStoredAuthorName(): string;
7270
7826
  /**
7271
7827
  * Persist the display name to edit under. A blank name clears it, so the user
7272
7828
  * can go back to the anonymous default rather than being stuck with a typo.
7273
7829
  */
7274
- declare function setStoredAuthorName(name: string): void;
7830
+ export declare function setStoredAuthorName(name: string): void;
7275
7831
  /**
7276
7832
  * The identity to stamp on edits made right now: the collaboration session's
7277
7833
  * name when one is active, else the locally configured name, else the anonymous
@@ -7279,7 +7835,29 @@ declare function setStoredAuthorName(name: string): void;
7279
7835
  *
7280
7836
  * @returns A non-empty identity string.
7281
7837
  */
7282
- declare function currentEditorIdentity(): string;
7838
+ export declare function currentEditorIdentity(): string;
7839
+ //#endregion
7840
+ //#region src/cesium-kml.d.ts
7841
+ /** Native KML/KMZ documents retain their own styling on the globe. */
7842
+ export declare const CESIUM_KML_SOURCE_KIND = "cesium-kml";
7843
+ export declare function isCesiumKmlLayer(layer: Pick<GeoLibreLayer, "metadata">): boolean;
7844
+ interface CesiumKmlLayerOptions {
7845
+ id?: string;
7846
+ name: string;
7847
+ /** HTTP(S) KML or KMZ URL. Relative resources resolve against this URL. */
7848
+ url?: string;
7849
+ /** Inline XML, or a KMZ data URL so local archives survive project saves. */
7850
+ data?: string;
7851
+ sourcePath?: string;
7852
+ }
7853
+ export declare function cesiumKmlSource(layer: Pick<GeoLibreLayer, "source" | "metadata">): string | null;
7854
+ export declare function createCesiumKmlLayer(options: CesiumKmlLayerOptions): GeoLibreLayer;
7855
+ //#endregion
7856
+ //#region src/file-name.d.ts
7857
+ /** Extract a display filename without changing the source used for file access. */
7858
+ export declare function localFileName(path: string): string;
7859
+ /** Keep imported layers distinguishable, including within a multi-file import. */
7860
+ export declare function uniqueImportedLayerName(name: string, names: Iterable<string>): string;
7283
7861
  //#endregion
7284
- export { ALL_APP_PRIVILEGES, ALL_DEPLOYMENT_CAPABILITIES, AddTileLayerOptions, AppCapabilities, AppPrivilege, AppRole, type AppState, ApplyLayerJoinsResult, ApplyVirtualFieldsResult, AttributeFormConfig, AttributeFormEvalOptions, AttributeFormFieldConfig, AttributeFormFieldError, AttributeFormValidation, AttributeFormValueMapEntry, AttributeFormWidget, BLANK_BASEMAP, BLEND_MODES, BUILT_IN_STYLE_PRESETS, BlendMode, CARTOCIUDAD_MIN_INTERVAL_MS, CARTOCIUDAD_PUBLIC_HOST, CHINA_BASEMAPS, CesiumBasemapImagery, CollabInvite, CollaborationChatMessage, CollaborationMode, CollaborationParticipant, CollaborationPresence, CollaborationRole, CollaborationState, ColorRamp, CommentAnchor, CommentAuthor, CommentReply, CompiledFeatureExpression, type ConversionToolKind, CopiedLayerStyle, CopiedRasterStyle, CopiedVectorStyle, CreateProjectOptions, type CredentialRedactionResult, DEFAULT_BASEMAP, DEFAULT_BLEND_MODE, DEFAULT_COLLABORATION_STATE, DEFAULT_DASHBOARD_COLUMNS, DEFAULT_EDITOR_IDENTITY, DEFAULT_EDITOR_TRACKING_CONFIG, DEFAULT_ELLIPSOID_ID, DEFAULT_FORWARD_GEOCODE_ENDPOINT, DEFAULT_GEOCODING_PROVIDER_ID, DEFAULT_LAYER_GROUP_OPACITY, DEFAULT_LAYER_STYLE, DEFAULT_LEGEND_CONFIG, DEFAULT_MAP_GRID_LAYOUT, DEFAULT_PRINT_LAYOUT, DEFAULT_PROJECT_NAME, DEFAULT_PROJECT_PREFERENCES, DEFAULT_REVERSE_GEOCODE_ENDPOINT, DEFAULT_ROUTING_ENDPOINT, DEFAULT_STORY_MAP, DEPLOYMENT_CAPABILITIES, DUCKDB_VECTOR_FEATURE_WARN_COUNT, DUCKDB_VECTOR_ROUTE_BYTES, DashboardWidget, DashboardWidgetAggregation, DashboardWidgetType, DeploymentCapability, DiagramData, DiagramDatum, DiagramField, DiagramSizeMode, DiagramType, DominantGeometry, EARTH_MEAN_RADIUS_METERS, EDITOR_IDENTITY_STORAGE_KEY, ELEVATION_REQUEST_TIMEOUT_MS, ELLIPSOIDS, EXPRESSION_FUNCTION_CATEGORIES, EditorTrackingConfig, EditorTrackingStampOptions, EffectiveVectorRule, ElevationFetchError, Ellipsoid, EllipsoidId, EvaluateMapExpressionOptions, ExpressionExpectedType, ExpressionFieldType, ExpressionFunctionCategory, ExpressionFunctionDoc, ExpressionPreview, ExpressionValidation, ExpressionVariable, ExternalNativePaintBridge, ExternalNativePaintMode, FEET_PER_METER, FEET_PER_MILE, FeatureExpressionMatches, FetchLike, FieldVisibility, FillPattern, GEOCODE_DISPLAY_NAME_KEY, GEOCODE_LAT_KEY, GEOCODE_LON_KEY, GEOCODE_PROVIDER_KEY, GEOCODE_SCORE_KEY, GEOCODE_STATUS_KEY, GEOCODING_PROVIDERS, GOOGLE_MAPS_API_KEY_HEADER, GeoLibreLayer, GeoLibreProject, type GeocodeMatch, type GeocodeRequest, type GeocodeStatus, type GeocoderConfig, type GeocodingPreferenceInput, GeocodingPreferences, type GeocodingProvider, type GeocodingProviderId, GeometryGeneratorType, type GpsStatusFix, GraduatedClassificationScheme, IDENTIFY_ALL_LAYERS_ID, IndicatorAggregation, InitialLayerStyleOptions, IsochroneRequestBody, LARGE_VECTOR_FEATURE_THRESHOLD, LAYER_LIBRARY_BUNDLE_TYPE, LAYER_LIBRARY_BUNDLE_VERSION, LAYER_PALETTE, LAYER_TYPES, LabelAnchor, LabelDedupe, LabelStyle, LabelTransform, LayerCapabilities, LayerConnection, LayerGroup, LayerJoin, LayerJoinStats, LayerLibraryAddPlan, LayerLibraryCaptureFailure, LayerLibraryCaptureResult, LayerLibraryConfigPatch, LayerLibraryEntry, LayerPanelGroupHeaders, LayerPanelUnit, LayerPopupConfig, LayerQuickFilter, LayerStyle, LayerStyleClipboardKind, LayerTreeItem, LayerType, LayerVirtualField, LegendConfig, LegendCustomEntry, LegendCustomItem, LegendCustomShape, LegendItemOverride, LegendPanelPosition, LineDecoration, LngLat, MAX_DASHBOARD_COLUMNS, MAX_DIAGRAM_FEATURES, MAX_DIAGRAM_SCAN_FEATURES, MAX_LAYER_LIBRARY_ENTRIES, MAX_LAYER_LIBRARY_ENTRY_BYTES, MAX_MAP_GRID_DIM, MAX_POINTS_PER_REQUEST, MAX_PROCESSING_HISTORY, MAX_REDACT_DEPTH, MERCATOR_METERS_PER_PIXEL_AT_ZOOM_0, METERS_PER_FOOT, METERS_PER_MILE, METERS_PER_NAUTICAL_MILE, MIN_DASHBOARD_COLUMNS, MIN_DIAGRAM_SIZE, MapGridLayout, MapPreferences, MapProjection, MapScaleUnit, MapViewState, MarkerShape, MatrixRequestBody, ModelGraphEdge, ModelGraphNode, ModelGraphNodeKind, ModelGraphPort, ModelPortKind, ModelToolProvider, NETCDF_IMAGE_SOURCE_KIND, NOMINATIM_MIN_INTERVAL_MS, NOMINATIM_PUBLIC_HOST, NO_DEPLOYMENT_CAPABILITIES, type NetworkToolKind, type NominatimForwardResult, type NominatimReverseResult, NonGeographicCoordinates, OPENFREEMAP_BASEMAPS, PHOTO_FULL_PROPERTY, PHOTO_PROPERTY, PLANETARY_BASEMAPS, PLANETARY_BASEMAP_GROUPS, PLANETARY_BASEMAP_SENTINEL_PREFIX, PLANET_SWITCHER_OPTIONS, POINTER_ELEVATION_CACHE_LIMIT, POINTER_ELEVATION_DEBOUNCE_MS, PROJECT_CREDENTIAL_FIELDS, PROJECT_VERSION, PROTOMAPS_BASEMAPS, PUBLIC_GEOCODE_ROW_CAP, PUBLISHABLE_PLUGIN_SETTINGS, ParticipantIdentity, PlanetaryBasemap, PlanetaryBasemapGroup, PlanetaryBasemapSectionId, PointRenderer, PointerElevationResolver, PointerElevationResolverOptions, PolylineBatchOptions, PolylineDecodeResult, PopupDateFormat, PopupExpressionOptions, PopupFieldConfig, PopupFieldFormat, PopupFieldKind, PopupFormatOptions, PopupRow, PrintLayoutConfig, PrintLayoutCorner, PrintLayoutLegendEntry, PrintLayoutPageFilter, ProcessingModel, ProcessingModelGraph, ProcessingModelStep, ProcessingRerunRequest, ProcessingRun, ProcessingRunKind, ProcessingRunStatus, ProjectComment, ProjectPluginControlPosition, ProjectPluginState, ProjectPreferences, ProjectTemplateEntry, ProportionalSizeRange, QuickFilterDateKind, QuickFilterKind, QuickFilterTextOperator, RAMP_STYLE_KEYS, RASTER_APPEARANCE_STATE_KEYS, REGIONAL_BASEMAPS, REGIONAL_BASEMAP_GROUPS, REGIONAL_BASEMAP_SENTINEL_PREFIX, ROLE_PRIVILEGES, type RasterToolKind, RecentProjectEntry, RegionalBasemap, RegionalBasemapRegionId, ResolvePopupRowsOptions, type ReverseGeocodeDisplay, RouteRequestBody, RoutingConfig, RoutingMetric, RoutingMode, RoutingPoint, RoutingRequestError, RuntimeEnvironmentVariable, SELECTION_MODES, SQL_QUERY_SOURCE_KIND, STYLE_LIBRARY_BUNDLE_TYPE, STYLE_LIBRARY_BUNDLE_VERSION, SYMBOL_STYLE_KEYS, SecondaryMapView, SelectionMode, type StatisticsToolKind, StoryActiveSlideMode, StoryChapter, StoryChapterAlignment, StoryChapterAnimation, StoryChapterLocation, StoryInsetPosition, StoryLayerOpacityChange, StoryMap, StorySlideMode, StrokeWidthUnit, StyleLibraryEntry, StyleLibraryEntryKind, TerrainMapLike, VECTOR_COLOR_RAMPS, ValidateMapExpressionOptions, VectorColorValue, VectorRule, VectorStyleMode, VectorStyleStop, type VectorToolKind, activeQuickFilters, appPrivilegeReason, applyCopiedLayerStyle, applyGroupEffects, applyJoinsToLayer, applyLayerJoins, applyLayerVirtualFields, applyMatchedSelection, applyProjectToStore, applySelectionMode, attributeFormFieldLabel, attributeLinkUrl, basemapToCesiumImagery, batchDecodePolylines, bodyLengthToEarth, buildForwardGeocodeUrl, buildIsochroneRequest, buildLayerPanelUnits, buildLayerTree, buildMatrixRequest, buildReverseGeocodeUrl, buildRouteRequest, canRedoProjectRestore, canSaveLayerToLibrary, canUndoProjectRestore, captureLayerLibraryEntry, cascadeLayerJoinRefresh, circleRadiusValue, clearExternalNativePaintBridge, clearHistory, clearQuickFilterValues, coerceAttributeFormValue, collectDiagramData, collectTransitiveJoinSourceIds, compareSequenceValues, compileFeatureExpression, compileQuickFilter, compileQuickFilters, controlRendersLayer, copyableLayerStyleKind, createDefaultAppCapabilities, createDefaultMapView, createDefaultPrintLayout, createEmptyProject, createEqualIntervalBreaks, createGraduatedClassBreaks, createLayerLibraryEntryId, createPointerElevationResolver, createProjectTemplate, createQuantileBreaks, createSampleStoryMap, createStyleLibraryEntryId, csvRowsToGeocodeRequests, currentEditorIdentity, darkenHex, decodePolyline, decodePolylineDetailed, detachProjectCopy, detectNonGeographicCoordinates, diagramAnchor, diagramPixelSize, diagramsSuppressedByPointRenderer, dominantGeometry, drawMarkerPath, earthAreaToBody, earthLengthToBody, editorTrackingFieldNames, effectiveLayerRenderState, effectiveVectorRules, encodePolyline, ensureEditorTrackingFields, evaluateMapExpression, excludeHiddenFieldsFromGeojson, excludeHiddenFieldsFromProject, extractCopiedLayerStyle, extractStyleLibraryStyle, extrusionColorValue, extrusionHeightValue, featureSelectionId, fetchElevations, formatCameraAltitude, formatExpressionPreviewValue, formatPixelValue, formatPopupValue, formatRoundNum, generatorCircleRadiusValue, generatorSizeRange, geoJSONToPolylineStr, geocodeForward, geocodeMatchToFeature, geocodeReverse, geocoderMinIntervalMs, geocoderNeedsApiKey, geojsonHasZCoordinates, getActiveBodyRadiusRatio, getActiveEllipsoid, getActiveMeanRadiusMeters, getActiveSemiMajorAxisMeters, getAttributeFormField, getBuildEnvironment, getCesiumIonToken, getEllipsoid, getExternalNativePaintBridge, getGeocoderConfig, getGeocodingProvider, getGoogleMapsApiKey, getHistoryCoalesceMs, getMapboxAccessToken, getMaxHistoryFeatureCount, getPlanetaryBasemapById, getPlanetaryBasemapByStyleUrl, getProtomapsApiKey, getProtomapsStyleUrl, getRegionalBasemapById, getRegionalBasemapByStyleUrl, getRoundNum, getRoutingConfig, getRuntimeEnvironment, getSpatialExtensionPath, getVectorColorRamp, googleMapsApiKeyHeaderValue, groupMemberIndices, hasActiveQuickFilter, hasAppPrivilege, hasPathTraversal, hasRestorableLayerSource, hasSimpleStyleProperties, inferFieldTypes, inferLayerCapabilities, initialLayerStyle, interpolateColors, interpolateHexColor, interpolateRampColors, intersectPrivileges, invertSelection, isAbsoluteFilesystemPath, isAllowedPluginManifestUrl, isAttributeFormFieldVisible, isCredentialFieldName, isDefaultPrintLayout, isDeploymentCapability, isDiagramStyleEnabled, isDuckDBQueryLayer, isExternalNativeLayerRecord, isGooglePhotorealisticTilesetUrl, isHexColor, isInitialLayerStyle, isInlineImageValue, isInternalPopupField, isIpadDesktopUserAgent, isMaintainedEditorTrackingField, isPopupClickEnabled, isPopupHoverEnabled, isRegionalBasemapSentinel, isSafePopupUrl, isStyleLibraryTargetLayer, isStyleSpecColor, isVectorColorExpression, isochroneResponseToFeatures, layerGroupDepth, layerGroupMoveability, layerJoinKey, layerLibraryConfigPatch, layerLibraryEntryNeedsLocalFile, layerPanelGroupHeaders, lineWidthValue, mapZoomStepOutputs, matchFeaturesByExpression, matrixResponseToFeatures, meanRadiusMeters, mercatorMetersPerPixelAtZoom0, metersWidthExpression, nextDelayMs, nextLayerPaletteColor, nominatimResultToFeature, nominatimReverseResultToDisplay, nonEmptyRecord, normalizeAppPrivileges, normalizeBlankBackgroundColor, normalizeDashboardColumns, normalizeGeocodingProviderId, normalizeGroupContiguity, normalizeHexColor, normalizeLayerCapabilities, normalizeLayerLibraryEntries, normalizeMapLayout, normalizeMapViewState, normalizeModelGraph, normalizeModels, normalizePrintLayoutConfig, normalizeProcessingHistory, normalizeProjectComments, normalizeSecondaryMapViews, normalizeStoryMap, normalizeStyleLibraryEntries, normalizeWidgets, parseContours, parseDeploymentCapabilities, parseHexColor, parseHexColorList, parseJsonExpression, parseLayerLibrary, parseProject, parseStoryMapCsv, parseStoryMapJson, parseStyleLibrary, parseValueMapText, persistedThreeDTilesRequestHeaders, pickEditorIdentity, planLayerLibraryAdd, pluginOwnsPaint, polylineStrToGeoJSON, popupFieldLabel, printLayoutConfigsEqual, projectFromStore, projectPathLabel, proportionalRadiusExpression, proportionalSizeRange, readStoredAuthorName, reapplyLayerJoins, redactCredentials, redactProjectCredentials, redactUrlCredentials, redo, registerProjectRestoreHistory, removeTrailingJsonCommas, reorderLayerGroupInPanel, requestIsochrone, requestMatrix, requestRoute, resolveConfiguredPopupTitle, resolveEditorTrackingConfig, resolveGeocoderConfig, resolveLayerCapabilities, resolveMapGrid, resolvePopupBody, resolvePopupRows, resolvePopupTitle, resolveRolePrivileges, resolveSvgSource, resolveThreeDTilesRequestHeaders, rgbToHex, routeResponseToFeatures, rowCap, ruleBasedColorExpression, ruleBasedVisibilityFilter, sameCesiumImagery, sampleMapTerrain, sampleMapTerrainPoint, sampleRemoteElevations, sanitizeLayerStylePatch, scaleAltitudeToActiveBody, scaleDenomination, scaleSpan, scrubCommentsForRemovedLayers, scrubLegendForRemovedLayers, scrubPrintLayoutForLayers, scrubPrintLayoutForRemovedLayers, scrubWidgetsForRemovedLayers, serializeLayerLibrary, serializeProject, serializeStoryMapCsv, serializeStoryMapJson, serializeStyleLibrary, setActiveEllipsoidId, setExternalNativePaintBridge, setGeocodingFetch, setHistoryCoalesceMs, setMaxHistoryFeatureCount, setStoredAuthorName, shouldThrottle, shouldUseTiledRendering, simpleStyleNumberValue, stampFeatureCollectionEditorTracking, stampFeatureEditorTracking, stampFeaturePropertiesEditorTracking, storyMapHasContent, stringifyPopupValue, stripGoogleMapsApiKeyHeader, stripJoinFields, stripVirtualFieldColumns, styleValue, subscribeProjectRestoreHistory, substituteExpressionVariables, supportsBridgedOpacity, transformGeojsonElevation, trimHistoryBySize, undo, unescapePolyline, unmatchedGeocodeFeature, unresolvedLayerLibraryJoins, useAppCapability, useAppStore, validateAttributeFormField, validateAttributeFormValues, validateMapExpression, valueMapLabelFor, valueMapToText, vectorCircleColorValue, vectorColorExpression, vectorFillColorValue, vectorFillOpacityValue, vectorLineColorValue, vectorOutlineColorValue, vectorStrokeWidthValue, visiblePopupFields, visiblePopupProperties };
7862
+ export type { AppState, CesiumIonAssetKind, CesiumIonLayerOptions, CesiumKmlLayerOptions, ConversionToolKind, CredentialRedactionResult, CzmlDocument, CzmlLayerOptions, CzmlPacket, CzmlSource, GeocodeMatch, GeocodeRequest, GeocodeStatus, GeocoderConfig, GeocodingPreferenceInput, GeocodingProvider, GeocodingProviderId, GpsStatusFix, NetworkToolKind, NominatimForwardResult, NominatimReverseResult, RasterToolKind, ReverseGeocodeDisplay, StatisticsToolKind, VectorToolKind };
7285
7863
  //# sourceMappingURL=index.d.mts.map