efficient-shell 4.137.0 → 4.137.1

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 (166) hide show
  1. package/LICENSE +6 -17
  2. package/README.md +3 -1
  3. package/dist/Browser-ZX5OTOKK.js +43 -0
  4. package/dist/Calculator-4SQGOQFQ.js +29 -0
  5. package/dist/ConfirmDialog-NPKW2XHM.js +1 -0
  6. package/dist/CurrencyConverter-2KOM7L6V.js +21 -0
  7. package/dist/Documents-IZTIQYPG.js +52 -0
  8. package/dist/Files-B63KKXGZ.js +89 -0
  9. package/dist/Notepad-WA77V45J.js +25 -0
  10. package/dist/PdfViewer-RBRGEKWF.js +1 -0
  11. package/dist/PomodoroTimer-SDUBKXUS.js +99 -0
  12. package/dist/Preview-D4KOA4OI.js +187 -0
  13. package/dist/Sidebar-Y57LYXXI.js +23 -0
  14. package/dist/Spreadsheet-JX5E6WH6.js +37 -0
  15. package/dist/Stock-XAQ5WMUZ.js +16 -0
  16. package/dist/Weather-HLAGJ5LV.js +60 -0
  17. package/dist/WorldClock-IRI4VCTA.js +32 -0
  18. package/dist/apps/index.js +1 -151
  19. package/dist/chunk-3A46NCXK.js +29 -0
  20. package/dist/chunk-44UO7FYU.js +11 -0
  21. package/dist/chunk-466CM2TJ.js +1 -0
  22. package/dist/chunk-57MIENLJ.js +1 -0
  23. package/dist/chunk-5CRAF2AD.js +2 -0
  24. package/dist/chunk-A2OQLLYK.js +6 -0
  25. package/dist/chunk-B43AGQET.js +4 -0
  26. package/dist/chunk-BR22X7E5.js +1 -0
  27. package/dist/chunk-BUTSU7FO.js +1 -0
  28. package/dist/chunk-D65T4H6J.js +1 -0
  29. package/dist/chunk-ESL5TDNA.js +1 -0
  30. package/dist/chunk-FBDZGO3V.js +1 -0
  31. package/dist/chunk-FHTLC7HH.js +1 -0
  32. package/dist/chunk-FQLMX3IE.js +948 -0
  33. package/dist/chunk-H562R4GX.js +34 -0
  34. package/dist/chunk-JN4WXTWJ.js +106 -0
  35. package/dist/chunk-LVDRBRYU.js +1 -0
  36. package/dist/chunk-LWLCNQY7.js +1 -0
  37. package/dist/chunk-MAIHBBWT.js +1 -0
  38. package/dist/chunk-NPJH5MD7.js +13 -0
  39. package/dist/chunk-OCSOMMY2.js +1 -0
  40. package/dist/chunk-OQDWLHZI.js +1 -0
  41. package/dist/chunk-OWSAMA3I.js +23 -0
  42. package/dist/chunk-PH3PRIFP.js +5 -0
  43. package/dist/chunk-TAWKWSPN.js +9 -0
  44. package/dist/chunk-U4GTZPXP.js +1 -0
  45. package/dist/chunk-UB4JIOLD.js +2 -0
  46. package/dist/chunk-UZAJ5BF6.js +9 -0
  47. package/dist/chunk-VEGMDXT4.js +1 -0
  48. package/dist/chunk-VTVSMRFX.js +1 -0
  49. package/dist/chunk-VVAGSKW7.js +1 -0
  50. package/dist/chunk-XO43FJRM.js +19 -0
  51. package/dist/chunk-Y7BOLDRM.js +69 -0
  52. package/dist/file-intake/index.js +1 -4
  53. package/dist/index.js +639 -7473
  54. package/dist/map/index.js +20 -540
  55. package/dist/markdown/index.js +6 -184
  56. package/dist/markup/index.js +1 -135
  57. package/dist/page-tabs/index.js +21 -709
  58. package/dist/sounds-OMHXVVQ4.js +1 -0
  59. package/dist/ui/index.js +1 -19
  60. package/package.json +4 -3
  61. package/dist/Browser-ZNX4WFUH.js +0 -482
  62. package/dist/Browser-ZNX4WFUH.js.map +0 -1
  63. package/dist/Calculator-6FGNKOXU.js +0 -192
  64. package/dist/Calculator-6FGNKOXU.js.map +0 -1
  65. package/dist/ConfirmDialog-NPQMIGUR.js +0 -4
  66. package/dist/ConfirmDialog-NPQMIGUR.js.map +0 -1
  67. package/dist/CurrencyConverter-FF7EXRYL.js +0 -236
  68. package/dist/CurrencyConverter-FF7EXRYL.js.map +0 -1
  69. package/dist/Documents-H3R7XSBH.js +0 -441
  70. package/dist/Documents-H3R7XSBH.js.map +0 -1
  71. package/dist/Files-ZHJIAUC2.js +0 -805
  72. package/dist/Files-ZHJIAUC2.js.map +0 -1
  73. package/dist/Notepad-VE7ISWRQ.js +0 -410
  74. package/dist/Notepad-VE7ISWRQ.js.map +0 -1
  75. package/dist/PdfViewer-SQBFYAGW.js +0 -5
  76. package/dist/PdfViewer-SQBFYAGW.js.map +0 -1
  77. package/dist/PomodoroTimer-IR3WREED.js +0 -633
  78. package/dist/PomodoroTimer-IR3WREED.js.map +0 -1
  79. package/dist/Preview-DAQGRNRM.js +0 -2959
  80. package/dist/Preview-DAQGRNRM.js.map +0 -1
  81. package/dist/Sidebar-YW6H4NDJ.js +0 -291
  82. package/dist/Sidebar-YW6H4NDJ.js.map +0 -1
  83. package/dist/Spreadsheet-HOCPHJOC.js +0 -519
  84. package/dist/Spreadsheet-HOCPHJOC.js.map +0 -1
  85. package/dist/Stock-LVRQPURG.js +0 -158
  86. package/dist/Stock-LVRQPURG.js.map +0 -1
  87. package/dist/Weather-LZQGVDJL.js +0 -431
  88. package/dist/Weather-LZQGVDJL.js.map +0 -1
  89. package/dist/WorldClock-XPD7WOZT.js +0 -202
  90. package/dist/WorldClock-XPD7WOZT.js.map +0 -1
  91. package/dist/apps/index.js.map +0 -1
  92. package/dist/chunk-5O42JXQE.js +0 -26
  93. package/dist/chunk-5O42JXQE.js.map +0 -1
  94. package/dist/chunk-5RPTS3BT.js +0 -70
  95. package/dist/chunk-5RPTS3BT.js.map +0 -1
  96. package/dist/chunk-6XJEJWNJ.js +0 -61
  97. package/dist/chunk-6XJEJWNJ.js.map +0 -1
  98. package/dist/chunk-7CCHEEYC.js +0 -94
  99. package/dist/chunk-7CCHEEYC.js.map +0 -1
  100. package/dist/chunk-BE7FZOFU.js +0 -17
  101. package/dist/chunk-BE7FZOFU.js.map +0 -1
  102. package/dist/chunk-COWYSHG2.js +0 -79
  103. package/dist/chunk-COWYSHG2.js.map +0 -1
  104. package/dist/chunk-D7PYW2QS.js +0 -265
  105. package/dist/chunk-D7PYW2QS.js.map +0 -1
  106. package/dist/chunk-DVZWYWSD.js +0 -26
  107. package/dist/chunk-DVZWYWSD.js.map +0 -1
  108. package/dist/chunk-E7TB6WD2.js +0 -153
  109. package/dist/chunk-E7TB6WD2.js.map +0 -1
  110. package/dist/chunk-FIHOGVUP.js +0 -416
  111. package/dist/chunk-FIHOGVUP.js.map +0 -1
  112. package/dist/chunk-GA35NEND.js +0 -56
  113. package/dist/chunk-GA35NEND.js.map +0 -1
  114. package/dist/chunk-HUBJAUGG.js +0 -316
  115. package/dist/chunk-HUBJAUGG.js.map +0 -1
  116. package/dist/chunk-I2TAAJHS.js +0 -465
  117. package/dist/chunk-I2TAAJHS.js.map +0 -1
  118. package/dist/chunk-ICTRCKUE.js +0 -3710
  119. package/dist/chunk-ICTRCKUE.js.map +0 -1
  120. package/dist/chunk-IPXN646P.js +0 -14
  121. package/dist/chunk-IPXN646P.js.map +0 -1
  122. package/dist/chunk-IRWSRJ4K.js +0 -48
  123. package/dist/chunk-IRWSRJ4K.js.map +0 -1
  124. package/dist/chunk-JOPU6WPY.js +0 -504
  125. package/dist/chunk-JOPU6WPY.js.map +0 -1
  126. package/dist/chunk-MGGY74RY.js +0 -14
  127. package/dist/chunk-MGGY74RY.js.map +0 -1
  128. package/dist/chunk-PVPPAWVM.js +0 -46
  129. package/dist/chunk-PVPPAWVM.js.map +0 -1
  130. package/dist/chunk-R7QGMK6N.js +0 -102
  131. package/dist/chunk-R7QGMK6N.js.map +0 -1
  132. package/dist/chunk-RT6DSB5Y.js +0 -143
  133. package/dist/chunk-RT6DSB5Y.js.map +0 -1
  134. package/dist/chunk-TRCWINHF.js +0 -105
  135. package/dist/chunk-TRCWINHF.js.map +0 -1
  136. package/dist/chunk-TW7LPMVR.js +0 -16
  137. package/dist/chunk-TW7LPMVR.js.map +0 -1
  138. package/dist/chunk-UTYKLGGT.js +0 -195
  139. package/dist/chunk-UTYKLGGT.js.map +0 -1
  140. package/dist/chunk-VNJJCH5A.js +0 -822
  141. package/dist/chunk-VNJJCH5A.js.map +0 -1
  142. package/dist/chunk-XJHZWSKV.js +0 -1103
  143. package/dist/chunk-XJHZWSKV.js.map +0 -1
  144. package/dist/chunk-Y3GYJ7YR.js +0 -549
  145. package/dist/chunk-Y3GYJ7YR.js.map +0 -1
  146. package/dist/chunk-YA4EE7ST.js +0 -14107
  147. package/dist/chunk-YA4EE7ST.js.map +0 -1
  148. package/dist/chunk-YDHXWCCJ.js +0 -145
  149. package/dist/chunk-YDHXWCCJ.js.map +0 -1
  150. package/dist/chunk-YE6GUDGP.js +0 -548
  151. package/dist/chunk-YE6GUDGP.js.map +0 -1
  152. package/dist/chunk-YNKK7NE3.js +0 -171
  153. package/dist/chunk-YNKK7NE3.js.map +0 -1
  154. package/dist/chunk-YPO6RDMX.js +0 -20
  155. package/dist/chunk-YPO6RDMX.js.map +0 -1
  156. package/dist/chunk-ZS7PMGUW.js +0 -7
  157. package/dist/chunk-ZS7PMGUW.js.map +0 -1
  158. package/dist/file-intake/index.js.map +0 -1
  159. package/dist/index.js.map +0 -1
  160. package/dist/map/index.js.map +0 -1
  161. package/dist/markdown/index.js.map +0 -1
  162. package/dist/markup/index.js.map +0 -1
  163. package/dist/page-tabs/index.js.map +0 -1
  164. package/dist/sounds-NT4DEZGD.js +0 -3
  165. package/dist/sounds-NT4DEZGD.js.map +0 -1
  166. package/dist/ui/index.js.map +0 -1
package/dist/map/index.js CHANGED
@@ -1,541 +1,21 @@
1
1
  "use client";
2
- import { Button_default } from '../chunk-RT6DSB5Y.js';
3
- import { rootIsDark, ROOT_THEME_ATTRIBUTES } from '../chunk-IPXN646P.js';
4
- import { useRef, useState, useEffect, useCallback, useMemo, useSyncExternalStore } from 'react';
5
- import { jsxs, jsx } from 'react/jsx-runtime';
6
- import { useQuery } from '@tanstack/react-query';
7
-
8
- // src/map/attribution.ts
9
- var COMPACT_SHOW = "maplibregl-compact-show";
10
- function foldAttributionOnce(control) {
11
- if (!control) return () => {
12
- };
13
- const fold = () => {
14
- if (!control.classList.contains(COMPACT_SHOW)) return false;
15
- control.classList.remove(COMPACT_SHOW);
16
- return true;
17
- };
18
- if (fold()) return () => {
19
- };
20
- const watcher = new MutationObserver(() => {
21
- if (fold()) watcher.disconnect();
22
- });
23
- watcher.observe(control, { attributes: true, attributeFilter: ["class"] });
24
- return () => watcher.disconnect();
25
- }
26
-
27
- // src/map/maplibre.ts
28
- var MAPLIBRE_WORKER_FILE = "maplibre-gl-worker.mjs";
29
- var mapLibreWorkerUrl = (version) => `/maplibre-gl/${version}/${MAPLIBRE_WORKER_FILE}`;
30
- var loading = null;
31
- function loadMapLibre() {
32
- loading ??= Promise.all([import('maplibre-gl'), import('maplibre-gl/dist/maplibre-gl.css')]).then(([maplibre]) => {
33
- maplibre.setWorkerUrl(mapLibreWorkerUrl(maplibre.getVersion()));
34
- return maplibre;
35
- }).catch((error) => {
36
- loading = null;
37
- throw error;
38
- });
39
- return loading;
40
- }
41
- function subscribe(onChange) {
42
- const watcher = new MutationObserver(onChange);
43
- watcher.observe(document.documentElement, { attributes: true, attributeFilter: ROOT_THEME_ATTRIBUTES });
44
- return () => watcher.disconnect();
45
- }
46
- var isDark = rootIsDark;
47
- function useDarkTheme() {
48
- return useSyncExternalStore(subscribe, isDark, () => false);
49
- }
50
- var ROUTE_SOURCE = "routes";
51
- function accentColor() {
52
- const probe = document.createElement("span");
53
- probe.className = "text-blue-600";
54
- probe.style.display = "none";
55
- document.body.appendChild(probe);
56
- const color = getComputedStyle(probe).color || "#2563eb";
57
- probe.remove();
58
- return toRgb(color);
59
- }
60
- function toRgb(css) {
61
- const ctx = document.createElement("canvas").getContext("2d");
62
- if (!ctx) return "#2563eb";
63
- ctx.fillStyle = "#2563eb";
64
- ctx.fillStyle = css;
65
- ctx.fillRect(0, 0, 1, 1);
66
- const [r, g, b] = ctx.getImageData(0, 0, 1, 1).data;
67
- return `rgb(${r}, ${g}, ${b})`;
68
- }
69
- var STYLES = {
70
- light: "https://tiles.openfreemap.org/styles/positron",
71
- dark: "https://tiles.openfreemap.org/styles/dark"
72
- };
73
- var WORLD = { center: [30, 20], zoom: 1 };
74
- var SVG_NS = "http://www.w3.org/2000/svg";
75
- function iconElement(paths, selected) {
76
- const svg = document.createElementNS(SVG_NS, "svg");
77
- svg.setAttribute("viewBox", "0 0 24 24");
78
- svg.setAttribute("fill", "none");
79
- svg.setAttribute("stroke", "currentColor");
80
- svg.setAttribute("stroke-width", "2");
81
- svg.setAttribute("aria-hidden", "true");
82
- svg.setAttribute("class", selected ? "h-4 w-4" : "h-3.5 w-3.5");
83
- for (const d of paths) {
84
- const path = document.createElementNS(SVG_NS, "path");
85
- path.setAttribute("stroke-linecap", "round");
86
- path.setAttribute("stroke-linejoin", "round");
87
- path.setAttribute("d", d);
88
- svg.appendChild(path);
89
- }
90
- return svg;
91
- }
92
- function pinElement(pin, selected) {
93
- const el = document.createElement("button");
94
- el.type = "button";
95
- el.title = pin.approximate ? `${pin.label} (approximate)` : pin.label;
96
- el.setAttribute("aria-label", pin.approximate ? `${pin.label}, approximate location` : pin.label);
97
- el.dataset.pin = pin.key;
98
- el.className = [
99
- "relative grid place-items-center rounded-full border-2 border-white font-semibold leading-none shadow-md cursor-pointer",
100
- pin.tone,
101
- selected ? "h-8 w-8 text-xs ring-2 ring-gray-900 ring-offset-1" : "h-6 w-6 text-[10px]",
102
- pin.approximate ? "border-dashed opacity-80" : "",
103
- pin.faded && !selected ? "opacity-40" : ""
104
- ].join(" ");
105
- if (pin.icon?.length) el.appendChild(iconElement(pin.icon, selected));
106
- else el.textContent = pin.glyph;
107
- if (pin.badge) {
108
- const badge = document.createElement("span");
109
- badge.setAttribute("aria-hidden", "true");
110
- badge.className = [
111
- "absolute -right-2 -top-2 grid h-4 min-w-4 place-items-center rounded-full px-0.5 text-[9px] font-semibold leading-none shadow",
112
- pin.badgeTone ?? "bg-white text-gray-900"
113
- ].join(" ");
114
- badge.textContent = pin.badge;
115
- el.appendChild(badge);
116
- }
117
- return el;
118
- }
119
- function EntityMap({
120
- pins,
121
- selectedKey,
122
- focus,
123
- onSelect,
124
- ariaLabel,
125
- className = "",
126
- children,
127
- routes,
128
- fitTo,
129
- attribution
130
- }) {
131
- const box = useRef(null);
132
- const map = useRef(null);
133
- const lib = useRef(null);
134
- const markers = useRef([]);
135
- const fitted = useRef("");
136
- const [ready, setReady] = useState(false);
137
- const [failed, setFailed] = useState(false);
138
- const theme = useDarkTheme() ? "dark" : "light";
139
- const latest = useRef({ onSelect, pins, selectedKey });
140
- useEffect(() => {
141
- latest.current = { onSelect, pins, selectedKey };
142
- });
143
- const revealSelected = useCallback(() => {
144
- const m = map.current;
145
- const { pins: shown, selectedKey: chosen } = latest.current;
146
- const pin = chosen ? shown.find((p) => p.key === chosen) : void 0;
147
- if (!m || !pin || m.getBounds().contains([pin.lng, pin.lat])) return;
148
- const reduced = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
149
- m.easeTo({ center: [pin.lng, pin.lat], duration: reduced ? 0 : 400 });
150
- }, []);
151
- useEffect(() => {
152
- let cancelled = false;
153
- let created = null;
154
- let observer = null;
155
- let unfoldWatch = () => {
156
- };
157
- void (async () => {
158
- try {
159
- const maplibre = await loadMapLibre();
160
- if (cancelled || !box.current) return;
161
- lib.current = maplibre;
162
- created = new maplibre.Map({
163
- container: box.current,
164
- style: STYLES[theme],
165
- center: WORLD.center,
166
- zoom: WORLD.zoom,
167
- attributionControl: attribution ? { compact: true, customAttribution: attribution } : { compact: true },
168
- dragRotate: false,
169
- pitchWithRotate: false,
170
- touchPitch: false,
171
- maxPitch: 0
172
- });
173
- created.touchZoomRotate.disableRotation();
174
- created.keyboard.disableRotation();
175
- created.addControl(new maplibre.NavigationControl({ showCompass: false }), "top-right");
176
- created.on("error", (event) => console.warn("[map]", event.error?.message));
177
- unfoldWatch = foldAttributionOnce(box.current.querySelector(".maplibregl-ctrl-attrib"));
178
- const current = created;
179
- observer = new ResizeObserver(() => {
180
- current.resize();
181
- revealSelected();
182
- });
183
- observer.observe(box.current);
184
- map.current = created;
185
- setReady(true);
186
- } catch (error) {
187
- console.error("[map] could not start", error);
188
- if (!cancelled) setFailed(true);
189
- }
190
- })();
191
- return () => {
192
- cancelled = true;
193
- observer?.disconnect();
194
- unfoldWatch();
195
- markers.current.forEach((m) => m.remove());
196
- markers.current = [];
197
- created?.remove();
198
- map.current = null;
199
- };
200
- }, []);
201
- const shownTheme = useRef(theme);
202
- useEffect(() => {
203
- if (!ready || !map.current || shownTheme.current === theme) return;
204
- shownTheme.current = theme;
205
- map.current.setStyle(STYLES[theme]);
206
- }, [ready, theme]);
207
- useEffect(() => {
208
- const m = map.current;
209
- const maplibre = lib.current;
210
- if (!ready || !m || !maplibre) return;
211
- markers.current.forEach((marker) => marker.remove());
212
- markers.current = [];
213
- const ordered = [...pins].sort((a, b) => Number(a.key === selectedKey) - Number(b.key === selectedKey));
214
- for (const pin of ordered) {
215
- const el = pinElement(pin, pin.key === selectedKey);
216
- el.addEventListener("click", (event) => {
217
- event.stopPropagation();
218
- latest.current.onSelect(pin.key);
219
- });
220
- markers.current.push(new maplibre.Marker({ element: el, anchor: "center" }).setLngLat([pin.lng, pin.lat]).addTo(m));
221
- }
222
- }, [ready, pins, selectedKey]);
223
- useEffect(() => {
224
- if (!ready || !selectedKey) return;
225
- const frame = requestAnimationFrame(revealSelected);
226
- return () => cancelAnimationFrame(frame);
227
- }, [ready, selectedKey, revealSelected]);
228
- useEffect(() => {
229
- const m = map.current;
230
- const maplibre = lib.current;
231
- const target = fitTo ? pins.filter((p) => fitTo.includes(p.key)) : pins;
232
- if (!ready || !m || !maplibre || target.length === 0) return;
233
- const key = target.map((p) => `${p.key}@${p.lat},${p.lng}`).sort().join("|");
234
- if (fitted.current === key) return;
235
- const first = fitted.current === "";
236
- fitted.current = key;
237
- if (target.length === 1) {
238
- m.jumpTo({ center: [target[0].lng, target[0].lat], zoom: 13 });
239
- return;
240
- }
241
- const bounds = new maplibre.LngLatBounds([target[0].lng, target[0].lat], [target[0].lng, target[0].lat]);
242
- for (const p of target) bounds.extend([p.lng, p.lat]);
243
- m.fitBounds(bounds, { padding: 48, maxZoom: 14, animate: !first });
244
- }, [ready, pins, fitTo]);
245
- useEffect(() => {
246
- const m = map.current;
247
- if (!ready || !m) return;
248
- const data = {
249
- type: "FeatureCollection",
250
- features: (routes ?? []).filter((r) => r.coordinates.length >= 2).map((r) => ({
251
- type: "Feature",
252
- properties: { key: r.key, estimate: r.estimate, faded: !!r.faded },
253
- geometry: { type: "LineString", coordinates: r.coordinates }
254
- }))
255
- };
256
- const draw = () => {
257
- const color = accentColor();
258
- const opacity = ["case", ["get", "faded"], 0.25, 0.85];
259
- const source = m.getSource(ROUTE_SOURCE);
260
- if (source) source.setData(data);
261
- else m.addSource(ROUTE_SOURCE, { type: "geojson", data });
262
- if (m.getLayer("routes-road")) m.setPaintProperty("routes-road", "line-color", color);
263
- else m.addLayer({
264
- id: "routes-road",
265
- type: "line",
266
- source: ROUTE_SOURCE,
267
- filter: ["!", ["get", "estimate"]],
268
- layout: { "line-join": "round", "line-cap": "round" },
269
- paint: { "line-color": color, "line-width": 4, "line-opacity": opacity }
270
- });
271
- if (m.getLayer("routes-estimate")) m.setPaintProperty("routes-estimate", "line-color", color);
272
- else m.addLayer({
273
- id: "routes-estimate",
274
- type: "line",
275
- source: ROUTE_SOURCE,
276
- filter: ["get", "estimate"],
277
- layout: { "line-join": "round", "line-cap": "round" },
278
- paint: { "line-color": color, "line-width": 3, "line-dasharray": [1.5, 1.5], "line-opacity": opacity }
279
- });
280
- };
281
- const tryDraw = () => {
282
- try {
283
- draw();
284
- } catch (error) {
285
- console.debug("[map] routes wait for the style", error);
286
- }
287
- };
288
- tryDraw();
289
- m.on("style.load", tryDraw);
290
- m.once("idle", tryDraw);
291
- return () => {
292
- m.off("style.load", tryDraw);
293
- m.off("idle", tryDraw);
294
- };
295
- }, [ready, routes, theme]);
296
- useEffect(() => {
297
- const m = map.current;
298
- if (!ready || !m || !focus) return;
299
- const pin = pins.find((p) => p.key === focus.key);
300
- if (!pin) return;
301
- const to = { center: [pin.lng, pin.lat], zoom: Math.max(m.getZoom(), 13) };
302
- if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) m.jumpTo(to);
303
- else m.flyTo({ ...to, duration: 600 });
304
- }, [ready, focus?.n]);
305
- return /* @__PURE__ */ jsxs("div", { className: `relative min-h-72 overflow-hidden rounded-lg border border-gray-200 bg-gray-100 ${className}`, children: [
306
- /* @__PURE__ */ jsx("div", { className: "absolute inset-0", children: /* @__PURE__ */ jsx("div", { ref: box, className: "h-full w-full", role: "region", "aria-label": ariaLabel }) }),
307
- failed && /* @__PURE__ */ jsx("p", { className: "absolute inset-0 grid place-items-center p-6 text-center text-sm text-gray-500", children: "The map could not be drawn here. The list has everything it shows." }),
308
- children
309
- ] });
310
- }
311
-
312
- // src/map/points.ts
313
- var PENDING_POLL_MS = 3e3;
314
- var mapPointsRefetchInterval = (data) => data?.pending ? PENDING_POLL_MS : false;
315
- var pointKey = (p) => `${p.kind}:${p.id}`;
316
- var isOnMap = (p) => (p.placement === "located" || p.placement === "approximate") && p.lat != null && p.lng != null;
317
- function placementNote(placement) {
318
- switch (placement) {
319
- case "located":
320
- return null;
321
- case "approximate":
322
- return "Approximate: only the suburb or postcode matched";
323
- case "pending":
324
- return "Locating\u2026";
325
- case "not_found":
326
- return "Not on the map: address not found";
327
- case "failed":
328
- return "Not on the map: the map service could not be reached";
329
- case "no_address":
330
- return "Not on the map: no city or postcode";
331
- }
332
- }
333
- var MAP_CATEGORIES = {
334
- importer: { label: "Importer", tone: "bg-sky-600 text-white" },
335
- dealer: { label: "Dealer", tone: "bg-purple-600 text-white" },
336
- retail: { label: "Retail", tone: "bg-green-600 text-white" },
337
- supplier: { label: "Supplier", tone: "bg-sky-600 text-white" },
338
- delivery_location: { label: "Delivery location", tone: "bg-amber-600 text-white" },
339
- warehouse: { label: "Warehouse", tone: "bg-amber-600 text-white" }
340
- };
341
- var DEFAULT_TONE = "bg-gray-700 text-white";
342
- var CATEGORY_ORDER = ["importer", "dealer", "retail", "supplier", "delivery_location", "warehouse"];
343
- function pinCategory(p) {
344
- if (p.kind === "supplier") return "supplier";
345
- if (p.kind === "customer") return p.category || "importer";
346
- return p.kind;
347
- }
348
- var categoryTone = (category, categories = MAP_CATEGORIES) => categories[category]?.tone ?? DEFAULT_TONE;
349
- var categoryLabel = (category, categories = MAP_CATEGORIES) => categories[category]?.label ?? category;
350
- var pinTone = (p, categories) => categoryTone(pinCategory(p), categories);
351
- function pinGlyph(p, number, categories = MAP_CATEGORIES) {
352
- if (number != null) return String(number);
353
- return (categories[pinCategory(p)]?.label ?? "").charAt(0).toUpperCase();
354
- }
355
- var SECONDARY_KINDS = ["delivery_location", "warehouse"];
356
- function locationNumbers(points, kinds = SECONDARY_KINDS) {
357
- const numbers = /* @__PURE__ */ new Map();
358
- let n = 0;
359
- for (const p of points) {
360
- if (kinds.includes(p.kind)) numbers.set(pointKey(p), ++n);
361
- }
362
- return numbers;
363
- }
364
- function summarize(points) {
365
- const summary = { onMap: 0, approximate: 0, pending: 0, off: 0 };
366
- for (const p of points) {
367
- if (isOnMap(p)) {
368
- summary.onMap += 1;
369
- if (p.placement === "approximate") summary.approximate += 1;
370
- } else if (p.placement === "pending") summary.pending += 1;
371
- else summary.off += 1;
372
- }
373
- return summary;
374
- }
375
- function summaryText(s) {
376
- const parts = [`${s.onMap} on the map`];
377
- if (s.approximate) parts.push(`${s.approximate} approximate`);
378
- if (s.pending) parts.push(`${s.pending} locating`);
379
- if (s.off) parts.push(`${s.off} not on the map`);
380
- return parts.join(" \xB7 ");
381
- }
382
- function legendCategories(points) {
383
- const present = [...new Set(points.filter(isOnMap).map(pinCategory))];
384
- const known = CATEGORY_ORDER.filter((c) => present.includes(c));
385
- return [...known, ...present.filter((c) => !CATEGORY_ORDER.includes(c))];
386
- }
387
- function offMapNotes(points, numbers) {
388
- return points.filter((p) => !isOnMap(p) && p.placement !== "pending").map((p) => {
389
- const n = numbers?.get(pointKey(p));
390
- const note = placementNote(p.placement)?.replace(/^Not on the map: /, "") ?? "";
391
- return { key: pointKey(p), text: `${n != null ? `${n}. ` : ""}${p.label}: ${note}` };
392
- });
393
- }
394
- function MapLegend({ categories, palette = MAP_CATEGORIES, floating = true }) {
395
- if (categories.length < 2) return null;
396
- return /* @__PURE__ */ jsx("div", { className: `${floating ? "absolute left-3 top-3 z-10 " : ""}flex flex-wrap gap-x-3 gap-y-1 rounded-lg border border-gray-200 bg-white px-2.5 py-1.5 text-xs text-gray-600 shadow-sm`, children: categories.map((c) => /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1.5", children: [
397
- /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: `h-2.5 w-2.5 rounded-full ${categoryTone(c, palette)}` }),
398
- categoryLabel(c, palette)
399
- ] }, c)) });
400
- }
401
- function SelectedCard({ point, number, onOpen, onClose, palette = MAP_CATEGORIES }) {
402
- const note = placementNote(point.placement);
403
- const category = pinCategory(point);
404
- return /* @__PURE__ */ jsxs(
405
- "section",
406
- {
407
- "aria-label": `${point.label}, chosen on the map`,
408
- className: "absolute bottom-3 left-3 right-3 z-10 max-w-md space-y-1.5 rounded-lg border border-gray-200 bg-white p-3 shadow-md",
409
- children: [
410
- /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-2", children: [
411
- /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
412
- /* @__PURE__ */ jsxs("h3", { className: "text-sm font-semibold text-gray-900 [overflow-wrap:anywhere]", children: [
413
- number != null && /* @__PURE__ */ jsxs("span", { className: "mr-1 text-gray-400", children: [
414
- number,
415
- "."
416
- ] }),
417
- point.label,
418
- point.code && /* @__PURE__ */ jsx("span", { className: "ml-1.5 text-xs font-normal text-gray-400", children: point.code })
419
- ] }),
420
- /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500", children: palette[category] ? categoryLabel(category, palette) : point.category })
421
- ] }),
422
- /* @__PURE__ */ jsx("button", { type: "button", onClick: onClose, "aria-label": "Close", className: "rounded p-0.5 text-gray-400 hover:text-gray-600", children: /* @__PURE__ */ jsx("svg", { "aria-hidden": true, className: "h-4 w-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", strokeWidth: 2, children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M6 18L18 6M6 6l12 12" }) }) })
423
- ] }),
424
- /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-700 [overflow-wrap:anywhere]", children: point.address || "\u2014" }),
425
- note && /* @__PURE__ */ jsx("p", { className: "text-xs text-gray-500", children: note }),
426
- point.matched && point.placement === "approximate" && /* @__PURE__ */ jsxs("p", { className: "text-xs text-gray-400 [overflow-wrap:anywhere]", children: [
427
- "Placed at: ",
428
- point.matched
429
- ] }),
430
- onOpen && /* @__PURE__ */ jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsx(Button_default, { variant: "secondary", size: "sm", onClick: onOpen, children: "Open" }) })
431
- ]
432
- }
433
- );
434
- }
435
- function useMapPoints(queryKey, queryFn, { staleTime } = {}) {
436
- return useQuery({
437
- queryKey,
438
- queryFn,
439
- staleTime,
440
- refetchInterval: (query) => mapPointsRefetchInterval(query.state.data)
441
- });
442
- }
443
- var NOTES_SHOWN = 3;
444
- function LocationsMap({
445
- queryKey,
446
- queryFn,
447
- refreshSignal,
448
- onOpen,
449
- ariaLabel,
450
- title = "Locations",
451
- palette = MAP_CATEGORIES,
452
- numbers: givenNumbers,
453
- className = "",
454
- mapClassName = "min-h-[240px] flex-1"
455
- }) {
456
- const { data, isError, refetch } = useMapPoints(queryKey, queryFn, { staleTime: 0 });
457
- const mounted = useRef(false);
458
- useEffect(() => {
459
- if (!mounted.current) {
460
- mounted.current = true;
461
- return;
462
- }
463
- void refetch();
464
- }, [refreshSignal]);
465
- const [selectedKey, setSelectedKey] = useState(null);
466
- const points = useMemo(() => data?.points ?? [], [data]);
467
- const numbers = useMemo(() => givenNumbers ?? locationNumbers(points), [givenNumbers, points]);
468
- const pins = useMemo(() => points.filter(isOnMap).map((p) => ({
469
- key: pointKey(p),
470
- label: p.label,
471
- lat: p.lat,
472
- lng: p.lng,
473
- glyph: pinGlyph(p, numbers.get(pointKey(p)) ?? null, palette),
474
- tone: pinTone(p, palette),
475
- approximate: p.placement === "approximate"
476
- })), [points, numbers, palette]);
477
- const notes = useMemo(() => offMapNotes(points, numbers), [points, numbers]);
478
- const legend = useMemo(() => legendCategories(points), [points]);
479
- const pending = data?.pending ?? 0;
480
- const selected = points.find((p) => pointKey(p) === selectedKey) ?? null;
481
- const open = selected && onOpen ? onOpen(selected) : null;
482
- return /* @__PURE__ */ jsxs("section", { "aria-label": title, className: `flex min-w-0 flex-col ${className}`, children: [
483
- /* @__PURE__ */ jsxs("div", { className: "flex min-h-[30px] items-center justify-between mb-2", children: [
484
- /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-gray-900", children: title }),
485
- data && /* @__PURE__ */ jsx("span", { className: "text-xs text-gray-500", children: summaryText(summarize(points)) })
486
- ] }),
487
- /* @__PURE__ */ jsxs(
488
- EntityMap,
489
- {
490
- pins,
491
- selectedKey,
492
- focus: null,
493
- onSelect: setSelectedKey,
494
- ariaLabel,
495
- className: mapClassName,
496
- children: [
497
- /* @__PURE__ */ jsxs("div", { className: "absolute left-3 top-3 z-10 flex max-w-[70%] flex-col items-start gap-1.5", children: [
498
- /* @__PURE__ */ jsx(MapLegend, { categories: legend, palette, floating: false }),
499
- isError && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 rounded-lg border border-gray-200 bg-white px-2.5 py-1.5 text-xs text-gray-600 shadow-sm", children: [
500
- "Couldn\u2019t load the locations.",
501
- /* @__PURE__ */ jsx("button", { type: "button", onClick: () => void refetch(), className: "font-medium text-blue-600 hover:text-blue-800 hover:underline", children: "Try again" })
502
- ] }),
503
- !isError && (pending > 0 || notes.length > 0) && /* @__PURE__ */ jsxs("div", { className: "max-w-full space-y-0.5 rounded-lg border border-gray-200 bg-white px-2.5 py-1.5 text-xs shadow-sm", "aria-live": "polite", children: [
504
- pending > 0 && /* @__PURE__ */ jsxs("p", { className: "flex items-center gap-1.5 text-gray-500", children: [
505
- /* @__PURE__ */ jsxs("svg", { className: "h-3 w-3 animate-spin", fill: "none", viewBox: "0 0 24 24", children: [
506
- /* @__PURE__ */ jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
507
- /* @__PURE__ */ jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8v4a4 4 0 00-4 4H4z" })
508
- ] }),
509
- "Locating ",
510
- pending,
511
- " address",
512
- pending === 1 ? "" : "es",
513
- "\u2026"
514
- ] }),
515
- notes.slice(0, NOTES_SHOWN).map((n) => /* @__PURE__ */ jsx("p", { className: "truncate text-amber-700", title: n.text, children: n.text }, n.key)),
516
- notes.length > NOTES_SHOWN && /* @__PURE__ */ jsxs("p", { className: "text-gray-500", children: [
517
- "+",
518
- notes.length - NOTES_SHOWN,
519
- " more not on the map"
520
- ] })
521
- ] })
522
- ] }),
523
- selected && /* @__PURE__ */ jsx(
524
- SelectedCard,
525
- {
526
- point: selected,
527
- number: numbers.get(pointKey(selected)) ?? null,
528
- onOpen: open,
529
- onClose: () => setSelectedKey(null),
530
- palette
531
- }
532
- )
533
- ]
534
- }
535
- )
536
- ] });
537
- }
538
-
539
- export { COMPACT_SHOW, EntityMap, LocationsMap, MAPLIBRE_WORKER_FILE, MAP_CATEGORIES, MapLegend, PENDING_POLL_MS, SECONDARY_KINDS, SelectedCard, categoryLabel, categoryTone, foldAttributionOnce, isOnMap, legendCategories, loadMapLibre, locationNumbers, mapLibreWorkerUrl, mapPointsRefetchInterval, offMapNotes, pinCategory, pinGlyph, pinTone, placementNote, pointKey, summarize, summaryText, useMapPoints };
540
- //# sourceMappingURL=index.js.map
541
- //# sourceMappingURL=index.js.map
2
+ import{Button_default as e}from"../chunk-PH3PRIFP.js";import{rootIsDark as t,ROOT_THEME_ATTRIBUTES as r}from"../chunk-MAIHBBWT.js";import{useRef as n,useState as a,useEffect as o,useCallback as l,useMemo as i,useSyncExternalStore as s}from"react";import{jsxs as c,jsx as d}from"react/jsx-runtime";import{useQuery as u}from"@tanstack/react-query";var p="maplibregl-compact-show";function m(e){if(!e)return()=>{};const t=()=>!!e.classList.contains(p)&&(e.classList.remove(p),!0);if(t())return()=>{};const r=new MutationObserver(()=>{t()&&r.disconnect()});return r.observe(e,{attributes:!0,attributeFilter:["class"]}),()=>r.disconnect()}var h="maplibre-gl-worker.mjs",g=e=>`/maplibre-gl/${e}/${h}`,f=null;function b(){return f??=Promise.all([import("maplibre-gl"),import("maplibre-gl/dist/maplibre-gl.css")]).then(([e])=>(e.setWorkerUrl(g(e.getVersion())),e)).catch(e=>{throw f=null,e}),f}function y(e){const t=new MutationObserver(e);return t.observe(document.documentElement,{attributes:!0,attributeFilter:r}),()=>t.disconnect()}var x=t;var w="routes";function v(){const e=document.createElement("span");e.className="text-blue-600",e.style.display="none",document.body.appendChild(e);const t=getComputedStyle(e).color||"#2563eb";return e.remove(),function(e){const t=document.createElement("canvas").getContext("2d");if(!t)return"#2563eb";t.fillStyle="#2563eb",t.fillStyle=e,t.fillRect(0,0,1,1);const[r,n,a]=t.getImageData(0,0,1,1).data;return`rgb(${r}, ${n}, ${a})`}(t)}var N={light:"https://tiles.openfreemap.org/styles/positron",dark:"https://tiles.openfreemap.org/styles/dark"},k={center:[30,20],zoom:1},C="http://www.w3.org/2000/svg";function $(e,t){const r=document.createElement("button");if(r.type="button",r.title=e.approximate?`${e.label} (approximate)`:e.label,r.setAttribute("aria-label",e.approximate?`${e.label}, approximate location`:e.label),r.dataset.pin=e.key,r.className=["relative grid place-items-center rounded-full border-2 border-white font-semibold leading-none shadow-md cursor-pointer",e.tone,t?"h-8 w-8 text-xs ring-2 ring-gray-900 ring-offset-1":"h-6 w-6 text-[10px]",e.approximate?"border-dashed opacity-80":"",e.faded&&!t?"opacity-40":""].join(" "),e.icon?.length?r.appendChild(function(e,t){const r=document.createElementNS(C,"svg");r.setAttribute("viewBox","0 0 24 24"),r.setAttribute("fill","none"),r.setAttribute("stroke","currentColor"),r.setAttribute("stroke-width","2"),r.setAttribute("aria-hidden","true"),r.setAttribute("class",t?"h-4 w-4":"h-3.5 w-3.5");for(const t of e){const e=document.createElementNS(C,"path");e.setAttribute("stroke-linecap","round"),e.setAttribute("stroke-linejoin","round"),e.setAttribute("d",t),r.appendChild(e)}return r}(e.icon,t)):r.textContent=e.glyph,e.badge){const t=document.createElement("span");t.setAttribute("aria-hidden","true"),t.className=["absolute -right-2 -top-2 grid h-4 min-w-4 place-items-center rounded-full px-0.5 text-[9px] font-semibold leading-none shadow",e.badgeTone??"bg-white text-gray-900"].join(" "),t.textContent=e.badge,r.appendChild(t)}return r}function L({pins:e,selectedKey:t,focus:r,onSelect:i,ariaLabel:u,className:p="",children:h,routes:g,fitTo:f,attribution:C}){const L=n(null),S=n(null),j=n(null),A=n([]),M=n(""),[T,z]=a(!1),[P,E]=a(!1),F=s(y,x,()=>!1)?"dark":"light",R=n({onSelect:i,pins:e,selectedKey:t});o(()=>{R.current={onSelect:i,pins:e,selectedKey:t}});const B=l(()=>{const e=S.current,{pins:t,selectedKey:r}=R.current,n=r?t.find(e=>e.key===r):void 0;if(!e||!n||e.getBounds().contains([n.lng,n.lat]))return;const a=window.matchMedia("(prefers-reduced-motion: reduce)").matches;e.easeTo({center:[n.lng,n.lat],duration:a?0:400})},[]);o(()=>{let e=!1,t=null,r=null,n=()=>{};return(async()=>{try{const a=await b();if(e||!L.current)return;j.current=a,t=new a.Map({container:L.current,style:N[F],center:k.center,zoom:k.zoom,attributionControl:C?{compact:!0,customAttribution:C}:{compact:!0},dragRotate:!1,pitchWithRotate:!1,touchPitch:!1,maxPitch:0}),t.touchZoomRotate.disableRotation(),t.keyboard.disableRotation(),t.addControl(new a.NavigationControl({showCompass:!1}),"top-right"),t.on("error",e=>console.warn("[map]",e.error?.message)),n=m(L.current.querySelector(".maplibregl-ctrl-attrib"));const o=t;r=new ResizeObserver(()=>{o.resize(),B()}),r.observe(L.current),S.current=t,z(!0)}catch(t){console.error("[map] could not start",t),e||E(!0)}})(),()=>{e=!0,r?.disconnect(),n(),A.current.forEach(e=>e.remove()),A.current=[],t?.remove(),S.current=null}},[]);const q=n(F);return o(()=>{T&&S.current&&q.current!==F&&(q.current=F,S.current.setStyle(N[F]))},[T,F]),o(()=>{const r=S.current,n=j.current;if(!T||!r||!n)return;A.current.forEach(e=>e.remove()),A.current=[];const a=[...e].sort((e,r)=>Number(e.key===t)-Number(r.key===t));for(const e of a){const a=$(e,e.key===t);a.addEventListener("click",t=>{t.stopPropagation(),R.current.onSelect(e.key)}),A.current.push(new n.Marker({element:a,anchor:"center"}).setLngLat([e.lng,e.lat]).addTo(r))}},[T,e,t]),o(()=>{if(!T||!t)return;const e=requestAnimationFrame(B);return()=>cancelAnimationFrame(e)},[T,t,B]),o(()=>{const t=S.current,r=j.current,n=f?e.filter(e=>f.includes(e.key)):e;if(!T||!t||!r||0===n.length)return;const a=n.map(e=>`${e.key}@${e.lat},${e.lng}`).sort().join("|");if(M.current===a)return;const o=""===M.current;if(M.current=a,1===n.length)return void t.jumpTo({center:[n[0].lng,n[0].lat],zoom:13});const l=new r.LngLatBounds([n[0].lng,n[0].lat],[n[0].lng,n[0].lat]);for(const e of n)l.extend([e.lng,e.lat]);t.fitBounds(l,{padding:48,maxZoom:14,animate:!o})},[T,e,f]),o(()=>{const e=S.current;if(!T||!e)return;const t={type:"FeatureCollection",features:(g??[]).filter(e=>e.coordinates.length>=2).map(e=>({type:"Feature",properties:{key:e.key,estimate:e.estimate,faded:!!e.faded},geometry:{type:"LineString",coordinates:e.coordinates}}))},r=()=>{try{(()=>{const r=v(),n=["case",["get","faded"],.25,.85],a=e.getSource(w);a?a.setData(t):e.addSource(w,{type:"geojson",data:t}),e.getLayer("routes-road")?e.setPaintProperty("routes-road","line-color",r):e.addLayer({id:"routes-road",type:"line",source:w,filter:["!",["get","estimate"]],layout:{"line-join":"round","line-cap":"round"},paint:{"line-color":r,"line-width":4,"line-opacity":n}}),e.getLayer("routes-estimate")?e.setPaintProperty("routes-estimate","line-color",r):e.addLayer({id:"routes-estimate",type:"line",source:w,filter:["get","estimate"],layout:{"line-join":"round","line-cap":"round"},paint:{"line-color":r,"line-width":3,"line-dasharray":[1.5,1.5],"line-opacity":n}})})()}catch(e){console.debug("[map] routes wait for the style",e)}};return r(),e.on("style.load",r),e.once("idle",r),()=>{e.off("style.load",r),e.off("idle",r)}},[T,g,F]),o(()=>{const t=S.current;if(!T||!t||!r)return;const n=e.find(e=>e.key===r.key);if(!n)return;const a={center:[n.lng,n.lat],zoom:Math.max(t.getZoom(),13)};window.matchMedia("(prefers-reduced-motion: reduce)").matches?t.jumpTo(a):t.flyTo({...a,duration:600})},[T,r?.n]),/* @__PURE__ */c("div",{className:`relative min-h-72 overflow-hidden rounded-lg border border-gray-200 bg-gray-100 ${p}`,children:[
3
+ /* @__PURE__ */d("div",{className:"absolute inset-0",children:/* @__PURE__ */d("div",{ref:L,className:"h-full w-full",role:"region","aria-label":u})}),P&&/* @__PURE__ */d("p",{className:"absolute inset-0 grid place-items-center p-6 text-center text-sm text-gray-500",children:"The map could not be drawn here. The list has everything it shows."}),h]})}var S=3e3,j=e=>!!e?.pending&&3e3,A=e=>`${e.kind}:${e.id}`,M=e=>("located"===e.placement||"approximate"===e.placement)&&null!=e.lat&&null!=e.lng;function T(e){switch(e){case"located":return null;case"approximate":return"Approximate: only the suburb or postcode matched";case"pending":return"Locating…";case"not_found":return"Not on the map: address not found";case"failed":return"Not on the map: the map service could not be reached";case"no_address":return"Not on the map: no city or postcode"}}var z={importer:{label:"Importer",tone:"bg-sky-600 text-white"},dealer:{label:"Dealer",tone:"bg-purple-600 text-white"},retail:{label:"Retail",tone:"bg-green-600 text-white"},supplier:{label:"Supplier",tone:"bg-sky-600 text-white"},delivery_location:{label:"Delivery location",tone:"bg-amber-600 text-white"},warehouse:{label:"Warehouse",tone:"bg-amber-600 text-white"}},P=["importer","dealer","retail","supplier","delivery_location","warehouse"];function E(e){return"supplier"===e.kind?"supplier":"customer"===e.kind?e.category||"importer":e.kind}var F=(e,t=z)=>t[e]?.tone??"bg-gray-700 text-white",R=(e,t=z)=>t[e]?.label??e,B=(e,t)=>F(E(e),t);function q(e,t,r=z){return null!=t?String(t):(r[E(e)]?.label??"").charAt(0).toUpperCase()}var K=["delivery_location","warehouse"];function O(e,t=K){const r=/* @__PURE__ */new Map;let n=0;for(const a of e)t.includes(a.kind)&&r.set(A(a),++n);return r}function W(e){const t={onMap:0,approximate:0,pending:0,off:0};for(const r of e)M(r)?(t.onMap+=1,"approximate"===r.placement&&(t.approximate+=1)):"pending"===r.placement?t.pending+=1:t.off+=1;return t}function I(e){const t=[`${e.onMap} on the map`];return e.approximate&&t.push(`${e.approximate} approximate`),e.pending&&t.push(`${e.pending} locating`),e.off&&t.push(`${e.off} not on the map`),t.join(" · ")}function _(e){const t=[...new Set(e.filter(M).map(E))];return[...P.filter(e=>t.includes(e)),...t.filter(e=>!P.includes(e))]}function D(e,t){return e.filter(e=>!M(e)&&"pending"!==e.placement).map(e=>{const r=t?.get(A(e)),n=T(e.placement)?.replace(/^Not on the map: /,"")??"";return{key:A(e),text:`${null!=r?`${r}. `:""}${e.label}: ${n}`}})}function H({categories:e,palette:t=z,floating:r=!0}){return e.length<2?null:/* @__PURE__ */d("div",{className:(r?"absolute left-3 top-3 z-10 ":"")+"flex flex-wrap gap-x-3 gap-y-1 rounded-lg border border-gray-200 bg-white px-2.5 py-1.5 text-xs text-gray-600 shadow-sm",children:e.map(e=>/* @__PURE__ */c("span",{className:"inline-flex items-center gap-1.5",children:[
4
+ /* @__PURE__ */d("span",{"aria-hidden":!0,className:`h-2.5 w-2.5 rounded-full ${F(e,t)}`}),R(e,t)]},e))})}function Z({point:t,number:r,onOpen:n,onClose:a,palette:o=z}){const l=T(t.placement),i=E(t);/* @__PURE__ */
5
+ return c("section",{"aria-label":`${t.label}, chosen on the map`,className:"absolute bottom-3 left-3 right-3 z-10 max-w-md space-y-1.5 rounded-lg border border-gray-200 bg-white p-3 shadow-md",children:[
6
+ /* @__PURE__ */c("div",{className:"flex items-start justify-between gap-2",children:[
7
+ /* @__PURE__ */c("div",{className:"min-w-0",children:[
8
+ /* @__PURE__ */c("h3",{className:"text-sm font-semibold text-gray-900 [overflow-wrap:anywhere]",children:[null!=r&&/* @__PURE__ */c("span",{className:"mr-1 text-gray-400",children:[r,"."]}),t.label,t.code&&/* @__PURE__ */d("span",{className:"ml-1.5 text-xs font-normal text-gray-400",children:t.code})]}),
9
+ /* @__PURE__ */d("p",{className:"text-xs text-gray-500",children:o[i]?R(i,o):t.category})]}),
10
+ /* @__PURE__ */d("button",{type:"button",onClick:a,"aria-label":"Close",className:"rounded p-0.5 text-gray-400 hover:text-gray-600",children:/* @__PURE__ */d("svg",{"aria-hidden":!0,className:"h-4 w-4",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:/* @__PURE__ */d("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M6 18L18 6M6 6l12 12"})})})]}),
11
+ /* @__PURE__ */d("p",{className:"text-sm text-gray-700 [overflow-wrap:anywhere]",children:t.address||"—"}),l&&/* @__PURE__ */d("p",{className:"text-xs text-gray-500",children:l}),t.matched&&"approximate"===t.placement&&/* @__PURE__ */c("p",{className:"text-xs text-gray-400 [overflow-wrap:anywhere]",children:["Placed at: ",t.matched]}),n&&/* @__PURE__ */d("div",{className:"flex justify-end",children:/* @__PURE__ */d(e,{variant:"secondary",size:"sm",onClick:n,children:"Open"})})]})}function U(e,t,{staleTime:r}={}){return u({queryKey:e,queryFn:t,staleTime:r,refetchInterval:e=>j(e.state.data)})}function V({queryKey:e,queryFn:t,refreshSignal:r,onOpen:l,ariaLabel:s,title:u="Locations",palette:p=z,numbers:m,className:h="",mapClassName:g="min-h-[240px] flex-1"}){const{data:f,isError:b,refetch:y}=U(e,t,{staleTime:0}),x=n(!1);o(()=>{x.current?y():x.current=!0},[r]);const[w,v]=a(null),N=i(()=>f?.points??[],[f]),k=i(()=>m??O(N),[m,N]),C=i(()=>N.filter(M).map(e=>({key:A(e),label:e.label,lat:e.lat,lng:e.lng,glyph:q(e,k.get(A(e))??null,p),tone:B(e,p),approximate:"approximate"===e.placement})),[N,k,p]),$=i(()=>D(N,k),[N,k]),S=i(()=>_(N),[N]),j=f?.pending??0,T=N.find(e=>A(e)===w)??null,P=T&&l?l(T):null;/* @__PURE__ */
12
+ return c("section",{"aria-label":u,className:`flex min-w-0 flex-col ${h}`,children:[
13
+ /* @__PURE__ */c("div",{className:"flex min-h-[30px] items-center justify-between mb-2",children:[
14
+ /* @__PURE__ */d("h3",{className:"text-sm font-semibold text-gray-900",children:u}),f&&/* @__PURE__ */d("span",{className:"text-xs text-gray-500",children:I(W(N))})]}),
15
+ /* @__PURE__ */c(L,{pins:C,selectedKey:w,focus:null,onSelect:v,ariaLabel:s,className:g,children:[
16
+ /* @__PURE__ */c("div",{className:"absolute left-3 top-3 z-10 flex max-w-[70%] flex-col items-start gap-1.5",children:[
17
+ /* @__PURE__ */d(H,{categories:S,palette:p,floating:!1}),b&&/* @__PURE__ */c("div",{className:"flex items-center gap-2 rounded-lg border border-gray-200 bg-white px-2.5 py-1.5 text-xs text-gray-600 shadow-sm",children:["Couldn’t load the locations.",
18
+ /* @__PURE__ */d("button",{type:"button",onClick:()=>{y()},className:"font-medium text-blue-600 hover:text-blue-800 hover:underline",children:"Try again"})]}),!b&&(j>0||$.length>0)&&/* @__PURE__ */c("div",{className:"max-w-full space-y-0.5 rounded-lg border border-gray-200 bg-white px-2.5 py-1.5 text-xs shadow-sm","aria-live":"polite",children:[j>0&&/* @__PURE__ */c("p",{className:"flex items-center gap-1.5 text-gray-500",children:[
19
+ /* @__PURE__ */c("svg",{className:"h-3 w-3 animate-spin",fill:"none",viewBox:"0 0 24 24",children:[
20
+ /* @__PURE__ */d("circle",{className:"opacity-25",cx:"12",cy:"12",r:"10",stroke:"currentColor",strokeWidth:"4"}),
21
+ /* @__PURE__ */d("path",{className:"opacity-75",fill:"currentColor",d:"M4 12a8 8 0 018-8v4a4 4 0 00-4 4H4z"})]}),"Locating ",j," address",1===j?"":"es","…"]}),$.slice(0,3).map(e=>/* @__PURE__ */d("p",{className:"truncate text-amber-700",title:e.text,children:e.text},e.key)),$.length>3&&/* @__PURE__ */c("p",{className:"text-gray-500",children:["+",$.length-3," more not on the map"]})]})]}),T&&/* @__PURE__ */d(Z,{point:T,number:k.get(A(T))??null,onOpen:P,onClose:()=>v(null),palette:p})]})]})}export{p as COMPACT_SHOW,L as EntityMap,V as LocationsMap,h as MAPLIBRE_WORKER_FILE,z as MAP_CATEGORIES,H as MapLegend,S as PENDING_POLL_MS,K as SECONDARY_KINDS,Z as SelectedCard,R as categoryLabel,F as categoryTone,m as foldAttributionOnce,M as isOnMap,_ as legendCategories,b as loadMapLibre,O as locationNumbers,g as mapLibreWorkerUrl,j as mapPointsRefetchInterval,D as offMapNotes,E as pinCategory,q as pinGlyph,B as pinTone,T as placementNote,A as pointKey,W as summarize,I as summaryText,U as useMapPoints};