@mailwoman/cartographer 9.3.0 → 10.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.
Files changed (45) hide show
  1. package/lib/base/buildings.ts +2 -1
  2. package/lib/base/composition.ts +37 -8
  3. package/lib/planetary/index.ts +9 -0
  4. package/lib/planetary/layers.ts +172 -0
  5. package/lib/planetary/sources.ts +41 -0
  6. package/lib/planetary/style.ts +70 -0
  7. package/lib/styles/fonts.ts +19 -0
  8. package/lib/styles/index.ts +1 -0
  9. package/out/base/buildings.d.ts.map +1 -1
  10. package/out/base/buildings.js +2 -1
  11. package/out/base/buildings.js.map +1 -1
  12. package/out/base/composition.d.ts +27 -1
  13. package/out/base/composition.d.ts.map +1 -1
  14. package/out/base/composition.js +21 -7
  15. package/out/base/composition.js.map +1 -1
  16. package/out/coverage/index.d.ts.map +1 -1
  17. package/out/planetary/index.d.ts +9 -0
  18. package/out/planetary/index.d.ts.map +1 -0
  19. package/out/planetary/index.js +9 -0
  20. package/out/planetary/index.js.map +1 -0
  21. package/out/planetary/layers.d.ts +93 -0
  22. package/out/planetary/layers.d.ts.map +1 -0
  23. package/out/planetary/layers.js +126 -0
  24. package/out/planetary/layers.js.map +1 -0
  25. package/out/planetary/sources.d.ts +23 -0
  26. package/out/planetary/sources.d.ts.map +1 -0
  27. package/out/planetary/sources.js +35 -0
  28. package/out/planetary/sources.js.map +1 -0
  29. package/out/planetary/style.d.ts +24 -0
  30. package/out/planetary/style.d.ts.map +1 -0
  31. package/out/planetary/style.js +38 -0
  32. package/out/planetary/style.js.map +1 -0
  33. package/out/race-dots/index.d.ts.map +1 -1
  34. package/out/styles/fonts.d.ts +19 -0
  35. package/out/styles/fonts.d.ts.map +1 -0
  36. package/out/styles/fonts.js +19 -0
  37. package/out/styles/fonts.js.map +1 -0
  38. package/out/styles/index.d.ts +1 -0
  39. package/out/styles/index.d.ts.map +1 -1
  40. package/out/styles/index.js +1 -0
  41. package/out/styles/index.js.map +1 -1
  42. package/out/styles/layers.d.ts.map +1 -1
  43. package/out/tiles/api.d.ts.map +1 -1
  44. package/out/tsconfig.test.tsbuildinfo +1 -1
  45. package/package.json +13 -3
@@ -11,6 +11,7 @@ import type {
11
11
  } from "@maplibre/maplibre-gl-style-spec"
12
12
 
13
13
  import { MailwomanBaseTileSetID } from "#base/theme"
14
+ import { PROTOMAPS_FONT_REGULAR } from "#styles/fonts"
14
15
  import { LayerID } from "#styles/layers"
15
16
 
16
17
  const BuildingLayerID = LayerID.bind(null, "buildings")
@@ -114,7 +115,7 @@ export const BuildingLayers: LayerSpecification[] = [
114
115
  "text-field": ["to-string", ["id"]],
115
116
  "text-offset": [0, 0],
116
117
  "text-anchor": "center",
117
- "text-font": ["Fira Sans Regular"],
118
+ "text-font": [PROTOMAPS_FONT_REGULAR],
118
119
  },
119
120
 
120
121
  paint: {
@@ -4,7 +4,7 @@
4
4
  * @author Teffen Ellis, et al.
5
5
  */
6
6
 
7
- import type { SourceSpecification } from "@maplibre/maplibre-gl-style-spec"
7
+ import type { LayerSpecification, SourceSpecification } from "@maplibre/maplibre-gl-style-spec"
8
8
  import type { LightSpecification, SkySpecification, StyleSpecification, TerrainSpecification } from "maplibre-gl"
9
9
 
10
10
  import { BaseLayers } from "#base/layers"
@@ -50,12 +50,38 @@ export function createSkySpec(spec?: Partial<SkySpecification>): SkySpecificatio
50
50
 
51
51
  //#region Style Composition
52
52
 
53
+ /**
54
+ * The glyph host every style composed here reads fonts from. The Protomaps font set, mirrored under the public bucket
55
+ * so a style never depends on an upstream host at render time.
56
+ */
57
+ export const PROTOMAPS_GLYPHS_URL = "https://public.mailwoman.ai/protomaps/fonts/{fontstack}/{range}.pbf"
58
+
59
+ /**
60
+ * The Earth sprite. It must match the basemap schema version: the v4 sprite carries the icons the v4 theme's layers
61
+ * reference by name, so a style over a different basemap version needs a different sprite.
62
+ */
63
+ export const PROTOMAPS_SPRITE_URL = "https://public.mailwoman.ai/protomaps/sprites/v4/light"
64
+
53
65
  export interface StyleSpecificationComposition {
54
66
  sources: Record<string, SourceSpecification>
55
67
  layers?: LayerSpecificationListInput[]
56
68
  light?: Partial<LightSpecification>
57
69
  sky?: Partial<SkySpecification>
58
70
  terrain?: Partial<TerrainSpecification>
71
+ /**
72
+ * The layer list every `layers` entry inserts into. Earth's basemap layers by default; a body with no roads, water or
73
+ * buildings brings its own.
74
+ */
75
+ baseLayers?: LayerSpecification[]
76
+ /**
77
+ * The `hillshade` source. Earth's terrarium DEM by default; `null` adds no such source.
78
+ */
79
+ hillshadeSource?: SourceSpecification | null
80
+ /**
81
+ * The sprite URL. Earth's Protomaps v4 sprite by default; `null` omits the key, for a style with no icons.
82
+ */
83
+ sprite?: string | null
84
+ glyphs?: string
59
85
  }
60
86
 
61
87
  /**
@@ -67,23 +93,29 @@ export class StyleSpecificationComposer {
67
93
  sky: SkySpecification
68
94
  // terrain: TerrainSpecification
69
95
  sources: TileSetSourceRecord
96
+ sprite: string | null
97
+ glyphs: string
70
98
 
71
99
  constructor(spec: StyleSpecificationComposition) {
72
100
  this.light = createLightSpec(spec.light)
73
101
  this.sky = createSkySpec(spec.sky)
102
+ this.sprite = spec.sprite === undefined ? PROTOMAPS_SPRITE_URL : spec.sprite
103
+ this.glyphs = spec.glyphs ?? PROTOMAPS_GLYPHS_URL
74
104
 
75
105
  // this.terrain = {
76
106
  // source: TerrainTileSetID,
77
107
  // ...spec.terrain,
78
108
  // }
79
109
 
110
+ const hillshadeSource = spec.hillshadeSource === undefined ? createTerrainDEMSource() : spec.hillshadeSource
111
+
80
112
  this.sources = {
81
113
  ...spec.sources,
82
114
  // [TerrainTileSetID]: createTerrainDEMSource(),
83
- [HillshadeTileSetID]: createTerrainDEMSource(),
115
+ ...(hillshadeSource ? { [HillshadeTileSetID]: hillshadeSource } : {}),
84
116
  }
85
117
 
86
- this.layersList = new LayerSpecificationList(BaseLayers)
118
+ this.layersList = new LayerSpecificationList(spec.baseLayers ?? BaseLayers)
87
119
 
88
120
  for (const layer of spec.layers || []) {
89
121
  this.layersList.insert(layer)
@@ -97,11 +129,8 @@ export class StyleSpecificationComposer {
97
129
  toJSON(): StyleSpecification {
98
130
  const styleSpec: StyleSpecification = {
99
131
  version: 8,
100
- // Sprite must match the basemap schema version — v4 sprites carry the icons referenced
101
- // by the v4 theme spec. Currently upstream URLs; we mirror these to nexus-assets/{fonts,
102
- // sprites/v4}/ for self-hosting, but no public route fronts that bucket yet.
103
- glyphs: "https://public.mailwoman.ai/protomaps/fonts/{fontstack}/{range}.pbf",
104
- sprite: "https://public.mailwoman.ai/protomaps/sprites/v4/light",
132
+ glyphs: this.glyphs,
133
+ ...(this.sprite === null ? {} : { sprite: this.sprite }),
105
134
  light: createLightSpec(this.light),
106
135
  sky: createSkySpec(this.sky),
107
136
  // terrain: this.terrain,
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @copyright Sister Software.
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ */
6
+
7
+ export * from "#planetary/layers"
8
+ export * from "#planetary/sources"
9
+ export * from "#planetary/style"
@@ -0,0 +1,172 @@
1
+ /**
2
+ * @copyright Sister Software.
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ */
6
+
7
+ import type {
8
+ BackgroundLayerSpecification,
9
+ CircleLayerSpecification,
10
+ HillshadeLayerSpecification,
11
+ SymbolLayerSpecification,
12
+ } from "@maplibre/maplibre-gl-style-spec"
13
+
14
+ import { PlanetaryHillshadeSourceID, PlanetaryNomenclatureSourceID } from "#planetary/sources"
15
+ import { PROTOMAPS_FONT_REGULAR } from "#styles/fonts"
16
+ import { LayerID } from "#styles/layers"
17
+
18
+ export interface PlanetaryPalette {
19
+ /**
20
+ * The body's own surface tone, under the relief. Named `space` for the layer it feeds, which paints the SPHERE under
21
+ * globe projection rather than the area around it — the field around the globe is the page behind a transparent
22
+ * canvas, and the app's stylesheet paints it.
23
+ */
24
+ space: string
25
+ /**
26
+ * Where a slope faces the light. With `shadow` and `accent` these are what make one body's relief differ from
27
+ * another's; the tiles carry encoded elevation and no colour of their own.
28
+ */
29
+ reliefHighlight: string
30
+ /**
31
+ * Where a slope faces away. Kept translucent so the surface tone reads through flat ground, which would otherwise
32
+ * take the shadow colour everywhere the terrain is level.
33
+ */
34
+ reliefShadow: string
35
+ /**
36
+ * The steepness wash, translucent for the same reason.
37
+ */
38
+ reliefAccent: string
39
+ labelColor: string
40
+ labelHalo: string
41
+ selection: string
42
+ }
43
+
44
+ /**
45
+ * One palette per body with a published style. The record's keys are the bodies a style can be composed for, so a body
46
+ * without a row here has no style rather than a wrong one.
47
+ */
48
+ export const PALETTES = {
49
+ moon: {
50
+ space: "#8d8f95",
51
+ reliefHighlight: "#eef2f8",
52
+ reliefShadow: "rgba(20, 26, 40, 0.55)",
53
+ reliefAccent: "rgba(90, 100, 120, 0.4)",
54
+ labelColor: "#e8eef7",
55
+ labelHalo: "#05070d",
56
+ selection: "#7fd1ff",
57
+ },
58
+ mars: {
59
+ space: "#9a5334",
60
+ reliefHighlight: "#f4a26b",
61
+ reliefShadow: "rgba(74, 29, 14, 0.55)",
62
+ reliefAccent: "rgba(140, 58, 28, 0.4)",
63
+ labelColor: "#f6e3d1",
64
+ labelHalo: "#1a0c06",
65
+ selection: "#ffb37f",
66
+ },
67
+ } as const satisfies Record<string, PlanetaryPalette>
68
+
69
+ export type PlanetaryStyleBody = keyof typeof PALETTES
70
+
71
+ const PLANETARY_NAMESPACE = "planetary"
72
+
73
+ /**
74
+ * The body's surface tone, under the relief. Under globe projection a background layer paints the SPHERE, not the
75
+ * viewport, so this is the ground the hillshade shades and not the field around the globe; the app's stylesheet paints
76
+ * that behind a transparent canvas.
77
+ */
78
+ export const PlanetarySpaceLayerID = LayerID(PLANETARY_NAMESPACE, "space")
79
+
80
+ /**
81
+ * The hillshade raster layer, present only when the body has a hillshade tileset.
82
+ */
83
+ export const PlanetaryHillshadeLayerID = LayerID(PLANETARY_NAMESPACE, "hillshade")
84
+
85
+ /**
86
+ * The nomenclature label layer, the one an app reads feature properties from on a click.
87
+ */
88
+ export const PlanetaryLabelsLayerID = LayerID(PLANETARY_NAMESPACE, "nomenclature-labels")
89
+
90
+ /**
91
+ * The selection ring layer, the one an app sets a feature `id` filter on.
92
+ */
93
+ export const PlanetarySelectionLayerID = LayerID(PLANETARY_NAMESPACE, "selection")
94
+
95
+ /**
96
+ * The IAU feature-type codes drawn as spaced capitals: a mare, planitia, oceanus or terra spans a region rather than
97
+ * marking a point, and the wide setting reads as an area name the way a printed atlas sets one.
98
+ */
99
+ const REGION_FEATURE_TYPE_CODES = ["ME", "PL", "OC", "TA"]
100
+
101
+ export function spaceLayer(palette: PlanetaryPalette): BackgroundLayerSpecification {
102
+ return {
103
+ id: PlanetarySpaceLayerID,
104
+ type: "background",
105
+ paint: { "background-color": palette.space },
106
+ }
107
+ }
108
+
109
+ /**
110
+ * The relief, shaded at draw time from the body's encoded elevation. The tiles carry height and no colour, so every
111
+ * body-specific decision is here: a greyscale image could not be tinted at all, because MapLibre's raster paint
112
+ * properties are brightness, contrast, saturation and hue-rotate, and the last two do nothing without chroma.
113
+ */
114
+ export function hillshadeLayer(palette: PlanetaryPalette): HillshadeLayerSpecification {
115
+ return {
116
+ id: PlanetaryHillshadeLayerID,
117
+ type: "hillshade",
118
+ source: PlanetaryHillshadeSourceID,
119
+ paint: {
120
+ // Under 1: these bodies carry relief far sharper than Earth's relative to their radius, and unexaggerated
121
+ // shading reads as noise at globe zooms.
122
+ "hillshade-exaggeration": 0.6,
123
+ "hillshade-highlight-color": palette.reliefHighlight,
124
+ "hillshade-shadow-color": palette.reliefShadow,
125
+ "hillshade-accent-color": palette.reliefAccent,
126
+ },
127
+ }
128
+ }
129
+
130
+ /**
131
+ * Labels by feature scale: the tile's per-feature `minzoom` already hides a small crater at a low zoom, so the symbol
132
+ * layer only sizes and prioritizes. `featureTypeCode` is the IAU feature-type code carried in the tile properties (AA
133
+ * crater, MO mons, VA vallis, ME mare, PL planitia, SF satellite feature); `diameterKm` is the feature's diameter.
134
+ */
135
+ export function labelLayer(palette: PlanetaryPalette): SymbolLayerSpecification {
136
+ return {
137
+ id: PlanetaryLabelsLayerID,
138
+ type: "symbol",
139
+ source: PlanetaryNomenclatureSourceID,
140
+ "source-layer": "nomenclature",
141
+ layout: {
142
+ "text-field": ["get", "name"],
143
+ "text-font": [PROTOMAPS_FONT_REGULAR],
144
+ "text-size": ["interpolate", ["linear"], ["coalesce", ["get", "diameterKm"], 0], 0, 11, 100, 14, 1000, 18],
145
+ "text-transform": ["match", ["get", "featureTypeCode"], REGION_FEATURE_TYPE_CODES, "uppercase", "none"],
146
+ "text-letter-spacing": ["match", ["get", "featureTypeCode"], REGION_FEATURE_TYPE_CODES, 0.15, 0.02],
147
+ "symbol-sort-key": ["-", 0, ["coalesce", ["get", "diameterKm"], 0]],
148
+ "text-allow-overlap": false,
149
+ },
150
+ paint: { "text-color": palette.labelColor, "text-halo-color": palette.labelHalo, "text-halo-width": 1.2 },
151
+ }
152
+ }
153
+
154
+ /**
155
+ * The selection ring. Its filter matches no feature until the app sets one by `id`, so the layer ships in the style and
156
+ * the app never inserts a layer at runtime.
157
+ */
158
+ export function selectionLayer(palette: PlanetaryPalette): CircleLayerSpecification {
159
+ return {
160
+ id: PlanetarySelectionLayerID,
161
+ type: "circle",
162
+ source: PlanetaryNomenclatureSourceID,
163
+ "source-layer": "nomenclature",
164
+ filter: ["==", ["get", "id"], ""],
165
+ paint: {
166
+ "circle-radius": 14,
167
+ "circle-color": "transparent",
168
+ "circle-stroke-color": palette.selection,
169
+ "circle-stroke-width": 2,
170
+ },
171
+ }
172
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * @copyright Sister Software.
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ */
6
+
7
+ import type { RasterDEMSourceSpecification, VectorSourceSpecification } from "@maplibre/maplibre-gl-style-spec"
8
+
9
+ import { TileSetSourceID } from "#styles/sources"
10
+
11
+ /**
12
+ * The vector source carrying a body's IAU nomenclature: one `nomenclature` source layer of named features.
13
+ */
14
+ export const PlanetaryNomenclatureSourceID = TileSetSourceID("nomenclature")
15
+
16
+ /**
17
+ * The elevation source a body's relief is shaded from. The archive carries terrarium-encoded height rather than a
18
+ * shaded picture, so the shading happens at draw time and each body can be tinted from the style.
19
+ */
20
+ export const PlanetaryHillshadeSourceID = TileSetSourceID("hillshade")
21
+
22
+ /**
23
+ * MapLibre resolves a TileJSON `url` itself: tiles, bounds, zoom range and attribution all come from the tile worker's
24
+ * document, so nothing here restates them.
25
+ */
26
+ export function nomenclatureSource(tileJSONURL: string): VectorSourceSpecification {
27
+ return {
28
+ type: "vector",
29
+ url: tileJSONURL,
30
+ }
31
+ }
32
+
33
+ export function hillshadeSource(tileJSONURL: string): RasterDEMSourceSpecification {
34
+ return {
35
+ type: "raster-dem",
36
+ // The build writes `height = (R * 256 + G + B / 256) - 32768`, which is terrarium's, not Mapbox's.
37
+ encoding: "terrarium",
38
+ url: tileJSONURL,
39
+ tileSize: 256,
40
+ }
41
+ }
@@ -0,0 +1,70 @@
1
+ /**
2
+ * @copyright Sister Software.
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ */
6
+
7
+ import type { SourceSpecification, StyleSpecification } from "@maplibre/maplibre-gl-style-spec"
8
+
9
+ import { StyleSpecificationComposer } from "#base/composition"
10
+ import {
11
+ hillshadeLayer,
12
+ labelLayer,
13
+ PALETTES,
14
+ type PlanetaryStyleBody,
15
+ selectionLayer,
16
+ spaceLayer,
17
+ } from "#planetary/layers"
18
+ import {
19
+ hillshadeSource,
20
+ nomenclatureSource,
21
+ PlanetaryHillshadeSourceID,
22
+ PlanetaryNomenclatureSourceID,
23
+ } from "#planetary/sources"
24
+
25
+ export interface PlanetaryStyleOptions {
26
+ body: PlanetaryStyleBody
27
+ /**
28
+ * The TileJSON document of the body's nomenclature tileset.
29
+ */
30
+ nomenclatureTileJSONURL: string
31
+ /**
32
+ * The TileJSON document of the body's hillshade tileset. Without one the style draws labels over bare space.
33
+ */
34
+ hillshadeTileJSONURL?: string
35
+ }
36
+
37
+ /**
38
+ * A body's whole style: space, the hillshade when a tileset exists, the nomenclature labels, and the selection ring. No
39
+ * Earth layer, no Earth DEM and no sprite reach the result, so a viewer loads nothing Earth-shaped.
40
+ */
41
+ export function createPlanetaryStyle(options: PlanetaryStyleOptions): StyleSpecification {
42
+ const palette = PALETTES[options.body]
43
+
44
+ const sources: Record<string, SourceSpecification> = {
45
+ [PlanetaryNomenclatureSourceID]: nomenclatureSource(options.nomenclatureTileJSONURL),
46
+ }
47
+
48
+ if (options.hillshadeTileJSONURL) {
49
+ sources[PlanetaryHillshadeSourceID] = hillshadeSource(options.hillshadeTileJSONURL)
50
+ }
51
+
52
+ const baseLayers = [
53
+ spaceLayer(palette),
54
+ ...(options.hillshadeTileJSONURL ? [hillshadeLayer(palette)] : []),
55
+ labelLayer(palette),
56
+ selectionLayer(palette),
57
+ ]
58
+
59
+ const style = new StyleSpecificationComposer({
60
+ sources,
61
+ baseLayers,
62
+ hillshadeSource: null,
63
+ sprite: null,
64
+ sky: { "sky-color": palette.space, "horizon-color": palette.space },
65
+ }).toJSON()
66
+
67
+ // MapLibre 6 reads the projection from the STYLE. Passed as a map option instead it is ignored and the body
68
+ // renders flat, which is a mercator sheet of terrain rather than a world.
69
+ return { ...style, projection: { type: "globe" } }
70
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * @copyright Sister Software.
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * The glyph stacks a symbol layer may name. MapLibre draws NO text at all when a glyph range answers 404 — not a
7
+ * fallback face, nothing — so a `text-font` naming an absent stack blanks every label in the style at every zoom,
8
+ * with no console error a reader would connect to the missing labels.
9
+ *
10
+ * The mirror behind `PROTOMAPS_GLYPHS_URL` serves five stacks: `Noto Sans Regular`, `Noto Sans Medium`,
11
+ * `Noto Sans Italic`, `Fira Code Regular` and `Fira Code Medium`. It serves no Fira Sans, and no
12
+ * `Open Sans Regular` — which is MapLibre's own default, so a symbol layer that omits `text-font` also draws
13
+ * nothing. Name a constant from this file rather than a string literal.
14
+ */
15
+
16
+ /**
17
+ * The regular text stack: body labels, point features, place names.
18
+ */
19
+ export const PROTOMAPS_FONT_REGULAR = "Noto Sans Regular"
@@ -4,5 +4,6 @@
4
4
  * @author Teffen Ellis, et al.
5
5
  */
6
6
 
7
+ export * from "#styles/fonts"
7
8
  export * from "#styles/layers"
8
9
  export * from "#styles/sources"
@@ -1 +1 @@
1
- {"version":3,"file":"buildings.d.ts","sourceRoot":"","sources":["../../lib/base/buildings.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAGX,kBAAkB,EAClB,MAAM,kCAAkC,CAAA;AA2CzC;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,kBAAkB,EAqE9C,CAAA"}
1
+ {"version":3,"file":"buildings.d.ts","sourceRoot":"","sources":["../../lib/base/buildings.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAGX,kBAAkB,EAClB,MAAM,kCAAkC,CAAA;AA4CzC;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,kBAAkB,EAqE9C,CAAA"}
@@ -4,6 +4,7 @@
4
4
  * @author Teffen Ellis, et al.
5
5
  */
6
6
  import { MailwomanBaseTileSetID } from "#base/theme";
7
+ import { PROTOMAPS_FONT_REGULAR } from "#styles/fonts";
7
8
  import { LayerID } from "#styles/layers";
8
9
  const BuildingLayerID = LayerID.bind(null, "buildings");
9
10
  /**
@@ -97,7 +98,7 @@ export const BuildingLayers = [
97
98
  "text-field": ["to-string", ["id"]],
98
99
  "text-offset": [0, 0],
99
100
  "text-anchor": "center",
100
- "text-font": ["Fira Sans Regular"],
101
+ "text-font": [PROTOMAPS_FONT_REGULAR],
101
102
  },
102
103
  paint: {
103
104
  "text-color": "black",
@@ -1 +1 @@
1
- {"version":3,"file":"buildings.js","sourceRoot":"","sources":["../../lib/base/buildings.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"buildings.js","sourceRoot":"","sources":["../../lib/base/buildings.ts"],"names":[],"mappings":"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"}
@@ -3,18 +3,42 @@
3
3
  * @license AGPL-3.0
4
4
  * @author Teffen Ellis, et al.
5
5
  */
6
- import type { SourceSpecification } from "@maplibre/maplibre-gl-style-spec";
6
+ import type { LayerSpecification, SourceSpecification } from "@maplibre/maplibre-gl-style-spec";
7
7
  import type { LightSpecification, SkySpecification, StyleSpecification, TerrainSpecification } from "maplibre-gl";
8
8
  import { LayerSpecificationList, type LayerSpecificationListInput, type LayerSpecificationListItem } from "#styles/layers";
9
9
  import type { TileSetSourceRecord } from "#styles/sources";
10
10
  export declare function createLightSpec(spec?: Partial<LightSpecification>): LightSpecification;
11
11
  export declare function createSkySpec(spec?: Partial<SkySpecification>): SkySpecification;
12
+ /**
13
+ * The glyph host every style composed here reads fonts from. The Protomaps font set, mirrored under the public bucket
14
+ * so a style never depends on an upstream host at render time.
15
+ */
16
+ export declare const PROTOMAPS_GLYPHS_URL = "https://public.mailwoman.ai/protomaps/fonts/{fontstack}/{range}.pbf";
17
+ /**
18
+ * The Earth sprite. It must match the basemap schema version: the v4 sprite carries the icons the v4 theme's layers
19
+ * reference by name, so a style over a different basemap version needs a different sprite.
20
+ */
21
+ export declare const PROTOMAPS_SPRITE_URL = "https://public.mailwoman.ai/protomaps/sprites/v4/light";
12
22
  export interface StyleSpecificationComposition {
13
23
  sources: Record<string, SourceSpecification>;
14
24
  layers?: LayerSpecificationListInput[];
15
25
  light?: Partial<LightSpecification>;
16
26
  sky?: Partial<SkySpecification>;
17
27
  terrain?: Partial<TerrainSpecification>;
28
+ /**
29
+ * The layer list every `layers` entry inserts into. Earth's basemap layers by default; a body with no roads, water or
30
+ * buildings brings its own.
31
+ */
32
+ baseLayers?: LayerSpecification[];
33
+ /**
34
+ * The `hillshade` source. Earth's terrarium DEM by default; `null` adds no such source.
35
+ */
36
+ hillshadeSource?: SourceSpecification | null;
37
+ /**
38
+ * The sprite URL. Earth's Protomaps v4 sprite by default; `null` omits the key, for a style with no icons.
39
+ */
40
+ sprite?: string | null;
41
+ glyphs?: string;
18
42
  }
19
43
  /**
20
44
  * A stateful class for composing a style specification.
@@ -24,6 +48,8 @@ export declare class StyleSpecificationComposer {
24
48
  light: LightSpecification;
25
49
  sky: SkySpecification;
26
50
  sources: TileSetSourceRecord;
51
+ sprite: string | null;
52
+ glyphs: string;
27
53
  constructor(spec: StyleSpecificationComposition);
28
54
  get layers(): LayerSpecificationListItem[];
29
55
  toJSON(): StyleSpecification;
@@ -1 +1 @@
1
- {"version":3,"file":"composition.d.ts","sourceRoot":"","sources":["../../lib/base/composition.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAA;AAC3E,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAIjH,OAAO,EACN,sBAAsB,EACtB,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,EAC/B,MAAM,gBAAgB,CAAA;AACvB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AAM1D,wBAAgB,eAAe,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,GAAG,kBAAkB,CAYtF;AAED,wBAAgB,aAAa,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,gBAAgB,CAUhF;AAMD,MAAM,WAAW,6BAA6B;IAC7C,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAA;IAC5C,MAAM,CAAC,EAAE,2BAA2B,EAAE,CAAA;IACtC,KAAK,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAA;IACnC,GAAG,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAA;IAC/B,OAAO,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAA;CACvC;AAED;;GAEG;AACH,qBAAa,0BAA0B;IACtC,UAAU,EAAE,sBAAsB,CAAA;IAClC,KAAK,EAAE,kBAAkB,CAAA;IACzB,GAAG,EAAE,gBAAgB,CAAA;IAErB,OAAO,EAAE,mBAAmB,CAAA;gBAEhB,IAAI,EAAE,6BAA6B;IAsB/C,IAAW,MAAM,IAAI,0BAA0B,EAAE,CAEhD;IAED,MAAM,IAAI,kBAAkB;IAkB5B,IAAI,IAAI,kBAAkB;CAG1B"}
1
+ {"version":3,"file":"composition.d.ts","sourceRoot":"","sources":["../../lib/base/composition.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAA;AAC/F,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAIjH,OAAO,EACN,sBAAsB,EACtB,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,EAC/B,MAAM,gBAAgB,CAAA;AACvB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AAM1D,wBAAgB,eAAe,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,GAAG,kBAAkB,CAYtF;AAED,wBAAgB,aAAa,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,gBAAgB,CAUhF;AAMD;;;GAGG;AACH,eAAO,MAAM,oBAAoB,wEAAwE,CAAA;AAEzG;;;GAGG;AACH,eAAO,MAAM,oBAAoB,2DAA2D,CAAA;AAE5F,MAAM,WAAW,6BAA6B;IAC7C,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAA;IAC5C,MAAM,CAAC,EAAE,2BAA2B,EAAE,CAAA;IACtC,KAAK,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAA;IACnC,GAAG,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAA;IAC/B,OAAO,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAA;IACvC;;;OAGG;IACH,UAAU,CAAC,EAAE,kBAAkB,EAAE,CAAA;IACjC;;OAEG;IACH,eAAe,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAAA;IAC5C;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,MAAM,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;GAEG;AACH,qBAAa,0BAA0B;IACtC,UAAU,EAAE,sBAAsB,CAAA;IAClC,KAAK,EAAE,kBAAkB,CAAA;IACzB,GAAG,EAAE,gBAAgB,CAAA;IAErB,OAAO,EAAE,mBAAmB,CAAA;IAC5B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,MAAM,EAAE,MAAM,CAAA;IAEd,YAAY,IAAI,EAAE,6BAA6B,EAwB9C;IAED,IAAW,MAAM,IAAI,0BAA0B,EAAE,CAEhD;IAED,MAAM,IAAI,kBAAkB,CAa3B;IAED,IAAI,IAAI,kBAAkB,CAEzB;CACD"}
@@ -32,6 +32,18 @@ export function createSkySpec(spec) {
32
32
  ...spec,
33
33
  };
34
34
  }
35
+ //#endregion
36
+ //#region Style Composition
37
+ /**
38
+ * The glyph host every style composed here reads fonts from. The Protomaps font set, mirrored under the public bucket
39
+ * so a style never depends on an upstream host at render time.
40
+ */
41
+ export const PROTOMAPS_GLYPHS_URL = "https://public.mailwoman.ai/protomaps/fonts/{fontstack}/{range}.pbf";
42
+ /**
43
+ * The Earth sprite. It must match the basemap schema version: the v4 sprite carries the icons the v4 theme's layers
44
+ * reference by name, so a style over a different basemap version needs a different sprite.
45
+ */
46
+ export const PROTOMAPS_SPRITE_URL = "https://public.mailwoman.ai/protomaps/sprites/v4/light";
35
47
  /**
36
48
  * A stateful class for composing a style specification.
37
49
  */
@@ -41,19 +53,24 @@ export class StyleSpecificationComposer {
41
53
  sky;
42
54
  // terrain: TerrainSpecification
43
55
  sources;
56
+ sprite;
57
+ glyphs;
44
58
  constructor(spec) {
45
59
  this.light = createLightSpec(spec.light);
46
60
  this.sky = createSkySpec(spec.sky);
61
+ this.sprite = spec.sprite === undefined ? PROTOMAPS_SPRITE_URL : spec.sprite;
62
+ this.glyphs = spec.glyphs ?? PROTOMAPS_GLYPHS_URL;
47
63
  // this.terrain = {
48
64
  // source: TerrainTileSetID,
49
65
  // ...spec.terrain,
50
66
  // }
67
+ const hillshadeSource = spec.hillshadeSource === undefined ? createTerrainDEMSource() : spec.hillshadeSource;
51
68
  this.sources = {
52
69
  ...spec.sources,
53
70
  // [TerrainTileSetID]: createTerrainDEMSource(),
54
- [HillshadeTileSetID]: createTerrainDEMSource(),
71
+ ...(hillshadeSource ? { [HillshadeTileSetID]: hillshadeSource } : {}),
55
72
  };
56
- this.layersList = new LayerSpecificationList(BaseLayers);
73
+ this.layersList = new LayerSpecificationList(spec.baseLayers ?? BaseLayers);
57
74
  for (const layer of spec.layers || []) {
58
75
  this.layersList.insert(layer);
59
76
  }
@@ -64,11 +81,8 @@ export class StyleSpecificationComposer {
64
81
  toJSON() {
65
82
  const styleSpec = {
66
83
  version: 8,
67
- // Sprite must match the basemap schema version — v4 sprites carry the icons referenced
68
- // by the v4 theme spec. Currently upstream URLs; we mirror these to nexus-assets/{fonts,
69
- // sprites/v4}/ for self-hosting, but no public route fronts that bucket yet.
70
- glyphs: "https://public.mailwoman.ai/protomaps/fonts/{fontstack}/{range}.pbf",
71
- sprite: "https://public.mailwoman.ai/protomaps/sprites/v4/light",
84
+ glyphs: this.glyphs,
85
+ ...(this.sprite === null ? {} : { sprite: this.sprite }),
72
86
  light: createLightSpec(this.light),
73
87
  sky: createSkySpec(this.sky),
74
88
  // terrain: this.terrain,
@@ -1 +1 @@
1
- {"version":3,"file":"composition.js","sourceRoot":"","sources":["../../lib/base/composition.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAC1E,OAAO,EACN,sBAAsB,GAGtB,MAAM,gBAAgB,CAAA;AAGvB,YAAY;AAEZ,uBAAuB;AAEvB,MAAM,UAAU,eAAe,CAAC,IAAkC;IACjE,OAAO;QACN,KAAK,EAAE,OAAO;QACd,SAAS,EAAE,IAAI;QACf,MAAM,EAAE,UAAU;QAClB,QAAQ,EAAE;YACT,EAAE,EAAE,SAAS;YACb,EAAE,EAAE,YAAY;YAChB,CAAC,CAAC,EAAE,QAAQ;SACZ;QACD,GAAG,IAAI;KACP,CAAA;AACF,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAgC;IAC7D,OAAO;QACN,WAAW,EAAE,SAAS;QACtB,eAAe,EAAE,qBAAqB;QACtC,WAAW,EAAE,oBAAoB;QACjC,mBAAmB,EAAE,IAAI;QACzB,mBAAmB,EAAE,IAAI;QACzB,kBAAkB,EAAE,GAAG;QACvB,GAAG,IAAI;KACP,CAAA;AACF,CAAC;AAcD;;GAEG;AACH,MAAM,OAAO,0BAA0B;IACtC,UAAU,CAAwB;IAClC,KAAK,CAAoB;IACzB,GAAG,CAAkB;IACrB,gCAAgC;IAChC,OAAO,CAAqB;IAE5B,YAAY,IAAmC;QAC9C,IAAI,CAAC,KAAK,GAAG,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACxC,IAAI,CAAC,GAAG,GAAG,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QAElC,mBAAmB;QACnB,6BAA6B;QAC7B,oBAAoB;QACpB,IAAI;QAEJ,IAAI,CAAC,OAAO,GAAG;YACd,GAAG,IAAI,CAAC,OAAO;YACf,gDAAgD;YAChD,CAAC,kBAAkB,CAAC,EAAE,sBAAsB,EAAE;SAC9C,CAAA;QAED,IAAI,CAAC,UAAU,GAAG,IAAI,sBAAsB,CAAC,UAAU,CAAC,CAAA;QAExD,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;YACvC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QAC9B,CAAC;IACF,CAAC;IAED,IAAW,MAAM;QAChB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IACnC,CAAC;IAED,MAAM;QACL,MAAM,SAAS,GAAuB;YACrC,OAAO,EAAE,CAAC;YACV,uFAAuF;YACvF,yFAAyF;YACzF,6EAA6E;YAC7E,MAAM,EAAE,qEAAqE;YAC7E,MAAM,EAAE,wDAAwD;YAChE,KAAK,EAAE,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC;YAClC,GAAG,EAAE,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC;YAC5B,yBAAyB;YACzB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,MAAM,EAAE,IAAI,CAAC,MAAM;SACnB,CAAA;QAED,OAAO,SAAS,CAAA;IACjB,CAAC;IAED,IAAI;QACH,OAAO,IAAI,CAAC,MAAM,EAAE,CAAA;IACrB,CAAC;CACD;AAED,YAAY"}
1
+ {"version":3,"file":"composition.js","sourceRoot":"","sources":["../../lib/base/composition.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/coverage/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAA;AAEzG,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEjD,eAAO,MAAM,iBAAiB,gCAAiC,CAAA;AAE/D;;GAEG;AACH,eAAO,MAAM,qBAAqB,aAAa,CAAA;AAE/C;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,YAAY,CAAA;AAE3C;;GAEG;AACH,eAAO,MAAM,wBAAwB,MAAM,CAAA;AAE3C;;GAEG;AACH,eAAO,MAAM,eAAe;;;CAGlB,CAAA;AAEV;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,yBAAyB,CAE3E;AAkBD;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,sBAAsB,EAGlD,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/coverage/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAA;AAEzG,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEjD,eAAO,MAAM,iBAAiB,gCAAiC,CAAA;AAE/D;;GAEG;AACH,eAAO,MAAM,qBAAqB,aAAa,CAAA;AAE/C;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,YAAY,CAAA;AAE3C;;GAEG;AACH,eAAO,MAAM,wBAAwB,MAAM,CAAA;AAE3C;;GAEG;AACH,eAAO,MAAM,eAAe;aAC3B,UAAU,EAAE,kBAAkB;aAC9B,MAAM,EAAE,qBAAqB;CACpB,CAAA;AAEV;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,yBAAyB,CAE3E;AAkBD;;;;GAIG;AACH,eAAO,MAAM,cAAc,EAAE,sBAAsB,EAGlD,CAAA"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @copyright Sister Software.
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ */
6
+ export * from "#planetary/layers";
7
+ export * from "#planetary/sources";
8
+ export * from "#planetary/style";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/planetary/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,mBAAmB,CAAA;AACjC,cAAc,oBAAoB,CAAA;AAClC,cAAc,kBAAkB,CAAA"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @copyright Sister Software.
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ */
6
+ export * from "#planetary/layers";
7
+ export * from "#planetary/sources";
8
+ export * from "#planetary/style";
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../lib/planetary/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,mBAAmB,CAAA;AACjC,cAAc,oBAAoB,CAAA;AAClC,cAAc,kBAAkB,CAAA"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * @copyright Sister Software.
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ */
6
+ import type { BackgroundLayerSpecification, CircleLayerSpecification, HillshadeLayerSpecification, SymbolLayerSpecification } from "@maplibre/maplibre-gl-style-spec";
7
+ export interface PlanetaryPalette {
8
+ /**
9
+ * The body's own surface tone, under the relief. Named `space` for the layer it feeds, which paints the SPHERE under
10
+ * globe projection rather than the area around it — the field around the globe is the page behind a transparent
11
+ * canvas, and the app's stylesheet paints it.
12
+ */
13
+ space: string;
14
+ /**
15
+ * Where a slope faces the light. With `shadow` and `accent` these are what make one body's relief differ from
16
+ * another's; the tiles carry encoded elevation and no colour of their own.
17
+ */
18
+ reliefHighlight: string;
19
+ /**
20
+ * Where a slope faces away. Kept translucent so the surface tone reads through flat ground, which would otherwise
21
+ * take the shadow colour everywhere the terrain is level.
22
+ */
23
+ reliefShadow: string;
24
+ /**
25
+ * The steepness wash, translucent for the same reason.
26
+ */
27
+ reliefAccent: string;
28
+ labelColor: string;
29
+ labelHalo: string;
30
+ selection: string;
31
+ }
32
+ /**
33
+ * One palette per body with a published style. The record's keys are the bodies a style can be composed for, so a body
34
+ * without a row here has no style rather than a wrong one.
35
+ */
36
+ export declare const PALETTES: {
37
+ readonly moon: {
38
+ readonly space: "#8d8f95";
39
+ readonly reliefHighlight: "#eef2f8";
40
+ readonly reliefShadow: "rgba(20, 26, 40, 0.55)";
41
+ readonly reliefAccent: "rgba(90, 100, 120, 0.4)";
42
+ readonly labelColor: "#e8eef7";
43
+ readonly labelHalo: "#05070d";
44
+ readonly selection: "#7fd1ff";
45
+ };
46
+ readonly mars: {
47
+ readonly space: "#9a5334";
48
+ readonly reliefHighlight: "#f4a26b";
49
+ readonly reliefShadow: "rgba(74, 29, 14, 0.55)";
50
+ readonly reliefAccent: "rgba(140, 58, 28, 0.4)";
51
+ readonly labelColor: "#f6e3d1";
52
+ readonly labelHalo: "#1a0c06";
53
+ readonly selection: "#ffb37f";
54
+ };
55
+ };
56
+ export type PlanetaryStyleBody = keyof typeof PALETTES;
57
+ /**
58
+ * The body's surface tone, under the relief. Under globe projection a background layer paints the SPHERE, not the
59
+ * viewport, so this is the ground the hillshade shades and not the field around the globe; the app's stylesheet paints
60
+ * that behind a transparent canvas.
61
+ */
62
+ export declare const PlanetarySpaceLayerID: "planetary/space";
63
+ /**
64
+ * The hillshade raster layer, present only when the body has a hillshade tileset.
65
+ */
66
+ export declare const PlanetaryHillshadeLayerID: "planetary/hillshade";
67
+ /**
68
+ * The nomenclature label layer, the one an app reads feature properties from on a click.
69
+ */
70
+ export declare const PlanetaryLabelsLayerID: "planetary/nomenclature-labels";
71
+ /**
72
+ * The selection ring layer, the one an app sets a feature `id` filter on.
73
+ */
74
+ export declare const PlanetarySelectionLayerID: "planetary/selection";
75
+ export declare function spaceLayer(palette: PlanetaryPalette): BackgroundLayerSpecification;
76
+ /**
77
+ * The relief, shaded at draw time from the body's encoded elevation. The tiles carry height and no colour, so every
78
+ * body-specific decision is here: a greyscale image could not be tinted at all, because MapLibre's raster paint
79
+ * properties are brightness, contrast, saturation and hue-rotate, and the last two do nothing without chroma.
80
+ */
81
+ export declare function hillshadeLayer(palette: PlanetaryPalette): HillshadeLayerSpecification;
82
+ /**
83
+ * Labels by feature scale: the tile's per-feature `minzoom` already hides a small crater at a low zoom, so the symbol
84
+ * layer only sizes and prioritizes. `featureTypeCode` is the IAU feature-type code carried in the tile properties (AA
85
+ * crater, MO mons, VA vallis, ME mare, PL planitia, SF satellite feature); `diameterKm` is the feature's diameter.
86
+ */
87
+ export declare function labelLayer(palette: PlanetaryPalette): SymbolLayerSpecification;
88
+ /**
89
+ * The selection ring. Its filter matches no feature until the app sets one by `id`, so the layer ships in the style and
90
+ * the app never inserts a layer at runtime.
91
+ */
92
+ export declare function selectionLayer(palette: PlanetaryPalette): CircleLayerSpecification;
93
+ //# sourceMappingURL=layers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layers.d.ts","sourceRoot":"","sources":["../../lib/planetary/layers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACX,4BAA4B,EAC5B,wBAAwB,EACxB,2BAA2B,EAC3B,wBAAwB,EACxB,MAAM,kCAAkC,CAAA;AAMzC,MAAM,WAAW,gBAAgB;IAChC;;;;OAIG;IACH,KAAK,EAAE,MAAM,CAAA;IACb;;;OAGG;IACH,eAAe,EAAE,MAAM,CAAA;IACvB;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAA;IACpB;;OAEG;IACH,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CACjB;AAED;;;GAGG;AACH,eAAO,MAAM,QAAQ;;iBAEnB,KAAK,EAAE,SAAS;iBAChB,eAAe,EAAE,SAAS;iBAC1B,YAAY,EAAE,wBAAwB;iBACtC,YAAY,EAAE,yBAAyB;iBACvC,UAAU,EAAE,SAAS;iBACrB,SAAS,EAAE,SAAS;iBACpB,SAAS,EAAE,SAAS;;;iBAGpB,KAAK,EAAE,SAAS;iBAChB,eAAe,EAAE,SAAS;iBAC1B,YAAY,EAAE,wBAAwB;iBACtC,YAAY,EAAE,wBAAwB;iBACtC,UAAU,EAAE,SAAS;iBACrB,SAAS,EAAE,SAAS;iBACpB,SAAS,EAAE,SAAS;;CAE+B,CAAA;AAErD,MAAM,MAAM,kBAAkB,GAAG,MAAM,OAAO,QAAQ,CAAA;AAItD;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,mBAAwC,CAAA;AAE1E;;GAEG;AACH,eAAO,MAAM,yBAAyB,uBAA4C,CAAA;AAElF;;GAEG;AACH,eAAO,MAAM,sBAAsB,iCAAsD,CAAA;AAEzF;;GAEG;AACH,eAAO,MAAM,yBAAyB,uBAA4C,CAAA;AAQlF,wBAAgB,UAAU,CAAC,OAAO,EAAE,gBAAgB,GAAG,4BAA4B,CAMlF;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,gBAAgB,GAAG,2BAA2B,CAcrF;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,gBAAgB,GAAG,wBAAwB,CAiB9E;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,gBAAgB,GAAG,wBAAwB,CAclF"}
@@ -0,0 +1,126 @@
1
+ /**
2
+ * @copyright Sister Software.
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ */
6
+ import { PlanetaryHillshadeSourceID, PlanetaryNomenclatureSourceID } from "#planetary/sources";
7
+ import { PROTOMAPS_FONT_REGULAR } from "#styles/fonts";
8
+ import { LayerID } from "#styles/layers";
9
+ /**
10
+ * One palette per body with a published style. The record's keys are the bodies a style can be composed for, so a body
11
+ * without a row here has no style rather than a wrong one.
12
+ */
13
+ export const PALETTES = {
14
+ moon: {
15
+ space: "#8d8f95",
16
+ reliefHighlight: "#eef2f8",
17
+ reliefShadow: "rgba(20, 26, 40, 0.55)",
18
+ reliefAccent: "rgba(90, 100, 120, 0.4)",
19
+ labelColor: "#e8eef7",
20
+ labelHalo: "#05070d",
21
+ selection: "#7fd1ff",
22
+ },
23
+ mars: {
24
+ space: "#9a5334",
25
+ reliefHighlight: "#f4a26b",
26
+ reliefShadow: "rgba(74, 29, 14, 0.55)",
27
+ reliefAccent: "rgba(140, 58, 28, 0.4)",
28
+ labelColor: "#f6e3d1",
29
+ labelHalo: "#1a0c06",
30
+ selection: "#ffb37f",
31
+ },
32
+ };
33
+ const PLANETARY_NAMESPACE = "planetary";
34
+ /**
35
+ * The body's surface tone, under the relief. Under globe projection a background layer paints the SPHERE, not the
36
+ * viewport, so this is the ground the hillshade shades and not the field around the globe; the app's stylesheet paints
37
+ * that behind a transparent canvas.
38
+ */
39
+ export const PlanetarySpaceLayerID = LayerID(PLANETARY_NAMESPACE, "space");
40
+ /**
41
+ * The hillshade raster layer, present only when the body has a hillshade tileset.
42
+ */
43
+ export const PlanetaryHillshadeLayerID = LayerID(PLANETARY_NAMESPACE, "hillshade");
44
+ /**
45
+ * The nomenclature label layer, the one an app reads feature properties from on a click.
46
+ */
47
+ export const PlanetaryLabelsLayerID = LayerID(PLANETARY_NAMESPACE, "nomenclature-labels");
48
+ /**
49
+ * The selection ring layer, the one an app sets a feature `id` filter on.
50
+ */
51
+ export const PlanetarySelectionLayerID = LayerID(PLANETARY_NAMESPACE, "selection");
52
+ /**
53
+ * The IAU feature-type codes drawn as spaced capitals: a mare, planitia, oceanus or terra spans a region rather than
54
+ * marking a point, and the wide setting reads as an area name the way a printed atlas sets one.
55
+ */
56
+ const REGION_FEATURE_TYPE_CODES = ["ME", "PL", "OC", "TA"];
57
+ export function spaceLayer(palette) {
58
+ return {
59
+ id: PlanetarySpaceLayerID,
60
+ type: "background",
61
+ paint: { "background-color": palette.space },
62
+ };
63
+ }
64
+ /**
65
+ * The relief, shaded at draw time from the body's encoded elevation. The tiles carry height and no colour, so every
66
+ * body-specific decision is here: a greyscale image could not be tinted at all, because MapLibre's raster paint
67
+ * properties are brightness, contrast, saturation and hue-rotate, and the last two do nothing without chroma.
68
+ */
69
+ export function hillshadeLayer(palette) {
70
+ return {
71
+ id: PlanetaryHillshadeLayerID,
72
+ type: "hillshade",
73
+ source: PlanetaryHillshadeSourceID,
74
+ paint: {
75
+ // Under 1: these bodies carry relief far sharper than Earth's relative to their radius, and unexaggerated
76
+ // shading reads as noise at globe zooms.
77
+ "hillshade-exaggeration": 0.6,
78
+ "hillshade-highlight-color": palette.reliefHighlight,
79
+ "hillshade-shadow-color": palette.reliefShadow,
80
+ "hillshade-accent-color": palette.reliefAccent,
81
+ },
82
+ };
83
+ }
84
+ /**
85
+ * Labels by feature scale: the tile's per-feature `minzoom` already hides a small crater at a low zoom, so the symbol
86
+ * layer only sizes and prioritizes. `featureTypeCode` is the IAU feature-type code carried in the tile properties (AA
87
+ * crater, MO mons, VA vallis, ME mare, PL planitia, SF satellite feature); `diameterKm` is the feature's diameter.
88
+ */
89
+ export function labelLayer(palette) {
90
+ return {
91
+ id: PlanetaryLabelsLayerID,
92
+ type: "symbol",
93
+ source: PlanetaryNomenclatureSourceID,
94
+ "source-layer": "nomenclature",
95
+ layout: {
96
+ "text-field": ["get", "name"],
97
+ "text-font": [PROTOMAPS_FONT_REGULAR],
98
+ "text-size": ["interpolate", ["linear"], ["coalesce", ["get", "diameterKm"], 0], 0, 11, 100, 14, 1000, 18],
99
+ "text-transform": ["match", ["get", "featureTypeCode"], REGION_FEATURE_TYPE_CODES, "uppercase", "none"],
100
+ "text-letter-spacing": ["match", ["get", "featureTypeCode"], REGION_FEATURE_TYPE_CODES, 0.15, 0.02],
101
+ "symbol-sort-key": ["-", 0, ["coalesce", ["get", "diameterKm"], 0]],
102
+ "text-allow-overlap": false,
103
+ },
104
+ paint: { "text-color": palette.labelColor, "text-halo-color": palette.labelHalo, "text-halo-width": 1.2 },
105
+ };
106
+ }
107
+ /**
108
+ * The selection ring. Its filter matches no feature until the app sets one by `id`, so the layer ships in the style and
109
+ * the app never inserts a layer at runtime.
110
+ */
111
+ export function selectionLayer(palette) {
112
+ return {
113
+ id: PlanetarySelectionLayerID,
114
+ type: "circle",
115
+ source: PlanetaryNomenclatureSourceID,
116
+ "source-layer": "nomenclature",
117
+ filter: ["==", ["get", "id"], ""],
118
+ paint: {
119
+ "circle-radius": 14,
120
+ "circle-color": "transparent",
121
+ "circle-stroke-color": palette.selection,
122
+ "circle-stroke-width": 2,
123
+ },
124
+ };
125
+ }
126
+ //# sourceMappingURL=layers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layers.js","sourceRoot":"","sources":["../../lib/planetary/layers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @copyright Sister Software.
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ */
6
+ import type { RasterDEMSourceSpecification, VectorSourceSpecification } from "@maplibre/maplibre-gl-style-spec";
7
+ import { TileSetSourceID } from "#styles/sources";
8
+ /**
9
+ * The vector source carrying a body's IAU nomenclature: one `nomenclature` source layer of named features.
10
+ */
11
+ export declare const PlanetaryNomenclatureSourceID: TileSetSourceID<"nomenclature">;
12
+ /**
13
+ * The elevation source a body's relief is shaded from. The archive carries terrarium-encoded height rather than a
14
+ * shaded picture, so the shading happens at draw time and each body can be tinted from the style.
15
+ */
16
+ export declare const PlanetaryHillshadeSourceID: TileSetSourceID<"hillshade">;
17
+ /**
18
+ * MapLibre resolves a TileJSON `url` itself: tiles, bounds, zoom range and attribution all come from the tile worker's
19
+ * document, so nothing here restates them.
20
+ */
21
+ export declare function nomenclatureSource(tileJSONURL: string): VectorSourceSpecification;
22
+ export declare function hillshadeSource(tileJSONURL: string): RasterDEMSourceSpecification;
23
+ //# sourceMappingURL=sources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sources.d.ts","sourceRoot":"","sources":["../../lib/planetary/sources.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,4BAA4B,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAA;AAE/G,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEjD;;GAEG;AACH,eAAO,MAAM,6BAA6B,iCAAkC,CAAA;AAE5E;;;GAGG;AACH,eAAO,MAAM,0BAA0B,8BAA+B,CAAA;AAEtE;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,yBAAyB,CAKjF;AAED,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,4BAA4B,CAQjF"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * @copyright Sister Software.
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ */
6
+ import { TileSetSourceID } from "#styles/sources";
7
+ /**
8
+ * The vector source carrying a body's IAU nomenclature: one `nomenclature` source layer of named features.
9
+ */
10
+ export const PlanetaryNomenclatureSourceID = TileSetSourceID("nomenclature");
11
+ /**
12
+ * The elevation source a body's relief is shaded from. The archive carries terrarium-encoded height rather than a
13
+ * shaded picture, so the shading happens at draw time and each body can be tinted from the style.
14
+ */
15
+ export const PlanetaryHillshadeSourceID = TileSetSourceID("hillshade");
16
+ /**
17
+ * MapLibre resolves a TileJSON `url` itself: tiles, bounds, zoom range and attribution all come from the tile worker's
18
+ * document, so nothing here restates them.
19
+ */
20
+ export function nomenclatureSource(tileJSONURL) {
21
+ return {
22
+ type: "vector",
23
+ url: tileJSONURL,
24
+ };
25
+ }
26
+ export function hillshadeSource(tileJSONURL) {
27
+ return {
28
+ type: "raster-dem",
29
+ // The build writes `height = (R * 256 + G + B / 256) - 32768`, which is terrarium's, not Mapbox's.
30
+ encoding: "terrarium",
31
+ url: tileJSONURL,
32
+ tileSize: 256,
33
+ };
34
+ }
35
+ //# sourceMappingURL=sources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sources.js","sourceRoot":"","sources":["../../lib/planetary/sources.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEjD;;GAEG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,eAAe,CAAC,cAAc,CAAC,CAAA;AAE5E;;;GAGG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,eAAe,CAAC,WAAW,CAAC,CAAA;AAEtE;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,WAAmB;IACrD,OAAO;QACN,IAAI,EAAE,QAAQ;QACd,GAAG,EAAE,WAAW;KAChB,CAAA;AACF,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,WAAmB;IAClD,OAAO;QACN,IAAI,EAAE,YAAY;QAClB,mGAAmG;QACnG,QAAQ,EAAE,WAAW;QACrB,GAAG,EAAE,WAAW;QAChB,QAAQ,EAAE,GAAG;KACb,CAAA;AACF,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * @copyright Sister Software.
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ */
6
+ import type { StyleSpecification } from "@maplibre/maplibre-gl-style-spec";
7
+ import { type PlanetaryStyleBody } from "#planetary/layers";
8
+ export interface PlanetaryStyleOptions {
9
+ body: PlanetaryStyleBody;
10
+ /**
11
+ * The TileJSON document of the body's nomenclature tileset.
12
+ */
13
+ nomenclatureTileJSONURL: string;
14
+ /**
15
+ * The TileJSON document of the body's hillshade tileset. Without one the style draws labels over bare space.
16
+ */
17
+ hillshadeTileJSONURL?: string;
18
+ }
19
+ /**
20
+ * A body's whole style: space, the hillshade when a tileset exists, the nomenclature labels, and the selection ring. No
21
+ * Earth layer, no Earth DEM and no sprite reach the result, so a viewer loads nothing Earth-shaped.
22
+ */
23
+ export declare function createPlanetaryStyle(options: PlanetaryStyleOptions): StyleSpecification;
24
+ //# sourceMappingURL=style.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"style.d.ts","sourceRoot":"","sources":["../../lib/planetary/style.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAuB,kBAAkB,EAAE,MAAM,kCAAkC,CAAA;AAG/F,OAAO,EAIN,KAAK,kBAAkB,EAGvB,MAAM,mBAAmB,CAAA;AAQ1B,MAAM,WAAW,qBAAqB;IACrC,IAAI,EAAE,kBAAkB,CAAA;IACxB;;OAEG;IACH,uBAAuB,EAAE,MAAM,CAAA;IAC/B;;OAEG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAA;CAC7B;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,qBAAqB,GAAG,kBAAkB,CA6BvF"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * @copyright Sister Software.
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ */
6
+ import { StyleSpecificationComposer } from "#base/composition";
7
+ import { hillshadeLayer, labelLayer, PALETTES, selectionLayer, spaceLayer, } from "#planetary/layers";
8
+ import { hillshadeSource, nomenclatureSource, PlanetaryHillshadeSourceID, PlanetaryNomenclatureSourceID, } from "#planetary/sources";
9
+ /**
10
+ * A body's whole style: space, the hillshade when a tileset exists, the nomenclature labels, and the selection ring. No
11
+ * Earth layer, no Earth DEM and no sprite reach the result, so a viewer loads nothing Earth-shaped.
12
+ */
13
+ export function createPlanetaryStyle(options) {
14
+ const palette = PALETTES[options.body];
15
+ const sources = {
16
+ [PlanetaryNomenclatureSourceID]: nomenclatureSource(options.nomenclatureTileJSONURL),
17
+ };
18
+ if (options.hillshadeTileJSONURL) {
19
+ sources[PlanetaryHillshadeSourceID] = hillshadeSource(options.hillshadeTileJSONURL);
20
+ }
21
+ const baseLayers = [
22
+ spaceLayer(palette),
23
+ ...(options.hillshadeTileJSONURL ? [hillshadeLayer(palette)] : []),
24
+ labelLayer(palette),
25
+ selectionLayer(palette),
26
+ ];
27
+ const style = new StyleSpecificationComposer({
28
+ sources,
29
+ baseLayers,
30
+ hillshadeSource: null,
31
+ sprite: null,
32
+ sky: { "sky-color": palette.space, "horizon-color": palette.space },
33
+ }).toJSON();
34
+ // MapLibre 6 reads the projection from the STYLE. Passed as a map option instead it is ignored and the body
35
+ // renders flat, which is a mercator sheet of terrain rather than a world.
36
+ return { ...style, projection: { type: "globe" } };
37
+ }
38
+ //# sourceMappingURL=style.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"style.js","sourceRoot":"","sources":["../../lib/planetary/style.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAA;AAC9D,OAAO,EACN,cAAc,EACd,UAAU,EACV,QAAQ,EAER,cAAc,EACd,UAAU,GACV,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EACN,eAAe,EACf,kBAAkB,EAClB,0BAA0B,EAC1B,6BAA6B,GAC7B,MAAM,oBAAoB,CAAA;AAc3B;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAA8B;IAClE,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IAEtC,MAAM,OAAO,GAAwC;QACpD,CAAC,6BAA6B,CAAC,EAAE,kBAAkB,CAAC,OAAO,CAAC,uBAAuB,CAAC;KACpF,CAAA;IAED,IAAI,OAAO,CAAC,oBAAoB,EAAE,CAAC;QAClC,OAAO,CAAC,0BAA0B,CAAC,GAAG,eAAe,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAA;IACpF,CAAC;IAED,MAAM,UAAU,GAAG;QAClB,UAAU,CAAC,OAAO,CAAC;QACnB,GAAG,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAClE,UAAU,CAAC,OAAO,CAAC;QACnB,cAAc,CAAC,OAAO,CAAC;KACvB,CAAA;IAED,MAAM,KAAK,GAAG,IAAI,0BAA0B,CAAC;QAC5C,OAAO;QACP,UAAU;QACV,eAAe,EAAE,IAAI;QACrB,MAAM,EAAE,IAAI;QACZ,GAAG,EAAE,EAAE,WAAW,EAAE,OAAO,CAAC,KAAK,EAAE,eAAe,EAAE,OAAO,CAAC,KAAK,EAAE;KACnE,CAAC,CAAC,MAAM,EAAE,CAAA;IAEX,4GAA4G;IAC5G,0EAA0E;IAC1E,OAAO,EAAE,GAAG,KAAK,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,CAAA;AACnD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/race-dots/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,wBAAwB,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAA;AAE3G,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEjD;;GAEG;AACH,eAAO,MAAM,iBAAiB,iCAAkC,CAAA;AAEhE;;GAEG;AACH,eAAO,MAAM,sBAAsB,SAAS,CAAA;AAE5C;;GAEG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;EAMrB,CAAA;AAEV;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,yBAAyB,CAE3E;AAmBD;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,wBAAwB,EAEpD,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/race-dots/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,wBAAwB,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAA;AAE3G,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEjD;;GAEG;AACH,eAAO,MAAM,iBAAiB,iCAAkC,CAAA;AAEhE;;GAEG;AACH,eAAO,MAAM,sBAAsB,SAAS,CAAA;AAE5C;;GAEG;AACH,eAAO,MAAM,kBAAkB;aAC5B,EAAE,EAAE,iBAAiB;aAAE,KAAK,EAAE,cAAc;aAAE,KAAK,EAAE,SAAS;aAAE,KAAK,YAAG,OAAO;;aAC/E,EAAE,EAAE,iBAAiB;aAAE,KAAK,EAAE,cAAc;aAAE,KAAK,EAAE,SAAS;aAAE,KAAK,YAAG,OAAO;;aAC/E,EAAE,EAAE,oBAAoB;aAAE,KAAK,EAAE,iBAAiB;aAAE,KAAK,EAAE,SAAS;aAAE,KAAK,YAAG,UAAU;;aACxF,EAAE,EAAE,iBAAiB;aAAE,KAAK,EAAE,cAAc;aAAE,KAAK,EAAE,SAAS;aAAE,KAAK,YAAG,OAAO;;aAC/E,EAAE,EAAE,iBAAiB;aAAE,KAAK,EAAE,cAAc;aAAE,KAAK,EAAE,SAAS;aAAE,KAAK,YAAG,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO;EACjG,CAAA;AAEV;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,yBAAyB,CAE3E;AAmBD;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,wBAAwB,EAEpD,CAAA"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * @copyright Sister Software.
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * The glyph stacks a symbol layer may name. MapLibre draws NO text at all when a glyph range answers 404 — not a
7
+ * fallback face, nothing — so a `text-font` naming an absent stack blanks every label in the style at every zoom,
8
+ * with no console error a reader would connect to the missing labels.
9
+ *
10
+ * The mirror behind `PROTOMAPS_GLYPHS_URL` serves five stacks: `Noto Sans Regular`, `Noto Sans Medium`,
11
+ * `Noto Sans Italic`, `Fira Code Regular` and `Fira Code Medium`. It serves no Fira Sans, and no
12
+ * `Open Sans Regular` — which is MapLibre's own default, so a symbol layer that omits `text-font` also draws
13
+ * nothing. Name a constant from this file rather than a string literal.
14
+ */
15
+ /**
16
+ * The regular text stack: body labels, point features, place names.
17
+ */
18
+ export declare const PROTOMAPS_FONT_REGULAR = "Noto Sans Regular";
19
+ //# sourceMappingURL=fonts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fonts.d.ts","sourceRoot":"","sources":["../../lib/styles/fonts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH;;GAEG;AACH,eAAO,MAAM,sBAAsB,sBAAsB,CAAA"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * @copyright Sister Software.
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * The glyph stacks a symbol layer may name. MapLibre draws NO text at all when a glyph range answers 404 — not a
7
+ * fallback face, nothing — so a `text-font` naming an absent stack blanks every label in the style at every zoom,
8
+ * with no console error a reader would connect to the missing labels.
9
+ *
10
+ * The mirror behind `PROTOMAPS_GLYPHS_URL` serves five stacks: `Noto Sans Regular`, `Noto Sans Medium`,
11
+ * `Noto Sans Italic`, `Fira Code Regular` and `Fira Code Medium`. It serves no Fira Sans, and no
12
+ * `Open Sans Regular` — which is MapLibre's own default, so a symbol layer that omits `text-font` also draws
13
+ * nothing. Name a constant from this file rather than a string literal.
14
+ */
15
+ /**
16
+ * The regular text stack: body labels, point features, place names.
17
+ */
18
+ export const PROTOMAPS_FONT_REGULAR = "Noto Sans Regular";
19
+ //# sourceMappingURL=fonts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fonts.js","sourceRoot":"","sources":["../../lib/styles/fonts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,mBAAmB,CAAA"}
@@ -3,6 +3,7 @@
3
3
  * @license AGPL-3.0
4
4
  * @author Teffen Ellis, et al.
5
5
  */
6
+ export * from "#styles/fonts";
6
7
  export * from "#styles/layers";
7
8
  export * from "#styles/sources";
8
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/styles/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,gBAAgB,CAAA;AAC9B,cAAc,iBAAiB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/styles/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,eAAe,CAAA;AAC7B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,iBAAiB,CAAA"}
@@ -3,6 +3,7 @@
3
3
  * @license AGPL-3.0
4
4
  * @author Teffen Ellis, et al.
5
5
  */
6
+ export * from "#styles/fonts";
6
7
  export * from "#styles/layers";
7
8
  export * from "#styles/sources";
8
9
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../lib/styles/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,gBAAgB,CAAA;AAC9B,cAAc,iBAAiB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../lib/styles/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,eAAe,CAAA;AAC7B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,iBAAiB,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"layers.d.ts","sourceRoot":"","sources":["../../lib/styles/layers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAA;AAE1E,QAAA,MAAM,KAAK,EAAE,OAAO,MAAuB,CAAA;AAC3C,QAAA,MAAM,KAAK,EAAE,OAAO,MAAuB,CAAA;AAE3C;;GAEG;AACH,wBAAgB,OAAO,CAAC,SAAS,SAAS,MAAM,EAAE,OAAO,SAAS,MAAM,EACvE,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE,OAAO,GACZ,GAAG,SAAS,IAAI,OAAO,EAAE,CAE3B;AAED,MAAM,MAAM,2BAA2B,CAAC,CAAC,SAAS,kBAAkB,GAAG,kBAAkB,IAAI,CAAC,GAC7F,CAAC;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,KAAK,CAAA;CAAE,GAAG;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC,CAAA;AAElF,MAAM,MAAM,0BAA0B,CAAC,CAAC,SAAS,kBAAkB,GAAG,kBAAkB,IAAI,CAAC,GAAG;IAC/F,CAAC,KAAK,CAAC,CAAC,EAAE,0BAA0B,CAAA;IACpC,CAAC,KAAK,CAAC,CAAC,EAAE,0BAA0B,CAAA;CACpC,CAAA;AAED,qBAAa,sBAAsB;;gBAItB,WAAW,EAAE,kBAAkB,EAAE;IA8BrC,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC,0BAA0B,CAAC;IAsBhE,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,0BAA0B,CAAC;IAI1D,MAAM,CAAC,KAAK,EAAE,2BAA2B;IA6CzC,MAAM,CAAC,OAAO,EAAE,MAAM;CAkB7B"}
1
+ {"version":3,"file":"layers.d.ts","sourceRoot":"","sources":["../../lib/styles/layers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAA;AAE1E,QAAA,MAAM,KAAK,EAAE,OAAO,MAAuB,CAAA;AAC3C,QAAA,MAAM,KAAK,EAAE,OAAO,MAAuB,CAAA;AAE3C;;GAEG;AACH,wBAAgB,OAAO,CAAC,SAAS,SAAS,MAAM,EAAE,OAAO,SAAS,MAAM,EACvE,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE,OAAO,GACZ,GAAG,SAAS,IAAI,OAAO,EAAE,CAE3B;AAED,MAAM,MAAM,2BAA2B,CAAC,CAAC,SAAS,kBAAkB,GAAG,kBAAkB,IAAI,CAAC,GAC7F,CAAC;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,KAAK,CAAA;CAAE,GAAG;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC,CAAA;AAElF,MAAM,MAAM,0BAA0B,CAAC,CAAC,SAAS,kBAAkB,GAAG,kBAAkB,IAAI,CAAC,GAAG;IAC/F,CAAC,KAAK,CAAC,CAAC,EAAE,0BAA0B,CAAA;IACpC,CAAC,KAAK,CAAC,CAAC,EAAE,0BAA0B,CAAA;CACpC,CAAA;AAED,qBAAa,sBAAsB;;IAIlC,YAAY,WAAW,EAAE,kBAAkB,EAAE,EA4B5C;IAEO,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC,0BAA0B,CAAC,CAoBvE;IAEO,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,0BAA0B,CAAC,CAEhE;IAEM,MAAM,CAAC,KAAK,EAAE,2BAA2B,QA2C/C;IAEM,MAAM,CAAC,OAAO,EAAE,MAAM,QAiB5B;CACD"}
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../lib/tiles/api.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAqB,MAAM,qBAAqB,CAAA;AAClE,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAA;AAE5D,OAAO,KAAK,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AAG3E;;GAEG;AACH,eAAO,MAAM,OAAO;;;;;EAKlB,CAAA;AAEF,wBAAgB,sBAAsB,CACrC,SAAS,EAAE,eAAe,GACxB,OAAO,CAAC,CAAC,eAAe,EAAE,yBAAyB,CAAC,CAAC,CAgBvD;AAED,wBAAsB,mBAAmB,CAAC,UAAU,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAWrG"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../lib/tiles/api.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAqB,MAAM,qBAAqB,CAAA;AAClE,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAA;AAE5D,OAAO,KAAK,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AAG3E;;GAEG;AACH,eAAO,MAAM,OAAO;;;QAGlB,OAAO;;EAEP,CAAA;AAEF,wBAAgB,sBAAsB,CACrC,SAAS,EAAE,eAAe,GACxB,OAAO,CAAC,CAAC,eAAe,EAAE,yBAAyB,CAAC,CAAC,CAgBvD;AAED,wBAAsB,mBAAmB,CAAC,UAAU,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAWrG"}
@@ -1 +1 @@
1
- {"root":["../test/unit/base/composition.test.ts","../test/unit/tiles/coords.test.ts"],"version":"6.0.3"}
1
+ {"version":"7.0.2","root":["../test/unit/base/composition.test.ts","../test/unit/planetary/style.test.ts","../test/unit/tiles/coords.test.ts"],"packageJsons":["../../../node_modules/@mapbox/point-geometry/package.json","../../../node_modules/@mapbox/tiny-sdf/package.json","../../../node_modules/@maplibre/geojson-vt/package.json","../../../node_modules/@maplibre/maplibre-gl-style-spec/package.json","../../../node_modules/@maplibre/vt-pbf/package.json","../../../node_modules/@standard-schema/spec/package.json","../../../node_modules/@types/chai/package.json","../../../node_modules/@types/deep-eql/package.json","../../../node_modules/@types/node/package.json","../../../node_modules/@vitest/browser-playwright/package.json","../../../node_modules/@vitest/coverage-v8/package.json","../../../node_modules/@vitest/expect/package.json","../../../node_modules/@vitest/mocker/package.json","../../../node_modules/@vitest/pretty-format/package.json","../../../node_modules/@vitest/runner/package.json","../../../node_modules/@vitest/snapshot/package.json","../../../node_modules/@vitest/spy/package.json","../../../node_modules/@vitest/utils/package.json","../../../node_modules/assertion-error/package.json","../../../node_modules/chai/package.json","../../../node_modules/deep-eql/package.json","../../../node_modules/esbuild/package.json","../../../node_modules/events/package.json","../../../node_modules/expect-type/package.json","../../../node_modules/gl-matrix/package.json","../../../node_modules/jiti/package.json","../../../node_modules/jsdom/package.json","../../../node_modules/kdbush/package.json","../../../node_modules/maplibre-gl/package.json","../../../node_modules/punycode/package.json","../../../node_modules/string_decoder/package.json","../../../node_modules/tagged-tag/package.json","../../../node_modules/terser/package.json","../../../node_modules/tinybench/package.json","../../../node_modules/tinyrainbow/package.json","../../../node_modules/type-fest/package.json","../../../node_modules/undici-types/package.json","../../../node_modules/vite/package.json","../../../node_modules/vitest/package.json","../../../node_modules/yaml/package.json","../package.json"],"missingPackageJsons":["../../../node_modules/@edge-runtime/vm/package.json","../../../node_modules/@maplibre/geojson-vt/dist/package.json","../../../node_modules/@maplibre/maplibre-gl-style-spec/dist/package.json","../../../node_modules/@maplibre/vt-pbf/dist/package.json","../../../node_modules/@opentelemetry/api/package.json","../../../node_modules/@standard-schema/spec/dist/package.json","../../../node_modules/@types/assert/package.json","../../../node_modules/@types/assert/strict/package.json","../../../node_modules/@types/async_hooks/package.json","../../../node_modules/@types/buffer/package.json","../../../node_modules/@types/child_process/package.json","../../../node_modules/@types/cluster/package.json","../../../node_modules/@types/console/package.json","../../../node_modules/@types/constants/package.json","../../../node_modules/@types/crypto/package.json","../../../node_modules/@types/dgram/package.json","../../../node_modules/@types/diagnostics_channel/package.json","../../../node_modules/@types/dns/package.json","../../../node_modules/@types/dns/promises/package.json","../../../node_modules/@types/domain/package.json","../../../node_modules/@types/events/package.json","../../../node_modules/@types/fs/package.json","../../../node_modules/@types/fs/promises/package.json","../../../node_modules/@types/http/package.json","../../../node_modules/@types/http2/package.json","../../../node_modules/@types/https/package.json","../../../node_modules/@types/inspector/package.json","../../../node_modules/@types/inspector/promises/package.json","../../../node_modules/@types/module/package.json","../../../node_modules/@types/net/package.json","../../../node_modules/@types/node/assert/package.json","../../../node_modules/@types/node/dns/package.json","../../../node_modules/@types/node/fs/package.json","../../../node_modules/@types/node/inspector/package.json","../../../node_modules/@types/node/path/package.json","../../../node_modules/@types/node/readline/package.json","../../../node_modules/@types/node/stream/package.json","../../../node_modules/@types/node/test/package.json","../../../node_modules/@types/node/timers/package.json","../../../node_modules/@types/node/util/package.json","../../../node_modules/@types/node/web-globals/package.json","../../../node_modules/@types/node/zlib/package.json","../../../node_modules/@types/os/package.json","../../../node_modules/@types/path/package.json","../../../node_modules/@types/path/posix/package.json","../../../node_modules/@types/path/win32/package.json","../../../node_modules/@types/perf_hooks/package.json","../../../node_modules/@types/process/package.json","../../../node_modules/@types/punycode/package.json","../../../node_modules/@types/querystring/package.json","../../../node_modules/@types/readline/package.json","../../../node_modules/@types/readline/promises/package.json","../../../node_modules/@types/repl/package.json","../../../node_modules/@types/stream/consumers/package.json","../../../node_modules/@types/stream/iter/package.json","../../../node_modules/@types/stream/package.json","../../../node_modules/@types/stream/promises/package.json","../../../node_modules/@types/stream/web/package.json","../../../node_modules/@types/string_decoder/package.json","../../../node_modules/@types/timers/package.json","../../../node_modules/@types/timers/promises/package.json","../../../node_modules/@types/tls/package.json","../../../node_modules/@types/trace_events/package.json","../../../node_modules/@types/tty/package.json","../../../node_modules/@types/url/package.json","../../../node_modules/@types/util/package.json","../../../node_modules/@types/util/types/package.json","../../../node_modules/@types/v8/package.json","../../../node_modules/@types/vm/package.json","../../../node_modules/@types/wasi/package.json","../../../node_modules/@types/worker_threads/package.json","../../../node_modules/@types/zlib/package.json","../../../node_modules/@vitejs/devtools/package.json","../../../node_modules/@vitest/browser-preview/package.json","../../../node_modules/@vitest/browser-webdriverio/package.json","../../../node_modules/@vitest/coverage-istanbul/package.json","../../../node_modules/@vitest/expect/dist/package.json","../../../node_modules/@vitest/mocker/dist/package.json","../../../node_modules/@vitest/pretty-format/dist/package.json","../../../node_modules/@vitest/runner/dist/package.json","../../../node_modules/@vitest/runner/utils/package.json","../../../node_modules/@vitest/snapshot/dist/package.json","../../../node_modules/@vitest/spy/dist/package.json","../../../node_modules/@vitest/ui/package.json","../../../node_modules/@vitest/utils/diff/package.json","../../../node_modules/@vitest/utils/display/package.json","../../../node_modules/@vitest/utils/dist/package.json","../../../node_modules/assert/package.json","../../../node_modules/assert/strict/package.json","../../../node_modules/async_hooks/package.json","../../../node_modules/buffer/package.json","../../../node_modules/child_process/package.json","../../../node_modules/cluster/package.json","../../../node_modules/console/package.json","../../../node_modules/constants/package.json","../../../node_modules/crypto/package.json","../../../node_modules/dgram/package.json","../../../node_modules/diagnostics_channel/package.json","../../../node_modules/dns/package.json","../../../node_modules/dns/promises/package.json","../../../node_modules/domain/package.json","../../../node_modules/expect-type/dist/package.json","../../../node_modules/fs/package.json","../../../node_modules/fs/promises/package.json","../../../node_modules/happy-dom/package.json","../../../node_modules/http/package.json","../../../node_modules/http2/package.json","../../../node_modules/https/package.json","../../../node_modules/inspector/package.json","../../../node_modules/inspector/promises/package.json","../../../node_modules/less/package.json","../../../node_modules/maplibre-gl/dist/package.json","../../../node_modules/module/package.json","../../../node_modules/msw/package.json","../../../node_modules/net/package.json","../../../node_modules/os/package.json","../../../node_modules/path/package.json","../../../node_modules/path/posix/package.json","../../../node_modules/path/win32/package.json","../../../node_modules/perf_hooks/package.json","../../../node_modules/process/package.json","../../../node_modules/querystring/package.json","../../../node_modules/readline/package.json","../../../node_modules/readline/promises/package.json","../../../node_modules/repl/package.json","../../../node_modules/sass-embedded/package.json","../../../node_modules/sass/package.json","../../../node_modules/stream/consumers/package.json","../../../node_modules/stream/iter/package.json","../../../node_modules/stream/package.json","../../../node_modules/stream/promises/package.json","../../../node_modules/stream/web/package.json","../../../node_modules/stylus/package.json","../../../node_modules/sugarss/package.json","../../../node_modules/timers/package.json","../../../node_modules/timers/promises/package.json","../../../node_modules/tinybench/dist/package.json","../../../node_modules/tinyrainbow/dist/package.json","../../../node_modules/tls/package.json","../../../node_modules/trace_events/package.json","../../../node_modules/tsx/package.json","../../../node_modules/tty/package.json","../../../node_modules/type-fest/source/internal/package.json","../../../node_modules/type-fest/source/package.json","../../../node_modules/url/package.json","../../../node_modules/util/package.json","../../../node_modules/util/types/package.json","../../../node_modules/v8/package.json","../../../node_modules/vite/dist/node/chunks/package.json","../../../node_modules/vite/dist/node/package.json","../../../node_modules/vite/dist/package.json","../../../node_modules/vite/module-runner/package.json","../../../node_modules/vite/types/package.json","../../../node_modules/vitest/dist/chunks/package.json","../../../node_modules/vitest/dist/package.json","../../../node_modules/vm/package.json","../../../node_modules/wasi/package.json","../../../node_modules/worker_threads/package.json","../../../node_modules/zlib/package.json"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mailwoman/cartographer",
3
- "version": "9.3.0",
3
+ "version": "10.0.0",
4
4
  "description": "Mapping utilities for the Mailwoman geo-spatial data pipeline.",
5
5
  "license": "AGPL-3.0-only OR LicenseRef-Commercial",
6
6
  "contributors": [
@@ -82,6 +82,11 @@
82
82
  "types": "./out/base/composition.d.ts",
83
83
  "node": "./out/base/composition.js",
84
84
  "default": "./out/base/composition.js"
85
+ },
86
+ "./planetary": {
87
+ "types": "./out/planetary/index.d.ts",
88
+ "node": "./out/planetary/index.js",
89
+ "default": "./out/planetary/index.js"
85
90
  }
86
91
  },
87
92
  "publishConfig": {
@@ -132,6 +137,11 @@
132
137
  "types": "./out/base/composition.d.ts",
133
138
  "node": "./out/base/composition.js",
134
139
  "default": "./out/base/composition.js"
140
+ },
141
+ "./planetary": {
142
+ "types": "./out/planetary/index.d.ts",
143
+ "node": "./out/planetary/index.js",
144
+ "default": "./out/planetary/index.js"
135
145
  }
136
146
  },
137
147
  "imports": {
@@ -143,8 +153,8 @@
143
153
  }
144
154
  },
145
155
  "dependencies": {
146
- "@mailwoman/core": "9.3.0",
147
- "@mailwoman/tiger": "9.3.0",
156
+ "@mailwoman/core": "10.0.0",
157
+ "@mailwoman/tiger": "10.0.0",
148
158
  "@maplibre/maplibre-gl-style-spec": "^26.4.1",
149
159
  "@protomaps/basemaps": "^5.7.2",
150
160
  "d3-scale-chromatic": "^3.1.0",