@k2b/ui 0.35.0 → 0.37.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 (87) hide show
  1. package/dist/browser/actions/Dropdown.js +132 -116
  2. package/dist/browser/actions/Dropdown.js.map +1 -1
  3. package/dist/browser/actions/Tabs.js +18 -15
  4. package/dist/browser/actions/Tabs.js.map +1 -1
  5. package/dist/browser/chat/ChatComposer.js +58 -25
  6. package/dist/browser/chat/ChatComposer.js.map +1 -1
  7. package/dist/browser/content/MapView.js +128 -13
  8. package/dist/browser/content/MapView.js.map +1 -1
  9. package/dist/browser/content/MapViewFrame.js +1 -1
  10. package/dist/browser/content/MapViewFrame.js.map +1 -1
  11. package/dist/browser/content/MessageRow.js +164 -152
  12. package/dist/browser/content/MessageRow.js.map +1 -1
  13. package/dist/browser/content/index.js +1 -0
  14. package/dist/browser/content/index.js.map +1 -1
  15. package/dist/browser/content/map-view-glyphs.js +23 -0
  16. package/dist/browser/content/map-view-glyphs.js.map +1 -0
  17. package/dist/browser/content/map-view-live.js +45 -22
  18. package/dist/browser/content/map-view-live.js.map +1 -1
  19. package/dist/browser/content/map-view-snapshot.js +191 -0
  20. package/dist/browser/content/map-view-snapshot.js.map +1 -0
  21. package/dist/browser/content/map-view-types.js.map +1 -1
  22. package/dist/browser/feedback/prompts.js +23 -9
  23. package/dist/browser/feedback/prompts.js.map +1 -1
  24. package/dist/browser/inputs/Combobox.js +164 -82
  25. package/dist/browser/inputs/Combobox.js.map +1 -1
  26. package/dist/browser/inputs/RichSelect.js +86 -67
  27. package/dist/browser/inputs/RichSelect.js.map +1 -1
  28. package/dist/browser/inputs/TextInput.js +1 -1
  29. package/dist/browser/inputs/TextInput.js.map +1 -1
  30. package/dist/browser/internal/keyed-for.js +47 -0
  31. package/dist/browser/internal/keyed-for.js.map +1 -0
  32. package/dist/browser/layout/AppWorkspace.js +73 -70
  33. package/dist/browser/layout/AppWorkspace.js.map +1 -1
  34. package/dist/browser/layout/ScrollArea.js +4 -1
  35. package/dist/browser/layout/ScrollArea.js.map +1 -1
  36. package/dist/browser/text-editor/engine.js +13 -10
  37. package/dist/browser/text-editor/engine.js.map +1 -1
  38. package/dist/ssr/actions/Dropdown.js +101 -85
  39. package/dist/ssr/actions/Dropdown.js.map +1 -1
  40. package/dist/ssr/actions/Tabs.js +12 -9
  41. package/dist/ssr/actions/Tabs.js.map +1 -1
  42. package/dist/ssr/chat/ChatComposer.js +41 -15
  43. package/dist/ssr/chat/ChatComposer.js.map +1 -1
  44. package/dist/ssr/content/MapView.js +128 -13
  45. package/dist/ssr/content/MapView.js.map +1 -1
  46. package/dist/ssr/content/MapViewFrame.js +1 -1
  47. package/dist/ssr/content/MapViewFrame.js.map +1 -1
  48. package/dist/ssr/content/MessageRow.js +9 -2
  49. package/dist/ssr/content/MessageRow.js.map +1 -1
  50. package/dist/ssr/content/index.js +1 -0
  51. package/dist/ssr/content/index.js.map +1 -1
  52. package/dist/ssr/content/map-view-glyphs.js +23 -0
  53. package/dist/ssr/content/map-view-glyphs.js.map +1 -0
  54. package/dist/ssr/content/map-view-snapshot.js +191 -0
  55. package/dist/ssr/content/map-view-snapshot.js.map +1 -0
  56. package/dist/ssr/content/map-view-types.js.map +1 -1
  57. package/dist/ssr/feedback/prompts.js +22 -8
  58. package/dist/ssr/feedback/prompts.js.map +1 -1
  59. package/dist/ssr/inputs/Combobox.js +79 -28
  60. package/dist/ssr/inputs/Combobox.js.map +1 -1
  61. package/dist/ssr/inputs/RichSelect.js +47 -28
  62. package/dist/ssr/inputs/RichSelect.js.map +1 -1
  63. package/dist/ssr/inputs/TextInput.js.map +1 -1
  64. package/dist/ssr/internal/keyed-for.js +47 -0
  65. package/dist/ssr/internal/keyed-for.js.map +1 -0
  66. package/dist/ssr/layout/AppWorkspace.js +1 -1
  67. package/dist/ssr/layout/AppWorkspace.js.map +1 -1
  68. package/dist/ssr/layout/ScrollArea.js +4 -1
  69. package/dist/ssr/layout/ScrollArea.js.map +1 -1
  70. package/dist/ssr/text-editor/engine.js +13 -10
  71. package/dist/ssr/text-editor/engine.js.map +1 -1
  72. package/dist/styles.css +1 -1
  73. package/dist/types/content/MapViewFrame.d.ts +1 -1
  74. package/dist/types/content/MessageRow.d.ts +1 -1
  75. package/dist/types/content/index.d.ts +2 -1
  76. package/dist/types/content/map-view-glyphs.d.ts +5 -0
  77. package/dist/types/content/map-view-live.d.ts +1 -1
  78. package/dist/types/content/map-view-snapshot.d.ts +13 -0
  79. package/dist/types/content/map-view-types.d.ts +15 -0
  80. package/dist/types/feedback/prompts.d.ts +5 -0
  81. package/dist/types/inputs/Combobox.d.ts +12 -0
  82. package/dist/types/inputs/TextInput.d.ts +2 -1
  83. package/dist/types/internal/keyed-for.d.ts +13 -0
  84. package/dist/types/layout/AppWorkspace.d.ts +4 -1
  85. package/dist/types/layout/ScrollArea.d.ts +2 -0
  86. package/dist/types/text-editor/engine.d.ts +1 -1
  87. package/package.json +4 -2
@@ -24,6 +24,7 @@ import { prefersReducedMotion } from "../motion";
24
24
  import { MapFootRow, MapGeometry, referenceScale, selectedMarker } from "./MapViewFrame";
25
25
  import { DEFAULT_PADDING, fitCamera, mapFrame, metersPerPixel, pinOffsets, scaleBar, sortMarkers, unprojectPoint } from "./map-view-geometry";
26
26
  import { useMapViewMessages } from "./map-view-messages";
27
+ import { MapSnapshotError, rasterizeMapView, snapshotAborted, snapshotWait } from "./map-view-snapshot";
27
28
  function supportsWebgl() {
28
29
  try {
29
30
  const canvas = document.createElement("canvas");
@@ -45,6 +46,7 @@ export function MapView(props) {
45
46
  const selectedId = createMemo(() => selected()?.id);
46
47
  const notice = children(() => props.notice);
47
48
  const empty = children(() => props.empty);
49
+ const attribution = children(() => props.attribution);
48
50
  const [state, setState] = createSignal("static");
49
51
  createEffect(() => props.onStateChange?.(state()));
50
52
  const [dark, setDark] = createSignal(false);
@@ -90,8 +92,99 @@ export function MapView(props) {
90
92
  let visible = false;
91
93
  let mounted = false;
92
94
  let touched = false;
93
- let replacingStyle = false;
94
95
  let generation = 0;
96
+ let revision = 0;
97
+ let idle = false;
98
+ let capturing = false;
99
+ const lifetime = new AbortController();
100
+ const handle = {
101
+ async snapshot(options = {}) {
102
+ const timeout = options.timeoutMs ?? 30_000;
103
+ if (!Number.isInteger(timeout) || timeout < 1 || timeout > 240_000) throw new RangeError("Invalid snapshot timeout");
104
+ if (disposed) throw new MapSnapshotError("disposed");
105
+ if (capturing) throw new MapSnapshotError("busy");
106
+ const controller = new AbortController();
107
+ const timer = setTimeout(() => controller.abort(new MapSnapshotError("timed_out")), timeout);
108
+ const signal = AbortSignal.any([controller.signal, lifetime.signal, ...(options.signal ? [options.signal] : [])]);
109
+ const initial = revision;
110
+ const initialGeneration = generation;
111
+ const assertCurrent = () => {
112
+ if (signal.aborted) throw snapshotAborted(signal);
113
+ if (disposed) throw new MapSnapshotError("disposed");
114
+ if (state() === "error") throw new MapSnapshotError("resource_failed");
115
+ if (["static", "empty", "no-webgl"].includes(state())) throw new MapSnapshotError("not_ready");
116
+ if (revision !== initial || generation !== initialGeneration) throw new MapSnapshotError("changed");
117
+ };
118
+ capturing = true;
119
+ try {
120
+ assertCurrent();
121
+ await snapshotWait(document.fonts.ready, signal);
122
+ // An idle event includes symbol placement/fades, unlike the initial load event.
123
+ await new Promise((resolve, reject) => {
124
+ let frameId = 0;
125
+ const stop = () => {
126
+ cancelAnimationFrame(frameId);
127
+ reject(snapshotAborted(signal));
128
+ };
129
+ const poll = () => {
130
+ try {
131
+ assertCurrent();
132
+ if (map && idle && map.isStyleLoaded() && map.areTilesLoaded() && !map.isMoving()) {
133
+ signal.removeEventListener("abort", stop);
134
+ resolve();
135
+ } else frameId = requestAnimationFrame(poll);
136
+ } catch (error) {
137
+ signal.removeEventListener("abort", stop);
138
+ reject(error);
139
+ }
140
+ };
141
+ signal.addEventListener("abort", stop, {
142
+ once: true
143
+ });
144
+ poll();
145
+ });
146
+ assertCurrent();
147
+ const instance = map;
148
+ const result = await new Promise((resolve, reject) => {
149
+ const clean = () => {
150
+ instance.off("render", render);
151
+ instance.off("remove", removed);
152
+ signal.removeEventListener("abort", stop);
153
+ };
154
+ const stop = () => {
155
+ clean();
156
+ reject(snapshotAborted(signal));
157
+ };
158
+ const removed = () => {
159
+ clean();
160
+ reject(new MapSnapshotError(disposed ? "disposed" : state() === "error" ? "resource_failed" : "changed"));
161
+ };
162
+ const render = () => {
163
+ clean();
164
+ try {
165
+ assertCurrent();
166
+ if (!instance.isStyleLoaded() || !instance.areTilesLoaded() || instance.isMoving()) throw new MapSnapshotError("changed");
167
+ syncOverlay();
168
+ rasterizeMapView(root, instance.getCanvas(), signal).then(resolve, reject);
169
+ } catch (error) {
170
+ reject(error);
171
+ }
172
+ };
173
+ signal.addEventListener("abort", stop, {
174
+ once: true
175
+ });
176
+ instance.on("render", render);
177
+ instance.on("remove", removed);
178
+ instance.triggerRepaint();
179
+ });
180
+ assertCurrent();
181
+ return result;
182
+ } finally {
183
+ clearTimeout(timer);
184
+ capturing = false;
185
+ }
186
+ }
187
+ };
95
188
  let intersection;
96
189
  let resize;
97
190
  let infoResize;
@@ -104,6 +197,7 @@ export function MapView(props) {
104
197
  };
105
198
  const removeMap = () => {
106
199
  generation++;
200
+ idle = false;
107
201
  const previous = map;
108
202
  map = undefined;
109
203
  previous?.remove();
@@ -111,7 +205,6 @@ export function MapView(props) {
111
205
  setLiveScale(undefined);
112
206
  setChosenZoom(undefined);
113
207
  currentStyle = undefined;
114
- replacingStyle = false;
115
208
  };
116
209
  // MapLibre wraps its center across the antimeridian; geometry is drawn in the world copy nearest the camera.
117
210
  const worldCopy = (live, f) => Math.round((live.getCenter().lng + 180) / 360 - (f.minX + f.spanX / 2));
@@ -154,8 +247,8 @@ export function MapView(props) {
154
247
  setState("loading");
155
248
  const fail = () => {
156
249
  if (disposed || attempt !== generation) return;
157
- removeMap();
158
250
  setState("error");
251
+ removeMap();
159
252
  };
160
253
  let engine;
161
254
  try {
@@ -204,22 +297,32 @@ export function MapView(props) {
204
297
  }
205
298
  }, fail);
206
299
  map = instance;
207
- instance.on("error", event => {
300
+ instance.on("error", () => {
208
301
  // A missing paid resource must remain visible and recoverable, including failures after initial load.
209
- if ("sourceId" in event || "tile" in event || state() === "loading" || replacingStyle) fail();
210
- });
211
- instance.on("style.load", () => {
212
- replacingStyle = false;
302
+ fail();
213
303
  });
214
304
  instance.on("load", () => {
215
305
  if (disposed || attempt !== generation) return;
216
- setState("ready");
217
306
  refit();
307
+ setState("ready");
308
+ syncOverlay();
309
+ });
310
+ instance.on("idle", () => {
311
+ if (map !== instance || disposed) return;
312
+ idle = true;
313
+ syncOverlay();
314
+ });
315
+ instance.on("dataloading", () => {
316
+ idle = false;
218
317
  });
219
318
  instance.on("movestart", event => {
319
+ idle = false;
220
320
  if (event.originalEvent) touch();
221
321
  });
222
- instance.on("move", syncOverlay);
322
+ instance.on("move", () => {
323
+ revision++;
324
+ syncOverlay();
325
+ });
223
326
  // Pin separation is decided again once a zoom ends, not on every animation frame.
224
327
  instance.on("zoomend", () => {
225
328
  if (map === instance && touched) setChosenZoom(instance.getZoom());
@@ -257,6 +360,7 @@ export function MapView(props) {
257
360
  };
258
361
  onMount(() => {
259
362
  mounted = true;
363
+ props.ref?.(handle);
260
364
  const theme = () => setDark(!!root.closest('.dark, .k2b-dark, [data-theme="dark"]'));
261
365
  theme();
262
366
  for (let ancestor = root; ancestor; ancestor = ancestor.parentElement) {
@@ -269,6 +373,7 @@ export function MapView(props) {
269
373
  }
270
374
  setMeasuredWidth(root.clientWidth);
271
375
  resize = new ResizeObserver(() => {
376
+ revision++;
272
377
  setMeasuredWidth(root.clientWidth);
273
378
  map?.resize();
274
379
  refit();
@@ -294,6 +399,7 @@ export function MapView(props) {
294
399
  });
295
400
  createEffect(on(frame, value => {
296
401
  if (!mounted) return;
402
+ revision++;
297
403
  if (!value) {
298
404
  removeMap();
299
405
  setState("empty");
@@ -307,8 +413,9 @@ export function MapView(props) {
307
413
  createEffect(() => {
308
414
  const style = resolvedStyle();
309
415
  if (state() === "ready" && map && style !== currentStyle) {
416
+ revision++;
417
+ idle = false;
310
418
  currentStyle = style;
311
- replacingStyle = true;
312
419
  map.setStyle(style);
313
420
  }
314
421
  });
@@ -319,12 +426,20 @@ export function MapView(props) {
319
426
  });
320
427
  onCleanup(() => {
321
428
  disposed = true;
429
+ lifetime.abort(new MapSnapshotError("disposed"));
322
430
  intersection?.disconnect();
323
431
  resize?.disconnect();
324
432
  infoResize?.disconnect();
325
433
  for (const observer of themes) observer.disconnect();
326
434
  removeMap();
327
435
  });
436
+ createEffect(() => {
437
+ // Deep reads also subscribe to in-place Solid store updates (tone/mark/labels included).
438
+ JSON.stringify([props.markers, props.lines, props.areas, props.ownLocation, props.selectedId, props.class]);
439
+ dark();
440
+ attribution();
441
+ revision++;
442
+ });
328
443
  const zoom = direction => {
329
444
  if (!map || state() !== "ready") return;
330
445
  touch();
@@ -401,7 +516,7 @@ export function MapView(props) {
401
516
  }), _el$29, _co$8);
402
517
  _$insert(_el$4, _$createComponent(Show, {
403
518
  get when() {
404
- return notice();
519
+ return notice.toArray().some(child => child != null && typeof child !== "boolean" && child !== "");
405
520
  },
406
521
  get children() {
407
522
  var _el$5 = _$getNextElement(_tmpl$);
@@ -528,7 +643,7 @@ export function MapView(props) {
528
643
  return scale();
529
644
  },
530
645
  get children() {
531
- return props.attribution;
646
+ return attribution();
532
647
  }
533
648
  }), _el$27, _co$7);
534
649
  _$effect(_p$ => {
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["content/MapView.tsx"],"sourcesContent":["import type { Map as LiveMap } from \"maplibre-gl\";\nimport { children, createEffect, createMemo, createSignal, type JSX, on, onCleanup, onMount, Show, untrack } from \"solid-js\";\nimport { Button, IconButton } from \"../actions/Button\";\nimport { prefersReducedMotion } from \"../motion\";\nimport { MapFootRow, MapGeometry, type MapScale, referenceScale, selectedMarker } from \"./MapViewFrame\";\nimport {\n DEFAULT_PADDING,\n fitCamera,\n type MapFrame,\n mapFrame,\n metersPerPixel,\n pinOffsets,\n scaleBar,\n sortMarkers,\n unprojectPoint,\n} from \"./map-view-geometry\";\nimport { useMapViewMessages } from \"./map-view-messages\";\nimport type { MapViewMarker, MapViewProps, MapViewStyle } from \"./map-view-types\";\n\nexport type { MapViewProps } from \"./map-view-types\";\n\ntype MapState = \"static\" | \"loading\" | \"ready\" | \"error\" | \"no-webgl\" | \"empty\";\n\nfunction supportsWebgl(): boolean {\n try {\n const canvas = document.createElement(\"canvas\");\n // MapLibre 6 draws with WebGL 2 only; a browser with just WebGL 1 gets the static frame and the notice.\n const gl = canvas.getContext(\"webgl2\");\n if (!gl) return false;\n gl.getExtension(\"WEBGL_lose_context\")?.loseContext();\n return true;\n } catch {\n return false;\n }\n}\n\n/** A static server frame enhanced with a same-origin MapLibre worker only after it enters the viewport. */\nexport function MapView(props: MapViewProps): JSX.Element {\n const messages = useMapViewMessages();\n const frame = createMemo(() => mapFrame(props, props.height, props.padding ?? DEFAULT_PADDING));\n const selected = createMemo(() => selectedMarker(props.markers ?? [], props.selectedId));\n const selectedId = createMemo(() => selected()?.id);\n const notice = children(() => props.notice);\n const empty = children(() => props.empty);\n const [state, setState] = createSignal<MapState>(\"static\");\n createEffect(() => props.onStateChange?.(state()));\n const [dark, setDark] = createSignal(false);\n const [boxStyle, setBoxStyle] = createSignal<JSX.CSSProperties>();\n const [liveScale, setLiveScale] = createSignal<MapScale>();\n const [measuredWidth, setMeasuredWidth] = createSignal<number>();\n // The zoom the person chose, once they zoomed; pin separation follows it relative to the current fit.\n const [chosenZoom, setChosenZoom] = createSignal<number>();\n const zoomFactor = createMemo(() => {\n const zoom = chosenZoom();\n const f = frame();\n const width = measuredWidth();\n if (zoom === undefined || !f || width === undefined) return 1;\n return 2 ** (zoom - fitCamera(f, width, props.padding ?? DEFAULT_PADDING).zoom);\n });\n const [needsReload, setNeedsReload] = createSignal(false);\n // The server picks the scale bar for the widest fit; once the width is known, the bar names a distance that fits it.\n const scale = createMemo((): MapScale | undefined => {\n const f = frame();\n if (!f) return undefined;\n const live = liveScale();\n if (live) return live;\n const width = measuredWidth();\n if (width === undefined) return referenceScale(f, props.padding ?? DEFAULT_PADDING);\n const camera = fitCamera(f, width, props.padding ?? DEFAULT_PADDING);\n const mpp = metersPerPixel(camera.center[1], camera.zoom);\n const bar = scaleBar(mpp);\n return { label: bar.label, width: `${bar.meters / mpp}px` };\n });\n const resolvedStyle = (): MapViewStyle => {\n const source = props.style;\n return typeof source === \"object\" && \"dark\" in source ? (dark() ? source.dark : source.light) : source;\n };\n let root!: HTMLDivElement;\n let live!: HTMLDivElement;\n let info!: HTMLDivElement;\n let map: LiveMap | undefined;\n let currentStyle: MapViewStyle | undefined;\n let disposed = false;\n let visible = false;\n let mounted = false;\n let touched = false;\n let replacingStyle = false;\n let generation = 0;\n let intersection: IntersectionObserver | undefined;\n let resize: ResizeObserver | undefined;\n let infoResize: ResizeObserver | undefined;\n const themes: MutationObserver[] = [];\n\n // From the person's first camera change on, the camera stays theirs; pin separation follows its zoom.\n const touch = () => {\n touched = true;\n if (map) setChosenZoom(map.getZoom());\n };\n const removeMap = () => {\n generation++;\n const previous = map;\n map = undefined;\n previous?.remove();\n setBoxStyle(undefined);\n setLiveScale(undefined);\n setChosenZoom(undefined);\n currentStyle = undefined;\n replacingStyle = false;\n };\n // MapLibre wraps its center across the antimeridian; geometry is drawn in the world copy nearest the camera.\n const worldCopy = (live: LiveMap, f: MapFrame): number => Math.round((live.getCenter().lng + 180) / 360 - (f.minX + f.spanX / 2));\n const syncOverlay = () => {\n const f = frame();\n if (!map || !f || state() !== \"ready\") return;\n const copy = worldCopy(map, f);\n const a = unprojectPoint(f.minX + copy, f.minY);\n const b = unprojectPoint(f.minX + copy + f.spanX, f.minY + f.spanY);\n const top = map.project([a.lon, a.lat]);\n const bottom = map.project([b.lon, b.lat]);\n setBoxStyle({\n left: `${top.x}px`,\n top: `${top.y}px`,\n width: `${bottom.x - top.x}px`,\n height: `${bottom.y - top.y}px`,\n transform: \"none\",\n });\n const mpp = metersPerPixel(map.getCenter().lat, map.getZoom());\n const bar = scaleBar(mpp);\n setLiveScale({ label: bar.label, width: `${bar.meters / mpp}px` });\n };\n const refit = () => {\n const f = frame();\n if (map && f && !touched) map.jumpTo(fitCamera(f, root.clientWidth, props.padding ?? DEFAULT_PADDING));\n syncOverlay();\n };\n const start = async () => {\n if (disposed || !visible || !frame()) return;\n removeMap();\n touched = false;\n if (!supportsWebgl()) {\n setState(\"no-webgl\");\n return;\n }\n const attempt = generation;\n setState(\"loading\");\n const fail = () => {\n if (disposed || attempt !== generation) return;\n removeMap();\n setState(\"error\");\n };\n let engine: typeof import(\"./map-view-live\");\n try {\n engine = await import(\"./map-view-live\");\n } catch {\n // The map code did not load, for example because the page outlived a release that removed its files.\n // Importing the same address again cannot help; a reload fetches the current page and its map code.\n if (disposed || attempt !== generation) return;\n setNeedsReload(true);\n fail();\n return;\n }\n try {\n const { createMap } = engine;\n if (disposed || attempt !== generation) return;\n const f = frame();\n if (!f) return;\n currentStyle = resolvedStyle();\n const t = messages();\n const instance = createMap(\n {\n container: live,\n style: currentStyle,\n ...fitCamera(f, root.clientWidth, props.padding ?? DEFAULT_PADDING),\n attributionControl: false,\n cooperativeGestures: true,\n dragRotate: false,\n // Shift-drag box zoom needs MapLibre's own stylesheet for its rectangle and starts without an input event.\n boxZoom: false,\n pitchWithRotate: false,\n touchPitch: false,\n maxPitch: 0,\n bearing: 0,\n pitch: 0,\n keyboard: true,\n trackResize: false,\n // MapLibre's own gestures (keyboard and double-click zoom, inertia) follow the same choice as our buttons.\n // The value is read when the map starts; MapLibre keeps one setting for all maps on the page.\n reduceMotion: prefersReducedMotion(),\n locale: {\n \"Map.Title\": t.canvasTitle,\n \"CooperativeGesturesHandler.WindowsHelpText\": t.gestureWindows,\n \"CooperativeGesturesHandler.MacHelpText\": t.gestureMac,\n \"CooperativeGesturesHandler.MobileHelpText\": t.gestureMobile,\n },\n },\n fail,\n );\n map = instance;\n instance.on(\"error\", (event) => {\n // A missing paid resource must remain visible and recoverable, including failures after initial load.\n if (\"sourceId\" in event || \"tile\" in event || state() === \"loading\" || replacingStyle) fail();\n });\n instance.on(\"style.load\", () => {\n replacingStyle = false;\n });\n instance.on(\"load\", () => {\n if (disposed || attempt !== generation) return;\n setState(\"ready\");\n refit();\n });\n instance.on(\"movestart\", (event) => {\n if (event.originalEvent) touch();\n });\n instance.on(\"move\", syncOverlay);\n // Pin separation is decided again once a zoom ends, not on every animation frame.\n instance.on(\"zoomend\", () => {\n if (map === instance && touched) setChosenZoom(instance.getZoom());\n });\n instance.on(\"resize\", syncOverlay);\n } catch {\n fail();\n }\n };\n const clearSelectedPin = () => {\n const marker = selected();\n if (!marker || state() !== \"ready\" || !map) return;\n const f = frame();\n const lon = marker.point.lon + (f ? worldCopy(map, f) * 360 : 0);\n const p = map.project([lon, marker.point.lat]);\n const offset = f ? pinOffsets(sortMarkers(props.markers ?? []), f, zoomFactor(), props.ownLocation?.point).get(marker.id) : undefined;\n const x = p.x + (offset?.dx ?? 0);\n const y = p.y + (offset?.dy ?? 0);\n const w = root.clientWidth;\n const h = root.clientHeight;\n const tile = info.getBoundingClientRect();\n const bounds = root.getBoundingClientRect();\n const tileTop = tile.top - bounds.top - 8;\n const covered =\n tile.height > 0 &&\n x >= tile.left - bounds.left - 8 &&\n x <= tile.right - bounds.left + 8 &&\n y >= tileTop &&\n y <= tile.bottom - bounds.top + 8;\n if (!covered && x >= 16 && x <= w - 16 && y >= 16 && y <= h - 16) return;\n touch();\n // Put the drawn pin, offset included, in the free band above the tile.\n const targetX = w / 2;\n const targetY = tile.height > 0 ? tileTop / 2 : h / 2;\n const target = map.unproject([x + w / 2 - targetX, y + h / 2 - targetY]);\n const camera = { center: [target.lng, target.lat] satisfies [number, number] };\n if (prefersReducedMotion()) map.jumpTo(camera);\n else map.easeTo(camera);\n };\n onMount(() => {\n mounted = true;\n const theme = () => setDark(!!root.closest('.dark, .k2b-dark, [data-theme=\"dark\"]'));\n theme();\n for (let ancestor: Element | null = root; ancestor; ancestor = ancestor.parentElement) {\n const observer = new MutationObserver(theme);\n observer.observe(ancestor, { attributes: true, attributeFilter: [\"class\", \"data-theme\"] });\n themes.push(observer);\n }\n setMeasuredWidth(root.clientWidth);\n resize = new ResizeObserver(() => {\n setMeasuredWidth(root.clientWidth);\n map?.resize();\n refit();\n });\n resize.observe(root);\n infoResize = new ResizeObserver(clearSelectedPin);\n infoResize.observe(info);\n const enter = () => {\n visible = true;\n intersection?.disconnect();\n if (frame()) void start();\n };\n if (!frame()) setState(\"empty\");\n if (typeof IntersectionObserver === \"undefined\") enter();\n else {\n intersection = new IntersectionObserver(\n (entries) => {\n if (entries.some((entry) => entry.isIntersecting)) enter();\n },\n { threshold: 0, rootMargin: \"0px\" },\n );\n intersection.observe(root);\n }\n });\n createEffect(\n on(\n frame,\n (value) => {\n if (!mounted) return;\n if (!value) {\n removeMap();\n setState(\"empty\");\n } else if (state() === \"empty\") {\n setState(\"static\");\n if (visible) void start();\n } else refit();\n },\n { defer: true },\n ),\n );\n createEffect(() => {\n const style = resolvedStyle();\n if (state() === \"ready\" && map && style !== currentStyle) {\n currentStyle = style;\n replacingStyle = true;\n map.setStyle(style);\n }\n });\n createEffect(() => {\n selected();\n state();\n untrack(clearSelectedPin);\n });\n onCleanup(() => {\n disposed = true;\n intersection?.disconnect();\n resize?.disconnect();\n infoResize?.disconnect();\n for (const observer of themes) observer.disconnect();\n removeMap();\n });\n const zoom = (direction: \"in\" | \"out\") => {\n if (!map || state() !== \"ready\") return;\n touch();\n const options = { animate: !prefersReducedMotion() };\n if (direction === \"in\") map.zoomIn(options);\n else map.zoomOut(options);\n };\n return (\n <div\n ref={root}\n class={`k2b-map-view${props.class ? ` ${props.class}` : \"\"}`}\n style={{ height: `${props.height}px` }}\n data-state={state()}\n role=\"region\"\n aria-label={messages().mapLabel}\n >\n <span class=\"k2b-sr-only\">{messages().summary({ count: props.markers?.length ?? 0 })}</span>\n <div ref={live} class=\"k2b-map-view__live\" />\n <Show\n when={frame()}\n fallback={\n <div class=\"k2b-map-view__empty\">\n <Show when={empty()}>\n <span>{empty()}</span>\n </Show>\n </div>\n }\n >\n {(value) => (\n <MapGeometry {...props} frame={value()} boxStyle={boxStyle()} zoomFactor={zoomFactor()} onSelect={props.onSelect} interactive />\n )}\n </Show>\n <div class=\"k2b-map-view__messages\">\n <Show when={notice()}>\n <div class=\"k2b-map-view__notice\">{notice()}</div>\n </Show>\n <Show when={state() === \"loading\" || state() === \"error\" || state() === \"no-webgl\"}>\n <div class=\"k2b-map-view__status\" role=\"status\">\n <i\n aria-hidden=\"true\"\n class={state() === \"loading\" ? \"ti ti-loader-2 k2b-spin\" : state() === \"error\" ? \"ti ti-alert-circle\" : \"ti ti-info-circle\"}\n />\n <span>{state() === \"loading\" ? messages().loading : state() === \"error\" ? messages().error : messages().noWebgl}</span>\n <Show when={state() === \"error\"}>\n <Button size=\"xs\" variant=\"text\" onClick={() => (needsReload() ? window.location.reload() : void start())}>\n {needsReload() ? messages().reload : messages().retry}\n </Button>\n </Show>\n </div>\n </Show>\n </div>\n <div class=\"k2b-map-view__controls\">\n <div class=\"k2b-map-view__zoom\">\n <IconButton label={messages().zoomIn} tooltip={false} disabled={state() !== \"ready\"} onClick={() => zoom(\"in\")}>\n <i class=\"ti ti-plus\" aria-hidden=\"true\" />\n </IconButton>\n <IconButton label={messages().zoomOut} tooltip={false} disabled={state() !== \"ready\"} onClick={() => zoom(\"out\")}>\n <i class=\"ti ti-minus\" aria-hidden=\"true\" />\n </IconButton>\n </div>\n <Show when={props.onLocate}>\n <IconButton\n class=\"k2b-map-view__locate\"\n tooltip={false}\n label={messages().locate}\n aria-pressed={!!props.ownLocation}\n onClick={() => props.onLocate?.()}\n >\n <i class=\"ti ti-current-location\" aria-hidden=\"true\" />\n </IconButton>\n </Show>\n </div>\n <div class=\"k2b-map-view__foot\">\n <div ref={info} class=\"k2b-map-view__info\" aria-live=\"polite\">\n <Show when={selectedId()} keyed>\n {(_id) => {\n // Keep the tile's state and focus for this selection while its marker data refreshes.\n const initial = selected();\n const current = () => selected() ?? initial;\n const marker: MapViewMarker = {\n get id() {\n return current()!.id;\n },\n get point() {\n return current()!.point;\n },\n get mark() {\n return current()!.mark;\n },\n get label() {\n return current()!.label;\n },\n get tone() {\n return current()!.tone;\n },\n get selected() {\n return current()!.selected;\n },\n };\n return props.infoTile?.(marker);\n }}\n </Show>\n </div>\n <MapFootRow scale={scale()}>{props.attribution}</MapFootRow>\n </div>\n </div>\n );\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["content/MapView.tsx"],"sourcesContent":["import type { Map as LiveMap } from \"maplibre-gl\";\nimport { children, createEffect, createMemo, createSignal, type JSX, on, onCleanup, onMount, Show, untrack } from \"solid-js\";\nimport { Button, IconButton } from \"../actions/Button\";\nimport { prefersReducedMotion } from \"../motion\";\nimport { MapFootRow, MapGeometry, type MapScale, referenceScale, selectedMarker } from \"./MapViewFrame\";\nimport {\n DEFAULT_PADDING,\n fitCamera,\n type MapFrame,\n mapFrame,\n metersPerPixel,\n pinOffsets,\n scaleBar,\n sortMarkers,\n unprojectPoint,\n} from \"./map-view-geometry\";\nimport { useMapViewMessages } from \"./map-view-messages\";\nimport { MapSnapshotError, rasterizeMapView, snapshotAborted, snapshotWait } from \"./map-view-snapshot\";\nimport type { MapViewHandle, MapViewMarker, MapViewProps, MapViewStyle } from \"./map-view-types\";\n\nexport type { MapViewProps } from \"./map-view-types\";\n\ntype MapState = \"static\" | \"loading\" | \"ready\" | \"error\" | \"no-webgl\" | \"empty\";\n\nfunction supportsWebgl(): boolean {\n try {\n const canvas = document.createElement(\"canvas\");\n // MapLibre 6 draws with WebGL 2 only; a browser with just WebGL 1 gets the static frame and the notice.\n const gl = canvas.getContext(\"webgl2\");\n if (!gl) return false;\n gl.getExtension(\"WEBGL_lose_context\")?.loseContext();\n return true;\n } catch {\n return false;\n }\n}\n\n/** A static server frame enhanced with a same-origin MapLibre worker only after it enters the viewport. */\nexport function MapView(props: MapViewProps): JSX.Element {\n const messages = useMapViewMessages();\n const frame = createMemo(() => mapFrame(props, props.height, props.padding ?? DEFAULT_PADDING));\n const selected = createMemo(() => selectedMarker(props.markers ?? [], props.selectedId));\n const selectedId = createMemo(() => selected()?.id);\n const notice = children(() => props.notice);\n const empty = children(() => props.empty);\n const attribution = children(() => props.attribution);\n const [state, setState] = createSignal<MapState>(\"static\");\n createEffect(() => props.onStateChange?.(state()));\n const [dark, setDark] = createSignal(false);\n const [boxStyle, setBoxStyle] = createSignal<JSX.CSSProperties>();\n const [liveScale, setLiveScale] = createSignal<MapScale>();\n const [measuredWidth, setMeasuredWidth] = createSignal<number>();\n // The zoom the person chose, once they zoomed; pin separation follows it relative to the current fit.\n const [chosenZoom, setChosenZoom] = createSignal<number>();\n const zoomFactor = createMemo(() => {\n const zoom = chosenZoom();\n const f = frame();\n const width = measuredWidth();\n if (zoom === undefined || !f || width === undefined) return 1;\n return 2 ** (zoom - fitCamera(f, width, props.padding ?? DEFAULT_PADDING).zoom);\n });\n const [needsReload, setNeedsReload] = createSignal(false);\n // The server picks the scale bar for the widest fit; once the width is known, the bar names a distance that fits it.\n const scale = createMemo((): MapScale | undefined => {\n const f = frame();\n if (!f) return undefined;\n const live = liveScale();\n if (live) return live;\n const width = measuredWidth();\n if (width === undefined) return referenceScale(f, props.padding ?? DEFAULT_PADDING);\n const camera = fitCamera(f, width, props.padding ?? DEFAULT_PADDING);\n const mpp = metersPerPixel(camera.center[1], camera.zoom);\n const bar = scaleBar(mpp);\n return { label: bar.label, width: `${bar.meters / mpp}px` };\n });\n const resolvedStyle = (): MapViewStyle => {\n const source = props.style;\n return typeof source === \"object\" && \"dark\" in source ? (dark() ? source.dark : source.light) : source;\n };\n let root!: HTMLDivElement;\n let live!: HTMLDivElement;\n let info!: HTMLDivElement;\n let map: LiveMap | undefined;\n let currentStyle: MapViewStyle | undefined;\n let disposed = false;\n let visible = false;\n let mounted = false;\n let touched = false;\n let generation = 0;\n let revision = 0;\n let idle = false;\n let capturing = false;\n const lifetime = new AbortController();\n const handle: MapViewHandle = {\n async snapshot(options = {}) {\n const timeout = options.timeoutMs ?? 30_000;\n if (!Number.isInteger(timeout) || timeout < 1 || timeout > 240_000) throw new RangeError(\"Invalid snapshot timeout\");\n if (disposed) throw new MapSnapshotError(\"disposed\");\n if (capturing) throw new MapSnapshotError(\"busy\");\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(new MapSnapshotError(\"timed_out\")), timeout);\n const signal = AbortSignal.any([controller.signal, lifetime.signal, ...(options.signal ? [options.signal] : [])]);\n const initial = revision;\n const initialGeneration = generation;\n const assertCurrent = () => {\n if (signal.aborted) throw snapshotAborted(signal);\n if (disposed) throw new MapSnapshotError(\"disposed\");\n if (state() === \"error\") throw new MapSnapshotError(\"resource_failed\");\n if ([\"static\", \"empty\", \"no-webgl\"].includes(state())) throw new MapSnapshotError(\"not_ready\");\n if (revision !== initial || generation !== initialGeneration) throw new MapSnapshotError(\"changed\");\n };\n capturing = true;\n try {\n assertCurrent();\n await snapshotWait(document.fonts.ready, signal);\n // An idle event includes symbol placement/fades, unlike the initial load event.\n await new Promise<void>((resolve, reject) => {\n let frameId = 0;\n const stop = () => {\n cancelAnimationFrame(frameId);\n reject(snapshotAborted(signal));\n };\n const poll = () => {\n try {\n assertCurrent();\n if (map && idle && map.isStyleLoaded() && map.areTilesLoaded() && !map.isMoving()) {\n signal.removeEventListener(\"abort\", stop);\n resolve();\n } else frameId = requestAnimationFrame(poll);\n } catch (error) {\n signal.removeEventListener(\"abort\", stop);\n reject(error);\n }\n };\n signal.addEventListener(\"abort\", stop, { once: true });\n poll();\n });\n assertCurrent();\n const instance = map!;\n const result = await new Promise<Awaited<ReturnType<typeof rasterizeMapView>>>((resolve, reject) => {\n const clean = () => {\n instance.off(\"render\", render);\n instance.off(\"remove\", removed);\n signal.removeEventListener(\"abort\", stop);\n };\n const stop = () => {\n clean();\n reject(snapshotAborted(signal));\n };\n const removed = () => {\n clean();\n reject(new MapSnapshotError(disposed ? \"disposed\" : state() === \"error\" ? \"resource_failed\" : \"changed\"));\n };\n const render = () => {\n clean();\n try {\n assertCurrent();\n if (!instance.isStyleLoaded() || !instance.areTilesLoaded() || instance.isMoving()) throw new MapSnapshotError(\"changed\");\n syncOverlay();\n rasterizeMapView(root, instance.getCanvas(), signal).then(resolve, reject);\n } catch (error) {\n reject(error);\n }\n };\n signal.addEventListener(\"abort\", stop, { once: true });\n instance.on(\"render\", render);\n instance.on(\"remove\", removed);\n instance.triggerRepaint();\n });\n assertCurrent();\n return result;\n } finally {\n clearTimeout(timer);\n capturing = false;\n }\n },\n };\n let intersection: IntersectionObserver | undefined;\n let resize: ResizeObserver | undefined;\n let infoResize: ResizeObserver | undefined;\n const themes: MutationObserver[] = [];\n\n // From the person's first camera change on, the camera stays theirs; pin separation follows its zoom.\n const touch = () => {\n touched = true;\n if (map) setChosenZoom(map.getZoom());\n };\n const removeMap = () => {\n generation++;\n idle = false;\n const previous = map;\n map = undefined;\n previous?.remove();\n setBoxStyle(undefined);\n setLiveScale(undefined);\n setChosenZoom(undefined);\n currentStyle = undefined;\n };\n // MapLibre wraps its center across the antimeridian; geometry is drawn in the world copy nearest the camera.\n const worldCopy = (live: LiveMap, f: MapFrame): number => Math.round((live.getCenter().lng + 180) / 360 - (f.minX + f.spanX / 2));\n const syncOverlay = () => {\n const f = frame();\n if (!map || !f || state() !== \"ready\") return;\n const copy = worldCopy(map, f);\n const a = unprojectPoint(f.minX + copy, f.minY);\n const b = unprojectPoint(f.minX + copy + f.spanX, f.minY + f.spanY);\n const top = map.project([a.lon, a.lat]);\n const bottom = map.project([b.lon, b.lat]);\n setBoxStyle({\n left: `${top.x}px`,\n top: `${top.y}px`,\n width: `${bottom.x - top.x}px`,\n height: `${bottom.y - top.y}px`,\n transform: \"none\",\n });\n const mpp = metersPerPixel(map.getCenter().lat, map.getZoom());\n const bar = scaleBar(mpp);\n setLiveScale({ label: bar.label, width: `${bar.meters / mpp}px` });\n };\n const refit = () => {\n const f = frame();\n if (map && f && !touched) map.jumpTo(fitCamera(f, root.clientWidth, props.padding ?? DEFAULT_PADDING));\n syncOverlay();\n };\n const start = async () => {\n if (disposed || !visible || !frame()) return;\n removeMap();\n touched = false;\n if (!supportsWebgl()) {\n setState(\"no-webgl\");\n return;\n }\n const attempt = generation;\n setState(\"loading\");\n const fail = () => {\n if (disposed || attempt !== generation) return;\n setState(\"error\");\n removeMap();\n };\n let engine: typeof import(\"./map-view-live\");\n try {\n engine = await import(\"./map-view-live\");\n } catch {\n // The map code did not load, for example because the page outlived a release that removed its files.\n // Importing the same address again cannot help; a reload fetches the current page and its map code.\n if (disposed || attempt !== generation) return;\n setNeedsReload(true);\n fail();\n return;\n }\n try {\n const { createMap } = engine;\n if (disposed || attempt !== generation) return;\n const f = frame();\n if (!f) return;\n currentStyle = resolvedStyle();\n const t = messages();\n const instance = createMap(\n {\n container: live,\n style: currentStyle,\n ...fitCamera(f, root.clientWidth, props.padding ?? DEFAULT_PADDING),\n attributionControl: false,\n cooperativeGestures: true,\n dragRotate: false,\n // Shift-drag box zoom needs MapLibre's own stylesheet for its rectangle and starts without an input event.\n boxZoom: false,\n pitchWithRotate: false,\n touchPitch: false,\n maxPitch: 0,\n bearing: 0,\n pitch: 0,\n keyboard: true,\n trackResize: false,\n // MapLibre's own gestures (keyboard and double-click zoom, inertia) follow the same choice as our buttons.\n // The value is read when the map starts; MapLibre keeps one setting for all maps on the page.\n reduceMotion: prefersReducedMotion(),\n locale: {\n \"Map.Title\": t.canvasTitle,\n \"CooperativeGesturesHandler.WindowsHelpText\": t.gestureWindows,\n \"CooperativeGesturesHandler.MacHelpText\": t.gestureMac,\n \"CooperativeGesturesHandler.MobileHelpText\": t.gestureMobile,\n },\n },\n fail,\n );\n map = instance;\n instance.on(\"error\", () => {\n // A missing paid resource must remain visible and recoverable, including failures after initial load.\n fail();\n });\n instance.on(\"load\", () => {\n if (disposed || attempt !== generation) return;\n refit();\n setState(\"ready\");\n syncOverlay();\n });\n instance.on(\"idle\", () => {\n if (map !== instance || disposed) return;\n idle = true;\n syncOverlay();\n });\n instance.on(\"dataloading\", () => {\n idle = false;\n });\n instance.on(\"movestart\", (event) => {\n idle = false;\n if (event.originalEvent) touch();\n });\n instance.on(\"move\", () => {\n revision++;\n syncOverlay();\n });\n // Pin separation is decided again once a zoom ends, not on every animation frame.\n instance.on(\"zoomend\", () => {\n if (map === instance && touched) setChosenZoom(instance.getZoom());\n });\n instance.on(\"resize\", syncOverlay);\n } catch {\n fail();\n }\n };\n const clearSelectedPin = () => {\n const marker = selected();\n if (!marker || state() !== \"ready\" || !map) return;\n const f = frame();\n const lon = marker.point.lon + (f ? worldCopy(map, f) * 360 : 0);\n const p = map.project([lon, marker.point.lat]);\n const offset = f ? pinOffsets(sortMarkers(props.markers ?? []), f, zoomFactor(), props.ownLocation?.point).get(marker.id) : undefined;\n const x = p.x + (offset?.dx ?? 0);\n const y = p.y + (offset?.dy ?? 0);\n const w = root.clientWidth;\n const h = root.clientHeight;\n const tile = info.getBoundingClientRect();\n const bounds = root.getBoundingClientRect();\n const tileTop = tile.top - bounds.top - 8;\n const covered =\n tile.height > 0 &&\n x >= tile.left - bounds.left - 8 &&\n x <= tile.right - bounds.left + 8 &&\n y >= tileTop &&\n y <= tile.bottom - bounds.top + 8;\n if (!covered && x >= 16 && x <= w - 16 && y >= 16 && y <= h - 16) return;\n touch();\n // Put the drawn pin, offset included, in the free band above the tile.\n const targetX = w / 2;\n const targetY = tile.height > 0 ? tileTop / 2 : h / 2;\n const target = map.unproject([x + w / 2 - targetX, y + h / 2 - targetY]);\n const camera = { center: [target.lng, target.lat] satisfies [number, number] };\n if (prefersReducedMotion()) map.jumpTo(camera);\n else map.easeTo(camera);\n };\n onMount(() => {\n mounted = true;\n props.ref?.(handle);\n const theme = () => setDark(!!root.closest('.dark, .k2b-dark, [data-theme=\"dark\"]'));\n theme();\n for (let ancestor: Element | null = root; ancestor; ancestor = ancestor.parentElement) {\n const observer = new MutationObserver(theme);\n observer.observe(ancestor, { attributes: true, attributeFilter: [\"class\", \"data-theme\"] });\n themes.push(observer);\n }\n setMeasuredWidth(root.clientWidth);\n resize = new ResizeObserver(() => {\n revision++;\n setMeasuredWidth(root.clientWidth);\n map?.resize();\n refit();\n });\n resize.observe(root);\n infoResize = new ResizeObserver(clearSelectedPin);\n infoResize.observe(info);\n const enter = () => {\n visible = true;\n intersection?.disconnect();\n if (frame()) void start();\n };\n if (!frame()) setState(\"empty\");\n if (typeof IntersectionObserver === \"undefined\") enter();\n else {\n intersection = new IntersectionObserver(\n (entries) => {\n if (entries.some((entry) => entry.isIntersecting)) enter();\n },\n { threshold: 0, rootMargin: \"0px\" },\n );\n intersection.observe(root);\n }\n });\n createEffect(\n on(\n frame,\n (value) => {\n if (!mounted) return;\n revision++;\n if (!value) {\n removeMap();\n setState(\"empty\");\n } else if (state() === \"empty\") {\n setState(\"static\");\n if (visible) void start();\n } else refit();\n },\n { defer: true },\n ),\n );\n createEffect(() => {\n const style = resolvedStyle();\n if (state() === \"ready\" && map && style !== currentStyle) {\n revision++;\n idle = false;\n currentStyle = style;\n map.setStyle(style);\n }\n });\n createEffect(() => {\n selected();\n state();\n untrack(clearSelectedPin);\n });\n onCleanup(() => {\n disposed = true;\n lifetime.abort(new MapSnapshotError(\"disposed\"));\n intersection?.disconnect();\n resize?.disconnect();\n infoResize?.disconnect();\n for (const observer of themes) observer.disconnect();\n removeMap();\n });\n createEffect(() => {\n // Deep reads also subscribe to in-place Solid store updates (tone/mark/labels included).\n JSON.stringify([props.markers, props.lines, props.areas, props.ownLocation, props.selectedId, props.class]);\n dark();\n attribution();\n revision++;\n });\n const zoom = (direction: \"in\" | \"out\") => {\n if (!map || state() !== \"ready\") return;\n touch();\n const options = { animate: !prefersReducedMotion() };\n if (direction === \"in\") map.zoomIn(options);\n else map.zoomOut(options);\n };\n return (\n <div\n ref={root}\n class={`k2b-map-view${props.class ? ` ${props.class}` : \"\"}`}\n style={{ height: `${props.height}px` }}\n data-state={state()}\n role=\"region\"\n aria-label={messages().mapLabel}\n >\n <span class=\"k2b-sr-only\">{messages().summary({ count: props.markers?.length ?? 0 })}</span>\n <div ref={live} class=\"k2b-map-view__live\" />\n <Show\n when={frame()}\n fallback={\n <div class=\"k2b-map-view__empty\">\n <Show when={empty()}>\n <span>{empty()}</span>\n </Show>\n </div>\n }\n >\n {(value) => (\n <MapGeometry {...props} frame={value()} boxStyle={boxStyle()} zoomFactor={zoomFactor()} onSelect={props.onSelect} interactive />\n )}\n </Show>\n <div class=\"k2b-map-view__messages\">\n <Show when={notice.toArray().some((child) => child != null && typeof child !== \"boolean\" && child !== \"\")}>\n <div class=\"k2b-map-view__notice\">{notice()}</div>\n </Show>\n <Show when={state() === \"loading\" || state() === \"error\" || state() === \"no-webgl\"}>\n <div class=\"k2b-map-view__status\" role=\"status\">\n <i\n aria-hidden=\"true\"\n class={state() === \"loading\" ? \"ti ti-loader-2 k2b-spin\" : state() === \"error\" ? \"ti ti-alert-circle\" : \"ti ti-info-circle\"}\n />\n <span>{state() === \"loading\" ? messages().loading : state() === \"error\" ? messages().error : messages().noWebgl}</span>\n <Show when={state() === \"error\"}>\n <Button size=\"xs\" variant=\"text\" onClick={() => (needsReload() ? window.location.reload() : void start())}>\n {needsReload() ? messages().reload : messages().retry}\n </Button>\n </Show>\n </div>\n </Show>\n </div>\n <div class=\"k2b-map-view__controls\">\n <div class=\"k2b-map-view__zoom\">\n <IconButton label={messages().zoomIn} tooltip={false} disabled={state() !== \"ready\"} onClick={() => zoom(\"in\")}>\n <i class=\"ti ti-plus\" aria-hidden=\"true\" />\n </IconButton>\n <IconButton label={messages().zoomOut} tooltip={false} disabled={state() !== \"ready\"} onClick={() => zoom(\"out\")}>\n <i class=\"ti ti-minus\" aria-hidden=\"true\" />\n </IconButton>\n </div>\n <Show when={props.onLocate}>\n <IconButton\n class=\"k2b-map-view__locate\"\n tooltip={false}\n label={messages().locate}\n aria-pressed={!!props.ownLocation}\n onClick={() => props.onLocate?.()}\n >\n <i class=\"ti ti-current-location\" aria-hidden=\"true\" />\n </IconButton>\n </Show>\n </div>\n <div class=\"k2b-map-view__foot\">\n <div ref={info} class=\"k2b-map-view__info\" aria-live=\"polite\">\n <Show when={selectedId()} keyed>\n {(_id) => {\n // Keep the tile's state and focus for this selection while its marker data refreshes.\n const initial = selected();\n const current = () => selected() ?? initial;\n const marker: MapViewMarker = {\n get id() {\n return current()!.id;\n },\n get point() {\n return current()!.point;\n },\n get mark() {\n return current()!.mark;\n },\n get label() {\n return current()!.label;\n },\n get tone() {\n return current()!.tone;\n },\n get selected() {\n return current()!.selected;\n },\n };\n return props.infoTile?.(marker);\n }}\n </Show>\n </div>\n <MapFootRow scale={scale()}>{attribution()}</MapFootRow>\n </div>\n </div>\n );\n}\n"],"mappings":"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","ignoreList":[]}
@@ -344,7 +344,7 @@ export function MapFootRow(props) {
344
344
  return _el$24;
345
345
  })();
346
346
  }
347
- /** Geometry without a browser, a canvas, or a network dependency; suitable for server rendering and PDF output. */
347
+ /** Geometry fallback without a browser, canvas, or network. Does not contain a geographic basemap image. */
348
348
  export function MapViewFrame(props) {
349
349
  const messages = useMapViewMessages();
350
350
  const frame = createMemo(() => mapFrame(props, props.height, props.padding ?? DEFAULT_PADDING));
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["content/MapViewFrame.tsx"],"sourcesContent":["import { createMemo, For, type JSX, Show } from \"solid-js\";\nimport {\n DEFAULT_PADDING,\n EARTH_CIRCUMFERENCE,\n isStop,\n linePoints,\n type MapFrame,\n mapFrame,\n pinHitRadii,\n pinOffsets,\n projectPoint,\n scaleBar,\n sortMarkers,\n unprojectPoint,\n} from \"./map-view-geometry\";\nimport { useMapViewMessages } from \"./map-view-messages\";\nimport type { MapViewFrameProps, MapViewMarker, MapViewPoint } from \"./map-view-types\";\n\nexport type { MapViewFrameProps } from \"./map-view-types\";\n\nconst S = 1e6;\nexport const mapNumber = (value: number): string => String(Number(value.toFixed(6)));\nexport const selectedMarker = (markers: MapViewMarker[], selectedId?: string): MapViewMarker | undefined =>\n selectedId !== undefined ? markers.find((marker) => marker.id === selectedId) : markers.find((marker) => marker.selected);\n\n/** The CSS form of fitCamera's width rule, so the server lays out exactly what MapLibre shows. */\nconst fittedWidth = (frame: MapFrame, padding: number): string =>\n `max(min(100% - ${2 * padding}px, ${frame.referenceWidth}px), ${frame.minWidth}px)`;\n\nexport function frameStyle(frame: MapFrame, padding: number): JSX.CSSProperties {\n return {\n left: \"50%\",\n top: \"50%\",\n width: fittedWidth(frame, padding),\n \"aspect-ratio\": `${frame.spanX} / ${frame.spanY}`,\n transform: \"translate(-50%, -50%)\",\n };\n}\nconst pointInFrame = (point: MapViewPoint, frame: MapFrame) => {\n const p = projectPoint(point);\n return { x: (p.x - frame.minX) / frame.spanX, y: (p.y - frame.minY) / frame.spanY };\n};\nconst positionStyle = (point: MapViewPoint, frame: MapFrame): JSX.CSSProperties => {\n const p = pointInFrame(point, frame);\n return { left: `${mapNumber(p.x * 100)}%`, top: `${mapNumber(p.y * 100)}%` };\n};\nconst path = (points: MapViewPoint[], frame: MapFrame, closed = false): string =>\n points\n .map((point, index) => {\n const p = projectPoint(point);\n return `${index ? \"L\" : \"M\"}${mapNumber((p.x - frame.minX) * S)} ${mapNumber((p.y - frame.minY) * S)}`;\n })\n .join(\" \") + (closed && points.length ? \" Z\" : \"\");\n\nexport function MapGeometry(\n props: MapViewFrameProps & {\n frame: MapFrame;\n boxStyle?: JSX.CSSProperties;\n onSelect?: (id: string) => void;\n /** Pins are buttons in MapView; the standalone frame draws them as labelled images, never focusable. */\n interactive?: boolean;\n /** 2^(live zoom - fitted zoom), so pin separation follows the person's zoom; 1 until then. */\n zoomFactor?: number;\n },\n): JSX.Element {\n const messages = useMapViewMessages();\n const markers = createMemo(() => sortMarkers(props.markers ?? []));\n const markerIds = createMemo(() => markers().map((marker) => marker.id));\n const markersById = createMemo(() => new Map(markers().map((marker) => [marker.id, marker])));\n const offsets = createMemo(() => pinOffsets(markers(), props.frame, props.zoomFactor, props.ownLocation?.point));\n const hitRadii = createMemo(() => pinHitRadii(markers(), props.frame, offsets(), props.zoomFactor));\n // Input order decides the fallback selection, as in MapView; sorting is only for drawing and keys.\n const selected = createMemo(() => selectedMarker(props.markers ?? [], props.selectedId));\n const keydown = (event: KeyboardEvent & { currentTarget: HTMLButtonElement }, id: string) => {\n const index = markerIds().indexOf(id);\n let next: number;\n switch (event.key) {\n case \"ArrowRight\":\n case \"ArrowDown\":\n next = (index + 1) % markers().length;\n break;\n case \"ArrowLeft\":\n case \"ArrowUp\":\n next = (index + markers().length - 1) % markers().length;\n break;\n case \"Home\":\n next = 0;\n break;\n case \"End\":\n next = markers().length - 1;\n break;\n default:\n return;\n }\n event.preventDefault();\n event.stopPropagation();\n const target = markers()[next];\n if (target) {\n event.currentTarget.parentElement?.querySelectorAll<HTMLButtonElement>(\".k2b-map-view__pin\")[next]?.focus({ preventScroll: true });\n props.onSelect?.(target.id);\n }\n };\n return (\n <div class=\"k2b-map-view__fit\" style={props.boxStyle ?? frameStyle(props.frame, props.padding ?? DEFAULT_PADDING)}>\n <svg\n class=\"k2b-map-view__geometry\"\n viewBox={`0 0 ${mapNumber(props.frame.spanX * S)} ${mapNumber(props.frame.spanY * S)}`}\n preserveAspectRatio=\"none\"\n overflow=\"visible\"\n aria-hidden=\"true\"\n >\n <For each={props.areas}>\n {(area) => (\n <path\n class=\"k2b-map-view__area\"\n data-tone={area.tone ?? \"accent\"}\n d={path(area.polygon, props.frame, true)}\n vector-effect=\"non-scaling-stroke\"\n />\n )}\n </For>\n <For each={props.lines}>\n {(line) => (\n <g class=\"k2b-map-view__line\" data-tone={line.tone ?? \"accent\"}>\n <Show when={!line.tone || line.tone === \"accent\" || line.tone === \"preview\"}>\n <path class=\"k2b-map-view__casing\" d={path(linePoints(line), props.frame)} vector-effect=\"non-scaling-stroke\" />\n </Show>\n <path class=\"k2b-map-view__stroke\" d={path(linePoints(line), props.frame)} vector-effect=\"non-scaling-stroke\" />\n </g>\n )}\n </For>\n <Show when={props.ownLocation}>\n {(location) => {\n const p = () => projectPoint(location().point);\n return (\n <circle\n class=\"k2b-map-view__accuracy\"\n cx={mapNumber((p().x - props.frame.minX) * S)}\n cy={mapNumber((p().y - props.frame.minY) * S)}\n r={mapNumber(\n ((location().accuracyMeters ?? 0) / (EARTH_CIRCUMFERENCE * Math.cos((location().point.lat * Math.PI) / 180))) * S,\n )}\n vector-effect=\"non-scaling-stroke\"\n />\n );\n }}\n </Show>\n </svg>\n <Show when={props.ownLocation}>\n {(location) => (\n <span\n class=\"k2b-map-view__me\"\n role=\"img\"\n aria-label={messages().ownLocation}\n style={positionStyle(location().point, props.frame)}\n />\n )}\n </Show>\n <div class=\"k2b-map-view__pins\" role=\"group\" aria-label={messages().pins}>\n <For each={markerIds()}>\n {(id) => {\n const marker = () => markersById().get(id)!;\n const name = () => (marker().mark === undefined ? marker().label : `${marker().mark} ${marker().label}`);\n const style = () => ({\n ...positionStyle(marker().point, props.frame),\n \"--k2b-map-pin-dx\": `${mapNumber(offsets().get(marker().id)?.dx ?? 0)}px`,\n \"--k2b-map-pin-dy\": `${mapNumber(offsets().get(marker().id)?.dy ?? 0)}px`,\n \"--k2b-map-pin-hit\": `${mapNumber(hitRadii().get(marker().id) ?? 22)}px`,\n });\n if (!props.interactive)\n return (\n <span\n class=\"k2b-map-view__pin\"\n data-id={marker().id}\n data-tone={marker().tone ?? \"accent\"}\n data-stop={isStop(marker()) || undefined}\n data-drop={marker().mark === undefined || undefined}\n data-selected={selected()?.id === marker().id || undefined}\n style={style()}\n role=\"img\"\n aria-label={name()}\n >\n <span aria-hidden=\"true\">{marker().mark}</span>\n </span>\n );\n return (\n <button\n type=\"button\"\n class=\"k2b-map-view__pin\"\n data-id={marker().id}\n data-tone={marker().tone ?? \"accent\"}\n data-stop={isStop(marker()) || undefined}\n data-drop={marker().mark === undefined || undefined}\n style={style()}\n aria-label={name()}\n aria-pressed={selected()?.id === marker().id}\n tabIndex={(selected() ?? markers()[0])?.id === marker().id ? 0 : -1}\n onKeyDown={(event) => keydown(event, id)}\n onClick={() => props.onSelect?.(marker().id)}\n >\n <span aria-hidden=\"true\">{marker().mark}</span>\n </button>\n );\n }}\n </For>\n </div>\n </div>\n );\n}\nexport type MapScale = { label: string; width: string };\nexport function referenceScale(frame: MapFrame, padding: number): MapScale {\n const center = unprojectPoint(frame.minX + frame.spanX / 2, frame.minY + frame.spanY / 2);\n const spanMeters = frame.spanX * EARTH_CIRCUMFERENCE * Math.cos((center.lat * Math.PI) / 180);\n const bar = scaleBar(spanMeters / frame.referenceWidth);\n return { label: bar.label, width: `calc(${fittedWidth(frame, padding)} * ${bar.meters / spanMeters})` };\n}\nexport function MapScaleBar(props: { scale: MapScale }): JSX.Element {\n return (\n <div class=\"k2b-map-view__scale\" style={{ width: props.scale.width }}>\n <span>{props.scale.label}</span>\n <div />\n </div>\n );\n}\n/** The scale bar and the attribution share the bottom row, so a long attribution wraps before it covers the scale. */\nexport function MapFootRow(props: { scale?: MapScale; children?: JSX.Element }): JSX.Element {\n return (\n <div class=\"k2b-map-view__foot-row\">\n <Show when={props.scale}>{(scale) => <MapScaleBar scale={scale()} />}</Show>\n <div class=\"k2b-map-view__attribution\">{props.children}</div>\n </div>\n );\n}\n/** Geometry without a browser, a canvas, or a network dependency; suitable for server rendering and PDF output. */\nexport function MapViewFrame(props: MapViewFrameProps): JSX.Element {\n const messages = useMapViewMessages();\n const frame = createMemo(() => mapFrame(props, props.height, props.padding ?? DEFAULT_PADDING));\n return (\n <div\n class={`k2b-map-view${props.class ? ` ${props.class}` : \"\"}`}\n style={{ height: `${props.height}px` }}\n data-state=\"static\"\n role=\"region\"\n aria-label={messages().mapLabel}\n >\n <span class=\"k2b-sr-only\">{messages().summary({ count: props.markers?.length ?? 0 })}</span>\n <Show when={frame()}>{(value) => <MapGeometry {...props} frame={value()} />}</Show>\n <div class=\"k2b-map-view__foot\">\n <MapFootRow scale={frame() ? referenceScale(frame()!, props.padding ?? DEFAULT_PADDING) : undefined}>\n {props.attribution}\n </MapFootRow>\n </div>\n </div>\n );\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["content/MapViewFrame.tsx"],"sourcesContent":["import { createMemo, For, type JSX, Show } from \"solid-js\";\nimport {\n DEFAULT_PADDING,\n EARTH_CIRCUMFERENCE,\n isStop,\n linePoints,\n type MapFrame,\n mapFrame,\n pinHitRadii,\n pinOffsets,\n projectPoint,\n scaleBar,\n sortMarkers,\n unprojectPoint,\n} from \"./map-view-geometry\";\nimport { useMapViewMessages } from \"./map-view-messages\";\nimport type { MapViewFrameProps, MapViewMarker, MapViewPoint } from \"./map-view-types\";\n\nexport type { MapViewFrameProps } from \"./map-view-types\";\n\nconst S = 1e6;\nexport const mapNumber = (value: number): string => String(Number(value.toFixed(6)));\nexport const selectedMarker = (markers: MapViewMarker[], selectedId?: string): MapViewMarker | undefined =>\n selectedId !== undefined ? markers.find((marker) => marker.id === selectedId) : markers.find((marker) => marker.selected);\n\n/** The CSS form of fitCamera's width rule, so the server lays out exactly what MapLibre shows. */\nconst fittedWidth = (frame: MapFrame, padding: number): string =>\n `max(min(100% - ${2 * padding}px, ${frame.referenceWidth}px), ${frame.minWidth}px)`;\n\nexport function frameStyle(frame: MapFrame, padding: number): JSX.CSSProperties {\n return {\n left: \"50%\",\n top: \"50%\",\n width: fittedWidth(frame, padding),\n \"aspect-ratio\": `${frame.spanX} / ${frame.spanY}`,\n transform: \"translate(-50%, -50%)\",\n };\n}\nconst pointInFrame = (point: MapViewPoint, frame: MapFrame) => {\n const p = projectPoint(point);\n return { x: (p.x - frame.minX) / frame.spanX, y: (p.y - frame.minY) / frame.spanY };\n};\nconst positionStyle = (point: MapViewPoint, frame: MapFrame): JSX.CSSProperties => {\n const p = pointInFrame(point, frame);\n return { left: `${mapNumber(p.x * 100)}%`, top: `${mapNumber(p.y * 100)}%` };\n};\nconst path = (points: MapViewPoint[], frame: MapFrame, closed = false): string =>\n points\n .map((point, index) => {\n const p = projectPoint(point);\n return `${index ? \"L\" : \"M\"}${mapNumber((p.x - frame.minX) * S)} ${mapNumber((p.y - frame.minY) * S)}`;\n })\n .join(\" \") + (closed && points.length ? \" Z\" : \"\");\n\nexport function MapGeometry(\n props: MapViewFrameProps & {\n frame: MapFrame;\n boxStyle?: JSX.CSSProperties;\n onSelect?: (id: string) => void;\n /** Pins are buttons in MapView; the standalone frame draws them as labelled images, never focusable. */\n interactive?: boolean;\n /** 2^(live zoom - fitted zoom), so pin separation follows the person's zoom; 1 until then. */\n zoomFactor?: number;\n },\n): JSX.Element {\n const messages = useMapViewMessages();\n const markers = createMemo(() => sortMarkers(props.markers ?? []));\n const markerIds = createMemo(() => markers().map((marker) => marker.id));\n const markersById = createMemo(() => new Map(markers().map((marker) => [marker.id, marker])));\n const offsets = createMemo(() => pinOffsets(markers(), props.frame, props.zoomFactor, props.ownLocation?.point));\n const hitRadii = createMemo(() => pinHitRadii(markers(), props.frame, offsets(), props.zoomFactor));\n // Input order decides the fallback selection, as in MapView; sorting is only for drawing and keys.\n const selected = createMemo(() => selectedMarker(props.markers ?? [], props.selectedId));\n const keydown = (event: KeyboardEvent & { currentTarget: HTMLButtonElement }, id: string) => {\n const index = markerIds().indexOf(id);\n let next: number;\n switch (event.key) {\n case \"ArrowRight\":\n case \"ArrowDown\":\n next = (index + 1) % markers().length;\n break;\n case \"ArrowLeft\":\n case \"ArrowUp\":\n next = (index + markers().length - 1) % markers().length;\n break;\n case \"Home\":\n next = 0;\n break;\n case \"End\":\n next = markers().length - 1;\n break;\n default:\n return;\n }\n event.preventDefault();\n event.stopPropagation();\n const target = markers()[next];\n if (target) {\n event.currentTarget.parentElement?.querySelectorAll<HTMLButtonElement>(\".k2b-map-view__pin\")[next]?.focus({ preventScroll: true });\n props.onSelect?.(target.id);\n }\n };\n return (\n <div class=\"k2b-map-view__fit\" style={props.boxStyle ?? frameStyle(props.frame, props.padding ?? DEFAULT_PADDING)}>\n <svg\n class=\"k2b-map-view__geometry\"\n viewBox={`0 0 ${mapNumber(props.frame.spanX * S)} ${mapNumber(props.frame.spanY * S)}`}\n preserveAspectRatio=\"none\"\n overflow=\"visible\"\n aria-hidden=\"true\"\n >\n <For each={props.areas}>\n {(area) => (\n <path\n class=\"k2b-map-view__area\"\n data-tone={area.tone ?? \"accent\"}\n d={path(area.polygon, props.frame, true)}\n vector-effect=\"non-scaling-stroke\"\n />\n )}\n </For>\n <For each={props.lines}>\n {(line) => (\n <g class=\"k2b-map-view__line\" data-tone={line.tone ?? \"accent\"}>\n <Show when={!line.tone || line.tone === \"accent\" || line.tone === \"preview\"}>\n <path class=\"k2b-map-view__casing\" d={path(linePoints(line), props.frame)} vector-effect=\"non-scaling-stroke\" />\n </Show>\n <path class=\"k2b-map-view__stroke\" d={path(linePoints(line), props.frame)} vector-effect=\"non-scaling-stroke\" />\n </g>\n )}\n </For>\n <Show when={props.ownLocation}>\n {(location) => {\n const p = () => projectPoint(location().point);\n return (\n <circle\n class=\"k2b-map-view__accuracy\"\n cx={mapNumber((p().x - props.frame.minX) * S)}\n cy={mapNumber((p().y - props.frame.minY) * S)}\n r={mapNumber(\n ((location().accuracyMeters ?? 0) / (EARTH_CIRCUMFERENCE * Math.cos((location().point.lat * Math.PI) / 180))) * S,\n )}\n vector-effect=\"non-scaling-stroke\"\n />\n );\n }}\n </Show>\n </svg>\n <Show when={props.ownLocation}>\n {(location) => (\n <span\n class=\"k2b-map-view__me\"\n role=\"img\"\n aria-label={messages().ownLocation}\n style={positionStyle(location().point, props.frame)}\n />\n )}\n </Show>\n <div class=\"k2b-map-view__pins\" role=\"group\" aria-label={messages().pins}>\n <For each={markerIds()}>\n {(id) => {\n const marker = () => markersById().get(id)!;\n const name = () => (marker().mark === undefined ? marker().label : `${marker().mark} ${marker().label}`);\n const style = () => ({\n ...positionStyle(marker().point, props.frame),\n \"--k2b-map-pin-dx\": `${mapNumber(offsets().get(marker().id)?.dx ?? 0)}px`,\n \"--k2b-map-pin-dy\": `${mapNumber(offsets().get(marker().id)?.dy ?? 0)}px`,\n \"--k2b-map-pin-hit\": `${mapNumber(hitRadii().get(marker().id) ?? 22)}px`,\n });\n if (!props.interactive)\n return (\n <span\n class=\"k2b-map-view__pin\"\n data-id={marker().id}\n data-tone={marker().tone ?? \"accent\"}\n data-stop={isStop(marker()) || undefined}\n data-drop={marker().mark === undefined || undefined}\n data-selected={selected()?.id === marker().id || undefined}\n style={style()}\n role=\"img\"\n aria-label={name()}\n >\n <span aria-hidden=\"true\">{marker().mark}</span>\n </span>\n );\n return (\n <button\n type=\"button\"\n class=\"k2b-map-view__pin\"\n data-id={marker().id}\n data-tone={marker().tone ?? \"accent\"}\n data-stop={isStop(marker()) || undefined}\n data-drop={marker().mark === undefined || undefined}\n style={style()}\n aria-label={name()}\n aria-pressed={selected()?.id === marker().id}\n tabIndex={(selected() ?? markers()[0])?.id === marker().id ? 0 : -1}\n onKeyDown={(event) => keydown(event, id)}\n onClick={() => props.onSelect?.(marker().id)}\n >\n <span aria-hidden=\"true\">{marker().mark}</span>\n </button>\n );\n }}\n </For>\n </div>\n </div>\n );\n}\nexport type MapScale = { label: string; width: string };\nexport function referenceScale(frame: MapFrame, padding: number): MapScale {\n const center = unprojectPoint(frame.minX + frame.spanX / 2, frame.minY + frame.spanY / 2);\n const spanMeters = frame.spanX * EARTH_CIRCUMFERENCE * Math.cos((center.lat * Math.PI) / 180);\n const bar = scaleBar(spanMeters / frame.referenceWidth);\n return { label: bar.label, width: `calc(${fittedWidth(frame, padding)} * ${bar.meters / spanMeters})` };\n}\nexport function MapScaleBar(props: { scale: MapScale }): JSX.Element {\n return (\n <div class=\"k2b-map-view__scale\" style={{ width: props.scale.width }}>\n <span>{props.scale.label}</span>\n <div />\n </div>\n );\n}\n/** The scale bar and the attribution share the bottom row, so a long attribution wraps before it covers the scale. */\nexport function MapFootRow(props: { scale?: MapScale; children?: JSX.Element }): JSX.Element {\n return (\n <div class=\"k2b-map-view__foot-row\">\n <Show when={props.scale}>{(scale) => <MapScaleBar scale={scale()} />}</Show>\n <div class=\"k2b-map-view__attribution\">{props.children}</div>\n </div>\n );\n}\n/** Geometry fallback without a browser, canvas, or network. Does not contain a geographic basemap image. */\nexport function MapViewFrame(props: MapViewFrameProps): JSX.Element {\n const messages = useMapViewMessages();\n const frame = createMemo(() => mapFrame(props, props.height, props.padding ?? DEFAULT_PADDING));\n return (\n <div\n class={`k2b-map-view${props.class ? ` ${props.class}` : \"\"}`}\n style={{ height: `${props.height}px` }}\n data-state=\"static\"\n role=\"region\"\n aria-label={messages().mapLabel}\n >\n <span class=\"k2b-sr-only\">{messages().summary({ count: props.markers?.length ?? 0 })}</span>\n <Show when={frame()}>{(value) => <MapGeometry {...props} frame={value()} />}</Show>\n <div class=\"k2b-map-view__foot\">\n <MapFootRow scale={frame() ? referenceScale(frame()!, props.padding ?? DEFAULT_PADDING) : undefined}>\n {props.attribution}\n </MapFootRow>\n </div>\n </div>\n );\n}\n"],"mappings":"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","ignoreList":[]}