@element-editor/ui 0.0.0-stage → 0.2.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.
- package/AGENTS.md +65 -0
- package/LICENSE +21 -0
- package/README.md +46 -2
- package/dist/BooleanOperations-BRO7NHUY.js +111 -0
- package/dist/BooleanOperations-C2uOHRu3.cjs +1 -0
- package/dist/DataTable-B-2VjBEz.cjs +2 -0
- package/dist/DataTable-CS-3dIqY.js +510 -0
- package/dist/DataTablePanel-58LwzXQR.cjs +1 -0
- package/dist/DataTablePanel-DDFUmMaM.js +208 -0
- package/dist/EditToolbarBtn-Ch9HCLHq.cjs +3 -0
- package/dist/EditToolbarBtn-SR4xHd8G.js +378 -0
- package/dist/FeatureEditModal-Cc8N6vei.cjs +1 -0
- package/dist/FeatureEditModal-Dr10p3nE.js +77 -0
- package/dist/FeatureList-Bo9w9nre.js +520 -0
- package/dist/FeatureList-VRYesXCq.cjs +1 -0
- package/dist/FeatureRowContextMenu-CtBqdC1j.cjs +1 -0
- package/dist/FeatureRowContextMenu-DCUIiDwc.js +130 -0
- package/dist/GeoJSONModal-BV9Tamf4.js +886 -0
- package/dist/GeoJSONModal-Dd-nBufy.cjs +9 -0
- package/dist/SchemaEditor-B4L17K1e.cjs +1 -0
- package/dist/SchemaEditor-ryoTgaLb.js +293 -0
- package/dist/SchemaModal-DvMbWskS.js +95 -0
- package/dist/SchemaModal-gAuDkd-L.cjs +1 -0
- package/dist/SettingsModal-BScVTjpn.js +237 -0
- package/dist/SettingsModal-CqaSFxxR.cjs +1 -0
- package/dist/ShortcutsModal-D1Y2bGT8.cjs +1 -0
- package/dist/ShortcutsModal-ozuS2Ysb.js +299 -0
- package/dist/components/ActiveDrawingToolbar.d.cts +1 -0
- package/dist/components/ActiveDrawingToolbar.d.ts +1 -0
- package/dist/components/BasemapPicker.d.cts +26 -0
- package/dist/components/BasemapPicker.d.ts +26 -0
- package/dist/components/BooleanOperations.d.cts +1 -0
- package/dist/components/BooleanOperations.d.ts +1 -0
- package/dist/components/BufferPanel.d.cts +1 -0
- package/dist/components/BufferPanel.d.ts +1 -0
- package/dist/components/DataTable.d.cts +9 -0
- package/dist/components/DataTable.d.ts +9 -0
- package/dist/components/DataTablePanel.d.cts +10 -0
- package/dist/components/DataTablePanel.d.ts +10 -0
- package/dist/components/EditingToolbar.d.cts +1 -0
- package/dist/components/EditingToolbar.d.ts +1 -0
- package/dist/components/ElementEditorErrorBoundary.d.cts +28 -0
- package/dist/components/ElementEditorErrorBoundary.d.ts +28 -0
- package/dist/components/ElementEditorUIProvider.d.cts +50 -0
- package/dist/components/ElementEditorUIProvider.d.ts +50 -0
- package/dist/components/FeatureMapContextMenu.d.cts +23 -0
- package/dist/components/FeatureMapContextMenu.d.ts +23 -0
- package/dist/components/FitBoundsButton.d.cts +6 -0
- package/dist/components/FitBoundsButton.d.ts +6 -0
- package/dist/components/FloatingToolbar.d.cts +3 -0
- package/dist/components/FloatingToolbar.d.ts +3 -0
- package/dist/components/LocateButton.d.cts +11 -0
- package/dist/components/LocateButton.d.ts +11 -0
- package/dist/components/ReadonlyBanner.d.cts +1 -0
- package/dist/components/ReadonlyBanner.d.ts +1 -0
- package/dist/components/ShortcutsModal.d.cts +1 -0
- package/dist/components/ShortcutsModal.d.ts +1 -0
- package/dist/components/SimplifyPanel.d.cts +1 -0
- package/dist/components/SimplifyPanel.d.ts +1 -0
- package/dist/components/SmoothPanel.d.cts +1 -0
- package/dist/components/SmoothPanel.d.ts +1 -0
- package/dist/components/UndoRedoToolbar.d.cts +20 -0
- package/dist/components/UndoRedoToolbar.d.ts +20 -0
- package/dist/components/VertexSelectionBar.d.cts +12 -0
- package/dist/components/VertexSelectionBar.d.ts +12 -0
- package/dist/components/ZoomIndicator.d.cts +15 -0
- package/dist/components/ZoomIndicator.d.ts +15 -0
- package/dist/components/dialogs/DynamicFieldRenderer.d.cts +11 -0
- package/dist/components/dialogs/DynamicFieldRenderer.d.ts +11 -0
- package/dist/components/dialogs/SettingsModal.d.cts +1 -0
- package/dist/components/dialogs/SettingsModal.d.ts +1 -0
- package/dist/components/lazyParts.d.cts +12 -0
- package/dist/components/lazyParts.d.ts +12 -0
- package/dist/components/sidebar/FeatureEditModal.d.cts +6 -0
- package/dist/components/sidebar/FeatureEditModal.d.ts +6 -0
- package/dist/components/sidebar/FeatureList.d.cts +4 -0
- package/dist/components/sidebar/FeatureList.d.ts +4 -0
- package/dist/components/sidebar/FeatureRow.d.cts +38 -0
- package/dist/components/sidebar/FeatureRow.d.ts +38 -0
- package/dist/components/sidebar/FeatureRowContextMenu.d.cts +12 -0
- package/dist/components/sidebar/FeatureRowContextMenu.d.ts +12 -0
- package/dist/components/sidebar/FeatureSidePanel.d.cts +8 -0
- package/dist/components/sidebar/FeatureSidePanel.d.ts +8 -0
- package/dist/components/sidebar/GeoJSONModal.d.cts +5 -0
- package/dist/components/sidebar/GeoJSONModal.d.ts +5 -0
- package/dist/components/sidebar/GroupRow.d.cts +21 -0
- package/dist/components/sidebar/GroupRow.d.ts +21 -0
- package/dist/components/sidebar/HideLayersToggle.d.cts +2 -0
- package/dist/components/sidebar/HideLayersToggle.d.ts +2 -0
- package/dist/components/sidebar/LayersPanel.d.cts +5 -0
- package/dist/components/sidebar/LayersPanel.d.ts +5 -0
- package/dist/components/sidebar/PartSubRow.d.cts +9 -0
- package/dist/components/sidebar/PartSubRow.d.ts +9 -0
- package/dist/components/sidebar/SchemaEditor.d.cts +4 -0
- package/dist/components/sidebar/SchemaEditor.d.ts +4 -0
- package/dist/components/sidebar/SchemaModal.d.cts +5 -0
- package/dist/components/sidebar/SchemaModal.d.ts +5 -0
- package/dist/components/sidebar/codeDock.d.cts +21 -0
- package/dist/components/sidebar/codeDock.d.ts +21 -0
- package/dist/components/ui/Button.d.cts +9 -0
- package/dist/components/ui/Button.d.ts +9 -0
- package/dist/components/ui/CloseButton.d.cts +6 -0
- package/dist/components/ui/CloseButton.d.ts +6 -0
- package/dist/components/ui/ContextMenu.d.cts +28 -0
- package/dist/components/ui/ContextMenu.d.ts +28 -0
- package/dist/components/ui/EditToolbarBtn.d.cts +13 -0
- package/dist/components/ui/EditToolbarBtn.d.ts +13 -0
- package/dist/components/ui/ElementToaster.d.cts +3 -0
- package/dist/components/ui/ElementToaster.d.ts +3 -0
- package/dist/components/ui/GeometryTypeIcon.d.cts +7 -0
- package/dist/components/ui/GeometryTypeIcon.d.ts +7 -0
- package/dist/components/ui/IconButton.d.cts +28 -0
- package/dist/components/ui/IconButton.d.ts +28 -0
- package/dist/components/ui/Input.d.cts +14 -0
- package/dist/components/ui/Input.d.ts +14 -0
- package/dist/components/ui/JsonCode.d.cts +4 -0
- package/dist/components/ui/JsonCode.d.ts +4 -0
- package/dist/components/ui/Kbd.d.cts +16 -0
- package/dist/components/ui/Kbd.d.ts +16 -0
- package/dist/components/ui/NoFeaturesEmptyState.d.cts +1 -0
- package/dist/components/ui/NoFeaturesEmptyState.d.ts +1 -0
- package/dist/components/ui/SearchDropdown.d.cts +28 -0
- package/dist/components/ui/SearchDropdown.d.ts +28 -0
- package/dist/components/ui/ToolButton.d.cts +19 -0
- package/dist/components/ui/ToolButton.d.ts +19 -0
- package/dist/components/ui/Tooltip.d.cts +12 -0
- package/dist/components/ui/Tooltip.d.ts +12 -0
- package/dist/components/ui/panelHeader.d.cts +2 -0
- package/dist/components/ui/panelHeader.d.ts +2 -0
- package/dist/components/ui/resizeEdge.d.cts +4 -0
- package/dist/components/ui/resizeEdge.d.ts +4 -0
- package/dist/contexts/ElementEditorConfigContext.d.cts +351 -0
- package/dist/contexts/ElementEditorConfigContext.d.ts +351 -0
- package/dist/contexts/EventContext.d.cts +69 -0
- package/dist/contexts/EventContext.d.ts +69 -0
- package/dist/contexts/MapControllerContext.d.cts +24 -0
- package/dist/contexts/MapControllerContext.d.ts +24 -0
- package/dist/contexts/ShortcutConfigContext.d.cts +16 -0
- package/dist/contexts/ShortcutConfigContext.d.ts +16 -0
- package/dist/contexts/ThemeContext.d.cts +12 -0
- package/dist/contexts/ThemeContext.d.ts +12 -0
- package/dist/element-editor-ui.cjs +1 -0
- package/dist/element-editor-ui.es.js +102 -0
- package/dist/geometryWorker-CCwg4tNC.cjs +1 -0
- package/dist/geometryWorker-DgQCFSmD.js +25 -0
- package/dist/hooks/dragShield.d.cts +7 -0
- package/dist/hooks/dragShield.d.ts +7 -0
- package/dist/hooks/themeInputs.d.cts +14 -0
- package/dist/hooks/themeInputs.d.ts +14 -0
- package/dist/hooks/useAccentPalette.d.cts +15 -0
- package/dist/hooks/useAccentPalette.d.ts +15 -0
- package/dist/hooks/useAccentStyle.d.cts +39 -0
- package/dist/hooks/useAccentStyle.d.ts +39 -0
- package/dist/hooks/useAdapterControls.d.cts +280 -0
- package/dist/hooks/useAdapterControls.d.ts +280 -0
- package/dist/hooks/useBalancedWrap.d.cts +8 -0
- package/dist/hooks/useBalancedWrap.d.ts +8 -0
- package/dist/hooks/useContextMenu.d.cts +11 -0
- package/dist/hooks/useContextMenu.d.ts +11 -0
- package/dist/hooks/useDataChangeSubscription.d.cts +9 -0
- package/dist/hooks/useDataChangeSubscription.d.ts +9 -0
- package/dist/hooks/useDragWindow.d.cts +9 -0
- package/dist/hooks/useDragWindow.d.ts +9 -0
- package/dist/hooks/useFocusTrap.d.cts +7 -0
- package/dist/hooks/useFocusTrap.d.ts +7 -0
- package/dist/hooks/useGeoJSONDrop.d.cts +40 -0
- package/dist/hooks/useGeoJSONDrop.d.ts +40 -0
- package/dist/hooks/useGeoJSONExport.d.cts +69 -0
- package/dist/hooks/useGeoJSONExport.d.ts +69 -0
- package/dist/hooks/useGeoJSONFileImport.d.cts +24 -0
- package/dist/hooks/useGeoJSONFileImport.d.ts +24 -0
- package/dist/hooks/useInlineRename.d.cts +26 -0
- package/dist/hooks/useInlineRename.d.ts +26 -0
- package/dist/hooks/useJumpToFeature.d.cts +3 -0
- package/dist/hooks/useJumpToFeature.d.ts +3 -0
- package/dist/hooks/useKeyboardShortcuts.d.cts +9 -0
- package/dist/hooks/useKeyboardShortcuts.d.ts +9 -0
- package/dist/hooks/useNominatim.d.cts +24 -0
- package/dist/hooks/useNominatim.d.ts +24 -0
- package/dist/hooks/usePanelOffset.d.cts +14 -0
- package/dist/hooks/usePanelOffset.d.ts +14 -0
- package/dist/hooks/useResizablePanel.d.cts +4 -0
- package/dist/hooks/useResizablePanel.d.ts +4 -0
- package/dist/hooks/useRootTokens.d.cts +27 -0
- package/dist/hooks/useRootTokens.d.ts +27 -0
- package/dist/hooks/useSearchState.d.cts +23 -0
- package/dist/hooks/useSearchState.d.ts +23 -0
- package/dist/hooks/useServiceAttribution.d.cts +13 -0
- package/dist/hooks/useServiceAttribution.d.ts +13 -0
- package/dist/hooks/useWindowEscape.d.cts +25 -0
- package/dist/hooks/useWindowEscape.d.ts +25 -0
- package/dist/hooks/useWindowFocus.d.cts +4 -0
- package/dist/hooks/useWindowFocus.d.ts +4 -0
- package/dist/hooks/useWorkerGeometryPreview.d.cts +22 -0
- package/dist/hooks/useWorkerGeometryPreview.d.ts +22 -0
- package/dist/index-CILw1Du5.js +3165 -0
- package/dist/index-DG4wEjGj.cjs +1 -0
- package/dist/index.d.cts +89 -0
- package/dist/index.d.ts +89 -0
- package/dist/internal.cjs +1 -0
- package/dist/internal.d.cts +16 -0
- package/dist/internal.d.ts +16 -0
- package/dist/internal.es.js +42 -0
- package/dist/primitives.cjs +1 -0
- package/dist/primitives.d.cts +19 -0
- package/dist/primitives.d.ts +19 -0
- package/dist/primitives.es.js +17 -0
- package/dist/store/StoreContext.d.cts +17 -0
- package/dist/store/StoreContext.d.ts +17 -0
- package/dist/types/events.d.cts +95 -0
- package/dist/types/events.d.ts +95 -0
- package/dist/useAccentStyle-CPo2XqAn.js +412 -0
- package/dist/useAccentStyle-hsGvyHZc.cjs +1 -0
- package/dist/useAdapterControls-BBObhzVX.cjs +1 -0
- package/dist/useAdapterControls-DVjkwRZ_.js +691 -0
- package/dist/useContextMenu-DJ2Cti85.js +10 -0
- package/dist/useContextMenu-DbxMvb1s.cjs +1 -0
- package/dist/useFocusTrap-BBjPCfDR.cjs +1 -0
- package/dist/useFocusTrap-CKxKT8De.js +25 -0
- package/dist/useJumpToFeature-Bdz2hqOC.js +16 -0
- package/dist/useJumpToFeature-LwjxGzfy.cjs +1 -0
- package/dist/useWindowFocus-DuQVjnHE.js +80 -0
- package/dist/useWindowFocus-EemgNOuz.cjs +1 -0
- package/dist/utils/booleanValue.d.cts +4 -0
- package/dist/utils/booleanValue.d.ts +4 -0
- package/dist/utils/clipboardError.d.cts +3 -0
- package/dist/utils/clipboardError.d.ts +3 -0
- package/dist/utils/download.d.cts +42 -0
- package/dist/utils/download.d.ts +42 -0
- package/dist/utils/geojsonDocument.d.cts +168 -0
- package/dist/utils/geojsonDocument.d.ts +168 -0
- package/dist/utils/geometryWorkerClient.d.cts +6 -0
- package/dist/utils/geometryWorkerClient.d.ts +6 -0
- package/dist/utils/layerOrder.d.cts +9 -0
- package/dist/utils/layerOrder.d.ts +9 -0
- package/dist/utils/lazyWithPreload.d.cts +24 -0
- package/dist/utils/lazyWithPreload.d.ts +24 -0
- package/dist/utils/lineSmooth.d.cts +7 -0
- package/dist/utils/lineSmooth.d.ts +7 -0
- package/dist/utils/platform.d.cts +2 -0
- package/dist/utils/platform.d.ts +2 -0
- package/dist/workers/geometryWorker.d.cts +1 -0
- package/dist/workers/geometryWorker.d.ts +1 -0
- package/package.json +133 -3
|
@@ -0,0 +1,691 @@
|
|
|
1
|
+
import { createContext as L, useState as W, useContext as v, useLayoutEffect as oe, useRef as p, useId as xe, useCallback as ee, useEffect as x, useMemo as he } from "react";
|
|
2
|
+
import { ElementEditorError as z, createDataStore as Ie, createUIStore as je, getFeatureCollectionBBox as Se, parseGeoJSONText as Ae, subscribeToDataChanges as Me, isGeometry as ye, validateFeature as Re } from "@element-editor/core";
|
|
3
|
+
import { warnOnce as C, httpErrorCode as Pe, normalizeFlyToTarget as De } from "@element-editor/core/internal";
|
|
4
|
+
import { a as Ue, d as Ge, e as Je, u as ie, f as ae } from "./useAccentStyle-CPo2XqAn.js";
|
|
5
|
+
import { jsx as M, jsxs as Be, Fragment as Le } from "react/jsx-runtime";
|
|
6
|
+
import { useStore as be } from "zustand";
|
|
7
|
+
import { Toaster as _e, toast as H } from "sonner";
|
|
8
|
+
const we = L("light"), qe = () => v(we), ke = L(null), ve = L(null);
|
|
9
|
+
function kt({ children: e }) {
|
|
10
|
+
const [t, a] = W("light"), [o, s] = W(void 0);
|
|
11
|
+
return /* @__PURE__ */ M(ke.Provider, { value: a, children: /* @__PURE__ */ M(ve.Provider, { value: s, children: /* @__PURE__ */ M(we.Provider, { value: t, children: /* @__PURE__ */ M(Ue.Provider, { value: o, children: e }) }) }) });
|
|
12
|
+
}
|
|
13
|
+
function vt(e) {
|
|
14
|
+
const t = v(ke), a = v(ve), o = Ge(a && e ? e.closest("[data-elm-theme]") : null);
|
|
15
|
+
oe(() => {
|
|
16
|
+
a == null || a(o);
|
|
17
|
+
}, [a, o]), oe(() => {
|
|
18
|
+
if (!t || !e) return;
|
|
19
|
+
const s = e.closest("[data-elm-theme]");
|
|
20
|
+
if (!s) {
|
|
21
|
+
C("adapter-no-theme-root", 'The map container is not inside an element with a `data-elm-theme` attribute, so the editor UI renders unstyled and keyboard shortcuts are off. Wrap the map and the editor UI in one element: <div data-elm-theme="light" style={{ position: \'relative\', height: 600 }}>…</div> ("dark" for dark mode).');
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const u = () => t(s.getAttribute("data-elm-theme") === "dark" ? "dark" : "light");
|
|
25
|
+
u();
|
|
26
|
+
const c = new MutationObserver(u);
|
|
27
|
+
return c.observe(s, { attributes: !0, attributeFilter: ["data-elm-theme"] }), () => c.disconnect();
|
|
28
|
+
}, [t, e]);
|
|
29
|
+
}
|
|
30
|
+
const Ze = { success: null, info: null, warning: null, error: null }, He = "ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, Noto Sans, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji", We = {
|
|
31
|
+
light: { "--normal-bg": "var(--elm-surface, #ffffff)", "--normal-border": "var(--elm-border, rgb(0 0 0 / 0.1))", "--normal-text": "var(--elm-text, #171717)" },
|
|
32
|
+
dark: { "--normal-bg": "var(--elm-surface, #171717)", "--normal-border": "var(--elm-border, rgb(255 255 255 / 0.1))", "--normal-text": "var(--elm-text, #fafafa)" }
|
|
33
|
+
}, ze = { "--border-radius": "calc(var(--elm-radius-control, 6px) + 2px)", fontFamily: `var(--elm-font, ${He})` }, Ke = { light: "!text-(--elm-text-muted,#737373)", dark: "!text-(--elm-text-muted,#a3a3a3)" };
|
|
34
|
+
function Ve(e) {
|
|
35
|
+
var u, c, h;
|
|
36
|
+
const t = qe(), a = Je(), { toastOptions: o, style: s } = e;
|
|
37
|
+
return /* @__PURE__ */ M(
|
|
38
|
+
_e,
|
|
39
|
+
{
|
|
40
|
+
theme: t,
|
|
41
|
+
icons: Ze,
|
|
42
|
+
...e,
|
|
43
|
+
style: { ...a, ...We[t], ...ze, ...s },
|
|
44
|
+
toastOptions: {
|
|
45
|
+
...o,
|
|
46
|
+
classNames: {
|
|
47
|
+
...o == null ? void 0 : o.classNames,
|
|
48
|
+
// Compact: sonner's default 16px padding → 11px; title 500 → 400.
|
|
49
|
+
toast: `!p-[11px] ${((u = o == null ? void 0 : o.classNames) == null ? void 0 : u.toast) ?? ""}`,
|
|
50
|
+
title: `!font-normal ${((c = o == null ? void 0 : o.classNames) == null ? void 0 : c.title) ?? ""}`,
|
|
51
|
+
description: `${Ke[t]} ${((h = o == null ? void 0 : o.classNames) == null ? void 0 : h.description) ?? ""}`
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
const Ye = /* @__PURE__ */ new Set(["feature:broken", "selection:copied", "selection:pasted", "error", "warning", "success"]);
|
|
58
|
+
function Qe(e) {
|
|
59
|
+
switch (e.type) {
|
|
60
|
+
case "feature:deleted":
|
|
61
|
+
return `Deleted "${e.label}"`;
|
|
62
|
+
case "features:deleted":
|
|
63
|
+
return `Deleted ${e.count} features`;
|
|
64
|
+
case "feature:duplicated":
|
|
65
|
+
return `Duplicated "${e.label}"`;
|
|
66
|
+
case "features:duplicated":
|
|
67
|
+
return `Duplicated ${e.count} features`;
|
|
68
|
+
case "feature:broken":
|
|
69
|
+
return `Broken into ${e.count} features`;
|
|
70
|
+
case "selection:copied":
|
|
71
|
+
return "Selection copied";
|
|
72
|
+
case "selection:pasted":
|
|
73
|
+
return e.count === 1 ? "Feature pasted" : `${e.count} features pasted`;
|
|
74
|
+
case "undo":
|
|
75
|
+
return "Undone";
|
|
76
|
+
case "redo":
|
|
77
|
+
return "Redone";
|
|
78
|
+
case "error":
|
|
79
|
+
return e.message;
|
|
80
|
+
case "warning":
|
|
81
|
+
return e.message;
|
|
82
|
+
case "success":
|
|
83
|
+
return e.message;
|
|
84
|
+
default:
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
const B = L(null), Te = L(null);
|
|
89
|
+
function Tt({
|
|
90
|
+
onEvent: e,
|
|
91
|
+
onError: t,
|
|
92
|
+
toaster: a = !1,
|
|
93
|
+
children: o
|
|
94
|
+
}) {
|
|
95
|
+
const s = p(e);
|
|
96
|
+
s.current = e;
|
|
97
|
+
const u = p(t);
|
|
98
|
+
u.current = t;
|
|
99
|
+
const c = v(B), h = p(c);
|
|
100
|
+
h.current = c;
|
|
101
|
+
const [y, E] = W(""), b = p(!!e), w = p(!!c && !e && !a), I = xe(), l = a && !b.current ? `elm-toaster-${I}` : void 0, g = w.current ? c == null ? void 0 : c.toasterId : l, _ = b.current || w.current && !!(c != null && c.managed), F = ee((j) => {
|
|
102
|
+
var R;
|
|
103
|
+
let m = j;
|
|
104
|
+
if (j.type === "error") {
|
|
105
|
+
const { cause: U, featureId: P, quiet: J, error: q, ...T } = j, Z = q ?? new z(T.code, T.source, T.description ? `${T.message}: ${T.description}` : T.message, { cause: U, featureId: P });
|
|
106
|
+
let O;
|
|
107
|
+
try {
|
|
108
|
+
O = (R = u.current) == null ? void 0 : R.call(u, Z);
|
|
109
|
+
} catch (G) {
|
|
110
|
+
console.error(G);
|
|
111
|
+
}
|
|
112
|
+
if (O === !1 || J) return;
|
|
113
|
+
m = typeof O == "string" ? { ...T, message: O, description: void 0 } : { ...T, error: Z };
|
|
114
|
+
}
|
|
115
|
+
if (w.current && h.current) {
|
|
116
|
+
h.current.emit(m);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
if (m.type === "error") {
|
|
120
|
+
const { error: U, ...P } = m;
|
|
121
|
+
m = P;
|
|
122
|
+
}
|
|
123
|
+
const A = Qe(m);
|
|
124
|
+
if (A && (s.current || !Ye.has(m.type)) && (E(""), requestAnimationFrame(() => E(A))), s.current) {
|
|
125
|
+
s.current(m);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
const k = { toasterId: g, description: m.description };
|
|
129
|
+
switch (m.type) {
|
|
130
|
+
case "feature:deleted":
|
|
131
|
+
case "features:deleted":
|
|
132
|
+
case "feature:duplicated":
|
|
133
|
+
case "features:duplicated":
|
|
134
|
+
break;
|
|
135
|
+
case "feature:broken":
|
|
136
|
+
H.success(`Broken into ${m.count} features`, {
|
|
137
|
+
...k,
|
|
138
|
+
action: { label: "Undo", onClick: m.undo },
|
|
139
|
+
duration: 5e3
|
|
140
|
+
});
|
|
141
|
+
break;
|
|
142
|
+
case "selection:copied":
|
|
143
|
+
H.success("Copied selection", k);
|
|
144
|
+
break;
|
|
145
|
+
case "selection:pasted":
|
|
146
|
+
H.success(m.count === 1 ? "Pasted feature" : `Pasted ${m.count} features`, k);
|
|
147
|
+
break;
|
|
148
|
+
case "undo":
|
|
149
|
+
case "redo":
|
|
150
|
+
break;
|
|
151
|
+
case "error":
|
|
152
|
+
H.error(m.message, k);
|
|
153
|
+
break;
|
|
154
|
+
case "warning":
|
|
155
|
+
H.warning(m.message, k);
|
|
156
|
+
break;
|
|
157
|
+
case "success":
|
|
158
|
+
H.success(m.message, k);
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
161
|
+
}, [g]), D = v(Te);
|
|
162
|
+
x(() => {
|
|
163
|
+
if (D)
|
|
164
|
+
return D((j, m) => F({ type: "error", code: j.code, source: j.source, message: j.message, error: j, quiet: m == null ? void 0 : m.quiet })), () => D(null);
|
|
165
|
+
}, [D, F]);
|
|
166
|
+
const K = he(() => ({ emit: F, managed: _, toasterId: g }), [F, _, g]);
|
|
167
|
+
return /* @__PURE__ */ Be(B.Provider, { value: K, children: [
|
|
168
|
+
o,
|
|
169
|
+
l && /* @__PURE__ */ M(Ve, { id: l, position: "bottom-right" }),
|
|
170
|
+
/* @__PURE__ */ M(
|
|
171
|
+
"div",
|
|
172
|
+
{
|
|
173
|
+
"aria-live": "polite",
|
|
174
|
+
"aria-atomic": "true",
|
|
175
|
+
role: "status",
|
|
176
|
+
style: {
|
|
177
|
+
position: "absolute",
|
|
178
|
+
width: 1,
|
|
179
|
+
height: 1,
|
|
180
|
+
padding: 0,
|
|
181
|
+
margin: -1,
|
|
182
|
+
overflow: "hidden",
|
|
183
|
+
clip: "rect(0, 0, 0, 0)",
|
|
184
|
+
whiteSpace: "nowrap",
|
|
185
|
+
border: 0
|
|
186
|
+
},
|
|
187
|
+
children: y
|
|
188
|
+
}
|
|
189
|
+
)
|
|
190
|
+
] });
|
|
191
|
+
}
|
|
192
|
+
function Xe() {
|
|
193
|
+
const e = v(B);
|
|
194
|
+
if (!e) throw new Error("useEmit must be used within EventProvider");
|
|
195
|
+
return e.emit;
|
|
196
|
+
}
|
|
197
|
+
function Ft() {
|
|
198
|
+
var e;
|
|
199
|
+
return ((e = v(B)) == null ? void 0 : e.managed) ?? !1;
|
|
200
|
+
}
|
|
201
|
+
function $t() {
|
|
202
|
+
var e;
|
|
203
|
+
return (e = v(B)) == null ? void 0 : e.toasterId;
|
|
204
|
+
}
|
|
205
|
+
function Ct() {
|
|
206
|
+
var e;
|
|
207
|
+
return (e = v(B)) == null ? void 0 : e.emit;
|
|
208
|
+
}
|
|
209
|
+
const de = /* @__PURE__ */ new WeakSet(), te = L(null);
|
|
210
|
+
function Et({ children: e }) {
|
|
211
|
+
var y;
|
|
212
|
+
const t = p(null), a = p(null), o = (y = v(B)) == null ? void 0 : y.emit, s = p(o);
|
|
213
|
+
s.current = o;
|
|
214
|
+
const u = ee((E) => {
|
|
215
|
+
a.current = E;
|
|
216
|
+
}, []), c = ie(), h = c.ui.geojsonEditorOpen;
|
|
217
|
+
if (!t.current) {
|
|
218
|
+
const E = (l, g) => {
|
|
219
|
+
a.current ? a.current(l, g) : s.current ? s.current({ type: "error", code: l.code, source: l.source, message: l.message, error: l, quiet: g == null ? void 0 : g.quiet }) : g != null && g.quiet || H.error(l.message);
|
|
220
|
+
}, b = { persistKey: c.persistKey, persist: c.persist }, w = Ie({ onError: E, persist: b }), I = je(w, { onError: E, persist: b });
|
|
221
|
+
if (h) {
|
|
222
|
+
I.setState({ codeModalOpen: !0 }), de.add(I);
|
|
223
|
+
const l = I.subscribe((g) => {
|
|
224
|
+
g.codeModalOpen || (de.delete(I), l());
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
t.current = { dataStore: w, uiStore: I };
|
|
228
|
+
}
|
|
229
|
+
return /* @__PURE__ */ M(te.Provider, { value: t.current, children: /* @__PURE__ */ M(Te.Provider, { value: u, children: e }) });
|
|
230
|
+
}
|
|
231
|
+
function et(e) {
|
|
232
|
+
const t = v(te);
|
|
233
|
+
if (!t) throw new Error("useDataStore must be used within GeoStoreProvider");
|
|
234
|
+
return be(t.dataStore, e);
|
|
235
|
+
}
|
|
236
|
+
function X(e) {
|
|
237
|
+
const t = v(te);
|
|
238
|
+
if (!t) throw new Error("useUIStore must be used within GeoStoreProvider");
|
|
239
|
+
return be(t.uiStore, e);
|
|
240
|
+
}
|
|
241
|
+
function Fe() {
|
|
242
|
+
const e = v(te);
|
|
243
|
+
if (!e) throw new Error("useGeoStore must be used within GeoStoreProvider");
|
|
244
|
+
return e;
|
|
245
|
+
}
|
|
246
|
+
const $e = L({
|
|
247
|
+
flyTo: null,
|
|
248
|
+
panTo: null,
|
|
249
|
+
fitBounds: null,
|
|
250
|
+
getCenter: null,
|
|
251
|
+
setZoom: null,
|
|
252
|
+
getZoomBounds: null
|
|
253
|
+
}), Ce = () => {
|
|
254
|
+
}, se = L(Ce);
|
|
255
|
+
function Ot({ children: e }) {
|
|
256
|
+
const [t, a] = W({
|
|
257
|
+
flyTo: null,
|
|
258
|
+
panTo: null,
|
|
259
|
+
fitBounds: null,
|
|
260
|
+
getCenter: null,
|
|
261
|
+
setZoom: null,
|
|
262
|
+
getZoomBounds: null
|
|
263
|
+
});
|
|
264
|
+
return v(se) !== Ce ? /* @__PURE__ */ M(Le, { children: e }) : /* @__PURE__ */ M(se.Provider, { value: a, children: /* @__PURE__ */ M($e.Provider, { value: t, children: e }) });
|
|
265
|
+
}
|
|
266
|
+
function Ee() {
|
|
267
|
+
return v($e);
|
|
268
|
+
}
|
|
269
|
+
function Nt() {
|
|
270
|
+
return v(se);
|
|
271
|
+
}
|
|
272
|
+
function Oe(e, t = "features.geojson") {
|
|
273
|
+
const a = t.toLowerCase().endsWith(".geojson") ? t : `${t}.geojson`, o = new Blob([e], { type: "application/geo+json" }), s = URL.createObjectURL(o), u = document.createElement("a");
|
|
274
|
+
return u.href = s, u.download = a, u.rel = "noopener", document.body.appendChild(u), u.click(), document.body.removeChild(u), URL.revokeObjectURL(s), { name: a, bytes: o.size };
|
|
275
|
+
}
|
|
276
|
+
async function xt(e, t = "features.geojson") {
|
|
277
|
+
const a = t.toLowerCase().endsWith(".geojson") ? t : `${t}.geojson`, o = new Blob([e], { type: "application/geo+json" }), s = window;
|
|
278
|
+
if (typeof s.showSaveFilePicker == "function")
|
|
279
|
+
try {
|
|
280
|
+
const u = await s.showSaveFilePicker({
|
|
281
|
+
suggestedName: a,
|
|
282
|
+
types: [{ description: "GeoJSON", accept: { "application/geo+json": [".geojson", ".json"] } }]
|
|
283
|
+
}), c = await u.createWritable();
|
|
284
|
+
return await c.write(o), await c.close(), { name: u.name || a, bytes: o.size };
|
|
285
|
+
} catch (u) {
|
|
286
|
+
if (u instanceof Error && u.name === "AbortError") return null;
|
|
287
|
+
}
|
|
288
|
+
return Oe(e, t), null;
|
|
289
|
+
}
|
|
290
|
+
async function tt(e, t, a) {
|
|
291
|
+
let o;
|
|
292
|
+
try {
|
|
293
|
+
o = await e.text();
|
|
294
|
+
} catch (u) {
|
|
295
|
+
return { ok: !1, code: "unknown", reason: "The file could not be read", cause: u };
|
|
296
|
+
}
|
|
297
|
+
const s = Ae(o);
|
|
298
|
+
if (!s.ok) {
|
|
299
|
+
const u = s.error;
|
|
300
|
+
return u.kind === "too-large" ? { ok: !1, code: "too-large", reason: `The file is over the ${Math.round(u.maxBytes / 1024 / 1024)} MB import limit` } : u.kind === "invalid-json" ? { ok: !1, code: "invalid-data", reason: `Not valid JSON (${u.cause.message})`, cause: u.cause } : { ok: !1, code: "invalid-data", reason: "Not a FeatureCollection" };
|
|
301
|
+
}
|
|
302
|
+
try {
|
|
303
|
+
const { skipped: u, duplicates: c } = t(s.fc, "replace");
|
|
304
|
+
return { ok: !0, count: a(), skipped: u, duplicates: c };
|
|
305
|
+
} catch (u) {
|
|
306
|
+
return { ok: !1, code: "invalid-data", reason: u instanceof Error ? u.message : "Not a FeatureCollection", cause: u };
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
function It() {
|
|
310
|
+
const { dataStore: e, uiStore: t } = Fe(), a = Xe(), { fitBounds: o } = Ee();
|
|
311
|
+
return ee(async (s) => {
|
|
312
|
+
if (t.getState().readonly) return;
|
|
313
|
+
if (!/\.(geo)?json$/i.test(s.name) && !/json/i.test(s.type)) {
|
|
314
|
+
a({ type: "error", code: "invalid-data", source: "import", message: "Import failed", description: `${s.name} is not a .geojson or .json file` });
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
const u = e.getState(), c = await tt(s, u.importGeoJSON, () => e.getState().features.length);
|
|
318
|
+
if (!c.ok) {
|
|
319
|
+
a({ type: "error", code: c.code, source: "import", message: "Import failed", description: c.reason, cause: c.cause });
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
const { features: h, schemas: y, groups: E } = e.getState(), b = Se({ type: "FeatureCollection", metadata: { schemas: y, groups: E }, features: h });
|
|
323
|
+
b && (o == null || o(b)), a({
|
|
324
|
+
type: "success",
|
|
325
|
+
message: `Loaded ${s.name}`,
|
|
326
|
+
description: c.count === 1 ? "1 feature" : `${c.count} features`
|
|
327
|
+
});
|
|
328
|
+
const w = c.skipped + c.duplicates;
|
|
329
|
+
w > 0 && a({
|
|
330
|
+
type: "warning",
|
|
331
|
+
message: `Skipped ${w === 1 ? "1 feature" : `${w} features`} from ${s.name}`,
|
|
332
|
+
description: [
|
|
333
|
+
c.skipped > 0 && `${c.skipped} with a missing or unsupported geometry`,
|
|
334
|
+
c.duplicates > 0 && `${c.duplicates} with a repeated id`
|
|
335
|
+
].filter(Boolean).join(", ")
|
|
336
|
+
});
|
|
337
|
+
}, [e, t, a, o]);
|
|
338
|
+
}
|
|
339
|
+
const rt = 400, nt = "https://nominatim.openstreetmap.org/search", jt = 'Geocoding by <a href="https://nominatim.org/" target="_blank" rel="noopener">Nominatim</a>';
|
|
340
|
+
function ot(e) {
|
|
341
|
+
return e instanceof z ? e : e instanceof SyntaxError ? new z("invalid-data", "search", "Search service sent an answer that could not be read. Try again later.", { cause: e }) : new z("network", "search", "Search unavailable. Check your connection.", { cause: e });
|
|
342
|
+
}
|
|
343
|
+
function at(e) {
|
|
344
|
+
const t = Pe(e), a = t === "rate-limited" ? "Too many searches — wait a moment and try again." : t === "busy" ? "Search service is busy — try again in a moment." : `Search failed (HTTP ${e}). Try again later.`;
|
|
345
|
+
return new z(t, "search", a);
|
|
346
|
+
}
|
|
347
|
+
function At(e) {
|
|
348
|
+
var _;
|
|
349
|
+
const [t, a] = W([]), [o, s] = W(!1), [u, c] = W(null), h = p(null), y = p(null), E = (_ = v(B)) == null ? void 0 : _.emit, b = p(E);
|
|
350
|
+
b.current = E;
|
|
351
|
+
const { network: w } = ie(), I = p(w);
|
|
352
|
+
I.current = w;
|
|
353
|
+
const l = p(null);
|
|
354
|
+
x(() => {
|
|
355
|
+
const F = e.trim();
|
|
356
|
+
if (F.length < 2) {
|
|
357
|
+
a([]), s(!1), c(null);
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
s(!0), c(null), y.current && clearTimeout(y.current);
|
|
361
|
+
const D = async () => {
|
|
362
|
+
var K, j;
|
|
363
|
+
l.current = null, y.current && clearTimeout(y.current), (K = h.current) == null || K.abort(), h.current = new AbortController();
|
|
364
|
+
try {
|
|
365
|
+
const { nominatim: m, fetch: A = fetch } = I.current, k = m || {}, R = new URLSearchParams({
|
|
366
|
+
q: F,
|
|
367
|
+
format: "json",
|
|
368
|
+
limit: "6",
|
|
369
|
+
addressdetails: "0",
|
|
370
|
+
polygon_geojson: "1",
|
|
371
|
+
...k.email && { email: k.email }
|
|
372
|
+
}), U = k.url ?? nt, P = await A(`${U}${U.includes("?") ? "&" : "?"}${R}`, { signal: h.current.signal });
|
|
373
|
+
if (!P.ok) throw at(P.status);
|
|
374
|
+
const J = await P.json(), q = /* @__PURE__ */ new Set(), T = /* @__PURE__ */ new Set(), Z = J.filter((O) => {
|
|
375
|
+
const G = `${O.lat},${O.lon}`;
|
|
376
|
+
return q.has(O.display_name) || T.has(G) ? !1 : (q.add(O.display_name), T.add(G), !0);
|
|
377
|
+
});
|
|
378
|
+
a(Z), c(null);
|
|
379
|
+
} catch (m) {
|
|
380
|
+
if (m instanceof Error && m.name === "AbortError") return;
|
|
381
|
+
const A = ot(m);
|
|
382
|
+
c(A.message), (j = b.current) == null || j.call(b, { type: "error", code: A.code, source: "search", message: A.message, error: A, quiet: !0 }), a([]);
|
|
383
|
+
} finally {
|
|
384
|
+
s(!1);
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
return l.current = D, y.current = setTimeout(D, rt), () => {
|
|
388
|
+
l.current = null, y.current && clearTimeout(y.current);
|
|
389
|
+
};
|
|
390
|
+
}, [e]), x(() => () => {
|
|
391
|
+
var F;
|
|
392
|
+
(F = h.current) == null || F.abort(), y.current && clearTimeout(y.current);
|
|
393
|
+
}, []);
|
|
394
|
+
const g = ee(() => {
|
|
395
|
+
var F;
|
|
396
|
+
(F = l.current) == null || F.call(l);
|
|
397
|
+
}, []);
|
|
398
|
+
return { results: t, loading: o, error: u, flush: g };
|
|
399
|
+
}
|
|
400
|
+
const fe = (e, t) => Object.is(e, t) || Array.isArray(e) && Array.isArray(t) && e.length === t.length && e.every((a, o) => Object.is(a, t[o]));
|
|
401
|
+
function st(e, t) {
|
|
402
|
+
return [
|
|
403
|
+
...e.routing === !1 ? ["route"] : [],
|
|
404
|
+
...e.nominatim === !1 ? ["search"] : [],
|
|
405
|
+
...e.overpass === !1 && t === "leaflet" ? ["picker"] : []
|
|
406
|
+
];
|
|
407
|
+
}
|
|
408
|
+
function V(e, t, a) {
|
|
409
|
+
const o = p({ has: !1, value: e });
|
|
410
|
+
o.current.has || (o.current = { has: !0, value: e }, e !== void 0 && !fe(a(), e) && t(e)), oe(() => {
|
|
411
|
+
fe(o.current.value, e) || (o.current = { has: !0, value: e }, t(e));
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
const ct = ["properties", "geometry", "schemaId", "hidden"];
|
|
415
|
+
function me(e, t) {
|
|
416
|
+
const a = e;
|
|
417
|
+
if (!a || typeof a != "object")
|
|
418
|
+
return C(`ref-${t}-patch`, `${t}: a patch must be an object; it was skipped.`), null;
|
|
419
|
+
const o = {};
|
|
420
|
+
for (const s of ct) a[s] !== void 0 && (o[s] = a[s]);
|
|
421
|
+
return o.geometry !== void 0 && !ye(o.geometry) ? (C(`ref-${t}-geometry`, `${t}: patch.geometry is not a valid GeoJSON geometry; the patch was skipped.`), null) : o.properties !== void 0 && (typeof o.properties != "object" || o.properties === null || Array.isArray(o.properties)) ? (C(`ref-${t}-properties`, `${t}: patch.properties must be an object; the patch was skipped.`), null) : o;
|
|
422
|
+
}
|
|
423
|
+
function re(e, t) {
|
|
424
|
+
C(`ref-${e}-unknown`, `${e}: no feature with id ${t.slice(0, 3).map((a) => JSON.stringify(a)).join(", ")}${t.length > 3 ? ", …" : ""}; skipped.`);
|
|
425
|
+
}
|
|
426
|
+
function ce(e) {
|
|
427
|
+
const { _validation: t, ...a } = e;
|
|
428
|
+
return a;
|
|
429
|
+
}
|
|
430
|
+
function it(e, t) {
|
|
431
|
+
const a = new Map(e.features.map((c) => [c.id, c])), o = new Set(e.groups.filter((c) => c.hidden).map((c) => c.id)), s = [], u = [];
|
|
432
|
+
for (const c of new Set(t)) {
|
|
433
|
+
const h = a.get(c);
|
|
434
|
+
h && !h.hidden && !(h.groupId && o.has(h.groupId)) ? s.push(h) : u.push(c);
|
|
435
|
+
}
|
|
436
|
+
return { keep: s, dropped: u };
|
|
437
|
+
}
|
|
438
|
+
function ut(e) {
|
|
439
|
+
const t = e;
|
|
440
|
+
return (t == null ? void 0 : t.type) === "Feature" ? { type: "FeatureCollection", features: [t] } : t;
|
|
441
|
+
}
|
|
442
|
+
const lt = Object.fromEntries(Object.entries(ae).map(([e, t]) => [t, e])), ne = (e) => lt[e] ?? null;
|
|
443
|
+
function ge(e) {
|
|
444
|
+
const t = new Map(e.schemas.map((s) => [s.id, s])), a = e.schemas[0] ?? e.getDefaultSchema(), o = {};
|
|
445
|
+
for (const s of e.features) {
|
|
446
|
+
const u = s.schemaId && t.get(s.schemaId) || a, c = Re(s, u).errors;
|
|
447
|
+
c.length > 0 && (o[s.id] = c);
|
|
448
|
+
}
|
|
449
|
+
return o;
|
|
450
|
+
}
|
|
451
|
+
function pe(e) {
|
|
452
|
+
return {
|
|
453
|
+
type: "FeatureCollection",
|
|
454
|
+
metadata: { schemas: e.schemas, groups: e.groups },
|
|
455
|
+
features: e.features.map(ce)
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
const dt = (e) => e.features.length === 0 && e.undoStack.length === 0 && e.redoStack.length === 0;
|
|
459
|
+
function ft(e, t) {
|
|
460
|
+
if (e === t) return !0;
|
|
461
|
+
const a = e == null ? void 0 : e.features, o = t == null ? void 0 : t.features;
|
|
462
|
+
return !Array.isArray(a) || !Array.isArray(o) ? !1 : a === o || a.length === o.length && a.every((s, u) => {
|
|
463
|
+
var c;
|
|
464
|
+
return (s == null ? void 0 : s.id) === ((c = o[u]) == null ? void 0 : c.id);
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
function Mt(e) {
|
|
468
|
+
const {
|
|
469
|
+
initialData: t,
|
|
470
|
+
schema: a,
|
|
471
|
+
onChange: o,
|
|
472
|
+
onSubmit: s,
|
|
473
|
+
onValidationError: u,
|
|
474
|
+
onFeatureAdd: c,
|
|
475
|
+
onFeatureUpdate: h,
|
|
476
|
+
onFeatureDelete: y,
|
|
477
|
+
onSelectionChange: E,
|
|
478
|
+
onFeatureSelect: b,
|
|
479
|
+
onZoomChange: w,
|
|
480
|
+
onToolChange: I
|
|
481
|
+
} = e, { dataStore: l, uiStore: g } = Fe(), _ = X((r) => r.setReadonly), F = X((r) => r.setEnabledTools), D = et((r) => r.setMaxFeatures), K = X((r) => r.setLayout), j = X((r) => r.setUnavailableTools), { network: m } = ie(), A = Ee(), k = p(A);
|
|
482
|
+
k.current = A;
|
|
483
|
+
const R = p(!1), U = p({});
|
|
484
|
+
U.current = { onChange: o, onFeatureAdd: c, onFeatureUpdate: h, onFeatureDelete: y, onSelectionChange: E }, x(() => Me(l, () => R.current ? { onSelectionChange: U.current.onSelectionChange } : U.current), [l]), V(e.readonly, (r) => _(r ?? !1), () => g.getState().readonly), V(e.tools, (r) => F(r ?? null), () => g.getState().enabledTools), V(e.maxFeatures, D, () => l.getState().maxFeatures), V(e.layout, (r) => K(r ?? "panel"), () => g.getState().layout), V(e.engine && st(m, e.engine), (r) => j(r ?? []), () => g.getState().unavailableTools), x(() => {
|
|
485
|
+
a && l.setState((r) => r.schemas.find((n) => n.id === a.id) ? r : { schemas: [...r.schemas, a] });
|
|
486
|
+
}, [a, l]);
|
|
487
|
+
const P = (r, n) => {
|
|
488
|
+
n !== 0 && g.getState().reportError(new z(
|
|
489
|
+
"invalid-data",
|
|
490
|
+
"import",
|
|
491
|
+
`${n} feature${n === 1 ? "" : "s"} in ${r} had no usable geometry (null or an unknown type) and ${n === 1 ? "was" : "were"} left out.`
|
|
492
|
+
));
|
|
493
|
+
}, J = p(!1), q = p(t), T = p(e.onInitialDataApplied);
|
|
494
|
+
T.current = e.onInitialDataApplied;
|
|
495
|
+
const Z = (r, n) => {
|
|
496
|
+
var d;
|
|
497
|
+
const i = ut(r);
|
|
498
|
+
R.current = !0;
|
|
499
|
+
try {
|
|
500
|
+
const { skipped: f } = l.getState().importGeoJSON(i, "replace", { undoable: !1 });
|
|
501
|
+
R.current = !1, P("initialData", f), J.current = l.getState().features.length > 0, (d = T.current) == null || d.call(T, i, n);
|
|
502
|
+
} catch (f) {
|
|
503
|
+
const S = `initialData is not a valid FeatureCollection (${f instanceof Error ? f.message : String(f)}). The editor started empty.`;
|
|
504
|
+
console.error(`[element-editor] ${S}`), g.getState().reportError(new z("invalid-data", "import", S, { cause: f }));
|
|
505
|
+
} finally {
|
|
506
|
+
R.current = !1;
|
|
507
|
+
}
|
|
508
|
+
};
|
|
509
|
+
x(() => {
|
|
510
|
+
t && Z(t, !1);
|
|
511
|
+
}, []), x(() => {
|
|
512
|
+
const r = q.current;
|
|
513
|
+
if (ft(r, t) || (q.current = t, !t && !J.current)) return;
|
|
514
|
+
if (t && !J.current && dt(l.getState())) {
|
|
515
|
+
Z(t, !0);
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
518
|
+
const n = J.current || !t;
|
|
519
|
+
C(n ? "initialData-changed" : "initialData-after-edit", n ? "`initialData` changed after the editor loaded its data; the change was ignored (`initialData` is the starting data). To replace the data, call `ref.current.setFeatureCollection(data, { silent: true })`, or remount the editor with a new `key` (e.g. key={projectId})." : "`initialData` arrived after the user started editing; it was ignored so their edits are kept. Render the editor once the data is there, call `ref.current.setFeatureCollection(data, { silent: true })`, or remount it with a new `key`.");
|
|
520
|
+
}, [t]);
|
|
521
|
+
const O = p(s), G = p(u), Y = p(w), ue = p(b);
|
|
522
|
+
x(() => {
|
|
523
|
+
O.current = s;
|
|
524
|
+
}, [s]), x(() => {
|
|
525
|
+
G.current = u;
|
|
526
|
+
}, [u]), x(() => {
|
|
527
|
+
Y.current = w;
|
|
528
|
+
}, [w]), x(() => {
|
|
529
|
+
ue.current = b;
|
|
530
|
+
}, [b]), x(() => l.subscribe((r, n) => {
|
|
531
|
+
var i;
|
|
532
|
+
r.currentZoom !== n.currentZoom && ((i = Y.current) == null || i.call(Y, r.currentZoom));
|
|
533
|
+
}), [l]), x(() => l.subscribe((r, n) => {
|
|
534
|
+
const i = ue.current;
|
|
535
|
+
if (!i) return;
|
|
536
|
+
const d = r.selectedIds.length === 1 ? r.selectedIds[0] : null, f = n.selectedIds.length === 1 ? n.selectedIds[0] : null, S = d ? r.features.find(($) => $.id === d) ?? null : null, N = f ? n.features.find(($) => $.id === f) ?? null : null;
|
|
537
|
+
S !== N && i(S);
|
|
538
|
+
}), [l]);
|
|
539
|
+
const Q = p(I);
|
|
540
|
+
return Q.current = I, x(() => g.subscribe((r, n) => {
|
|
541
|
+
var d;
|
|
542
|
+
if (r.editingMode === n.editingMode) return;
|
|
543
|
+
const i = ne(r.editingMode);
|
|
544
|
+
i !== ne(n.editingMode) && ((d = Q.current) == null || d.call(Q, i));
|
|
545
|
+
}), [g]), he(() => ({
|
|
546
|
+
getFeatureCollection: () => pe(l.getState()),
|
|
547
|
+
getFeature: (r) => {
|
|
548
|
+
const n = l.getState().features.find((i) => i.id === r);
|
|
549
|
+
return n ? ce(n) : null;
|
|
550
|
+
},
|
|
551
|
+
setFeatureCollection: (r, n) => {
|
|
552
|
+
R.current = !!(n != null && n.silent);
|
|
553
|
+
try {
|
|
554
|
+
const { skipped: i } = l.getState().importGeoJSON(r, "replace", { undoable: (n == null ? void 0 : n.undoable) !== !1 });
|
|
555
|
+
P("the data passed to setFeatureCollection", i);
|
|
556
|
+
} finally {
|
|
557
|
+
R.current = !1;
|
|
558
|
+
}
|
|
559
|
+
},
|
|
560
|
+
exportGeoJSON: () => l.getState().exportGeoJSON(),
|
|
561
|
+
exportAs: (r) => {
|
|
562
|
+
r === "geojson" && Oe(l.getState().exportGeoJSON());
|
|
563
|
+
},
|
|
564
|
+
importGeoJSON: (r, n = "replace") => l.getState().importGeoJSON(r, n),
|
|
565
|
+
updateFeatures: (r, n) => {
|
|
566
|
+
if (!Array.isArray(r)) {
|
|
567
|
+
C("ref-updateFeatures-array", "updateFeatures: expected an array of { id, patch }.");
|
|
568
|
+
return;
|
|
569
|
+
}
|
|
570
|
+
const i = l.getState(), d = new Set(i.features.map((N) => N.id)), f = [], S = [];
|
|
571
|
+
for (const N of r) {
|
|
572
|
+
const $ = me(N == null ? void 0 : N.patch, "updateFeatures");
|
|
573
|
+
if ($) {
|
|
574
|
+
if (!d.has(N.id)) {
|
|
575
|
+
S.push(String(N.id));
|
|
576
|
+
continue;
|
|
577
|
+
}
|
|
578
|
+
f.push({ id: N.id, patch: $ });
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
S.length && re("updateFeatures", S), f.length && i.updateFeatures(f, { undoable: (n == null ? void 0 : n.undoable) ?? !0 });
|
|
582
|
+
},
|
|
583
|
+
addFeature: (r, n) => {
|
|
584
|
+
const i = r;
|
|
585
|
+
if (!i || typeof i != "object" || !ye(i.geometry))
|
|
586
|
+
return C("ref-addFeature-geometry", "addFeature: the feature needs a valid GeoJSON geometry; nothing was added."), null;
|
|
587
|
+
const d = l.getState(), f = i.id !== void 0 && i.id !== null && String(i.id) !== "" ? String(i.id) : crypto.randomUUID();
|
|
588
|
+
if (d.features.some((Ne) => Ne.id === f))
|
|
589
|
+
return C("ref-addFeature-duplicate", `addFeature: a feature with id ${JSON.stringify(f)} already exists; nothing was added.`), null;
|
|
590
|
+
const { _validation: S, bbox: N, ...$ } = i, le = d.addFeature(
|
|
591
|
+
{ ...$, type: "Feature", id: f, properties: i.properties ?? {} },
|
|
592
|
+
{ programmatic: !0, undoable: n == null ? void 0 : n.undoable }
|
|
593
|
+
);
|
|
594
|
+
return le && ce(le);
|
|
595
|
+
},
|
|
596
|
+
updateFeature: (r, n, i) => {
|
|
597
|
+
const d = me(n, "updateFeature");
|
|
598
|
+
if (!d) return !1;
|
|
599
|
+
const f = l.getState();
|
|
600
|
+
return f.features.some((S) => S.id === r) ? (f.updateFeatures([{ id: r, patch: d }], { undoable: (i == null ? void 0 : i.undoable) ?? !0 }), !0) : (re("updateFeature", [String(r)]), !1);
|
|
601
|
+
},
|
|
602
|
+
removeFeatures: (r, n) => {
|
|
603
|
+
if (!Array.isArray(r))
|
|
604
|
+
return C("ref-removeFeatures-array", "removeFeatures: expected an array of ids."), 0;
|
|
605
|
+
const i = l.getState(), d = new Set(i.features.map((S) => S.id)), f = r.filter((S) => !d.has(S));
|
|
606
|
+
return f.length && re("removeFeatures", f.map(String)), i.deleteFeatures(r, { undoable: n == null ? void 0 : n.undoable });
|
|
607
|
+
},
|
|
608
|
+
getSelection: () => [...l.getState().selectedIds],
|
|
609
|
+
select: (r, n) => {
|
|
610
|
+
var S, N;
|
|
611
|
+
if (!Array.isArray(r)) {
|
|
612
|
+
C("ref-select-array", "select: expected an array of feature ids.");
|
|
613
|
+
return;
|
|
614
|
+
}
|
|
615
|
+
const i = l.getState(), { keep: d, dropped: f } = it(i, r);
|
|
616
|
+
if (f.length && C("ref-select-dropped", `select: left out ${f.slice(0, 3).map(($) => JSON.stringify($)).join(", ")}${f.length > 3 ? ", …" : ""}: unknown ids or hidden features (a group id isn't selectable; select its features).`), d.length === 0 ? i.clearSelection() : d.length === 1 ? i.selectFeature(d[0].id) : i.setSelection(d.map(($) => $.id)), n != null && n.fit && d.length > 0) {
|
|
617
|
+
const $ = Se({ type: "FeatureCollection", features: d });
|
|
618
|
+
$ && ((N = (S = k.current).fitBounds) == null || N.call(S, $));
|
|
619
|
+
}
|
|
620
|
+
},
|
|
621
|
+
setTool: (r) => {
|
|
622
|
+
const n = g.getState();
|
|
623
|
+
if (r === null)
|
|
624
|
+
return n.setEditingMode("none"), !0;
|
|
625
|
+
const i = r !== "search" && Object.prototype.hasOwnProperty.call(ae, r) ? ae[r] : null;
|
|
626
|
+
return i ? n.readonly && r !== "measure" ? (C("ref-setTool-readonly", `setTool(${JSON.stringify(r)}): the editor is readonly; only 'measure' is available.`), !1) : n.isToolAvailable(r) ? n.editingMode === i ? !0 : r !== "measure" && !l.getState().canAddFeatures(1) ? !1 : (n.setEditingMode(i), !0) : (C(`ref-setTool-disabled-${r}`, `setTool: ${JSON.stringify(r)} is not in the \`tools\` list${n.unavailableTools.includes(r) ? " (config.network turns it off)" : ""}.`), !1) : (C(`ref-setTool-${String(r)}`, `setTool: ${JSON.stringify(r)} is not a drawing tool${r === "search" ? " (search is a box in the toolbar, not a tool)" : ""}.`), !1);
|
|
627
|
+
},
|
|
628
|
+
getTool: () => ne(g.getState().editingMode),
|
|
629
|
+
canUndo: () => l.getState().undoStack.length > 0,
|
|
630
|
+
canRedo: () => l.getState().redoStack.length > 0,
|
|
631
|
+
validate: () => {
|
|
632
|
+
const r = ge(l.getState());
|
|
633
|
+
return { valid: Object.keys(r).length === 0, errors: r };
|
|
634
|
+
},
|
|
635
|
+
getMap: () => {
|
|
636
|
+
var r, n;
|
|
637
|
+
return ((n = (r = k.current).getMap) == null ? void 0 : n.call(r)) ?? null;
|
|
638
|
+
},
|
|
639
|
+
flyTo: (r, n) => {
|
|
640
|
+
var d, f;
|
|
641
|
+
const i = De(r, n);
|
|
642
|
+
i && ((f = (d = k.current).flyTo) == null || f.call(d, [i.center[1], i.center[0]], i.zoom));
|
|
643
|
+
},
|
|
644
|
+
setZoom: (r) => {
|
|
645
|
+
const n = k.current.setZoom;
|
|
646
|
+
return n ? (n(r), !0) : !1;
|
|
647
|
+
},
|
|
648
|
+
fitBounds: (r) => {
|
|
649
|
+
var n, i;
|
|
650
|
+
return (i = (n = k.current).fitBounds) == null ? void 0 : i.call(n, r);
|
|
651
|
+
},
|
|
652
|
+
submit: () => {
|
|
653
|
+
var i, d;
|
|
654
|
+
const r = l.getState(), n = ge(r);
|
|
655
|
+
return Object.keys(n).length > 0 ? ((i = G.current) == null || i.call(G, n), !1) : ((d = O.current) == null || d.call(O, pe(r)), !0);
|
|
656
|
+
},
|
|
657
|
+
undo: () => l.getState().undo(),
|
|
658
|
+
redo: () => l.getState().redo(),
|
|
659
|
+
clearSelection: () => l.getState().clearSelection()
|
|
660
|
+
}), [l, g]);
|
|
661
|
+
}
|
|
662
|
+
export {
|
|
663
|
+
B as E,
|
|
664
|
+
Et as G,
|
|
665
|
+
Ot as M,
|
|
666
|
+
nt as N,
|
|
667
|
+
te as S,
|
|
668
|
+
kt as T,
|
|
669
|
+
jt as a,
|
|
670
|
+
It as b,
|
|
671
|
+
Ct as c,
|
|
672
|
+
qe as d,
|
|
673
|
+
Fe as e,
|
|
674
|
+
et as f,
|
|
675
|
+
Ee as g,
|
|
676
|
+
Xe as h,
|
|
677
|
+
Ft as i,
|
|
678
|
+
$t as j,
|
|
679
|
+
de as k,
|
|
680
|
+
At as l,
|
|
681
|
+
Tt as m,
|
|
682
|
+
st as n,
|
|
683
|
+
Ve as o,
|
|
684
|
+
we as p,
|
|
685
|
+
Mt as q,
|
|
686
|
+
vt as r,
|
|
687
|
+
xt as s,
|
|
688
|
+
Oe as t,
|
|
689
|
+
X as u,
|
|
690
|
+
Nt as v
|
|
691
|
+
};
|