@octostar/map-component 0.1.11 → 0.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +22 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +28 -14
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../client/src/lib/utils.ts","../client/src/hooks/use-toast.ts","../client/src/components/drawing-toolbar.tsx","../client/src/components/color-picker-popover.tsx","../client/src/components/icon-picker.tsx","../client/src/components/layers-panel.tsx","../client/src/components/properties-panel.tsx","../client/src/components/status-indicator.tsx","../client/src/lib/timeline-store.ts","../client/src/components/timebar.tsx","../client/src/components/map-drop-zone.tsx","../client/src/components/cluster-pie-chart.tsx","../client/src/components/map-editor-canvas.tsx","../client/src/components/action-panel.tsx","../client/src/components/debug-sidebar.tsx"],"sourcesContent":["import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","import { App } from \"antd\";\n\nexport function useToast() {\n const { message } = App.useApp();\n\n const toast = ({ title, description, variant }: { title?: string; description?: string; variant?: 'default' | 'destructive' }) => {\n const content = description ? `${title ? title + ': ' : ''}${description}` : title;\n if (variant === 'destructive') {\n message.error(content);\n } else {\n message.success(content);\n }\n };\n\n return { toast };\n}\n\nexport { useToast as toast };\n","import { useState, useRef, useEffect } from 'react';\nimport { MapPin, Minus, Pentagon, Trash2, X, Undo2, Redo2, MousePointer2, Pencil, Ruler, Move, ChevronDown, Square, Hexagon, Type, MoveRight, Circle, Navigation, MoreVertical, Search, Loader2, Plus, Database, Filter } from 'lucide-react';\nimport { Button, Tooltip, Dropdown, Modal, Input, Divider, Tabs } from 'antd';\nimport type { MenuProps } from 'antd';\nimport { cn } from '@/lib/utils';\nimport { useToast } from '@/hooks/use-toast';\nimport type { SearchEngineParams, GeocoderProvider, GeocoderResult } from '@/lib/map-editor-api';\n\nexport type DrawingMode = 'simple_select' | 'view_select' | 'draw_point' | 'draw_line_string' | 'draw_polygon' | 'draw_rectangle' | 'direct_select' | 'draw_text' | 'draw_arrow' | 'draw_circle';\nexport type MeasureMode = 'none' | 'distance' | 'area';\nexport type SelectionMode = 'click' | 'rectangle' | 'polygon' | 'circle';\n\ninterface DrawingToolbarProps {\n activeMode: DrawingMode;\n onModeChange: (mode: DrawingMode) => void;\n onClear: () => void;\n onDeleteSelected: () => void;\n onUndo: () => void;\n onRedo: () => void;\n featureCount: number;\n selectedCount: number;\n canUndo: boolean;\n canRedo: boolean;\n disabled?: boolean;\n isEditMode: boolean;\n onToggleEditMode: () => void;\n hasVisibleLayers: boolean;\n hasEditableLayer: boolean;\n measureMode: MeasureMode;\n onMeasureModeChange: (mode: MeasureMode) => void;\n selectionMode: SelectionMode;\n onSelectionModeChange: (mode: SelectionMode) => void;\n enableMeasurement?: boolean;\n enableSelection?: boolean;\n hiddenDrawingTools?: ('point' | 'line' | 'polygon' | 'text' | 'arrow' | 'circle')[];\n hiddenSelectionTools?: ('click' | 'rectangle' | 'polygon' | 'circle')[];\n selectionOnly?: boolean;\n onGoTo?: (coords: [number, number], zoom?: number) => void;\n onDropPoint?: (coords: [number, number], name?: string) => void;\n showGoToButton?: boolean;\n isSelectionToolActive?: boolean;\n onSelectionToolActiveChange?: (active: boolean) => void;\n showClearFilter?: boolean;\n onClearFilter?: () => void;\n /** Notifies the parent when the filter tool is toggled on or off */\n onFilterActiveChange?: (active: boolean) => void;\n /** Callback to invoke the external search engine - when provided, shows \"+\" add menu */\n onSearchEngineRequest?: () => Promise<void>;\n /** Whether the search engine request is currently in progress */\n isSearchEngineLoading?: boolean;\n /** Custom geocoding URL - should accept ?q={query} parameter and return Nominatim-compatible JSON */\n geocodingUrl?: string;\n /** Custom geocoder provider function - use instead of geocodingUrl when geocoding is an internal API */\n geocoderProvider?: GeocoderProvider;\n /** Whether to show keyboard shortcut hints in tooltips and menus. Default: true. */\n showShortcutHints?: boolean;\n /** When true, render each selection tool as a separate button instead of a dropdown */\n expandSelectionTools?: boolean;\n /** Show a dedicated Filter button that activates rectangle selection for geo-filtering */\n showFilterTool?: boolean;\n}\n\ninterface ToolButtonProps {\n mode: DrawingMode;\n activeMode: DrawingMode;\n onModeChange: (mode: DrawingMode) => void;\n icon: React.ReactNode;\n label: string;\n shortcut: string;\n disabled?: boolean;\n showShortcutHint?: boolean;\n}\n\nfunction ToolButton({ mode, activeMode, onModeChange, icon, label, shortcut, disabled, showShortcutHint = true }: ToolButtonProps) {\n const isActive = activeMode === mode;\n \n const handleClick = () => {\n if (isActive) {\n onModeChange('simple_select');\n } else {\n onModeChange(mode);\n }\n };\n \n return (\n <Tooltip \n title={showShortcutHint\n ? <span className=\"flex items-center gap-2\">{label}<kbd className=\"px-1.5 py-0.5 text-xs font-mono bg-black/20 rounded\">{shortcut}</kbd></span>\n : label\n } \n placement=\"right\"\n >\n <Button\n type=\"text\"\n onClick={handleClick}\n disabled={disabled}\n className={cn(\n \"relative transition-all duration-150 flex items-center justify-center !w-9 !h-9 !min-w-0 !p-0\",\n isActive && \"tool-active bg-primary/10\"\n )}\n aria-label={label}\n aria-pressed={isActive}\n data-testid={`button-tool-${mode.replace('draw_', '').replace('_string', '')}`}\n icon={icon}\n />\n </Tooltip>\n );\n}\n\nconst SELECTION_MODES = [\n { id: 'click' as SelectionMode, label: 'Click Select', icon: MousePointer2, shortcut: 'V' },\n { id: 'rectangle' as SelectionMode, label: 'Rectangle Select', icon: Square, shortcut: 'R' },\n { id: 'polygon' as SelectionMode, label: 'Polygon Select', icon: Hexagon, shortcut: 'S' },\n { id: 'circle' as SelectionMode, label: 'Circle Select', icon: Circle, shortcut: 'O' },\n];\n\nexport function DrawingToolbar({ \n activeMode, \n onModeChange, \n onClear, \n onDeleteSelected, \n onUndo, \n onRedo, \n featureCount, \n selectedCount, \n canUndo, \n canRedo, \n disabled,\n isEditMode,\n onToggleEditMode,\n hasVisibleLayers,\n hasEditableLayer,\n measureMode,\n onMeasureModeChange,\n selectionMode,\n onSelectionModeChange,\n enableMeasurement = true,\n enableSelection = true,\n hiddenDrawingTools = [],\n hiddenSelectionTools = [],\n selectionOnly = false,\n onGoTo,\n onDropPoint,\n showGoToButton = false,\n isSelectionToolActive = true,\n onSelectionToolActiveChange,\n showClearFilter = false,\n onClearFilter,\n onFilterActiveChange,\n onSearchEngineRequest,\n geocodingUrl = 'https://nominatim.openstreetmap.org/search',\n geocoderProvider,\n showShortcutHints = true,\n expandSelectionTools = false,\n showFilterTool = false,\n}: DrawingToolbarProps) {\n const { toast } = useToast();\n const [goToDialogOpen, setGoToDialogOpen] = useState(false);\n const [goToLat, setGoToLat] = useState('');\n const [goToLng, setGoToLng] = useState('');\n const [goToAddress, setGoToAddress] = useState('');\n const [isSearching, setIsSearching] = useState(false);\n const [filterActive, setFilterActive] = useState(false);\n const [isCompact, setIsCompact] = useState(false);\n const toolbarRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n onFilterActiveChange?.(filterActive);\n }, [filterActive, onFilterActiveChange]);\n const rafIdRef = useRef<number | null>(null);\n const isCompactRef = useRef(false);\n \n useEffect(() => {\n const HYSTERESIS_MARGIN = 20;\n const BOTTOM_MARGIN = 80;\n \n const checkOverflow = () => {\n if (rafIdRef.current !== null) {\n cancelAnimationFrame(rafIdRef.current);\n }\n \n rafIdRef.current = requestAnimationFrame(() => {\n if (!toolbarRef.current) return;\n \n const toolbar = toolbarRef.current;\n const toolbarRect = toolbar.getBoundingClientRect();\n const viewportHeight = window.innerHeight;\n \n const timeButton = toolbar.querySelector('[data-testid=\"button-timeline-toggle\"]');\n \n let toolbarBottom: number;\n if (isCompactRef.current) {\n const estimatedExpandedHeight = toolbarRect.height + 260;\n toolbarBottom = toolbarRect.top + estimatedExpandedHeight;\n } else {\n toolbarBottom = toolbarRect.bottom;\n }\n \n let threshold: number;\n if (timeButton) {\n const timeButtonRect = timeButton.getBoundingClientRect();\n threshold = timeButtonRect.top;\n } else {\n threshold = viewportHeight - BOTTOM_MARGIN;\n }\n \n let shouldBeCompact: boolean;\n if (isCompactRef.current) {\n shouldBeCompact = toolbarBottom > (threshold - HYSTERESIS_MARGIN);\n } else {\n shouldBeCompact = toolbarRect.bottom > threshold;\n }\n \n if (shouldBeCompact !== isCompactRef.current) {\n isCompactRef.current = shouldBeCompact;\n setIsCompact(shouldBeCompact);\n }\n });\n };\n \n checkOverflow();\n \n const resizeObserver = new ResizeObserver(() => {\n checkOverflow();\n });\n \n if (toolbarRef.current) {\n resizeObserver.observe(toolbarRef.current);\n }\n \n window.addEventListener('resize', checkOverflow);\n \n return () => {\n if (rafIdRef.current !== null) {\n cancelAnimationFrame(rafIdRef.current);\n }\n resizeObserver.disconnect();\n window.removeEventListener('resize', checkOverflow);\n };\n }, [isEditMode, enableMeasurement, enableSelection, selectionOnly]);\n \n const drawingDisabled = disabled || !hasVisibleLayers;\n \n const visibleSelectionModes = SELECTION_MODES.filter(\n mode => !hiddenSelectionTools.includes(mode.id)\n );\n \n const handleGoTo = () => {\n const lat = parseFloat(goToLat.trim());\n const lng = parseFloat(goToLng.trim());\n \n if (isNaN(lat) || isNaN(lng)) {\n toast({ title: 'Invalid coordinates', description: 'Please enter valid latitude and longitude values', variant: 'destructive' });\n return;\n }\n \n if (lat < -90 || lat > 90) {\n toast({ title: 'Invalid latitude', description: 'Latitude must be between -90 and 90', variant: 'destructive' });\n return;\n }\n \n if (lng < -180 || lng > 180) {\n toast({ title: 'Invalid longitude', description: 'Longitude must be between -180 and 180', variant: 'destructive' });\n return;\n }\n \n if (onDropPoint) {\n onDropPoint([lng, lat]);\n } else {\n onGoTo?.([lng, lat]);\n }\n setGoToDialogOpen(false);\n setGoToLat('');\n setGoToLng('');\n };\n\n const handleAddressSearch = async () => {\n if (!goToAddress.trim()) return;\n \n setIsSearching(true);\n try {\n let result: GeocoderResult | null = null;\n \n // Use geocoderProvider if available, otherwise fall back to URL-based geocoding\n if (geocoderProvider) {\n result = await geocoderProvider(goToAddress.trim());\n } else {\n const response = await fetch(\n `${geocodingUrl}?format=json&q=${encodeURIComponent(goToAddress)}&limit=1`\n );\n \n if (!response.ok) throw new Error('Search failed');\n \n const results = await response.json();\n \n if (results.length > 0) {\n const { lon, lat, display_name } = results[0];\n result = {\n lon: parseFloat(lon),\n lat: parseFloat(lat),\n displayName: display_name\n };\n }\n }\n \n if (!result) {\n toast({\n title: 'Location not found',\n description: 'Try a different search term',\n variant: 'destructive'\n });\n return;\n }\n \n const coords: [number, number] = [result.lon, result.lat];\n const shortName = result.displayName.split(',').slice(0, 2).join(',');\n \n if (onDropPoint) {\n onDropPoint(coords, shortName);\n } else {\n onGoTo?.(coords);\n }\n \n setGoToDialogOpen(false);\n setGoToAddress('');\n \n toast({\n title: 'Location found',\n description: shortName\n });\n } catch (error) {\n toast({\n title: 'Search error',\n description: 'Could not search for location. Check your connection.',\n variant: 'destructive'\n });\n } finally {\n setIsSearching(false);\n }\n };\n\n const handleClearAll = () => {\n Modal.confirm({\n title: 'Clear all features?',\n content: `This will remove all ${featureCount} feature${featureCount !== 1 ? 's' : ''} from the map. This action cannot be undone.`,\n okText: 'Clear all',\n okButtonProps: { danger: true },\n cancelText: 'Cancel',\n onOk: onClear,\n });\n };\n\n const getSelectionMenuItems = (): MenuProps['items'] => {\n const items: MenuProps['items'] = visibleSelectionModes.map((mode) => {\n const Icon = mode.icon;\n const isThisModeActive = isSelectionToolActive && selectionMode === mode.id;\n return {\n key: mode.id,\n label: (\n <span className=\"flex items-center gap-2\">\n <Icon className=\"w-4 h-4\" />\n {mode.label}\n </span>\n ),\n className: isThisModeActive ? 'bg-primary/10' : '',\n onClick: () => {\n if (isEditMode) {\n onToggleEditMode();\n }\n setFilterActive(false);\n if (selectionMode === mode.id && isSelectionToolActive) {\n onSelectionToolActiveChange?.(false);\n } else {\n onSelectionModeChange(mode.id);\n onSelectionToolActiveChange?.(true);\n }\n onModeChange('simple_select');\n },\n };\n });\n \n return items;\n };\n\n const getMoreMenuItems = (): MenuProps['items'] => {\n const items: MenuProps['items'] = [];\n \n if (!hiddenDrawingTools.includes('text')) {\n items.push({\n key: 'text',\n label: (\n <div className=\"flex items-center justify-between w-full\">\n <span className=\"flex items-center gap-2\">\n <Type className=\"w-4 h-4\" />\n Add Text\n </span>\n {showShortcutHints && <kbd className=\"px-1.5 py-0.5 text-xs font-mono bg-black/10 dark:bg-white/10 rounded\">T</kbd>}\n </div>\n ),\n disabled: drawingDisabled,\n className: activeMode === 'draw_text' ? 'bg-primary/10' : '',\n onClick: () => onModeChange(activeMode === 'draw_text' ? 'simple_select' : 'draw_text'),\n });\n }\n \n if (!hiddenDrawingTools.includes('arrow')) {\n items.push({\n key: 'arrow',\n label: (\n <div className=\"flex items-center justify-between w-full\">\n <span className=\"flex items-center gap-2\">\n <MoveRight className=\"w-4 h-4\" />\n Draw Arrow\n </span>\n {showShortcutHints && <kbd className=\"px-1.5 py-0.5 text-xs font-mono bg-black/10 dark:bg-white/10 rounded\">W</kbd>}\n </div>\n ),\n disabled: drawingDisabled,\n className: activeMode === 'draw_arrow' ? 'bg-primary/10' : '',\n onClick: () => onModeChange(activeMode === 'draw_arrow' ? 'simple_select' : 'draw_arrow'),\n });\n }\n \n if (!hiddenDrawingTools.includes('circle')) {\n items.push({\n key: 'circle',\n label: (\n <div className=\"flex items-center justify-between w-full\">\n <span className=\"flex items-center gap-2\">\n <Circle className=\"w-4 h-4\" />\n Draw Circle\n </span>\n {showShortcutHints && <kbd className=\"px-1.5 py-0.5 text-xs font-mono bg-black/10 dark:bg-white/10 rounded\">C</kbd>}\n </div>\n ),\n disabled: drawingDisabled,\n className: activeMode === 'draw_circle' ? 'bg-primary/10' : '',\n onClick: () => onModeChange(activeMode === 'draw_circle' ? 'simple_select' : 'draw_circle'),\n });\n }\n \n items.push({ type: 'divider' });\n \n items.push({\n key: 'undo',\n label: (\n <div className=\"flex items-center justify-between w-full\">\n <span className=\"flex items-center gap-2\">\n <Undo2 className=\"w-4 h-4\" />\n Undo\n </span>\n {showShortcutHints && <kbd className=\"px-1.5 py-0.5 text-xs font-mono bg-black/10 dark:bg-white/10 rounded\">Ctrl+Z</kbd>}\n </div>\n ),\n disabled: disabled || !canUndo,\n onClick: onUndo,\n });\n \n items.push({\n key: 'redo',\n label: (\n <div className=\"flex items-center justify-between w-full\">\n <span className=\"flex items-center gap-2\">\n <Redo2 className=\"w-4 h-4\" />\n Redo\n </span>\n {showShortcutHints && <kbd className=\"px-1.5 py-0.5 text-xs font-mono bg-black/10 dark:bg-white/10 rounded\">Ctrl+Y</kbd>}\n </div>\n ),\n disabled: disabled || !canRedo,\n onClick: onRedo,\n });\n \n items.push({ type: 'divider' });\n \n items.push({\n key: 'delete',\n label: (\n <div className=\"flex items-center justify-between w-full text-red-500\">\n <span className=\"flex items-center gap-2\">\n <X className=\"w-4 h-4\" />\n Delete selected ({selectedCount})\n </span>\n {showShortcutHints && <kbd className=\"px-1.5 py-0.5 text-xs font-mono bg-black/10 dark:bg-white/10 rounded\">Del</kbd>}\n </div>\n ),\n disabled: disabled || selectedCount === 0,\n onClick: onDeleteSelected,\n });\n \n items.push({\n key: 'clear',\n label: (\n <div className=\"flex items-center gap-2 text-red-500\">\n <Trash2 className=\"w-4 h-4\" />\n Clear all ({featureCount})\n </div>\n ),\n disabled: disabled || featureCount === 0,\n onClick: handleClearAll,\n });\n \n return items;\n };\n\n const compactOverflowItems = isEditMode && isCompact && !selectionOnly ? (\n <Tooltip title=\"More tools\" placement=\"right\">\n <Dropdown\n menu={{ items: getMoreMenuItems() }}\n trigger={['click']}\n placement=\"bottomRight\"\n >\n <Button\n type=\"text\"\n className=\"relative flex items-center justify-center !w-9 !h-9 !min-w-0 !p-0\"\n aria-label=\"More tools\"\n data-testid=\"button-more-tools\"\n icon={<MoreVertical className=\"w-5 h-5\" />}\n />\n </Dropdown>\n </Tooltip>\n ) : null;\n\n return (\n <div \n ref={toolbarRef}\n className=\"absolute top-4 left-4 z-10 flex flex-col gap-0.5 p-1 bg-background/80 floating-panel rounded-lg shadow-lg border border-border pl-[2px] pr-[2px] pt-[2px] pb-[2px]\"\n role=\"toolbar\"\n aria-label=\"Drawing tools\"\n data-testid=\"toolbar-drawing\"\n >\n {enableSelection && (\n <>\n {expandSelectionTools ? (\n <>\n {visibleSelectionModes.map((mode) => {\n const Icon = mode.icon;\n const isThisModeActive = isSelectionToolActive && selectionMode === mode.id;\n return (\n <Tooltip key={mode.id} title={mode.label} placement=\"right\">\n <Button\n type=\"text\"\n disabled={disabled}\n onClick={() => {\n if (isEditMode) onToggleEditMode();\n if (selectionMode === mode.id && isSelectionToolActive) {\n onSelectionToolActiveChange?.(false);\n } else {\n onSelectionModeChange(mode.id);\n onSelectionToolActiveChange?.(true);\n }\n onModeChange('simple_select');\n }}\n className={cn(\n \"relative transition-all duration-150 flex items-center justify-center !w-9 !h-9 !min-w-0 !p-0\",\n isThisModeActive && \"tool-active bg-primary/10\"\n )}\n aria-label={mode.label}\n data-testid={`button-select-${mode.id}`}\n icon={<Icon className=\"w-5 h-5\" />}\n />\n </Tooltip>\n );\n })}\n </>\n ) : (\n <div className=\"relative flex items-center\">\n <Tooltip title={`${selectionMode.charAt(0).toUpperCase() + selectionMode.slice(1)} Select`} placement=\"right\">\n <Button\n type=\"text\"\n disabled={disabled}\n onClick={() => {\n if (isEditMode) onToggleEditMode();\n if (isSelectionToolActive && !filterActive) {\n onSelectionToolActiveChange?.(false);\n } else {\n setFilterActive(false);\n onSelectionToolActiveChange?.(true);\n }\n onModeChange('simple_select');\n }}\n className={cn(\n \"relative transition-all duration-150 flex items-center justify-center !w-9 !h-9 !min-w-0 !p-0\",\n isSelectionToolActive && selectionMode !== 'click' && !filterActive && \"tool-active bg-primary/10\"\n )}\n aria-label=\"Select Tool\"\n data-testid=\"button-select-tool\"\n >\n {selectionMode === 'click' && <MousePointer2 className=\"w-5 h-5\" />}\n {selectionMode === 'rectangle' && <Square className=\"w-5 h-5\" />}\n {selectionMode === 'polygon' && <Hexagon className=\"w-5 h-5\" />}\n {selectionMode === 'circle' && <Circle className=\"w-5 h-5\" />}\n </Button>\n </Tooltip>\n <Dropdown\n menu={{ items: getSelectionMenuItems() }}\n trigger={['click']}\n placement=\"bottomRight\"\n >\n <button\n disabled={disabled}\n className=\"absolute -bottom-1 -right-1 w-4 h-4 flex items-center justify-center rounded-sm bg-background/80 hover:bg-accent cursor-pointer border-0 p-0\"\n aria-label=\"Switch selection mode\"\n data-testid=\"button-select-mode-switch\"\n onClick={(e) => e.stopPropagation()}\n >\n <ChevronDown className=\"w-3 h-3 opacity-70\" />\n </button>\n </Dropdown>\n </div>\n )}\n \n {showFilterTool && (\n <Tooltip title=\"Filter Area\" placement=\"right\">\n <Button\n type=\"text\"\n disabled={disabled}\n onClick={() => {\n if (isEditMode) onToggleEditMode();\n if (filterActive && isSelectionToolActive) {\n setFilterActive(false);\n onSelectionToolActiveChange?.(false);\n } else {\n setFilterActive(true);\n onSelectionModeChange('rectangle');\n onSelectionToolActiveChange?.(true);\n }\n onModeChange('simple_select');\n }}\n className={cn(\n \"relative transition-all duration-150 flex items-center justify-center !w-9 !h-9 !min-w-0 !p-0\",\n isSelectionToolActive && filterActive && \"tool-active bg-primary/10\"\n )}\n aria-label=\"Filter Area\"\n data-testid=\"button-filter-tool\"\n icon={<Filter className=\"w-5 h-5\" />}\n />\n </Tooltip>\n )}\n\n {showClearFilter && (\n <Tooltip title=\"Clear Filter\" placement=\"right\">\n <Button\n type=\"text\"\n onClick={onClearFilter}\n disabled={disabled}\n className=\"relative transition-all duration-150 text-red-500 hover:text-red-500 flex items-center justify-center !w-9 !h-9 !min-w-0 !p-0\"\n aria-label=\"Clear Filter\"\n data-testid=\"button-clear-filter-toolbar\"\n icon={<X className=\"w-5 h-5\" />}\n />\n </Tooltip>\n )}\n \n <Divider className=\"!my-0.5 !min-w-0\" />\n </>\n )}\n \n {enableMeasurement && (\n <>\n <Tooltip \n title={<span className=\"flex items-center gap-2\">Measure Distance<kbd className=\"px-1.5 py-0.5 text-xs font-mono bg-black/20 rounded\">M</kbd></span>} \n placement=\"right\"\n >\n <Button\n type=\"text\"\n onClick={() => onMeasureModeChange(measureMode === 'distance' ? 'none' : 'distance')}\n disabled={disabled}\n className={cn(\n \"relative transition-all duration-150 flex items-center justify-center !w-9 !h-9 !min-w-0 !p-0\",\n measureMode === 'distance' && \"tool-active bg-primary/10\"\n )}\n aria-label=\"Measure Distance\"\n aria-pressed={measureMode === 'distance'}\n data-testid=\"button-measure-distance\"\n icon={<Ruler className=\"w-5 h-5\" />}\n />\n </Tooltip>\n \n <Tooltip \n title={<span className=\"flex items-center gap-2\">Measure Area<kbd className=\"px-1.5 py-0.5 text-xs font-mono bg-black/20 rounded\">A</kbd></span>} \n placement=\"right\"\n >\n <Button\n type=\"text\"\n onClick={() => onMeasureModeChange(measureMode === 'area' ? 'none' : 'area')}\n disabled={disabled}\n className={cn(\n \"relative transition-all duration-150 flex items-center justify-center !w-9 !h-9 !min-w-0 !p-0\",\n measureMode === 'area' && \"tool-active bg-primary/10\"\n )}\n aria-label=\"Measure Area\"\n aria-pressed={measureMode === 'area'}\n data-testid=\"button-measure-area\"\n icon={<Move className=\"w-5 h-5\" />}\n />\n </Tooltip>\n\n <Divider className=\"!my-0.5 !min-w-0\" />\n </>\n )}\n\n {onGoTo && (\n <>\n <Tooltip \n title=\"Go To\" \n placement=\"right\"\n >\n <Button\n type=\"text\"\n onClick={() => setGoToDialogOpen(true)}\n disabled={disabled}\n className=\"relative transition-all duration-150 flex items-center justify-center !w-9 !h-9 !min-w-0 !p-0\"\n aria-label=\"Go To\"\n data-testid=\"button-goto-address\"\n icon={<Navigation className=\"w-5 h-5\" />}\n />\n </Tooltip>\n {!enableMeasurement && <Divider className=\"!my-0.5 !min-w-0\" />}\n </>\n )}\n \n {!selectionOnly && (\n <Tooltip \n title={\n !hasEditableLayer && !isEditMode ? (\n <div className=\"flex flex-col gap-1 max-w-48\">\n <span className=\"text-amber-500 font-medium\">No editable layer</span>\n <span className=\"text-xs\">Select an editable layer with the pencil icon to enable editing</span>\n </div>\n ) : showShortcutHints ? (\n <span className=\"flex items-center gap-2\">Edit Mode<kbd className=\"px-1.5 py-0.5 text-xs font-mono bg-black/20 rounded\">E</kbd></span>\n ) : (\n \"Edit Mode\"\n )\n } \n placement=\"right\"\n >\n <Button\n type=\"text\"\n onClick={onToggleEditMode}\n disabled={disabled || (!isEditMode && !hasEditableLayer)}\n className={cn(\n \"relative transition-all duration-150 flex items-center justify-center !w-9 !h-9 !min-w-0 !p-0\",\n isEditMode && \"tool-active bg-primary/10\"\n )}\n aria-label=\"Edit Mode\"\n aria-pressed={isEditMode}\n data-testid=\"button-edit-mode\"\n icon={<Pencil className=\"w-5 h-5\" />}\n />\n </Tooltip>\n )}\n \n {isEditMode && !selectionOnly && (\n <>\n <Divider className=\"!my-0.5 !min-w-0\" />\n \n {/* Database Search button - shown when search engine is available */}\n {onSearchEngineRequest && (\n <Tooltip title=\"Search Database\" placement=\"right\">\n <Button\n type=\"text\"\n onClick={onSearchEngineRequest}\n disabled={drawingDisabled}\n className=\"relative transition-all duration-150 flex items-center justify-center !w-9 !h-9 !min-w-0 !p-0\"\n aria-label=\"Search Database\"\n data-testid=\"button-search-database\"\n icon={\n <div className=\"relative w-5 h-5\">\n <Database className=\"w-5 h-5\" />\n <Search className=\"w-3 h-3 absolute -bottom-0.5 right-[-4px] stroke-[2.5]\" />\n </div>\n }\n />\n </Tooltip>\n )}\n \n {/* Drop Point button */}\n {!hiddenDrawingTools.includes('point') && (\n <ToolButton\n mode=\"draw_point\"\n activeMode={activeMode}\n onModeChange={onModeChange}\n icon={<MapPin className=\"w-5 h-5\" />}\n label=\"Drop Point\"\n shortcut=\"P\"\n disabled={drawingDisabled}\n showShortcutHint={showShortcutHints}\n />\n )}\n \n {!hiddenDrawingTools.includes('line') && (\n <ToolButton\n mode=\"draw_line_string\"\n activeMode={activeMode}\n onModeChange={onModeChange}\n icon={<Minus className=\"w-5 h-5\" />}\n label=\"Draw Line\"\n shortcut=\"L\"\n disabled={drawingDisabled}\n showShortcutHint={showShortcutHints}\n />\n )}\n \n {!hiddenDrawingTools.includes('polygon') && (\n <Dropdown\n menu={{\n items: [\n {\n key: 'polygon',\n label: (\n <span className=\"flex items-center gap-2\">\n <Pentagon className=\"w-4 h-4\" />\n Draw Polygon\n {showShortcutHints && <kbd className=\"ml-auto px-1.5 py-0.5 text-xs font-mono bg-black/10 dark:bg-white/10 rounded\">G</kbd>}\n </span>\n ),\n onClick: () => onModeChange('draw_polygon'),\n },\n {\n key: 'rectangle',\n label: (\n <span className=\"flex items-center gap-2\">\n <Square className=\"w-4 h-4\" />\n Draw Rectangle\n {showShortcutHints && <kbd className=\"ml-auto px-1.5 py-0.5 text-xs font-mono bg-black/10 dark:bg-white/10 rounded\">B</kbd>}\n </span>\n ),\n onClick: () => onModeChange('draw_rectangle'),\n },\n ],\n }}\n trigger={['click']}\n placement=\"bottomRight\"\n disabled={drawingDisabled}\n >\n <Tooltip \n title={showShortcutHints\n ? <span className=\"flex items-center gap-2\">Draw Polygon/Rectangle<kbd className=\"px-1.5 py-0.5 text-xs font-mono bg-black/20 rounded\">G</kbd></span>\n : \"Draw Polygon/Rectangle\"\n } \n placement=\"right\"\n >\n <Button\n type=\"text\"\n disabled={drawingDisabled}\n className={cn(\n \"relative transition-all duration-150 flex items-center justify-center !w-9 !h-9 !min-w-0 !p-0\",\n (activeMode === 'draw_polygon' || activeMode === 'draw_rectangle') && \"tool-active bg-primary/10\"\n )}\n aria-label=\"Draw Polygon or Rectangle\"\n data-testid=\"button-tool-polygon-menu\"\n icon={\n <div className=\"relative\">\n {activeMode === 'draw_rectangle' ? <Square className=\"w-5 h-5\" /> : <Pentagon className=\"w-5 h-5\" />}\n <ChevronDown className=\"w-2.5 h-2.5 absolute -bottom-0.5 -right-1\" />\n </div>\n }\n />\n </Tooltip>\n </Dropdown>\n )}\n \n {!isCompact && (\n <>\n <Divider className=\"!my-0.5 !min-w-0\" />\n \n {!hiddenDrawingTools.includes('text') && (\n <ToolButton\n mode=\"draw_text\"\n activeMode={activeMode}\n onModeChange={onModeChange}\n icon={<Type className=\"w-5 h-5\" />}\n label=\"Add Text\"\n shortcut=\"T\"\n disabled={drawingDisabled}\n showShortcutHint={showShortcutHints}\n />\n )}\n \n {!hiddenDrawingTools.includes('arrow') && (\n <ToolButton\n mode=\"draw_arrow\"\n activeMode={activeMode}\n onModeChange={onModeChange}\n icon={<MoveRight className=\"w-5 h-5\" />}\n label=\"Draw Arrow\"\n shortcut=\"W\"\n disabled={drawingDisabled}\n showShortcutHint={showShortcutHints}\n />\n )}\n \n {!hiddenDrawingTools.includes('circle') && (\n <ToolButton\n mode=\"draw_circle\"\n activeMode={activeMode}\n onModeChange={onModeChange}\n icon={<Circle className=\"w-5 h-5\" />}\n label=\"Draw Circle\"\n shortcut=\"C\"\n disabled={drawingDisabled}\n showShortcutHint={showShortcutHints}\n />\n )}\n \n <Divider className=\"!my-0.5 !min-w-0\" />\n \n <Tooltip \n title={showShortcutHints\n ? <span className=\"flex items-center gap-2\">Undo<kbd className=\"px-1.5 py-0.5 text-xs font-mono bg-black/20 rounded\">Ctrl+Z</kbd></span>\n : \"Undo\"\n } \n placement=\"right\"\n >\n <Button\n type=\"text\"\n onClick={onUndo}\n disabled={disabled || !canUndo}\n aria-label=\"Undo\"\n data-testid=\"button-undo\"\n className=\"flex items-center justify-center !w-9 !h-9 !min-w-0 !p-0\"\n icon={<Undo2 className=\"w-5 h-5\" />}\n />\n </Tooltip>\n \n <Tooltip \n title={showShortcutHints\n ? <span className=\"flex items-center gap-2\">Redo<kbd className=\"px-1.5 py-0.5 text-xs font-mono bg-black/20 rounded\">Ctrl+Y</kbd></span>\n : \"Redo\"\n } \n placement=\"right\"\n >\n <Button\n type=\"text\"\n onClick={onRedo}\n disabled={disabled || !canRedo}\n aria-label=\"Redo\"\n data-testid=\"button-redo\"\n className=\"flex items-center justify-center !w-9 !h-9 !min-w-0 !p-0\"\n icon={<Redo2 className=\"w-5 h-5\" />}\n />\n </Tooltip>\n \n <Tooltip \n title={showShortcutHints\n ? <span className=\"flex items-center gap-2\">Delete selected ({selectedCount})<kbd className=\"px-1.5 py-0.5 text-xs font-mono bg-black/20 rounded\">Del</kbd></span>\n : `Delete selected (${selectedCount})`\n } \n placement=\"right\"\n >\n <Button\n type=\"text\"\n onClick={onDeleteSelected}\n disabled={disabled || selectedCount === 0}\n className=\"text-red-500 hover:text-red-500 flex items-center justify-center !w-9 !h-9 !min-w-0 !p-0\"\n aria-label=\"Delete selected features\"\n data-testid=\"button-delete-selected\"\n icon={<X className=\"w-5 h-5\" />}\n />\n </Tooltip>\n \n <Tooltip title=\"Clear all features\" placement=\"right\">\n <Button\n type=\"text\"\n onClick={handleClearAll}\n disabled={disabled || featureCount === 0}\n className=\"text-red-500 hover:text-red-500 flex items-center justify-center !w-9 !h-9 !min-w-0 !p-0\"\n aria-label=\"Clear all features\"\n data-testid=\"button-clear-all\"\n icon={<Trash2 className=\"w-5 h-5\" />}\n />\n </Tooltip>\n </>\n )}\n \n {compactOverflowItems}\n </>\n )}\n \n <Modal\n open={goToDialogOpen}\n onCancel={() => setGoToDialogOpen(false)}\n title={onDropPoint ? \"Drop Point at Location\" : \"Go To Location\"}\n footer={null}\n width={400}\n >\n <Tabs\n defaultActiveKey=\"address\"\n items={[\n {\n key: 'address',\n label: 'Search Address',\n children: (\n <div className=\"space-y-4 pt-2\">\n <p className=\"text-muted-foreground text-sm\">\n Search for a place to {onDropPoint ? 'drop a point there' : 'navigate there'}.\n </p>\n <div className=\"flex gap-2\">\n <Input\n placeholder=\"e.g. Paris, France or 123 Main St\"\n value={goToAddress}\n onChange={(e) => setGoToAddress(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleAddressSearch();\n }}\n disabled={isSearching}\n data-testid=\"input-goto-address\"\n />\n <Button\n type=\"primary\"\n onClick={handleAddressSearch}\n disabled={isSearching || !goToAddress.trim()}\n data-testid=\"button-search-address\"\n icon={isSearching ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <Search className=\"w-4 h-4\" />}\n />\n </div>\n </div>\n ),\n },\n {\n key: 'coordinates',\n label: 'Coordinates',\n children: (\n <div className=\"space-y-4 pt-2\">\n <p className=\"text-muted-foreground text-sm\">\n Enter coordinates to {onDropPoint ? 'drop a point' : 'navigate'} to a specific location.\n </p>\n <div className=\"grid grid-cols-2 gap-3\">\n <div className=\"space-y-2\">\n <label htmlFor=\"goto-lat\" className=\"text-sm font-medium\">Latitude</label>\n <Input\n id=\"goto-lat\"\n type=\"number\"\n step=\"any\"\n placeholder=\"-90 to 90\"\n value={goToLat}\n onChange={(e) => setGoToLat(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleGoTo();\n }}\n data-testid=\"input-goto-lat\"\n />\n </div>\n <div className=\"space-y-2\">\n <label htmlFor=\"goto-lng\" className=\"text-sm font-medium\">Longitude</label>\n <Input\n id=\"goto-lng\"\n type=\"number\"\n step=\"any\"\n placeholder=\"-180 to 180\"\n value={goToLng}\n onChange={(e) => setGoToLng(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleGoTo();\n }}\n data-testid=\"input-goto-lng\"\n />\n </div>\n </div>\n <div className=\"flex justify-end gap-2 pt-2\">\n <Button onClick={() => setGoToDialogOpen(false)} data-testid=\"button-goto-cancel\">\n Cancel\n </Button>\n <Button type=\"primary\" onClick={handleGoTo} data-testid=\"button-goto-navigate\">\n {onDropPoint ? 'Drop Point' : 'Go To'}\n </Button>\n </div>\n </div>\n ),\n },\n ]}\n />\n </Modal>\n </div>\n );\n}\n","import { Button, Popover, Input } from 'antd';\n\nconst PRESET_COLORS = [\n '#3b82f6', \n '#ef4444', \n '#22c55e', \n '#f59e0b', \n '#8b5cf6', \n '#06b6d4', \n '#ec4899', \n '#6366f1', \n '#14b8a6', \n '#f97316', \n];\n\ninterface ColorPickerPopoverProps {\n value: string;\n onChange: (color: string) => void;\n testId?: string;\n}\n\nexport function ColorPickerPopover({ value, onChange, testId }: ColorPickerPopoverProps) {\n const popoverContent = (\n <div>\n <div className=\"grid grid-cols-5 gap-1\">\n {PRESET_COLORS.map((color) => (\n <button\n key={color}\n type=\"button\"\n className=\"w-6 h-6 rounded-sm border border-border hover:scale-110 transition-transform\"\n style={{ backgroundColor: color }}\n onClick={() => onChange(color)}\n data-testid={testId ? `button-${testId}-${color.replace('#', '')}` : undefined}\n />\n ))}\n </div>\n <div className=\"mt-2 flex items-center gap-2\">\n <input\n type=\"color\"\n value={value}\n onChange={(e) => onChange(e.target.value)}\n className=\"h-7 w-10 p-0 border-0 cursor-pointer\"\n data-testid={testId ? `input-${testId}-picker` : undefined}\n />\n <Input\n type=\"text\"\n value={value}\n onChange={(e) => onChange(e.target.value)}\n className=\"!h-7 flex-1 text-xs font-mono\"\n data-testid={testId ? `input-${testId}` : undefined}\n />\n </div>\n </div>\n );\n\n return (\n <Popover \n content={popoverContent} \n trigger=\"click\"\n placement=\"bottomLeft\"\n overlayClassName=\"z-[10001]\"\n >\n <Button \n type=\"default\"\n size=\"small\"\n className=\"!h-7 !w-16 !p-1\"\n data-testid={testId ? `button-${testId}` : undefined}\n >\n <span \n className=\"w-full h-full rounded-sm block\"\n style={{ backgroundColor: value }}\n />\n </Button>\n </Popover>\n );\n}\n\nexport { PRESET_COLORS };\n","import { useState, useMemo, useCallback } from 'react';\nimport { Button, Modal, Input } from 'antd';\nimport { \n MapPin, Home, Building2, Store, Factory, Warehouse, Church,\n Hospital, School, GraduationCap, Library, Landmark, Castle,\n Car, Bus, Train, Plane, Ship, Bike, Fuel,\n Utensils, Coffee, Beer, Wine, Pizza, IceCream,\n Trees, Mountain, Waves, Sun, Cloud, Umbrella,\n Heart, Star, Flag, AlertTriangle, Info, HelpCircle,\n Camera, Music, Film, Gamepad2, Trophy, Medal,\n Briefcase, Wrench, Hammer, Scissors, Paintbrush, Palette,\n ShoppingCart, Gift, Package, CreditCard, Wallet,\n Phone, Mail, Globe, Wifi, Radio, Tv,\n User, Users, Baby, Dog, Cat, Bird,\n Flower2, Leaf, Apple, Carrot, Egg,\n Tent, Compass, Anchor, Navigation,\n CrossIcon, PlusCircle, MinusCircle, CheckCircle, XCircle,\n Clock, Calendar, Bookmark, Tag, Zap, Flame,\n Lock, Key, Shield, Eye, Search,\n Circle, Square, Triangle, Hexagon, Octagon, Pentagon,\n ArrowUp, ArrowDown, ArrowLeft, ArrowRight,\n type LucideIcon\n} from 'lucide-react';\n\ninterface IconDef {\n id: string;\n name: string;\n icon: LucideIcon;\n category: string;\n}\n\nconst ICONS: IconDef[] = [\n // Location & Places\n { id: 'map-pin', name: 'Map Pin', icon: MapPin, category: 'places' },\n { id: 'home', name: 'Home', icon: Home, category: 'places' },\n { id: 'building', name: 'Building', icon: Building2, category: 'places' },\n { id: 'store', name: 'Store', icon: Store, category: 'places' },\n { id: 'factory', name: 'Factory', icon: Factory, category: 'places' },\n { id: 'warehouse', name: 'Warehouse', icon: Warehouse, category: 'places' },\n { id: 'church', name: 'Church', icon: Church, category: 'places' },\n { id: 'hospital', name: 'Hospital', icon: Hospital, category: 'places' },\n { id: 'school', name: 'School', icon: School, category: 'places' },\n { id: 'graduation', name: 'University', icon: GraduationCap, category: 'places' },\n { id: 'library', name: 'Library', icon: Library, category: 'places' },\n { id: 'landmark', name: 'Landmark', icon: Landmark, category: 'places' },\n { id: 'castle', name: 'Castle', icon: Castle, category: 'places' },\n \n // Transport\n { id: 'car', name: 'Car', icon: Car, category: 'transport' },\n { id: 'bus', name: 'Bus', icon: Bus, category: 'transport' },\n { id: 'train', name: 'Train', icon: Train, category: 'transport' },\n { id: 'plane', name: 'Plane', icon: Plane, category: 'transport' },\n { id: 'ship', name: 'Ship', icon: Ship, category: 'transport' },\n { id: 'bike', name: 'Bike', icon: Bike, category: 'transport' },\n { id: 'fuel', name: 'Gas Station', icon: Fuel, category: 'transport' },\n \n // Food & Drink\n { id: 'utensils', name: 'Restaurant', icon: Utensils, category: 'food' },\n { id: 'coffee', name: 'Coffee', icon: Coffee, category: 'food' },\n { id: 'beer', name: 'Bar', icon: Beer, category: 'food' },\n { id: 'wine', name: 'Wine', icon: Wine, category: 'food' },\n { id: 'pizza', name: 'Pizza', icon: Pizza, category: 'food' },\n { id: 'ice-cream', name: 'Ice Cream', icon: IceCream, category: 'food' },\n \n // Nature\n { id: 'trees', name: 'Forest', icon: Trees, category: 'nature' },\n { id: 'mountain', name: 'Mountain', icon: Mountain, category: 'nature' },\n { id: 'waves', name: 'Water', icon: Waves, category: 'nature' },\n { id: 'sun', name: 'Sun', icon: Sun, category: 'nature' },\n { id: 'cloud', name: 'Cloud', icon: Cloud, category: 'nature' },\n { id: 'umbrella', name: 'Umbrella', icon: Umbrella, category: 'nature' },\n { id: 'flower', name: 'Flower', icon: Flower2, category: 'nature' },\n { id: 'leaf', name: 'Leaf', icon: Leaf, category: 'nature' },\n \n // Symbols\n { id: 'heart', name: 'Heart', icon: Heart, category: 'symbols' },\n { id: 'star', name: 'Star', icon: Star, category: 'symbols' },\n { id: 'flag', name: 'Flag', icon: Flag, category: 'symbols' },\n { id: 'alert', name: 'Warning', icon: AlertTriangle, category: 'symbols' },\n { id: 'info', name: 'Info', icon: Info, category: 'symbols' },\n { id: 'help', name: 'Help', icon: HelpCircle, category: 'symbols' },\n { id: 'check', name: 'Check', icon: CheckCircle, category: 'symbols' },\n { id: 'x', name: 'X', icon: XCircle, category: 'symbols' },\n { id: 'plus', name: 'Plus', icon: PlusCircle, category: 'symbols' },\n { id: 'minus', name: 'Minus', icon: MinusCircle, category: 'symbols' },\n { id: 'zap', name: 'Zap', icon: Zap, category: 'symbols' },\n { id: 'flame', name: 'Flame', icon: Flame, category: 'symbols' },\n \n // Activities\n { id: 'camera', name: 'Camera', icon: Camera, category: 'activities' },\n { id: 'music', name: 'Music', icon: Music, category: 'activities' },\n { id: 'film', name: 'Cinema', icon: Film, category: 'activities' },\n { id: 'gamepad', name: 'Gaming', icon: Gamepad2, category: 'activities' },\n { id: 'trophy', name: 'Trophy', icon: Trophy, category: 'activities' },\n { id: 'medal', name: 'Medal', icon: Medal, category: 'activities' },\n { id: 'tent', name: 'Camping', icon: Tent, category: 'activities' },\n { id: 'compass', name: 'Compass', icon: Compass, category: 'activities' },\n \n // Work & Tools\n { id: 'briefcase', name: 'Office', icon: Briefcase, category: 'work' },\n { id: 'wrench', name: 'Repair', icon: Wrench, category: 'work' },\n { id: 'hammer', name: 'Construction', icon: Hammer, category: 'work' },\n { id: 'scissors', name: 'Scissors', icon: Scissors, category: 'work' },\n { id: 'paintbrush', name: 'Art', icon: Paintbrush, category: 'work' },\n { id: 'palette', name: 'Palette', icon: Palette, category: 'work' },\n \n // Shopping\n { id: 'cart', name: 'Shopping', icon: ShoppingCart, category: 'shopping' },\n { id: 'gift', name: 'Gift', icon: Gift, category: 'shopping' },\n { id: 'package', name: 'Package', icon: Package, category: 'shopping' },\n { id: 'credit-card', name: 'Payment', icon: CreditCard, category: 'shopping' },\n { id: 'wallet', name: 'Wallet', icon: Wallet, category: 'shopping' },\n \n // Communication\n { id: 'phone', name: 'Phone', icon: Phone, category: 'communication' },\n { id: 'mail', name: 'Mail', icon: Mail, category: 'communication' },\n { id: 'globe', name: 'Web', icon: Globe, category: 'communication' },\n { id: 'wifi', name: 'WiFi', icon: Wifi, category: 'communication' },\n { id: 'radio', name: 'Radio', icon: Radio, category: 'communication' },\n { id: 'tv', name: 'TV', icon: Tv, category: 'communication' },\n \n // People & Animals\n { id: 'user', name: 'Person', icon: User, category: 'people' },\n { id: 'users', name: 'Group', icon: Users, category: 'people' },\n { id: 'baby', name: 'Baby', icon: Baby, category: 'people' },\n { id: 'dog', name: 'Dog', icon: Dog, category: 'people' },\n { id: 'cat', name: 'Cat', icon: Cat, category: 'people' },\n { id: 'bird', name: 'Bird', icon: Bird, category: 'people' },\n \n // Food Items\n { id: 'apple', name: 'Apple', icon: Apple, category: 'food' },\n { id: 'carrot', name: 'Carrot', icon: Carrot, category: 'food' },\n { id: 'egg', name: 'Egg', icon: Egg, category: 'food' },\n \n // Maritime\n { id: 'anchor', name: 'Anchor', icon: Anchor, category: 'maritime' },\n { id: 'navigation', name: 'Navigation', icon: Navigation, category: 'maritime' },\n \n // Security\n { id: 'lock', name: 'Lock', icon: Lock, category: 'security' },\n { id: 'key', name: 'Key', icon: Key, category: 'security' },\n { id: 'shield', name: 'Shield', icon: Shield, category: 'security' },\n { id: 'eye', name: 'Eye', icon: Eye, category: 'security' },\n { id: 'search', name: 'Search', icon: Search, category: 'security' },\n \n // Time\n { id: 'clock', name: 'Clock', icon: Clock, category: 'time' },\n { id: 'calendar', name: 'Calendar', icon: Calendar, category: 'time' },\n { id: 'bookmark', name: 'Bookmark', icon: Bookmark, category: 'time' },\n { id: 'tag', name: 'Tag', icon: Tag, category: 'time' },\n \n // Shapes\n { id: 'circle', name: 'Circle', icon: Circle, category: 'shapes' },\n { id: 'square', name: 'Square', icon: Square, category: 'shapes' },\n { id: 'triangle', name: 'Triangle', icon: Triangle, category: 'shapes' },\n { id: 'hexagon', name: 'Hexagon', icon: Hexagon, category: 'shapes' },\n { id: 'octagon', name: 'Octagon', icon: Octagon, category: 'shapes' },\n { id: 'pentagon', name: 'Pentagon', icon: Pentagon, category: 'shapes' },\n \n // Arrows\n { id: 'arrow-up', name: 'Arrow Up', icon: ArrowUp, category: 'arrows' },\n { id: 'arrow-down', name: 'Arrow Down', icon: ArrowDown, category: 'arrows' },\n { id: 'arrow-left', name: 'Arrow Left', icon: ArrowLeft, category: 'arrows' },\n { id: 'arrow-right', name: 'Arrow Right', icon: ArrowRight, category: 'arrows' },\n];\n\nconst CATEGORIES = [\n { id: 'places', label: 'Places' },\n { id: 'transport', label: 'Transport' },\n { id: 'food', label: 'Food' },\n { id: 'nature', label: 'Nature' },\n { id: 'symbols', label: 'Symbols' },\n { id: 'activities', label: 'Activities' },\n { id: 'work', label: 'Work' },\n { id: 'shopping', label: 'Shopping' },\n { id: 'communication', label: 'Communication' },\n { id: 'people', label: 'People' },\n { id: 'maritime', label: 'Maritime' },\n { id: 'security', label: 'Security' },\n { id: 'time', label: 'Time' },\n { id: 'shapes', label: 'Shapes' },\n { id: 'arrows', label: 'Arrows' },\n];\n\n// Map of icon IDs to their components for rendering on the map\nconst ICON_MAP = new Map<string, LucideIcon>(ICONS.map(i => [i.id, i.icon]));\n\ninterface IconPickerProps {\n value: string;\n onChange: (icon: string) => void;\n disabled?: boolean;\n}\n\nexport function IconPicker({ value, onChange, disabled = false }: IconPickerProps) {\n const [open, setOpen] = useState(false);\n const [search, setSearch] = useState('');\n const [activeCategory, setActiveCategory] = useState<string | null>(null);\n\n const filteredIcons = useMemo(() => {\n let result = ICONS;\n \n if (activeCategory) {\n result = result.filter(i => i.category === activeCategory);\n }\n \n if (search.trim()) {\n const searchLower = search.toLowerCase().trim();\n result = result.filter(i => \n i.name.toLowerCase().includes(searchLower) ||\n i.id.toLowerCase().includes(searchLower) ||\n i.category.toLowerCase().includes(searchLower)\n );\n }\n \n return result;\n }, [activeCategory, search]);\n\n const handleSelect = useCallback((iconId: string) => {\n onChange(iconId);\n setOpen(false);\n }, [onChange]);\n\n const selectedIcon = useMemo(() => {\n return ICONS.find(i => i.id === value);\n }, [value]);\n\n const SelectedIconComponent = selectedIcon?.icon;\n\n return (\n <>\n <Button\n type=\"default\"\n size=\"small\"\n disabled={disabled}\n onClick={() => setOpen(true)}\n className=\"!w-10 !h-8 !p-0 overflow-hidden\"\n data-testid=\"button-icon-picker\"\n >\n {SelectedIconComponent ? (\n <SelectedIconComponent className=\"w-5 h-5\" />\n ) : (\n <MapPin className=\"w-4 h-4 text-muted-foreground\" />\n )}\n </Button>\n \n <Modal\n open={open}\n onCancel={() => setOpen(false)}\n title=\"Select Icon\"\n footer={null}\n width={600}\n className=\"icon-picker-modal\"\n styles={{ body: { maxHeight: '70vh', display: 'flex', flexDirection: 'column', padding: 0 } }}\n data-testid=\"dialog-icon-picker\"\n >\n <div className=\"px-4 pb-2 space-y-2 shrink-0 pt-2\">\n <Input\n placeholder=\"Search icons...\"\n value={search}\n onChange={(e) => {\n setSearch(e.target.value);\n if (e.target.value) setActiveCategory(null);\n }}\n className=\"h-9\"\n data-testid=\"input-icon-search\"\n autoFocus\n />\n \n <div className=\"overflow-x-auto whitespace-nowrap\">\n <div className=\"flex gap-1 pb-2\">\n <Button\n type={activeCategory === null && !search ? \"primary\" : \"text\"}\n size=\"small\"\n className=\"!h-7 text-xs !px-3 shrink-0\"\n onClick={() => { setActiveCategory(null); setSearch(''); }}\n data-testid=\"button-category-all\"\n >\n All ({ICONS.length})\n </Button>\n {CATEGORIES.map(cat => {\n const count = ICONS.filter(i => i.category === cat.id).length;\n return (\n <Button\n key={cat.id}\n type={activeCategory === cat.id ? \"primary\" : \"text\"}\n size=\"small\"\n className=\"!h-7 text-xs !px-3 shrink-0\"\n onClick={() => { setActiveCategory(cat.id); setSearch(''); }}\n data-testid={`button-category-${cat.id}`}\n >\n {cat.label} ({count})\n </Button>\n );\n })}\n </div>\n </div>\n </div>\n \n <div \n className=\"flex-1 overflow-y-auto px-4 pb-4 min-h-0\"\n style={{ maxHeight: '400px' }}\n >\n <div className=\"grid grid-cols-8 sm:grid-cols-10 md:grid-cols-12 gap-1\">\n {filteredIcons.map((iconDef) => {\n const IconComponent = iconDef.icon;\n return (\n <Button\n key={iconDef.id}\n type={value === iconDef.id ? \"primary\" : \"text\"}\n size=\"small\"\n className=\"!w-10 !h-10 !p-1\"\n onClick={() => handleSelect(iconDef.id)}\n title={iconDef.name}\n data-testid={`button-icon-${iconDef.id}`}\n >\n <IconComponent className=\"w-5 h-5\" />\n </Button>\n );\n })}\n </div>\n {filteredIcons.length === 0 && (\n <div className=\"text-center text-muted-foreground text-sm py-12\">\n No icons found for \"{search}\"\n </div>\n )}\n </div>\n \n <div className=\"px-4 py-3 border-t shrink-0 flex items-center justify-between gap-2\">\n {selectedIcon ? (\n <div className=\"flex items-center gap-2 text-sm text-muted-foreground min-w-0\">\n {SelectedIconComponent && <SelectedIconComponent className=\"w-5 h-5 shrink-0\" />}\n <span className=\"truncate\">{selectedIcon.name}</span>\n </div>\n ) : (\n <span className=\"text-sm text-muted-foreground\">No icon selected</span>\n )}\n <div className=\"flex gap-2 shrink-0\">\n {value && (\n <Button\n type=\"default\"\n size=\"small\"\n onClick={() => { onChange(''); setOpen(false); }}\n data-testid=\"button-clear-icon\"\n >\n Clear\n </Button>\n )}\n <Button\n type=\"text\"\n size=\"small\"\n onClick={() => setOpen(false)}\n data-testid=\"button-close-icon-picker\"\n >\n Cancel\n </Button>\n </div>\n </div>\n </Modal>\n </>\n );\n}\n\n// Export utilities for rendering icons on the map\nexport function getIconComponent(iconId: string): LucideIcon | null {\n return ICON_MAP.get(iconId) || null;\n}\n\nexport function isValidIconId(value: string): boolean {\n return ICON_MAP.has(value);\n}\n\nexport { ICONS, ICON_MAP };\nexport type { IconDef };\n","import { useState, useCallback } from 'react';\nimport { Layers, Eye, EyeOff, Plus, Trash2, ChevronDown, ChevronRight, Pencil, MoreHorizontal, Download, Upload, Map, Satellite, Focus, Type, Lock, FolderOpen, Smile, Box, Database, Search } from 'lucide-react';\nimport { Button, Input, Divider, Dropdown, Modal, Select, Switch, Slider, Tooltip, Tag } from 'antd';\nimport { ColorPickerPopover } from '@/components/color-picker-popover';\nimport { IconPicker } from '@/components/icon-picker';\n\nexport type BuiltInMapStyle = 'streets' | 'satellite' | 'dark';\nexport type MapStyle = BuiltInMapStyle | (string & {});\n\nexport const MAP_STYLES: { id: MapStyle; name: string; icon: typeof Map }[] = [\n { id: 'streets', name: 'Streets', icon: Map },\n { id: 'satellite', name: 'Satellite', icon: Satellite },\n { id: 'dark', name: 'Dark', icon: Map },\n];\n\nexport interface TraceConfig {\n enabled: boolean;\n groupByField: string | null;\n}\n\nexport interface HeatmapConfig {\n enabled: boolean;\n intensity: number;\n radius: number;\n hideFeatures?: boolean;\n}\n\nexport interface ClusterConfig {\n enabled: boolean;\n groupByField: string | null;\n showPointDots?: boolean;\n}\n\nexport type LabelMode = 'standard' | 'field' | 'fixed';\nexport type SizeMode = 'standard' | 'field' | 'override';\nexport type ColorMode = 'standard' | 'field' | 'fixed';\n\nexport interface LabelConfig {\n mode: LabelMode;\n fieldName?: string;\n fixedText?: string;\n}\n\nexport interface SizeConfig {\n mode: SizeMode;\n fieldName?: string;\n overrideValue?: number;\n}\n\nexport interface ColorConfig {\n mode: ColorMode;\n fieldName?: string;\n fixedColor?: string;\n}\n\nexport interface IconConfig {\n enabled: boolean;\n icon: string;\n size: number;\n}\n\nexport interface VisualConfig {\n label?: LabelConfig;\n size?: SizeConfig;\n color?: ColorConfig;\n icon?: IconConfig;\n}\n\nexport type AltitudeDisplayMode = '3d' | 'flat' | 'both';\n\nexport interface Layer {\n id: string;\n name: string;\n visible: boolean;\n featureIds: string[];\n readOnly?: boolean;\n traceConfig?: TraceConfig;\n heatmapConfig?: HeatmapConfig;\n clusterConfig?: ClusterConfig;\n visualConfig?: VisualConfig;\n altitudeDisplayMode?: AltitudeDisplayMode;\n hasAltitudeData?: boolean;\n}\n\nexport interface AutoLabelConfig {\n enabled: boolean;\n threshold: number;\n}\n\ninterface LayersPanelProps {\n layers: Layer[];\n onAddLayer: (name: string) => void;\n onRemoveLayer: (layerId: string) => void;\n onRenameLayer: (layerId: string, name: string) => void;\n onToggleLayerVisibility: (layerId: string) => void;\n onMoveFeatureToLayer: (featureId: string, layerId: string) => void;\n selectedFeatureIds: string[];\n getFeatureCount: (layerId: string) => number;\n /** Get count of unsaved features in a layer (for displaying unsaved badge) */\n getLayerUnsavedCount?: (layerId: string) => number;\n /** Get total count of unsaved features across all layers (for map-level indicator) */\n getMapUnsavedCount?: () => number;\n activeEditingLayerId: string;\n onSetActiveEditingLayer: (layerId: string) => void;\n onSaveLayerGeoJSON: (layerId: string) => void;\n onLoadLayerGeoJSON: (layerId: string) => void;\n onLoadNewLayerGeoJSON: () => void;\n onSaveAllGeoJSON: () => void;\n onSearchAndAddToNewLayer?: () => Promise<void>;\n onWorkspaceLoad?: (layerId: string) => Promise<void>;\n onWorkspaceSave?: (layerId: string) => Promise<void>;\n onFitToFeatures?: () => void;\n onFitToLayerFeatures?: (layerId: string) => void;\n currentMapStyle: MapStyle;\n onMapStyleChange: (style: MapStyle) => void;\n onUpdateTraceConfig: (layerId: string, config: TraceConfig) => void;\n getAvailableTraceFields: (layerId: string) => string[];\n getLayerFields?: (layerId: string) => { name: string; isNumeric: boolean }[];\n onUpdateHeatmapConfig?: (layerId: string, config: HeatmapConfig) => void;\n onUpdateClusterConfig?: (layerId: string, config: ClusterConfig) => void;\n onUpdateVisualConfig?: (layerId: string, config: VisualConfig) => void;\n hasPointFeatures?: (layerId: string) => boolean;\n autoLabelConfig?: AutoLabelConfig;\n onUpdateAutoLabelConfig?: (config: AutoLabelConfig) => void;\n visibleFeatureCount?: number;\n is3DTerrainEnabled?: boolean;\n onToggle3DTerrain?: () => void;\n onUpdateAltitudeDisplayMode?: (layerId: string, mode: AltitudeDisplayMode) => void;\n /** Hide satellite basemap option (for air-gapped deployments) */\n hideSatellite?: boolean;\n /** Hide terrain basemap and 3D toggle (for air-gapped deployments) */\n hideTerrain?: boolean;\n /** Hide the entire basemap style switcher (for air-gapped deployments with only a local tile server) */\n hideBasemapSwitcher?: boolean;\n /** When true, hide unsaved badges (persistence is handled externally) */\n externalPersistence?: boolean;\n}\n\nexport function LayersPanel({\n layers,\n onAddLayer,\n onRemoveLayer,\n onRenameLayer,\n onToggleLayerVisibility,\n onMoveFeatureToLayer,\n selectedFeatureIds,\n getFeatureCount,\n getLayerUnsavedCount,\n getMapUnsavedCount,\n activeEditingLayerId,\n onSetActiveEditingLayer,\n onSaveLayerGeoJSON,\n onLoadLayerGeoJSON,\n onLoadNewLayerGeoJSON,\n onSaveAllGeoJSON,\n onSearchAndAddToNewLayer,\n onWorkspaceLoad,\n onWorkspaceSave,\n onFitToFeatures,\n onFitToLayerFeatures,\n currentMapStyle,\n onMapStyleChange,\n onUpdateTraceConfig,\n getAvailableTraceFields,\n getLayerFields,\n onUpdateHeatmapConfig,\n onUpdateClusterConfig,\n onUpdateVisualConfig,\n hasPointFeatures,\n autoLabelConfig,\n onUpdateAutoLabelConfig,\n visibleFeatureCount,\n is3DTerrainEnabled = false,\n onToggle3DTerrain,\n onUpdateAltitudeDisplayMode,\n hideSatellite = false,\n hideTerrain = false,\n hideBasemapSwitcher = false,\n externalPersistence = false,\n}: LayersPanelProps) {\n const [newLayerName, setNewLayerName] = useState('');\n const [editingLayerId, setEditingLayerId] = useState<string | null>(null);\n const [editingName, setEditingName] = useState('');\n const [expandedLayers, setExpandedLayers] = useState<Set<string>>(new Set());\n\n const handleAddLayer = useCallback(() => {\n if (!newLayerName.trim()) return;\n onAddLayer(newLayerName.trim());\n setNewLayerName('');\n }, [newLayerName, onAddLayer]);\n\n const handleStartEdit = useCallback((layer: Layer) => {\n setEditingLayerId(layer.id);\n setEditingName(layer.name);\n }, []);\n\n const handleSaveEdit = useCallback(() => {\n if (editingLayerId && editingName.trim()) {\n onRenameLayer(editingLayerId, editingName.trim());\n }\n setEditingLayerId(null);\n setEditingName('');\n }, [editingLayerId, editingName, onRenameLayer]);\n\n const handleCancelEdit = useCallback(() => {\n setEditingLayerId(null);\n setEditingName('');\n }, []);\n\n const toggleExpanded = useCallback((layerId: string) => {\n setExpandedLayers(prev => {\n const next = new Set(prev);\n if (next.has(layerId)) {\n next.delete(layerId);\n } else {\n next.add(layerId);\n }\n return next;\n });\n }, []);\n\n const handleMoveSelectedToLayer = useCallback((layerId: string) => {\n selectedFeatureIds.forEach(featureId => {\n onMoveFeatureToLayer(featureId, layerId);\n });\n }, [selectedFeatureIds, onMoveFeatureToLayer]);\n\n const handleDeleteLayer = useCallback((layer: Layer) => {\n Modal.confirm({\n title: `Delete layer \"${layer.name}\"?`,\n content: 'This will delete the layer. Features in this layer will be moved to the default layer.',\n okText: 'Delete',\n okButtonProps: { danger: true },\n cancelText: 'Cancel',\n onOk: () => onRemoveLayer(layer.id),\n });\n }, [onRemoveLayer]);\n\n return (\n <div \n className=\"absolute top-16 right-4 z-10 w-[420px] bg-background/95 floating-panel rounded-lg shadow-lg border border-border max-h-[calc(100vh-5rem)] flex flex-col overflow-hidden\"\n data-testid=\"panel-layers\"\n >\n {/* Map Styles Section */}\n <div className=\"p-2 border-b border-border shrink-0\">\n <div className=\"flex items-center gap-1.5 mb-1.5\">\n <Map className=\"w-4 h-4 text-muted-foreground\" />\n <h3 className=\"text-sm font-semibold flex-1\">Map Options</h3>\n <Dropdown\n trigger={['click']}\n placement=\"bottomRight\"\n menu={{\n items: [\n {\n key: 'auto-labels',\n label: (\n <div className=\"px-1.5 py-1.5\" onClick={(e) => e.stopPropagation()}>\n <div className=\"flex items-center justify-between gap-1.5 mb-1.5\">\n <div className=\"flex items-center gap-1.5\">\n <Type className=\"w-4 h-4 text-muted-foreground\" />\n <span className=\"text-sm\">Auto-show labels</span>\n </div>\n <Switch\n size=\"small\"\n checked={autoLabelConfig?.enabled ?? false}\n onChange={(checked) => onUpdateAutoLabelConfig?.({ \n enabled: checked, \n threshold: autoLabelConfig?.threshold ?? 100 \n })}\n data-testid=\"switch-auto-labels\"\n />\n </div>\n {autoLabelConfig?.enabled && (\n <div className=\"ml-5 space-y-1\">\n <div className=\"flex items-center gap-1.5\">\n <span className=\"text-xs text-muted-foreground\">When features on screen</span>\n <span className=\"text-xs font-medium\">< {autoLabelConfig.threshold}</span>\n </div>\n <Slider\n value={autoLabelConfig.threshold}\n min={10}\n max={500}\n step={10}\n onChange={(value) => onUpdateAutoLabelConfig?.({ \n ...autoLabelConfig, \n threshold: value \n })}\n className=\"w-full\"\n data-testid=\"slider-auto-label-threshold\"\n />\n {visibleFeatureCount !== undefined && (\n <div className=\"text-xs text-muted-foreground\">\n Visible: <span className=\"font-medium\">{visibleFeatureCount}</span>\n {visibleFeatureCount < autoLabelConfig.threshold ? (\n <span className=\"text-green-600 dark:text-green-400 ml-1\">(shown)</span>\n ) : (\n <span className=\"text-amber-600 dark:text-amber-400 ml-1\">(hidden)</span>\n )}\n </div>\n )}\n </div>\n )}\n </div>\n ),\n },\n { type: 'divider' },\n {\n key: 'load-all',\n icon: <Upload className=\"w-[18px] h-[18px]\" />,\n label: 'Load Entire Map from GeoJSON',\n onClick: onLoadNewLayerGeoJSON,\n },\n {\n key: 'save-all',\n icon: <Download className=\"w-[18px] h-[18px]\" />,\n label: 'Save Entire Map as GeoJSON',\n onClick: onSaveAllGeoJSON,\n },\n ...(onWorkspaceLoad || onWorkspaceSave ? [{ type: 'divider' as const }] : []),\n ...(onWorkspaceLoad ? [{\n key: 'workspace-load-all',\n icon: <FolderOpen className=\"w-[18px] h-[18px]\" />,\n label: 'Load All from Workspace...',\n onClick: () => {\n // Load to active layer or first layer if available\n const targetLayerId = activeEditingLayerId || (layers.length > 0 ? layers[0].id : null);\n if (targetLayerId) {\n onWorkspaceLoad(targetLayerId);\n }\n },\n }] : []),\n ...(onWorkspaceSave ? [{\n key: 'workspace-save-all',\n icon: <FolderOpen className=\"w-[18px] h-[18px]\" />,\n label: 'Save All to Workspace...',\n onClick: () => {\n // Save from active layer or first layer if available\n const targetLayerId = activeEditingLayerId || (layers.length > 0 ? layers[0].id : null);\n if (targetLayerId) {\n onWorkspaceSave(targetLayerId);\n }\n },\n }] : []),\n ...(onFitToFeatures ? [\n { type: 'divider' as const },\n {\n key: 'fit-all',\n icon: <Focus className=\"w-[18px] h-[18px]\" />,\n label: 'Fit Map to All Features',\n onClick: onFitToFeatures,\n },\n ] : []),\n ],\n }}\n >\n <Button \n type=\"text\" \n icon={<MoreHorizontal className=\"w-[18px] h-[18px]\" />}\n className=\"!w-7 !h-7 !min-w-0 !p-0\"\n data-testid=\"button-global-settings-menu\"\n />\n </Dropdown>\n </div>\n {!hideBasemapSwitcher && (\n <div className=\"flex items-center gap-1.5\">\n <div className=\"grid grid-cols-3 gap-1 flex-1\">\n {MAP_STYLES\n .filter((style) => {\n if (hideSatellite && style.id === 'satellite') return false;\n return true;\n })\n .map((style) => {\n const Icon = style.icon;\n const isActive = currentMapStyle === style.id;\n return (\n <Button\n key={style.id}\n type={isActive ? \"primary\" : \"default\"}\n size=\"small\"\n onClick={() => onMapStyleChange(style.id)}\n className={`flex flex-col items-center gap-1 !h-auto !py-2 w-full ${isActive ? '' : 'bg-background'}`}\n data-testid={`button-map-style-${style.id}`}\n >\n <Icon className=\"w-[18px] h-[18px]\" />\n <span className=\"text-sm\">{style.name}</span>\n </Button>\n );\n })}\n </div>\n {onToggle3DTerrain && !hideTerrain && (\n <Button\n type=\"default\"\n size=\"small\"\n onClick={onToggle3DTerrain}\n className={`flex flex-col items-center gap-0.5 !h-auto !py-1.5 !px-2 !rounded-full transition-all shrink-0 ${\n is3DTerrainEnabled \n ? '!bg-primary !text-primary-foreground !border-primary shadow-md' \n : '!bg-muted/50 !border-dashed !border-muted-foreground/40'\n }`}\n data-testid=\"button-3d-terrain\"\n >\n <Box className=\"w-4 h-4\" />\n <span className=\"text-xs font-medium\">3D</span>\n </Button>\n )}\n </div>\n )}\n </div>\n {/* Layers Section */}\n <div className=\"flex items-center gap-1.5 px-2 py-1.5 border-b border-border shrink-0\">\n <Layers className=\"w-4 h-4 text-muted-foreground\" />\n <h3 className=\"text-sm font-semibold flex-1\">Layers</h3>\n <Tag className=\"text-xs px-1.5 py-0\">{layers.length}</Tag>\n </div>\n <div className=\"flex-1 min-h-0 overflow-y-auto\">\n <div className=\"p-1.5 space-y-0.5 pr-2\">\n {layers.map((layer) => {\n const featureCount = getFeatureCount(layer.id);\n const isExpanded = expandedLayers.has(layer.id);\n const isEditing = editingLayerId === layer.id;\n const isDefault = layer.id === 'default';\n const isActiveEditing = layer.id === activeEditingLayerId;\n \n return (\n <div key={layer.id}>\n <div \n className={`flex items-center gap-1 px-[5px] py-[5px] rounded-md hover-elevate group min-w-0 ${isActiveEditing ? 'bg-primary/10 border border-primary/30' : ''}`}\n data-testid={`layer-item-${layer.id}`}\n >\n {/* Left control cluster - tighter spacing */}\n <div className=\"flex items-center gap-0 shrink-0\">\n <Button \n type=\"text\" \n icon={isExpanded ? <ChevronDown className=\"w-3.5 h-3.5\" /> : <ChevronRight className=\"w-3.5 h-3.5\" />}\n onClick={() => toggleExpanded(layer.id)}\n className=\"!w-6 !h-7 !min-w-0 !p-0\"\n />\n \n <Button\n type=\"text\"\n icon={layer.visible ? <Eye className=\"w-4 h-4\" /> : <EyeOff className=\"w-4 h-4 text-muted-foreground\" />}\n onClick={() => onToggleLayerVisibility(layer.id)}\n className=\"!w-6 !h-7 !min-w-0 !p-0\"\n data-testid={`button-toggle-visibility-${layer.id}`}\n />\n \n {layer.readOnly ? (\n <Tooltip title={<><p className=\"font-medium\">High-Performance Mode</p><p className=\"text-sm text-muted-foreground\">View-only, optimized for large datasets</p></>}>\n <div className=\"h-7 w-6 flex items-center justify-center relative\">\n <Lock className=\"w-4 h-4 text-muted-foreground\" />\n <span className=\"absolute -top-0.5 -right-0.5 w-2.5 h-2.5 bg-green-500 rounded-full\" />\n </div>\n </Tooltip>\n ) : (\n <Tooltip title={isActiveEditing ? \"This is the layer being edited\" : \"Click to edit this layer\"}>\n <Button\n type=\"text\"\n icon={<Pencil className={`w-4 h-4 ${isActiveEditing ? 'text-primary' : ''}`} />}\n onClick={() => {\n if (!layer.visible) return;\n if (isActiveEditing) {\n onSetActiveEditingLayer('');\n } else {\n onSetActiveEditingLayer(layer.id);\n }\n }}\n disabled={!layer.visible}\n className={`!w-6 !h-7 !min-w-0 !p-0 ${isActiveEditing ? 'ring-2 ring-primary ring-offset-1 ring-offset-background' : ''}`}\n data-testid={`button-set-active-${layer.id}`}\n />\n </Tooltip>\n )}\n </div>\n \n {/* Layer name - uses all remaining space */}\n {isEditing ? (\n <Input\n value={editingName}\n onChange={(e) => setEditingName(e.target.value)}\n onBlur={handleSaveEdit}\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleSaveEdit();\n if (e.key === 'Escape') handleCancelEdit();\n }}\n className=\"!h-7 text-sm flex-1 min-w-0\"\n autoFocus\n data-testid={`input-edit-layer-${layer.id}`}\n />\n ) : (\n <div className=\"flex items-center gap-1.5 flex-1 min-w-0\">\n <Tooltip title={layer.name}>\n <button\n onClick={() => handleStartEdit(layer)}\n className=\"text-left text-base truncate px-1 min-w-0\"\n data-testid={`button-layer-name-${layer.id}`}\n >\n {layer.name}\n </button>\n </Tooltip>\n {!externalPersistence && getLayerUnsavedCount && getLayerUnsavedCount(layer.id) > 0 && (\n <Tag color=\"orange\" className=\"!text-[10px] !px-1 !py-0 !leading-4 !border-0 shrink-0\">\n {getLayerUnsavedCount(layer.id)} unsaved\n </Tag>\n )}\n </div>\n )}\n \n {/* Right side - feature count and menu */}\n <div className=\"flex items-center gap-1 shrink-0\">\n <Tag className=\"text-sm\">{featureCount}</Tag>\n \n <Dropdown\n trigger={['click']}\n placement=\"bottomRight\"\n menu={{\n items: [\n {\n key: 'load-desktop',\n icon: <Upload className=\"w-[18px] h-[18px]\" />,\n label: 'Load GeoJSON from desktop',\n onClick: () => onLoadLayerGeoJSON(layer.id),\n },\n {\n key: 'save-desktop',\n icon: <Download className=\"w-[18px] h-[18px]\" />,\n label: 'Save GeoJSON to desktop',\n onClick: () => onSaveLayerGeoJSON(layer.id),\n },\n ...(onWorkspaceLoad || onWorkspaceSave ? [{ type: 'divider' as const }] : []),\n ...(onWorkspaceLoad ? [{\n key: 'load-workspace',\n icon: <FolderOpen className=\"w-[18px] h-[18px]\" />,\n label: 'Load from workspace',\n onClick: () => onWorkspaceLoad(layer.id),\n }] : []),\n ...(onWorkspaceSave ? [{\n key: 'save-workspace',\n icon: <FolderOpen className=\"w-[18px] h-[18px]\" />,\n label: 'Save to workspace',\n onClick: () => onWorkspaceSave(layer.id),\n }] : []),\n ...(onFitToLayerFeatures && featureCount > 0 ? [\n { type: 'divider' as const },\n {\n key: 'fit',\n icon: <Focus className=\"w-[18px] h-[18px]\" />,\n label: 'Fit Map to Layer',\n onClick: () => onFitToLayerFeatures(layer.id),\n },\n ] : []),\n ...(!isDefault ? [\n { type: 'divider' as const },\n {\n key: 'delete',\n icon: <Trash2 className=\"w-[18px] h-[18px]\" />,\n label: 'Delete Layer',\n danger: true,\n onClick: () => handleDeleteLayer(layer),\n },\n ] : []),\n ],\n }}\n >\n <Button\n type=\"text\"\n icon={<MoreHorizontal className=\"w-4 h-4\" />}\n className=\"!w-7 !h-7 !min-w-0 !p-0 shrink-0 opacity-0 group-hover:opacity-100\"\n data-testid={`button-layer-menu-${layer.id}`}\n />\n </Dropdown>\n </div>\n </div>\n {isExpanded && (\n <div className=\"pl-2 border-l border-border space-y-1.5 py-1.5 ml-[8px] mr-[8px]\">\n {selectedFeatureIds.length > 0 && !layer.readOnly && (\n <Button\n type=\"default\"\n size=\"small\"\n onClick={() => handleMoveSelectedToLayer(layer.id)}\n className=\"w-full text-xs\"\n data-testid={`button-move-to-layer-${layer.id}`}\n >\n Move {selectedFeatureIds.length} selected here\n </Button>\n )}\n \n {hasPointFeatures?.(layer.id) && (\n <div className=\"space-y-1 p-1.5 bg-muted/30 rounded-md\">\n <div className=\"flex items-center gap-1.5 text-xs font-medium\">\n <span>Point Features</span>\n </div>\n \n {/* Trace Config */}\n <div className=\"flex items-center gap-1.5\">\n <Switch\n size=\"small\"\n checked={layer.traceConfig?.enabled ?? false}\n onChange={(checked) => onUpdateTraceConfig(layer.id, { \n enabled: checked, \n groupByField: layer.traceConfig?.groupByField ?? null \n })}\n data-testid={`switch-trace-${layer.id}`}\n />\n <span className=\"text-xs\">Trace Lines</span>\n </div>\n {layer.traceConfig?.enabled && (\n <Select\n size=\"small\"\n value={layer.traceConfig.groupByField ?? 'all'}\n onChange={(val) => onUpdateTraceConfig(layer.id, { \n enabled: true, \n groupByField: val === 'all' ? null : val \n })}\n className=\"w-full text-xs\"\n options={[\n { value: 'all', label: 'Connect all points' },\n ...getAvailableTraceFields(layer.id).map(f => ({ value: f, label: `Group by ${f}` })),\n ]}\n data-testid={`select-trace-field-${layer.id}`}\n />\n )}\n \n {/* Heatmap Config */}\n {onUpdateHeatmapConfig && (\n <>\n <Divider className=\"!my-1\" />\n <div className=\"flex items-center gap-1.5\">\n <Switch\n size=\"small\"\n checked={layer.heatmapConfig?.enabled ?? false}\n onChange={(checked) => onUpdateHeatmapConfig(layer.id, { \n enabled: checked, \n intensity: layer.heatmapConfig?.intensity ?? 1.0,\n radius: layer.heatmapConfig?.radius ?? 20,\n hideFeatures: layer.heatmapConfig?.hideFeatures ?? false,\n })}\n data-testid={`switch-heatmap-${layer.id}`}\n />\n <span className=\"text-xs\">Heatmap</span>\n </div>\n {layer.heatmapConfig?.enabled && (\n <div className=\"space-y-1 pl-4\">\n <div className=\"flex items-center gap-1\">\n <span className=\"text-[10px] w-12\">Intensity</span>\n <Slider\n value={layer.heatmapConfig.intensity}\n min={0.1}\n max={2.0}\n step={0.1}\n className=\"flex-1\"\n onChange={(val) => onUpdateHeatmapConfig(layer.id, { \n ...layer.heatmapConfig!, \n intensity: val \n })}\n />\n </div>\n <div className=\"flex items-center gap-1\">\n <span className=\"text-[10px] w-12\">Radius</span>\n <Slider\n value={layer.heatmapConfig.radius}\n min={5}\n max={50}\n step={1}\n className=\"flex-1\"\n onChange={(val) => onUpdateHeatmapConfig(layer.id, { \n ...layer.heatmapConfig!, \n radius: val \n })}\n />\n </div>\n <div className=\"flex items-center gap-1.5\">\n <Switch\n size=\"small\"\n checked={layer.heatmapConfig.hideFeatures ?? false}\n onChange={(checked) => onUpdateHeatmapConfig(layer.id, { \n ...layer.heatmapConfig!, \n hideFeatures: checked \n })}\n />\n <span className=\"text-[10px]\">Hide points</span>\n </div>\n </div>\n )}\n </>\n )}\n \n {/* Cluster Config */}\n {onUpdateClusterConfig && (\n <>\n <Divider className=\"!my-1\" />\n <div className=\"flex items-center gap-1.5\">\n <Switch\n size=\"small\"\n checked={layer.clusterConfig?.enabled ?? false}\n onChange={(checked) => onUpdateClusterConfig(layer.id, { \n enabled: checked, \n groupByField: layer.clusterConfig?.groupByField ?? null,\n showPointDots: layer.clusterConfig?.showPointDots ?? false,\n })}\n data-testid={`switch-cluster-${layer.id}`}\n />\n <span className=\"text-xs\">Clustering</span>\n </div>\n {layer.clusterConfig?.enabled && getLayerFields && (\n <div className=\"space-y-1 pl-4\">\n <Select\n size=\"small\"\n value={layer.clusterConfig.groupByField ?? 'count'}\n onChange={(val) => onUpdateClusterConfig(layer.id, { \n ...layer.clusterConfig!, \n groupByField: val === 'count' ? null : val \n })}\n className=\"w-full text-xs\"\n options={[\n { value: 'count', label: 'Simple count' },\n ...getLayerFields(layer.id).filter(f => !f.isNumeric).map(f => ({ value: f.name, label: `Pie by ${f.name}` })),\n ]}\n data-testid={`select-cluster-field-${layer.id}`}\n />\n <div className=\"flex items-center gap-1.5\">\n <Switch\n size=\"small\"\n checked={layer.clusterConfig.showPointDots ?? false}\n onChange={(checked) => onUpdateClusterConfig(layer.id, { \n ...layer.clusterConfig!, \n showPointDots: checked \n })}\n />\n <span className=\"text-[10px]\">Show point dots</span>\n </div>\n </div>\n )}\n </>\n )}\n </div>\n )}\n \n {/* 3D Altitude Mode */}\n {layer.hasAltitudeData && onUpdateAltitudeDisplayMode && (\n <div className=\"space-y-1 p-1.5 bg-muted/30 rounded-md\">\n <div className=\"flex items-center gap-1.5 text-xs font-medium\">\n <Box className=\"w-3.5 h-3.5\" />\n <span>Altitude Display</span>\n </div>\n <Select\n size=\"small\"\n value={layer.altitudeDisplayMode ?? '3d'}\n onChange={(val) => onUpdateAltitudeDisplayMode(layer.id, val as AltitudeDisplayMode)}\n className=\"w-full text-xs\"\n options={[\n { value: '3d', label: '3D (show altitude)' },\n { value: 'flat', label: 'Flat (ignore altitude)' },\n { value: 'both', label: 'Both (3D + flat shadow)' },\n ]}\n data-testid={`select-altitude-mode-${layer.id}`}\n />\n </div>\n )}\n \n {/* Visual Config */}\n {onUpdateVisualConfig && getLayerFields && (\n <div className=\"space-y-1.5 p-1.5 bg-muted/30 rounded-md\">\n <div className=\"text-sm font-medium\">Visual Settings</div>\n \n {/* Label Mode */}\n <div className=\"flex items-center gap-1 text-sm text-muted-foreground\">\n <Type className=\"w-3.5 h-3.5\" />\n <span>Labels</span>\n </div>\n <Select\n size=\"small\"\n value={layer.visualConfig?.label?.mode ?? 'standard'}\n onChange={(val) => onUpdateVisualConfig(layer.id, {\n ...layer.visualConfig,\n label: { mode: val as LabelMode },\n })}\n className=\"w-full text-sm\"\n options={[\n { value: 'standard', label: 'Use name property' },\n { value: 'field', label: 'Use field...' },\n { value: 'fixed', label: 'Fixed text...' },\n ]}\n data-testid={`select-label-mode-${layer.id}`}\n />\n {layer.visualConfig?.label?.mode === 'field' && (\n <Select\n size=\"small\"\n value={layer.visualConfig?.label?.fieldName ?? ''}\n onChange={(val) => onUpdateVisualConfig(layer.id, {\n ...layer.visualConfig,\n label: { mode: 'field', fieldName: val },\n })}\n className=\"w-full text-sm\"\n placeholder=\"Select field...\"\n options={getLayerFields(layer.id).map(f => ({ value: f.name, label: f.name }))}\n data-testid={`select-label-field-${layer.id}`}\n />\n )}\n {layer.visualConfig?.label?.mode === 'fixed' && (\n <Input\n size=\"small\"\n value={layer.visualConfig?.label?.fixedText ?? ''}\n onChange={(e) => onUpdateVisualConfig(layer.id, {\n ...layer.visualConfig,\n label: { mode: 'fixed', fixedText: e.target.value },\n })}\n placeholder=\"Enter label text...\"\n className=\"text-sm\"\n data-testid={`input-label-text-${layer.id}`}\n />\n )}\n\n {/* Size Mode */}\n <div className=\"flex items-center gap-1 text-sm text-muted-foreground pt-0.5\">\n <span className=\"w-3.5 h-3.5 text-center\">S</span>\n <span>Size</span>\n </div>\n <Select\n size=\"small\"\n value={layer.visualConfig?.size?.mode ?? 'standard'}\n onChange={(val) => onUpdateVisualConfig(layer.id, {\n ...layer.visualConfig,\n size: { mode: val as SizeMode },\n })}\n className=\"w-full text-sm\"\n options={[\n { value: 'standard', label: 'Default size' },\n { value: 'field', label: 'Size by field...' },\n { value: 'override', label: 'Override size...' },\n ]}\n data-testid={`select-size-mode-${layer.id}`}\n />\n {layer.visualConfig?.size?.mode === 'field' && (\n <Select\n size=\"small\"\n value={layer.visualConfig?.size?.fieldName ?? ''}\n onChange={(val) => onUpdateVisualConfig(layer.id, {\n ...layer.visualConfig,\n size: { mode: 'field', fieldName: val },\n })}\n className=\"w-full text-sm\"\n placeholder=\"Select numeric field...\"\n options={getLayerFields(layer.id).filter(f => f.isNumeric).map(f => ({ value: f.name, label: f.name }))}\n data-testid={`select-size-field-${layer.id}`}\n />\n )}\n {layer.visualConfig?.size?.mode === 'override' && (\n <div className=\"flex items-center gap-1\">\n <Slider\n value={layer.visualConfig?.size?.overrideValue ?? 5}\n min={1}\n max={10}\n step={1}\n className=\"flex-1\"\n onChange={(val) => onUpdateVisualConfig(layer.id, {\n ...layer.visualConfig,\n size: { mode: 'override', overrideValue: val },\n })}\n />\n <span className=\"text-sm w-4 text-right\">{layer.visualConfig?.size?.overrideValue ?? 5}</span>\n </div>\n )}\n\n {/* Color Mode */}\n <div className=\"flex items-center gap-1 text-sm text-muted-foreground pt-0.5\">\n <span className=\"w-3.5 h-3.5 rounded-full bg-current\" />\n <span>Color</span>\n </div>\n <Select\n size=\"small\"\n value={layer.visualConfig?.color?.mode ?? 'standard'}\n onChange={(val) => onUpdateVisualConfig(layer.id, {\n ...layer.visualConfig,\n color: { mode: val as ColorMode },\n })}\n className=\"w-full text-sm\"\n options={[\n { value: 'standard', label: 'Use feature color' },\n { value: 'field', label: 'Color by field...' },\n { value: 'fixed', label: 'Fixed color...' },\n ]}\n data-testid={`select-color-mode-${layer.id}`}\n />\n {layer.visualConfig?.color?.mode === 'field' && (\n <Select\n size=\"small\"\n value={layer.visualConfig?.color?.fieldName ?? ''}\n onChange={(val) => onUpdateVisualConfig(layer.id, {\n ...layer.visualConfig,\n color: { mode: 'field', fieldName: val },\n })}\n className=\"w-full text-sm\"\n placeholder=\"Select field...\"\n options={getLayerFields(layer.id).map(f => ({ value: f.name, label: f.name }))}\n data-testid={`select-color-field-${layer.id}`}\n />\n )}\n {layer.visualConfig?.color?.mode === 'fixed' && (\n <ColorPickerPopover\n value={layer.visualConfig?.color?.fixedColor ?? '#3b82f6'}\n onChange={(color) => {\n onUpdateVisualConfig?.(layer.id, {\n ...layer.visualConfig,\n color: {\n mode: 'fixed',\n fixedColor: color,\n },\n });\n }}\n testId={`color-fixed-${layer.id}`}\n />\n )}\n\n {hasPointFeatures?.(layer.id) && (\n <>\n <div className=\"flex items-center gap-1 text-sm text-muted-foreground pt-0.5\">\n <Smile className=\"w-3.5 h-3.5\" />\n <span>Point Icon</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <Switch\n size=\"small\"\n checked={layer.visualConfig?.icon?.enabled ?? false}\n onChange={(checked) => {\n onUpdateVisualConfig?.(layer.id, {\n ...layer.visualConfig,\n icon: {\n enabled: checked,\n icon: layer.visualConfig?.icon?.icon ?? '📍',\n size: layer.visualConfig?.icon?.size ?? 24,\n },\n });\n }}\n data-testid={`switch-icon-${layer.id}`}\n />\n {layer.visualConfig?.icon?.enabled && (\n <div className=\"flex items-center gap-1 flex-1\">\n <IconPicker\n value={layer.visualConfig?.icon?.icon ?? '📍'}\n onChange={(icon) => {\n onUpdateVisualConfig?.(layer.id, {\n ...layer.visualConfig,\n icon: {\n enabled: true,\n icon,\n size: layer.visualConfig?.icon?.size ?? 24,\n },\n });\n }}\n />\n <Slider\n value={layer.visualConfig?.icon?.size ?? 24}\n min={12}\n max={48}\n step={2}\n className=\"flex-1\"\n onChange={(val) => {\n onUpdateVisualConfig?.(layer.id, {\n ...layer.visualConfig,\n icon: {\n enabled: true,\n icon: layer.visualConfig?.icon?.icon ?? '📍',\n size: val,\n },\n });\n }}\n />\n <span className=\"text-sm w-6 text-right\">{layer.visualConfig?.icon?.size ?? 24}</span>\n </div>\n )}\n </div>\n </>\n )}\n </div>\n )}\n </div>\n )}\n </div>\n );\n })}\n </div>\n </div>\n <div className=\"p-1.5 border-t border-border shrink-0\">\n <div className=\"flex items-center gap-1\">\n <Input\n value={newLayerName}\n onChange={(e) => setNewLayerName(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n handleAddLayer();\n }\n }}\n placeholder=\"New layer name\"\n className=\"!h-8 text-sm flex-1\"\n data-testid=\"input-new-layer\"\n />\n <Tooltip title=\"Create new layer\">\n <Button\n type=\"default\"\n icon={<Plus className=\"w-4 h-4\" />}\n onClick={handleAddLayer}\n disabled={!newLayerName.trim()}\n className=\"!w-8 !h-8 !min-w-0 !p-0 shrink-0\"\n data-testid=\"button-add-layer\"\n />\n </Tooltip>\n <Tooltip title=\"Load GeoJSON from desktop as new layer\">\n <Button\n type=\"default\"\n icon={<FolderOpen className=\"w-4 h-4\" />}\n onClick={onLoadNewLayerGeoJSON}\n className=\"!w-8 !h-8 !min-w-0 !p-0 shrink-0\"\n data-testid=\"button-open-layer\"\n />\n </Tooltip>\n {onSearchAndAddToNewLayer && (\n <Tooltip title=\"Search and add...\">\n <Button\n type=\"default\"\n icon={\n <div className=\"relative w-5 h-4\">\n <Database className=\"w-4 h-4\" />\n <Search className=\"w-3 h-3 absolute -bottom-0.5 right-[-4px] stroke-[2.5]\" />\n </div>\n }\n onClick={onSearchAndAddToNewLayer}\n className=\"!w-8 !h-8 !min-w-0 !p-0 shrink-0\"\n data-testid=\"button-search-new-layer\"\n />\n </Tooltip>\n )}\n </div>\n </div>\n </div>\n );\n}\n","import { useState, useEffect, useCallback, useRef } from 'react';\nimport { X, Plus, Trash2, MapPin, Minus, Pentagon, Palette, Calendar as CalendarIcon, Type, MoveRight, Circle, Smile, Info, MoreHorizontal, User, Car, Building, TreePine, Package, Save, Blend } from 'lucide-react';\nimport { Button, Input, Divider, Slider, Popover, Tooltip, Tag, Tabs, Badge as AntBadge, ColorPicker, Select, Collapse } from 'antd';\nimport { ChevronDown } from 'lucide-react';\nimport type { InputRef } from 'antd';\nimport { format } from 'date-fns';\nimport { IconPicker } from '@/components/icon-picker';\nimport { useToast } from '@/hooks/use-toast';\nimport * as turf from '@turf/turf';\nimport type { EntityCardProvider, TypePickerProvider, EntityType, FeatureSaveProvider, FeatureSaveContext } from '@/lib/map-editor-api';\n\nconst { TextArea } = Input;\n\nfunction formatDateForState(value: unknown): string {\n if (!value) return '';\n if (value instanceof Date) {\n return value.toISOString();\n }\n if (typeof value === 'string') {\n const date = new Date(value);\n if (!isNaN(date.getTime())) {\n return date.toISOString();\n }\n }\n return '';\n}\n\ninterface FeatureProperties {\n name?: string;\n description?: string;\n [key: string]: unknown;\n}\n\ninterface SelectedFeature {\n id: string;\n type: string;\n properties: FeatureProperties;\n geometry: GeoJSON.Geometry;\n}\n\ninterface PropertiesPanelProps {\n selectedFeatures: SelectedFeature[];\n onUpdateProperties: (featureId: string, properties: FeatureProperties) => void;\n onUpdateGeometry?: (featureId: string, geometry: GeoJSON.Geometry) => void;\n onClose: () => void;\n isEditMode?: boolean;\n layerName?: string;\n layerId?: string;\n autoFocusLabel?: boolean;\n entityCardProvider?: EntityCardProvider;\n typePickerProvider?: TypePickerProvider;\n featureSaveProvider?: FeatureSaveProvider;\n onFeatureSaved?: (featureId: string, newId: string, metadata: { workspace: string; sourceName: string }) => void;\n}\n\nfunction getFeatureTypeIcon(geometryType: string, kind?: string) {\n if (kind === 'text') {\n return <Type className=\"w-4 h-4\" />;\n }\n if (kind === 'arrow') {\n return <MoveRight className=\"w-4 h-4\" />;\n }\n if (kind === 'circle') {\n return <Circle className=\"w-4 h-4\" />;\n }\n switch (geometryType) {\n case 'Point':\n return <MapPin className=\"w-4 h-4\" />;\n case 'LineString':\n return <Minus className=\"w-4 h-4\" />;\n case 'Polygon':\n return <Pentagon className=\"w-4 h-4\" />;\n default:\n return null;\n }\n}\n\nfunction getFeatureTypeLabel(geometryType: string, kind?: string) {\n if (kind === 'text') {\n return 'Text';\n }\n if (kind === 'arrow') {\n return 'Arrow';\n }\n if (kind === 'circle') {\n return 'Circle';\n }\n switch (geometryType) {\n case 'Point':\n return 'Point';\n case 'LineString':\n return 'Line';\n case 'Polygon':\n return 'Polygon';\n default:\n return geometryType;\n }\n}\n\ninterface CustomProperty {\n key: string;\n value: string;\n}\n\nconst PRESET_COLORS = [\n '#3b82f6', \n '#ef4444', \n '#22c55e', \n '#f59e0b', \n '#8b5cf6', \n '#06b6d4', \n '#ec4899', \n '#6366f1', \n '#14b8a6', \n '#f97316', \n];\n\n// Module-level variable to persist tab preference across feature selections\nlet persistedTabPreference: string = 'properties';\n\nexport function PropertiesPanel({ selectedFeatures, onUpdateProperties, onUpdateGeometry, onClose, isEditMode = true, layerName, layerId, autoFocusLabel = false, entityCardProvider, typePickerProvider, featureSaveProvider, onFeatureSaved }: PropertiesPanelProps) {\n const feature = selectedFeatures[0];\n const { toast } = useToast();\n const hasMultipleSelection = selectedFeatures.length > 1;\n const [isSaving, setIsSaving] = useState(false);\n \n // Initialize activeTab from persisted preference (force cards during multi-selection)\n const getInitialTab = () => {\n if (hasMultipleSelection && entityCardProvider) return 'cards';\n // Use persisted preference for single selection\n return entityCardProvider ? persistedTabPreference : 'properties';\n };\n const [activeTab, setActiveTab] = useState<string>(getInitialTab);\n \n // Handle tab click to block forbidden transitions at the event level\n const handleTabClick = useCallback((key: string, e: React.MouseEvent | React.KeyboardEvent) => {\n if (key === 'properties' && hasMultipleSelection) {\n e.preventDefault();\n e.stopPropagation();\n }\n }, [hasMultipleSelection]);\n \n // Handle tab change - guards and persists preference\n const handleTabChange = useCallback((key: string) => {\n // Don't allow switching to properties during multi-selection\n if (key === 'properties' && hasMultipleSelection) return;\n setActiveTab(key);\n // Persist the user's choice (only for valid selections)\n if (!hasMultipleSelection) {\n persistedTabPreference = key;\n }\n }, [hasMultipleSelection]);\n \n // Auto-switch to cards tab when entering multi-selection\n // Restore persisted preference when exiting multi-selection\n const prevMultiSelection = useRef(hasMultipleSelection);\n useEffect(() => {\n if (entityCardProvider) {\n if (hasMultipleSelection && !prevMultiSelection.current) {\n // Entering multi-selection: force cards tab\n setActiveTab('cards');\n } else if (!hasMultipleSelection && prevMultiSelection.current) {\n // Exiting multi-selection: restore persisted preference\n setActiveTab(persistedTabPreference);\n }\n }\n prevMultiSelection.current = hasMultipleSelection;\n }, [hasMultipleSelection, entityCardProvider]);\n const [name, setName] = useState('');\n const [description, setDescription] = useState('');\n const [startDate, setStartDate] = useState('');\n const [endDate, setEndDate] = useState('');\n const [customProperties, setCustomProperties] = useState<CustomProperty[]>([]);\n const [newPropertyKey, setNewPropertyKey] = useState('');\n \n const [strokeColor, setStrokeColor] = useState('#3b82f6');\n const [strokeWidth, setStrokeWidth] = useState(2);\n const [strokeOpacity, setStrokeOpacity] = useState(1);\n const [fillColor, setFillColor] = useState('#3b82f6');\n const [fillOpacity, setFillOpacity] = useState(0.2);\n \n const [labelText, setLabelText] = useState('New Label');\n const [fontSize, setFontSize] = useState(14);\n const [fontColor, setFontColor] = useState('#000000');\n const [fontWeight, setFontWeight] = useState<'normal' | 'bold'>('normal');\n \n const [arrowSize, setArrowSize] = useState(72);\n \n const [pointIcon, setPointIcon] = useState('');\n const [pointIconSize, setPointIconSize] = useState(24);\n \n const [latitude, setLatitude] = useState('');\n const [longitude, setLongitude] = useState('');\n \n // Entity type state\n const [entityType, setEntityType] = useState<string | undefined>(undefined);\n \n const latInputFocused = useRef(false);\n const lngInputFocused = useRef(false);\n\n useEffect(() => {\n if (feature) {\n if (feature.properties.kind === 'text') {\n const textLabel = (feature.properties.label as string) || (feature.properties.text as string) || 'New Label';\n setName(textLabel);\n setLabelText(textLabel);\n } else {\n setName((feature.properties.name as string) || '');\n setLabelText('');\n }\n setDescription((feature.properties.description as string) || '');\n setStartDate(formatDateForState(feature.properties.startDate));\n setEndDate(formatDateForState(feature.properties.endDate));\n \n setStrokeColor((feature.properties.stroke as string) || '#3b82f6');\n setStrokeWidth((feature.properties['stroke-width'] as number) || 2);\n setStrokeOpacity((feature.properties['stroke-opacity'] as number) ?? 1);\n setFillColor((feature.properties.fill as string) || '#3b82f6');\n setFillOpacity((feature.properties['fill-opacity'] as number) ?? 0.2);\n \n setFontSize((feature.properties.fontSize as number) || 14);\n setFontColor((feature.properties.fontColor as string) || '#000000');\n setFontWeight((feature.properties.fontWeight as 'normal' | 'bold') || 'normal');\n \n setArrowSize((feature.properties.arrowSize as number) || 72);\n \n setPointIcon((feature.properties.pointIcon as string) || (feature.properties.icon as string) || '');\n setPointIconSize((feature.properties.pointIconSize as number) || (feature.properties.iconSize as number) || 24);\n \n // Entity type\n setEntityType((feature.properties.entityType as string) || undefined);\n \n if (feature.geometry.type === 'Point') {\n const coords = feature.geometry.coordinates as [number, number];\n setLongitude(coords[0].toFixed(6));\n setLatitude(coords[1].toFixed(6));\n } else {\n try {\n const centroid = turf.centroid(feature.geometry as turf.AllGeoJSON);\n const coords = centroid.geometry.coordinates as [number, number];\n setLongitude(coords[0].toFixed(6));\n setLatitude(coords[1].toFixed(6));\n } catch {\n setLongitude('');\n setLatitude('');\n }\n }\n \n const reserved = ['name', 'description', 'startDate', 'endDate', 'stroke', 'stroke-width', 'stroke-opacity', 'fill', 'fill-opacity', 'kind', 'label', 'fontSize', 'fontColor', 'fontWeight', 'arrowSize', 'circleCenter', 'circleRadius', 'icon', 'iconSize', 'pointIcon', 'pointIconSize', 'entityType'];\n const custom: CustomProperty[] = [];\n Object.entries(feature.properties).forEach(([key, value]) => {\n // Skip reserved properties, internal properties (prefixed with _), and display control properties (isHidden*)\n if (!reserved.includes(key) && value !== undefined && value !== null && !key.startsWith('_') && !key.startsWith('isHidden')) {\n custom.push({ key, value: String(value) });\n }\n });\n setCustomProperties(custom);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [feature?.id]);\n \n useEffect(() => {\n if (!feature) return;\n \n if (latInputFocused.current || lngInputFocused.current) return;\n \n if (feature.geometry.type === 'Point') {\n const coords = feature.geometry.coordinates as [number, number];\n setLongitude(coords[0].toFixed(6));\n setLatitude(coords[1].toFixed(6));\n } else {\n try {\n const centroid = turf.centroid(feature.geometry as turf.AllGeoJSON);\n const coords = centroid.geometry.coordinates as [number, number];\n setLongitude(coords[0].toFixed(6));\n setLatitude(coords[1].toFixed(6));\n } catch {\n // Keep existing values if centroid calculation fails\n }\n }\n }, [feature?.geometry]);\n \n const nameInputRef = useRef<InputRef>(null);\n useEffect(() => {\n if (autoFocusLabel && feature?.properties?.kind === 'text' && nameInputRef.current) {\n setTimeout(() => {\n nameInputRef.current?.focus();\n nameInputRef.current?.select();\n }, 50);\n }\n }, [autoFocusLabel, feature?.id, feature?.properties?.kind]);\n\n const handleSave = useCallback((overrides?: Partial<{\n strokeColor: string;\n fillColor: string;\n strokeWidth: number;\n strokeOpacity: number;\n fillOpacity: number;\n labelText: string;\n fontSize: number;\n fontColor: string;\n fontWeight: 'normal' | 'bold';\n arrowSize: number;\n pointIcon: string;\n pointIconSize: number;\n entityType: string;\n }>) => {\n if (!feature || !isEditMode) return;\n \n const properties: FeatureProperties = {\n ...feature.properties,\n name: name || undefined,\n description: description || undefined,\n startDate: startDate || undefined,\n endDate: endDate || undefined,\n 'stroke': overrides?.strokeColor ?? strokeColor,\n 'stroke-width': overrides?.strokeWidth ?? strokeWidth,\n 'stroke-opacity': overrides?.strokeOpacity ?? strokeOpacity,\n 'fill': overrides?.fillColor ?? fillColor,\n 'fill-opacity': overrides?.fillOpacity ?? fillOpacity,\n };\n \n // Entity type\n if (overrides?.entityType !== undefined) {\n properties.entityType = overrides.entityType;\n } else if (entityType !== undefined) {\n properties.entityType = entityType;\n }\n \n if (feature.properties.kind === 'text') {\n properties.label = overrides?.labelText ?? name;\n properties.fontSize = overrides?.fontSize ?? fontSize;\n properties.fontColor = overrides?.fontColor ?? fontColor;\n properties.fontWeight = overrides?.fontWeight ?? fontWeight;\n delete properties.text;\n }\n \n if (feature.properties.kind === 'arrow') {\n properties.arrowSize = overrides?.arrowSize ?? arrowSize;\n }\n \n if (feature.geometry.type === 'Point' && feature.properties.kind !== 'text') {\n const iconValue = overrides?.pointIcon ?? pointIcon;\n const iconSizeValue = overrides?.pointIconSize ?? pointIconSize;\n if (iconValue) {\n properties.icon = iconValue;\n properties.iconSize = iconSizeValue;\n } else {\n delete properties.icon;\n delete properties.iconSize;\n }\n }\n \n customProperties.forEach(({ key, value }) => {\n if (key.trim()) {\n properties[key.trim()] = value;\n }\n });\n \n onUpdateProperties(feature.id, properties);\n }, [feature, name, description, startDate, endDate, strokeColor, strokeWidth, strokeOpacity, fillColor, fillOpacity, fontSize, fontColor, fontWeight, arrowSize, pointIcon, pointIconSize, entityType, customProperties, onUpdateProperties, isEditMode]);\n\n const handleAddProperty = useCallback(() => {\n if (!newPropertyKey.trim() || !isEditMode) return;\n setCustomProperties(prev => [...prev, { key: newPropertyKey.trim(), value: '' }]);\n setNewPropertyKey('');\n }, [newPropertyKey, isEditMode]);\n\n const handleRemoveProperty = useCallback((index: number) => {\n if (!isEditMode) return;\n setCustomProperties(prev => prev.filter((_, i) => i !== index));\n }, [isEditMode]);\n\n const handlePropertyKeyChange = useCallback((index: number, key: string) => {\n if (!isEditMode) return;\n setCustomProperties(prev => prev.map((prop, i) => i === index ? { ...prop, key } : prop));\n }, [isEditMode]);\n\n const handlePropertyValueChange = useCallback((index: number, value: string) => {\n if (!isEditMode) return;\n setCustomProperties(prev => prev.map((prop, i) => i === index ? { ...prop, value } : prop));\n }, [isEditMode]);\n \n // Handle feature save to workspace\n const handleFeatureSave = useCallback(async () => {\n if (!featureSaveProvider || !feature || !layerId || !layerName) return;\n \n setIsSaving(true);\n try {\n const geoFeature: GeoJSON.Feature = {\n type: 'Feature',\n id: feature.id,\n geometry: feature.geometry,\n properties: feature.properties,\n };\n \n const context: FeatureSaveContext = {\n feature: geoFeature,\n layer: { id: layerId, name: layerName },\n currentWorkspace: feature.properties._workspace as string | undefined,\n currentSourceName: feature.properties._sourceName as string | undefined,\n };\n \n const result = await featureSaveProvider(context);\n \n if (result) {\n // Notify parent to update the feature with new ID and metadata\n onFeatureSaved?.(feature.id, result.id, {\n workspace: result.workspace,\n sourceName: result.sourceName,\n });\n toast({\n title: 'Feature saved',\n description: `Saved to ${result.workspace}`,\n });\n }\n } catch (error) {\n toast({\n title: 'Save failed',\n description: error instanceof Error ? error.message : 'Failed to save feature',\n variant: 'destructive',\n });\n } finally {\n setIsSaving(false);\n }\n }, [featureSaveProvider, feature, layerId, layerName, onFeatureSaved, toast]);\n\n if (selectedFeatures.length === 0) {\n return null;\n }\n \n // Check if feature is unsaved\n const isUnsaved = feature?.properties?._unsaved === true;\n\n // Entity Cards content - renders cards for each selected feature\n const entityCardsContent = (\n <div className=\"p-2 space-y-2\">\n {entityCardProvider ? (\n selectedFeatures.map((f) => {\n const geoFeature: GeoJSON.Feature = {\n type: 'Feature',\n id: f.id,\n geometry: f.geometry,\n properties: f.properties,\n };\n const card = entityCardProvider(geoFeature);\n return card ? (\n <div key={f.id} className=\"border border-border rounded-md p-2 bg-card\">\n {card}\n </div>\n ) : null;\n })\n ) : (\n <div className=\"text-center py-4 text-muted-foreground text-sm\">\n No entity card provider registered\n </div>\n )}\n </div>\n );\n\n // Properties content disabled overlay for multi-selection\n const propertiesDisabledOverlay = (\n <div className=\"absolute inset-0 bg-background/80 flex items-center justify-center z-10 rounded-md\">\n <p className=\"text-sm text-muted-foreground text-center px-4\">\n Select a single feature to see/set properties\n </p>\n </div>\n );\n\n // Multi-selection without entity card provider - show simple message\n if (hasMultipleSelection && !entityCardProvider) {\n return (\n <div \n className=\"absolute top-4 right-4 z-10 w-72 bg-background/95 floating-panel rounded-lg shadow-lg border border-border\"\n data-testid=\"panel-properties\"\n >\n <div className=\"flex items-center justify-between gap-2 px-2.5 py-2 border-b border-border\">\n <div className=\"flex items-center gap-2\">\n <Package className=\"w-4 h-4 text-primary\" />\n <span className=\"text-sm font-semibold\">\n {selectedFeatures.length} selected {selectedFeatures.length === 1 ? 'feature' : 'features'}\n </span>\n </div>\n <Button type=\"text\" icon={<X className=\"w-3.5 h-3.5\" />} onClick={onClose} className=\"!w-6 !h-6 !min-w-0 !p-0\" data-testid=\"button-close-properties\" />\n </div>\n <div className=\"p-2.5\">\n <p className=\"text-xs text-muted-foreground\">\n Select a single feature to edit properties.\n </p>\n </div>\n </div>\n );\n }\n\n // Properties panel (with optional tabs if entityCardProvider exists)\n const propertiesContent = (\n <div className=\"p-2 space-y-2\">\n <div className=\"space-y-0.5\">\n <div className=\"flex items-center justify-between gap-2\">\n <label htmlFor=\"feature-name\" className=\"text-xs text-muted-foreground\">\n {feature.properties.kind === 'text' ? 'Label' : 'Name'}\n </label>\n {isUnsaved && (\n <div className=\"flex items-center gap-1\">\n <Tag color=\"orange\" className=\"!text-[10px] !px-1 !py-0 !leading-4 !border-0\">\n unsaved\n </Tag>\n {featureSaveProvider && isEditMode && (\n <Button\n type=\"primary\"\n size=\"small\"\n icon={<Save className=\"w-3 h-3\" />}\n loading={isSaving}\n onClick={handleFeatureSave}\n className=\"!h-5 !px-1.5 !text-[11px] !p-[1px]\"\n style={{ padding: '1px 6px' }}\n data-testid=\"button-save-feature\"\n >\n Save\n </Button>\n )}\n </div>\n )}\n </div>\n <Input\n ref={nameInputRef}\n id=\"feature-name\"\n value={name}\n onChange={(e) => {\n setName(e.target.value);\n if (feature.properties.kind === 'text') {\n handleSave({ labelText: e.target.value });\n }\n }}\n onBlur={() => handleSave()}\n placeholder={isEditMode ? (feature.properties.kind === 'text' ? \"Enter label...\" : \"Feature name\") : \"No name\"}\n readOnly={!isEditMode}\n className=\"!h-6 text-[13px]\"\n data-testid=\"input-feature-name\"\n />\n </div>\n \n {/* Icon and Type field - Icon first, then Type */}\n {(typePickerProvider || (feature.geometry.type === 'Point' && feature.properties.kind !== 'text')) && (\n <div className=\"flex items-center gap-2\">\n {/* Point Icon - inline with Type */}\n {feature.geometry.type === 'Point' && feature.properties.kind !== 'text' && (\n <div className=\"flex items-center gap-1\">\n <label className=\"text-xs text-muted-foreground\">Icon</label>\n <IconPicker\n value={pointIcon}\n onChange={(icon) => {\n setPointIcon(icon);\n handleSave({ pointIcon: icon });\n }}\n disabled={!isEditMode}\n />\n {pointIcon && (\n <Button\n type=\"text\"\n icon={<X className=\"w-3 h-3\" />}\n onClick={() => {\n setPointIcon('');\n handleSave({ pointIcon: '' });\n }}\n disabled={!isEditMode}\n className=\"!w-5 !h-5 !min-w-0 !p-0\"\n data-testid=\"button-clear-point-icon\"\n />\n )}\n </div>\n )}\n \n {/* Entity Type field */}\n {typePickerProvider && (\n <div className=\"flex items-center gap-1 flex-1\">\n <label className=\"text-xs text-muted-foreground\">Type</label>\n <Input\n value={entityType || ''}\n readOnly\n placeholder=\"No type\"\n className=\"!h-6 text-[13px] flex-1\"\n data-testid=\"input-entity-type\"\n />\n {isEditMode && (\n <Button\n type=\"text\"\n size=\"small\"\n icon={<MoreHorizontal className=\"w-3.5 h-3.5\" />}\n onClick={() => {\n typePickerProvider(\n entityType,\n (selectedType) => {\n setEntityType(selectedType.id);\n handleSave({ entityType: selectedType.id });\n }\n );\n }}\n className=\"!w-6 !h-6 !min-w-0 !p-0 shrink-0\"\n data-testid=\"button-open-type-picker\"\n />\n )}\n </div>\n )}\n </div>\n )}\n \n {/* Lat/Lng display */}\n <div className=\"space-y-0.5\">\n <div className=\"flex items-center gap-1\">\n <label className=\"text-xs text-muted-foreground\">\n Lat / Lng\n </label>\n {feature.geometry.type !== 'Point' && (\n <Tooltip title=\"Lat and Lng refer to the centroid of this feature\">\n <span className=\"text-[13px] text-muted-foreground cursor-help\">*</span>\n </Tooltip>\n )}\n </div>\n <div className=\"flex gap-1\">\n <Input\n value={latitude}\n onChange={(e) => setLatitude(e.target.value)}\n onFocus={() => { latInputFocused.current = true; }}\n onBlur={() => {\n latInputFocused.current = false;\n if (feature.geometry.type === 'Point' && isEditMode && onUpdateGeometry) {\n const lat = parseFloat(latitude);\n const lng = parseFloat(longitude);\n const coords = (feature.geometry as GeoJSON.Point).coordinates as [number, number];\n \n if (isNaN(lat)) {\n toast({ title: 'Invalid latitude', description: 'Please enter a valid number', variant: 'destructive' });\n setLatitude(coords[1].toFixed(6));\n } else if (lat < -90 || lat > 90) {\n toast({ title: 'Invalid latitude', description: 'Latitude must be between -90 and 90', variant: 'destructive' });\n setLatitude(coords[1].toFixed(6));\n } else if (isNaN(lng) || lng < -180 || lng > 180) {\n // Longitude invalid, don't update yet\n } else {\n onUpdateGeometry(feature.id, {\n type: 'Point',\n coordinates: [lng, lat],\n });\n }\n }\n }}\n placeholder=\"Latitude\"\n readOnly={feature.geometry.type !== 'Point' || !isEditMode}\n className=\"!h-6 text-[13px] flex-1\"\n data-testid=\"input-feature-latitude\"\n />\n <Input\n value={longitude}\n onChange={(e) => setLongitude(e.target.value)}\n onFocus={() => { lngInputFocused.current = true; }}\n onBlur={() => {\n lngInputFocused.current = false;\n if (feature.geometry.type === 'Point' && isEditMode && onUpdateGeometry) {\n const lat = parseFloat(latitude);\n const lng = parseFloat(longitude);\n const coords = (feature.geometry as GeoJSON.Point).coordinates as [number, number];\n \n if (isNaN(lng)) {\n toast({ title: 'Invalid longitude', description: 'Please enter a valid number', variant: 'destructive' });\n setLongitude(coords[0].toFixed(6));\n } else if (lng < -180 || lng > 180) {\n toast({ title: 'Invalid longitude', description: 'Longitude must be between -180 and 180', variant: 'destructive' });\n setLongitude(coords[0].toFixed(6));\n } else if (isNaN(lat) || lat < -90 || lat > 90) {\n // Latitude invalid, don't update yet\n } else {\n onUpdateGeometry(feature.id, {\n type: 'Point',\n coordinates: [lng, lat],\n });\n }\n }\n }}\n placeholder=\"Longitude\"\n readOnly={feature.geometry.type !== 'Point' || !isEditMode}\n className=\"!h-6 text-[13px] flex-1\"\n data-testid=\"input-feature-longitude\"\n />\n </div>\n </div>\n \n <div className=\"space-y-0.5\">\n <label htmlFor=\"feature-description\" className=\"text-xs text-muted-foreground\">Description</label>\n <TextArea\n id=\"feature-description\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n onBlur={() => handleSave()}\n placeholder={isEditMode ? \"Add description...\" : \"No description\"}\n className=\"!min-h-[50px] resize-none text-[13px]\"\n readOnly={!isEditMode}\n data-testid=\"input-feature-description\"\n />\n </div>\n \n <Divider className=\"!my-1.5\" />\n \n <Collapse\n size=\"small\"\n defaultActiveKey={startDate || endDate ? ['temporal'] : []}\n ghost\n className=\"[&_.ant-collapse-header]:!px-0 [&_.ant-collapse-header]:!py-1 [&_.ant-collapse-content-box]:!px-0 [&_.ant-collapse-content-box]:!py-1\"\n items={[{\n key: 'temporal',\n label: (\n <div className=\"flex items-center gap-1\">\n <CalendarIcon className=\"w-3 h-3 text-foreground\" />\n <span className=\"text-xs font-medium\">Temporal</span>\n {(startDate || endDate) && (\n <span className=\"text-[10px] text-muted-foreground ml-1\">\n ({startDate && endDate ? '2 dates' : '1 date'})\n </span>\n )}\n </div>\n ),\n children: (\n <div className=\"space-y-1.5\">\n <div className=\"flex items-center gap-2\">\n <label className=\"text-[13px] text-muted-foreground w-8 shrink-0\">Start</label>\n <input\n type=\"datetime-local\"\n value={startDate ? format(new Date(startDate), \"yyyy-MM-dd'T'HH:mm\") : ''}\n onChange={(e) => {\n const val = e.target.value;\n if (val) {\n const newDate = new Date(val).toISOString();\n setStartDate(newDate);\n setTimeout(() => handleSave(), 0);\n } else {\n setStartDate('');\n setTimeout(() => handleSave(), 0);\n }\n }}\n className=\"flex-1 h-6 text-[13px] px-2 rounded-md border border-input bg-background\"\n disabled={!isEditMode}\n data-testid=\"input-feature-start-date\"\n />\n {startDate && isEditMode && (\n <Button\n type=\"text\"\n icon={<X className=\"w-3 h-3\" />}\n onClick={() => {\n setStartDate('');\n setTimeout(() => handleSave(), 0);\n }}\n className=\"!w-6 !h-6 !min-w-0 !p-0 shrink-0\"\n data-testid=\"button-clear-start-date\"\n />\n )}\n </div>\n <div className=\"flex items-center gap-2\">\n <label className=\"text-[13px] text-muted-foreground w-8 shrink-0\">End</label>\n <input\n type=\"datetime-local\"\n value={endDate ? format(new Date(endDate), \"yyyy-MM-dd'T'HH:mm\") : ''}\n onChange={(e) => {\n const val = e.target.value;\n if (val) {\n const newDate = new Date(val).toISOString();\n setEndDate(newDate);\n setTimeout(() => handleSave(), 0);\n } else {\n setEndDate('');\n setTimeout(() => handleSave(), 0);\n }\n }}\n className=\"flex-1 h-6 text-[13px] px-2 rounded-md border border-input bg-background\"\n disabled={!isEditMode}\n data-testid=\"input-feature-end-date\"\n />\n {endDate && isEditMode && (\n <Button\n type=\"text\"\n icon={<X className=\"w-3 h-3\" />}\n onClick={() => {\n setEndDate('');\n setTimeout(() => handleSave(), 0);\n }}\n className=\"!w-6 !h-6 !min-w-0 !p-0 shrink-0\"\n data-testid=\"button-clear-end-date\"\n />\n )}\n </div>\n </div>\n ),\n }]}\n />\n \n <Divider className=\"!my-1.5\" />\n \n <div className=\"space-y-1\">\n <div className=\"flex items-center gap-1\">\n <Palette className=\"w-3 h-3 text-foreground\" />\n <span className=\"text-xs font-medium\">Style</span>\n </div>\n \n {/* Text Feature Styling */}\n {feature.properties.kind === 'text' && (\n <div className=\"space-y-1.5\">\n <div>\n <label className=\"text-[13px] text-muted-foreground\">Font Size</label>\n <div className=\"flex items-center gap-1\">\n <Slider\n value={fontSize}\n min={8}\n max={48}\n step={1}\n className=\"flex-1\"\n onChange={(val) => {\n setFontSize(val);\n handleSave({ fontSize: val });\n }}\n disabled={!isEditMode}\n />\n <span className=\"text-xs w-6 text-right\">{fontSize}</span>\n </div>\n </div>\n <div>\n <label className=\"text-[13px] text-muted-foreground\">Font Color</label>\n <div className=\"flex gap-1 flex-wrap\">\n {PRESET_COLORS.map((color) => (\n <button\n key={color}\n onClick={() => {\n if (!isEditMode) return;\n setFontColor(color);\n handleSave({ fontColor: color });\n }}\n className={`w-5 h-5 rounded-md border-2 ${fontColor === color ? 'border-primary' : 'border-transparent'}`}\n style={{ backgroundColor: color }}\n disabled={!isEditMode}\n data-testid={`button-font-color-${color}`}\n />\n ))}\n </div>\n </div>\n <div>\n <label className=\"text-[13px] text-muted-foreground\">Font Weight</label>\n <div className=\"flex gap-1\">\n <Button\n type={fontWeight === 'normal' ? 'primary' : 'default'}\n size=\"small\"\n onClick={() => {\n if (!isEditMode) return;\n setFontWeight('normal');\n handleSave({ fontWeight: 'normal' });\n }}\n disabled={!isEditMode}\n className=\"flex-1\"\n >\n Normal\n </Button>\n <Button\n type={fontWeight === 'bold' ? 'primary' : 'default'}\n size=\"small\"\n onClick={() => {\n if (!isEditMode) return;\n setFontWeight('bold');\n handleSave({ fontWeight: 'bold' });\n }}\n disabled={!isEditMode}\n className=\"flex-1\"\n >\n Bold\n </Button>\n </div>\n </div>\n </div>\n )}\n \n {/* Arrow Feature Styling */}\n {feature.properties.kind === 'arrow' && (\n <div className=\"space-y-1.5\">\n <div>\n <label className=\"text-[13px] text-muted-foreground\">Arrow Size</label>\n <div className=\"flex items-center gap-1\">\n <Slider\n value={arrowSize}\n min={24}\n max={200}\n step={4}\n className=\"flex-1\"\n onChange={(val) => {\n setArrowSize(val);\n handleSave({ arrowSize: val });\n }}\n disabled={!isEditMode}\n />\n <span className=\"text-xs w-8 text-right\">{arrowSize}px</span>\n </div>\n </div>\n </div>\n )}\n \n {/* Standard Geometry Styling */}\n {feature.properties.kind !== 'text' && (\n <>\n <div className=\"flex items-center gap-2\">\n <label className=\"text-[13px] text-muted-foreground shrink-0\">Stroke</label>\n <Tooltip title=\"Stroke Color\">\n <span>\n <ColorPicker\n value={strokeColor}\n onChange={(color) => {\n const hex = color.toHexString();\n setStrokeColor(hex);\n handleSave({ strokeColor: hex });\n }}\n disabled={!isEditMode}\n size=\"small\"\n showText={false}\n data-testid=\"color-picker-stroke\"\n />\n </span>\n </Tooltip>\n <Tooltip title=\"Stroke Width\">\n <span>\n <Select\n value={strokeWidth}\n onChange={(val) => {\n setStrokeWidth(val);\n handleSave({ strokeWidth: val });\n }}\n disabled={!isEditMode}\n size=\"small\"\n className=\"w-14\"\n options={[\n { value: 1, label: '1px' },\n { value: 2, label: '2px' },\n { value: 3, label: '3px' },\n { value: 4, label: '4px' },\n { value: 5, label: '5px' },\n { value: 6, label: '6px' },\n { value: 7, label: '7px' },\n { value: 8, label: '8px' },\n { value: 9, label: '9px' },\n { value: 10, label: '10px' },\n ]}\n data-testid=\"select-stroke-width\"\n />\n </span>\n </Tooltip>\n <Tooltip title=\"Stroke Opacity\">\n <span className=\"flex items-center gap-1\">\n <Blend className=\"w-3 h-3 text-muted-foreground\" />\n <Select\n value={strokeOpacity}\n onChange={(val) => {\n setStrokeOpacity(val);\n handleSave({ strokeOpacity: val });\n }}\n disabled={!isEditMode}\n size=\"small\"\n className=\"w-[72px]\"\n options={[\n { value: 0, label: '0%' },\n { value: 0.1, label: '10%' },\n { value: 0.2, label: '20%' },\n { value: 0.3, label: '30%' },\n { value: 0.4, label: '40%' },\n { value: 0.5, label: '50%' },\n { value: 0.6, label: '60%' },\n { value: 0.7, label: '70%' },\n { value: 0.8, label: '80%' },\n { value: 0.9, label: '90%' },\n { value: 1, label: '100%' },\n ]}\n data-testid=\"select-stroke-opacity\"\n />\n </span>\n </Tooltip>\n </div>\n \n {(feature.geometry.type === 'Polygon' || feature.properties.kind === 'circle') && (\n <div className=\"flex items-center gap-2\">\n <label className=\"text-[13px] text-muted-foreground shrink-0\">Fill</label>\n <Tooltip title=\"Fill Color\">\n <span>\n <ColorPicker\n value={fillColor}\n onChange={(color) => {\n const hex = color.toHexString();\n setFillColor(hex);\n handleSave({ fillColor: hex });\n }}\n disabled={!isEditMode}\n size=\"small\"\n showText={false}\n data-testid=\"color-picker-fill\"\n />\n </span>\n </Tooltip>\n <Tooltip title=\"Fill Opacity\">\n <span className=\"flex items-center gap-1\">\n <Blend className=\"w-3 h-3 text-muted-foreground\" />\n <Select\n value={fillOpacity}\n onChange={(val) => {\n setFillOpacity(val);\n handleSave({ fillOpacity: val });\n }}\n disabled={!isEditMode}\n size=\"small\"\n className=\"w-[72px]\"\n options={[\n { value: 0, label: '0%' },\n { value: 0.1, label: '10%' },\n { value: 0.2, label: '20%' },\n { value: 0.3, label: '30%' },\n { value: 0.4, label: '40%' },\n { value: 0.5, label: '50%' },\n { value: 0.6, label: '60%' },\n { value: 0.7, label: '70%' },\n { value: 0.8, label: '80%' },\n { value: 0.9, label: '90%' },\n { value: 1, label: '100%' },\n ]}\n data-testid=\"select-fill-opacity\"\n />\n </span>\n </Tooltip>\n </div>\n )}\n \n {/* Point Icon Size - only show when icon is selected (icon picker is now in Icon+Type row) */}\n {feature.geometry.type === 'Point' && feature.properties.kind !== 'text' && pointIcon && (\n <div className=\"flex items-center gap-2\">\n <label className=\"text-[13px] text-muted-foreground shrink-0\">Size</label>\n <Slider\n value={pointIconSize}\n min={12}\n max={48}\n step={2}\n className=\"flex-1\"\n onChange={(val) => {\n setPointIconSize(val);\n handleSave({ pointIconSize: val });\n }}\n disabled={!isEditMode}\n />\n <span className=\"text-xs w-6 text-right\">{pointIconSize}</span>\n </div>\n )}\n </>\n )}\n </div>\n \n <Divider className=\"!my-1.5\" />\n \n <div className=\"space-y-1\">\n <span className=\"text-xs font-medium\">Custom Properties</span>\n \n {customProperties.length === 0 && !isEditMode && (\n <p className=\"text-[13px] text-muted-foreground\">None</p>\n )}\n \n {customProperties.length > 0 && (\n <div className=\"space-y-0.5\">\n {customProperties.map((prop, index) => (\n <div key={index} className=\"flex items-center gap-0.5\">\n <Input\n value={prop.key}\n onChange={(e) => handlePropertyKeyChange(index, e.target.value)}\n onBlur={() => handleSave()}\n placeholder=\"Key\"\n className=\"flex-1 text-[13px] font-mono !h-5 !px-1\"\n readOnly={!isEditMode}\n data-testid={`input-property-key-${index}`}\n />\n <Input\n value={prop.value}\n onChange={(e) => handlePropertyValueChange(index, e.target.value)}\n onBlur={() => handleSave()}\n placeholder=\"Val\"\n className=\"flex-1 text-[13px] !h-5 !px-1\"\n readOnly={!isEditMode}\n data-testid={`input-property-value-${index}`}\n />\n {isEditMode && (\n <button\n type=\"button\"\n onClick={() => {\n handleRemoveProperty(index);\n setTimeout(() => handleSave(), 0);\n }}\n className=\"text-destructive shrink-0 h-5 w-5 flex items-center justify-center\"\n data-testid={`button-remove-property-${index}`}\n >\n <Trash2 className=\"w-2.5 h-2.5\" />\n </button>\n )}\n </div>\n ))}\n </div>\n )}\n \n {isEditMode && (\n <div className=\"flex items-center gap-0.5\">\n <Input\n value={newPropertyKey}\n onChange={(e) => setNewPropertyKey(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n handleAddProperty();\n }\n }}\n placeholder=\"New property...\"\n className=\"flex-1 text-[13px] !h-5 !px-1\"\n data-testid=\"input-new-property-key\"\n />\n <button\n type=\"button\"\n onClick={handleAddProperty}\n disabled={!newPropertyKey.trim()}\n className=\"h-5 w-5 flex items-center justify-center border border-border rounded disabled:opacity-50\"\n data-testid=\"button-add-property\"\n >\n <Plus className=\"w-2.5 h-2.5\" />\n </button>\n </div>\n )}\n </div>\n \n <Divider className=\"!my-1.5\" />\n \n <div className=\"flex items-center gap-3 flex-wrap\">\n {layerName && (\n <div>\n <span className=\"text-[13px] text-muted-foreground\">Layer: </span>\n <span className=\"text-[13px] text-foreground\" data-testid=\"text-feature-layer\">{layerName}</span>\n </div>\n )}\n <div>\n <span className=\"text-[13px] text-muted-foreground\">ID: </span>\n <code className=\"text-[13px] font-mono text-muted-foreground\">{feature.id.slice(0, 12)}...</code>\n </div>\n </div>\n </div>\n );\n\n // With entityCardProvider - show tabs (works for both single and multi-selection)\n if (entityCardProvider) {\n return (\n <div \n className=\"absolute top-4 right-4 z-10 w-72 bg-background/95 floating-panel rounded-lg shadow-lg border border-border flex flex-col overflow-hidden\"\n style={{ maxHeight: 'calc(100vh - 6rem)' }}\n data-testid=\"panel-properties\"\n >\n <div className=\"flex items-center justify-between gap-2 px-3 py-2 border-b border-border shrink-0 bg-background/95\">\n <div className=\"flex items-center gap-2 min-w-0\">\n <span className=\"text-primary shrink-0\">\n {hasMultipleSelection ? (\n <Package className=\"w-4 h-4\" />\n ) : (\n getFeatureTypeIcon(feature.geometry.type, feature.properties.kind as string | undefined)\n )}\n </span>\n <span className=\"text-sm font-semibold\">\n {selectedFeatures.length} selected {selectedFeatures.length === 1 ? 'feature' : 'features'}\n </span>\n </div>\n <Button type=\"text\" icon={<X className=\"w-4 h-4\" />} onClick={onClose} className=\"!w-6 !h-6 !min-w-0 !p-0 shrink-0\" data-testid=\"button-close-properties\" />\n </div>\n \n <Tabs\n activeKey={activeTab}\n onChange={handleTabChange}\n onTabClick={handleTabClick}\n size=\"small\"\n className=\"flex-1 min-h-0 flex flex-col [&_.ant-tabs-nav]:px-2 [&_.ant-tabs-nav]:mb-0 [&_.ant-tabs-nav]:shrink-0 [&_.ant-tabs-content-holder]:flex-1 [&_.ant-tabs-content-holder]:min-h-0 [&_.ant-tabs-content-holder]:flex [&_.ant-tabs-content-holder]:flex-col [&_.ant-tabs-content]:flex-1 [&_.ant-tabs-content]:min-h-0 [&_.ant-tabs-content]:flex [&_.ant-tabs-content]:flex-col [&_.ant-tabs-tabpane-active]:flex-1 [&_.ant-tabs-tabpane-active]:min-h-0 [&_.ant-tabs-tabpane-active]:flex [&_.ant-tabs-tabpane-active]:flex-col\"\n items={[\n {\n key: 'cards',\n label: selectedFeatures.length >= 2 ? `Entity Cards (${selectedFeatures.length})` : 'Entity Cards',\n children: (\n <div className=\"flex-1 min-h-0 overflow-y-auto overflow-x-hidden scrollbar-visible\">\n {entityCardsContent}\n </div>\n ),\n },\n {\n key: 'properties',\n label: 'Properties',\n disabled: hasMultipleSelection,\n children: (\n <div className=\"flex-1 min-h-0 overflow-y-auto overflow-x-hidden scrollbar-visible relative\">\n {hasMultipleSelection ? (\n <>\n {propertiesDisabledOverlay}\n <div \n className=\"opacity-30 pointer-events-none\" \n aria-hidden=\"true\"\n {...{ inert: '' } as any}\n >\n {propertiesContent}\n </div>\n </>\n ) : propertiesContent}\n </div>\n ),\n },\n ]}\n />\n </div>\n );\n }\n\n // Single selection without entityCardProvider - original view\n return (\n <div \n className=\"absolute top-4 right-4 z-10 w-64 bg-background/95 floating-panel rounded-lg shadow-lg border border-border flex flex-col overflow-hidden\"\n style={{ maxHeight: 'calc(100vh - 6rem)' }}\n data-testid=\"panel-properties\"\n >\n <div className=\"flex items-center justify-between gap-2 px-3 py-2 border-b border-border shrink-0 bg-background/95\">\n <div className=\"flex items-center gap-2 min-w-0\">\n <span className=\"text-primary shrink-0\">\n {getFeatureTypeIcon(feature.geometry.type, feature.properties.kind as string | undefined)}\n </span>\n <span className=\"text-sm font-semibold\">1 selected feature</span>\n {!isEditMode && (\n <Tag className=\"text-xs px-1.5 py-0\">View</Tag>\n )}\n </div>\n <Button type=\"text\" icon={<X className=\"w-4 h-4\" />} onClick={onClose} className=\"!w-6 !h-6 !min-w-0 !p-0 shrink-0\" data-testid=\"button-close-properties\" />\n </div>\n \n <div className=\"flex-1 overflow-y-auto overflow-x-hidden scrollbar-visible\">\n {propertiesContent}\n </div>\n </div>\n );\n}\n","import { Tag } from 'antd';\nimport type { DrawingMode, SelectionMode } from '@/components/drawing-toolbar';\n\ninterface StatusIndicatorProps {\n activeMode: DrawingMode;\n featureCount: number;\n selectedCount?: number;\n selectionMode?: SelectionMode;\n}\n\nexport function StatusIndicator({ featureCount, selectedCount = 0 }: StatusIndicatorProps) {\n const hasSelection = selectedCount > 0;\n \n if (!hasSelection) {\n return null;\n }\n \n return (\n <div \n className=\"absolute bottom-4 left-4 z-10 flex items-center gap-2 px-3 py-1.5 bg-background/80 floating-panel rounded-lg shadow-lg border border-border\"\n role=\"status\"\n aria-live=\"polite\"\n data-testid=\"status-indicator\"\n >\n <Tag className=\"font-mono text-xs !m-0\" data-testid=\"badge-feature-count\">\n {featureCount} feature{featureCount !== 1 ? 's' : ''}\n </Tag>\n \n <div className=\"w-px h-4 bg-border\" />\n \n <Tag className=\"font-mono text-xs !m-0\" data-testid=\"badge-selected-count\">\n {selectedCount} selected\n </Tag>\n </div>\n );\n}\n","import { create } from 'zustand';\n\nexport interface TemporalFeature {\n id: string;\n startDate: Date | null;\n endDate: Date | null;\n layerId: string;\n}\n\nexport interface TimelineState {\n isEnabled: boolean;\n hasTemporalData: boolean;\n temporalFeatures: TemporalFeature[];\n untimedFeatureIds: string[];\n \n globalMinDate: Date | null;\n globalMaxDate: Date | null;\n \n rangeStart: Date | null;\n rangeEnd: Date | null;\n \n isPlaying: boolean;\n playbackSpeed: number;\n \n histogramBins: { start: Date; end: Date; count: number }[];\n \n setEnabled: (enabled: boolean) => void;\n setTemporalFeatures: (features: TemporalFeature[], untimedIds: string[]) => void;\n setRange: (start: Date | null, end: Date | null) => void;\n setPlaying: (playing: boolean) => void;\n setPlaybackSpeed: (speed: number) => void;\n advancePlayhead: () => boolean;\n reset: () => void;\n}\n\nfunction parseDate(value: unknown): Date | null {\n if (!value) return null;\n if (value instanceof Date) return value;\n if (typeof value === 'string' || typeof value === 'number') {\n const date = new Date(value);\n return isNaN(date.getTime()) ? null : date;\n }\n return null;\n}\n\nexport function normalizeTemporalProperties(properties: Record<string, unknown>): {\n startDate: Date | null;\n endDate: Date | null;\n} {\n // Check various common date property names for start date\n let startDate = parseDate(properties.startDate) || \n parseDate(properties.startdate) || \n parseDate(properties.start_date) ||\n parseDate(properties.date) ||\n parseDate(properties.timestamp) ||\n parseDate(properties.flightDate) ||\n parseDate(properties.time) ||\n parseDate(properties.datetime);\n \n // Check various common date property names for end date\n let endDate = parseDate(properties.endDate) || \n parseDate(properties.enddate) || \n parseDate(properties.end_date);\n \n if (startDate && endDate && endDate < startDate) {\n [startDate, endDate] = [endDate, startDate];\n }\n \n return { startDate, endDate };\n}\n\nexport function isFeatureInRange(\n feature: TemporalFeature,\n rangeStart: Date | null,\n rangeEnd: Date | null\n): boolean {\n if (!feature.startDate && !feature.endDate) return true;\n if (!rangeStart || !rangeEnd) return true;\n \n const featureStart = feature.startDate || feature.endDate!;\n const featureEnd = feature.endDate || feature.startDate!;\n \n return featureStart <= rangeEnd && featureEnd >= rangeStart;\n}\n\nfunction computeHistogramBins(\n features: TemporalFeature[],\n minDate: Date,\n maxDate: Date,\n binCount: number = 50\n): { start: Date; end: Date; count: number }[] {\n let range = maxDate.getTime() - minDate.getTime();\n \n // Handle single point case: create arbitrary padding (±1 day or ±1 hour if small)\n let effectiveMin = minDate;\n let effectiveMax = maxDate;\n if (range === 0) {\n // Single point - add padding of 1 day on each side\n const padding = 24 * 60 * 60 * 1000; // 1 day in ms\n effectiveMin = new Date(minDate.getTime() - padding);\n effectiveMax = new Date(maxDate.getTime() + padding);\n range = effectiveMax.getTime() - effectiveMin.getTime();\n }\n \n const binSize = range / binCount;\n \n const bins: { start: Date; end: Date; count: number }[] = [];\n \n for (let i = 0; i < binCount; i++) {\n bins.push({\n start: new Date(effectiveMin.getTime() + i * binSize),\n end: new Date(effectiveMin.getTime() + (i + 1) * binSize),\n count: 0,\n });\n }\n \n features.forEach(feature => {\n if (!feature.startDate) return;\n const featureTime = feature.startDate.getTime();\n const binIndex = Math.min(\n Math.floor((featureTime - effectiveMin.getTime()) / binSize),\n binCount - 1\n );\n if (binIndex >= 0 && binIndex < binCount) {\n bins[binIndex].count++;\n }\n });\n \n return bins;\n}\n\nexport const useTimelineStore = create<TimelineState>((set, get) => ({\n isEnabled: false,\n hasTemporalData: false,\n temporalFeatures: [],\n untimedFeatureIds: [],\n \n globalMinDate: null,\n globalMaxDate: null,\n \n rangeStart: null,\n rangeEnd: null,\n \n isPlaying: false,\n playbackSpeed: 1,\n \n histogramBins: [],\n \n setEnabled: (enabled) => {\n if (enabled) {\n // When opening timebar, reset range to full extent\n const state = get();\n set({ \n isEnabled: true,\n rangeStart: state.globalMinDate,\n rangeEnd: state.globalMaxDate,\n });\n } else {\n // When closing, just disable - no filtering should apply\n set({ isEnabled: false, isPlaying: false });\n }\n },\n \n setTemporalFeatures: (features, untimedIds) => {\n const timedFeatures = features.filter(f => f.startDate || f.endDate);\n \n if (timedFeatures.length === 0) {\n set({\n hasTemporalData: false,\n temporalFeatures: [],\n untimedFeatureIds: untimedIds,\n globalMinDate: null,\n globalMaxDate: null,\n rangeStart: null,\n rangeEnd: null,\n histogramBins: [],\n });\n return;\n }\n \n let minDate: Date | null = null;\n let maxDate: Date | null = null;\n \n timedFeatures.forEach(f => {\n const start = f.startDate;\n const end = f.endDate || f.startDate;\n \n if (start && (!minDate || start < minDate)) minDate = start;\n if (end && (!maxDate || end > maxDate)) maxDate = end;\n });\n \n const state = get();\n const histogramBins = minDate && maxDate \n ? computeHistogramBins(timedFeatures, minDate, maxDate)\n : [];\n \n set({\n hasTemporalData: true,\n temporalFeatures: timedFeatures,\n untimedFeatureIds: untimedIds,\n globalMinDate: minDate,\n globalMaxDate: maxDate,\n rangeStart: state.rangeStart || minDate,\n rangeEnd: state.rangeEnd || maxDate,\n histogramBins,\n });\n },\n \n setRange: (start, end) => set({ rangeStart: start, rangeEnd: end }),\n \n setPlaying: (playing) => set({ isPlaying: playing }),\n \n setPlaybackSpeed: (speed) => set({ playbackSpeed: speed }),\n \n advancePlayhead: () => {\n const state = get();\n if (!state.globalMinDate || !state.globalMaxDate || !state.rangeStart) {\n return false;\n }\n \n const totalRange = state.globalMaxDate.getTime() - state.globalMinDate.getTime();\n const stepSize = totalRange / 10;\n \n const newStart = new Date(state.rangeStart.getTime() + stepSize);\n const newEnd = state.rangeEnd ? new Date(state.rangeEnd.getTime() + stepSize) : null;\n \n if (newStart >= state.globalMaxDate) {\n set({ \n isPlaying: false,\n rangeStart: state.globalMinDate,\n rangeEnd: state.globalMaxDate,\n });\n return false;\n }\n \n set({\n rangeStart: newStart,\n rangeEnd: newEnd && newEnd <= state.globalMaxDate ? newEnd : state.globalMaxDate,\n });\n return true;\n },\n \n reset: () => set({\n isEnabled: false,\n hasTemporalData: false,\n temporalFeatures: [],\n untimedFeatureIds: [],\n globalMinDate: null,\n globalMaxDate: null,\n rangeStart: null,\n rangeEnd: null,\n isPlaying: false,\n histogramBins: [],\n }),\n}));\n","import { useEffect, useRef, useCallback, useState } from 'react';\nimport { Clock, Play, Pause, SkipBack } from 'lucide-react';\nimport { Button, Slider } from 'antd';\nimport { useTimelineStore, isFeatureInRange } from '@/lib/timeline-store';\nimport { cn } from '@/lib/utils';\n\n// Export timebar height for positioning other elements\nexport const TIMEBAR_HEIGHT = 152; // timescale(20) + histogram(64) + slider(24) + controls(28) + padding(16)\nexport const TIMEBAR_BOTTOM_OFFSET = 12;\n\ninterface TimebarProps {\n onFilterChange: (visibleIds: string[], hiddenIds: string[], untimedIds: string[]) => void;\n selectedFeatureIds?: string[];\n selectedFeatureColors?: Map<string, string>; // Map of feature ID to color\n className?: string;\n}\n\nfunction formatDate(date: Date | null): string {\n if (!date) return '';\n return date.toLocaleDateString('en-US', { \n month: 'short', \n day: 'numeric',\n year: 'numeric'\n });\n}\n\nfunction formatTickDate(date: Date, showYear: boolean): string {\n if (showYear) {\n return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: '2-digit' });\n }\n return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });\n}\n\nfunction Timescale({ minDate, maxDate, binCount }: { minDate: Date; maxDate: Date; binCount: number }) {\n // Calculate optimal number of ticks (5-7 labels max)\n const tickCount = Math.min(7, Math.max(3, Math.floor(binCount / 3)));\n const range = maxDate.getTime() - minDate.getTime();\n const showYear = range > 180 * 24 * 60 * 60 * 1000; // Show year if range > 6 months\n \n const ticks = Array.from({ length: tickCount }, (_, i) => {\n const percent = i / (tickCount - 1);\n const date = new Date(minDate.getTime() + percent * range);\n return { percent: percent * 100, date };\n });\n \n return (\n <div className=\"relative h-4 text-[9px] text-muted-foreground mb-1\">\n {ticks.map((tick, i) => (\n <div\n key={i}\n className=\"absolute transform -translate-x-1/2 whitespace-nowrap\"\n style={{ left: `${tick.percent}%` }}\n >\n <div className=\"flex flex-col items-center\">\n <span className=\"font-mono\">{formatTickDate(tick.date, showYear)}</span>\n <div className=\"w-px h-1 bg-muted-foreground/40\" />\n </div>\n </div>\n ))}\n </div>\n );\n}\n\nfunction formatDateTime(date: Date): string {\n return date.toLocaleDateString('en-US', { \n month: 'short', \n day: 'numeric',\n year: 'numeric',\n hour: 'numeric',\n minute: '2-digit'\n });\n}\n\ninterface HistogramProps {\n bins: { start: Date; end: Date; count: number }[];\n maxCount: number;\n selectedBins?: number[];\n colorGroupedBins?: { color: string; bins: number[] }[]; // Multiple colored selection lines\n}\n\nfunction Histogram({ bins, maxCount, selectedBins, colorGroupedBins }: HistogramProps) {\n const [hoveredBin, setHoveredBin] = useState<number | null>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n \n if (bins.length === 0 || maxCount === 0) return null;\n \n // Show color-grouped lines if available, otherwise fall back to single line\n const hasColorGroups = colorGroupedBins && colorGroupedBins.length > 0 && \n colorGroupedBins.some(group => group.bins.some(count => count > 0));\n const hasSelection = !hasColorGroups && selectedBins && selectedBins.length > 0 && \n selectedBins.some(count => count > 0);\n \n return (\n <div className=\"relative h-16\" ref={containerRef}>\n {/* Background bars (all features) */}\n <div className=\"absolute inset-0 flex items-end gap-px\">\n {bins.map((bin, i) => {\n const height = (bin.count / maxCount) * 100;\n const isHovered = hoveredBin === i;\n return (\n <div\n key={i}\n className={cn(\n \"flex-1 rounded-t-sm min-w-[2px] transition-colors cursor-pointer\",\n isHovered ? \"bg-primary/80\" : \"bg-primary/50\"\n )}\n style={{ height: `${Math.max(height, bin.count > 0 ? 4 : 0)}%` }}\n onMouseEnter={() => setHoveredBin(i)}\n onMouseLeave={() => setHoveredBin(null)}\n data-testid={`bar-histogram-${i}`}\n />\n );\n })}\n </div>\n \n {/* Color-grouped line chart overlays for selected features */}\n {hasColorGroups && (\n <svg className=\"absolute inset-0 pointer-events-none w-full h-full\" viewBox=\"0 0 100 100\" preserveAspectRatio=\"none\">\n {colorGroupedBins!.map((group, groupIndex) => {\n // Only render if this group has data\n if (!group.bins.some(count => count > 0)) return null;\n return (\n <polyline\n key={groupIndex}\n fill=\"none\"\n stroke={group.color}\n strokeWidth=\"2\"\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n vectorEffect=\"non-scaling-stroke\"\n points={group.bins.map((count, i) => {\n const x = (i + 0.5) * (100 / bins.length);\n const y = 100 - (count / maxCount) * 100;\n return `${x},${y}`;\n }).join(' ')}\n />\n );\n })}\n </svg>\n )}\n \n {/* Fallback: Single line chart overlay for selected features (no color info) */}\n {hasSelection && (\n <svg className=\"absolute inset-0 pointer-events-none w-full h-full\" viewBox=\"0 0 100 100\" preserveAspectRatio=\"none\">\n <polyline\n fill=\"none\"\n stroke=\"hsl(var(--foreground))\"\n strokeWidth=\"1.5\"\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n vectorEffect=\"non-scaling-stroke\"\n points={selectedBins!.map((count, i) => {\n const x = (i + 0.5) * (100 / bins.length);\n const y = 100 - (count / maxCount) * 100;\n return `${x},${y}`;\n }).join(' ')}\n />\n </svg>\n )}\n \n {/* Hover tooltip */}\n {hoveredBin !== null && bins[hoveredBin] && (\n <div \n className=\"absolute z-30 bg-popover border border-border rounded-md shadow-lg px-2 py-1.5 text-xs pointer-events-none whitespace-nowrap\"\n style={{\n left: `${(hoveredBin + 0.5) * (100 / bins.length)}%`,\n bottom: '100%',\n transform: 'translateX(-50%)',\n marginBottom: '4px'\n }}\n >\n <div className=\"font-medium\">{formatDateTime(bins[hoveredBin].start)}</div>\n <div className=\"text-muted-foreground\">\n {bins[hoveredBin].count} event{bins[hoveredBin].count !== 1 ? 's' : ''}\n {selectedBins && selectedBins[hoveredBin] > 0 && (\n <span className=\"ml-1 text-foreground font-medium\">\n ({selectedBins[hoveredBin]} selected)\n </span>\n )}\n </div>\n </div>\n )}\n </div>\n );\n}\n\nexport function TimebarToggle({ onClick, hasData }: { onClick: () => void; hasData: boolean }) {\n if (!hasData) return null;\n \n return (\n <Button\n type=\"text\"\n icon={<Clock className=\"w-5 h-5\" />}\n onClick={onClick}\n className=\"relative !w-9 !h-9 !min-w-0 !p-0\"\n aria-label=\"Toggle timeline\"\n data-testid=\"button-timeline-toggle\"\n />\n );\n}\n\nexport function Timebar({ onFilterChange, selectedFeatureIds = [], selectedFeatureColors, className }: TimebarProps) {\n const {\n isEnabled,\n hasTemporalData,\n temporalFeatures,\n untimedFeatureIds,\n globalMinDate,\n globalMaxDate,\n rangeStart,\n rangeEnd,\n isPlaying,\n histogramBins,\n setRange,\n setPlaying,\n } = useTimelineStore();\n \n // Compute color-grouped bins for selected features\n const colorGroupedBins = histogramBins.length > 0 && selectedFeatureIds.length > 0 && \n selectedFeatureColors && selectedFeatureColors.size > 0 && globalMinDate && globalMaxDate\n ? (() => {\n const selectedSet = new Set(selectedFeatureIds);\n const selectedTemporalFeatures = temporalFeatures.filter(f => selectedSet.has(f.id));\n \n if (selectedTemporalFeatures.length === 0) return [];\n \n // Group features by color\n const colorGroups = new Map<string, typeof selectedTemporalFeatures>();\n selectedTemporalFeatures.forEach(f => {\n const color = selectedFeatureColors.get(f.id) || '#3b82f6';\n if (!colorGroups.has(color)) colorGroups.set(color, []);\n colorGroups.get(color)!.push(f);\n });\n \n // Compute bins for each color group\n const result: { color: string; bins: number[] }[] = [];\n colorGroups.forEach((features, color) => {\n const bins = histogramBins.map((bin, binIndex) => {\n let count = 0;\n const isLastBin = binIndex === histogramBins.length - 1;\n features.forEach(f => {\n if (!f.startDate) return;\n const featureTime = f.startDate.getTime();\n // Use <= for last bin's end to include points exactly on maxDate\n const inBin = featureTime >= bin.start.getTime() && \n (isLastBin ? featureTime <= bin.end.getTime() : featureTime < bin.end.getTime());\n if (inBin) {\n count++;\n }\n });\n return count;\n });\n result.push({ color, bins });\n });\n \n return result;\n })()\n : [];\n \n // Compute bins for selected features only (fallback when no color info)\n const selectedBins = histogramBins.length > 0 && selectedFeatureIds.length > 0 && \n (!selectedFeatureColors || selectedFeatureColors.size === 0) && globalMinDate && globalMaxDate\n ? (() => {\n const selectedSet = new Set(selectedFeatureIds);\n const selectedTemporalFeatures = temporalFeatures.filter(f => selectedSet.has(f.id));\n \n if (selectedTemporalFeatures.length === 0) return [];\n \n const bins = histogramBins.map((bin, binIndex) => {\n let count = 0;\n const isLastBin = binIndex === histogramBins.length - 1;\n selectedTemporalFeatures.forEach(f => {\n if (!f.startDate) return;\n const featureTime = f.startDate.getTime();\n // Use <= for last bin's end to include points exactly on maxDate\n const inBin = featureTime >= bin.start.getTime() && \n (isLastBin ? featureTime <= bin.end.getTime() : featureTime < bin.end.getTime());\n if (inBin) {\n count++;\n }\n });\n return count;\n });\n return bins;\n })()\n : [];\n \n const animationFrameRef = useRef<number | null>(null);\n const lastFrameTimeRef = useRef<number>(0);\n const playbackDuration = 10000; // Complete playback in 10 seconds\n const targetFps = 30;\n const frameInterval = 1000 / targetFps; // ~33ms between frames\n \n const applyFilter = useCallback(() => {\n const visibleIds: string[] = [];\n const hiddenIds: string[] = [];\n \n temporalFeatures.forEach(feature => {\n if (isFeatureInRange(feature, rangeStart, rangeEnd)) {\n visibleIds.push(feature.id);\n } else {\n hiddenIds.push(feature.id);\n }\n });\n \n onFilterChange(visibleIds, hiddenIds, untimedFeatureIds);\n }, [temporalFeatures, untimedFeatureIds, rangeStart, rangeEnd, onFilterChange]);\n \n useEffect(() => {\n if (isEnabled && hasTemporalData) {\n applyFilter();\n }\n }, [isEnabled, hasTemporalData, rangeStart, rangeEnd, applyFilter]);\n \n useEffect(() => {\n if (!isPlaying || !globalMinDate || !globalMaxDate) {\n if (animationFrameRef.current) {\n cancelAnimationFrame(animationFrameRef.current);\n animationFrameRef.current = null;\n }\n return;\n }\n \n const totalRange = globalMaxDate.getTime() - globalMinDate.getTime();\n const stepPerFrame = totalRange / (playbackDuration / frameInterval);\n \n const animate = (timestamp: number) => {\n if (!lastFrameTimeRef.current) {\n lastFrameTimeRef.current = timestamp;\n }\n \n const elapsed = timestamp - lastFrameTimeRef.current;\n \n if (elapsed >= frameInterval) {\n lastFrameTimeRef.current = timestamp;\n \n const state = useTimelineStore.getState();\n if (!state.rangeStart || !state.globalMaxDate || !state.globalMinDate) {\n setPlaying(false);\n return;\n }\n \n const newStart = new Date(state.rangeStart.getTime() + stepPerFrame);\n const newEnd = state.rangeEnd \n ? new Date(state.rangeEnd.getTime() + stepPerFrame) \n : null;\n \n if (newStart >= state.globalMaxDate) {\n setRange(state.globalMinDate, state.globalMaxDate);\n setPlaying(false);\n return;\n }\n \n setRange(\n newStart,\n newEnd && newEnd <= state.globalMaxDate ? newEnd : state.globalMaxDate\n );\n }\n \n animationFrameRef.current = requestAnimationFrame(animate);\n };\n \n lastFrameTimeRef.current = 0;\n animationFrameRef.current = requestAnimationFrame(animate);\n \n return () => {\n if (animationFrameRef.current) {\n cancelAnimationFrame(animationFrameRef.current);\n animationFrameRef.current = null;\n }\n };\n }, [isPlaying, globalMinDate, globalMaxDate, setRange, setPlaying]);\n \n if (!isEnabled || !hasTemporalData || !globalMinDate || !globalMaxDate) {\n return null;\n }\n \n const totalRange = globalMaxDate.getTime() - globalMinDate.getTime();\n const startPercent = rangeStart \n ? ((rangeStart.getTime() - globalMinDate.getTime()) / totalRange) * 100 \n : 0;\n const endPercent = rangeEnd \n ? ((rangeEnd.getTime() - globalMinDate.getTime()) / totalRange) * 100 \n : 100;\n \n const maxBinCount = Math.max(...histogramBins.map(b => b.count), 1);\n \n const handleSliderChange = (values: number[]) => {\n const newStart = new Date(globalMinDate.getTime() + (values[0] / 100) * totalRange);\n const newEnd = new Date(globalMinDate.getTime() + (values[1] / 100) * totalRange);\n setRange(newStart, newEnd);\n setPlaying(false);\n };\n \n const handleReset = () => {\n setRange(globalMinDate, globalMaxDate);\n setPlaying(false);\n };\n \n const handlePlayPause = () => {\n if (!isPlaying && rangeStart && rangeStart >= globalMaxDate) {\n setRange(globalMinDate, globalMaxDate);\n }\n setPlaying(!isPlaying);\n };\n \n return (\n <div \n className={cn(\n \"absolute bottom-3 left-4 right-4 z-20 bg-background/95 floating-panel rounded-lg shadow-lg border border-border px-4 pt-3 pb-1\",\n className\n )}\n data-testid=\"timebar-panel\"\n >\n <Timescale minDate={globalMinDate} maxDate={globalMaxDate} binCount={histogramBins.length} />\n <Histogram \n bins={histogramBins} \n maxCount={maxBinCount} \n selectedBins={selectedBins}\n colorGroupedBins={colorGroupedBins}\n />\n \n <div className=\"mt-1\">\n <Slider\n range\n value={[startPercent, endPercent]}\n onChange={(values) => handleSliderChange(values as number[])}\n min={0}\n max={100}\n step={0.5}\n className=\"w-full\"\n data-testid=\"slider-timeline-range\"\n />\n </div>\n \n <div className=\"flex items-center justify-between mt-1\">\n <div className=\"flex items-center gap-1\">\n <Button\n type=\"text\"\n size=\"small\"\n icon={<SkipBack className=\"w-3.5 h-3.5\" />}\n onClick={handleReset}\n aria-label=\"Reset timeline\"\n data-testid=\"button-timeline-reset\"\n className=\"!h-7 !w-7 !p-0 !min-w-0\"\n />\n <Button\n type=\"text\"\n size=\"small\"\n icon={isPlaying ? <Pause className=\"w-3.5 h-3.5\" /> : <Play className=\"w-3.5 h-3.5\" />}\n onClick={handlePlayPause}\n aria-label={isPlaying ? 'Pause' : 'Play'}\n data-testid=\"button-timeline-play\"\n className=\"!h-7 !w-7 !p-0 !min-w-0\"\n />\n <span className=\"text-xs text-muted-foreground ml-1\">\n {temporalFeatures.length} feature{temporalFeatures.length !== 1 ? 's' : ''}\n </span>\n </div>\n \n <div className=\"flex items-center gap-2 text-xs text-muted-foreground font-mono\">\n <span data-testid=\"text-timeline-start\">{formatDate(rangeStart)}</span>\n <span>-</span>\n <span data-testid=\"text-timeline-end\">{formatDate(rangeEnd)}</span>\n </div>\n </div>\n </div>\n );\n}\n","import { useState, useCallback } from 'react';\nimport { Upload } from 'lucide-react';\nimport { cn } from '@/lib/utils';\n\ninterface MapDropZoneProps {\n onDrop: (name: string, data: GeoJSON.FeatureCollection) => void;\n children: React.ReactNode;\n}\n\nexport function MapDropZone({ onDrop, children }: MapDropZoneProps) {\n const [isDragOver, setIsDragOver] = useState(false);\n \n const handleDragOver = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n \n if (e.dataTransfer.types.includes('application/json')) {\n setIsDragOver(true);\n e.dataTransfer.dropEffect = 'copy';\n }\n }, []);\n \n const handleDragLeave = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n setIsDragOver(false);\n }, []);\n \n const handleDrop = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n setIsDragOver(false);\n \n try {\n const jsonData = e.dataTransfer.getData('application/json');\n if (jsonData) {\n const parsed = JSON.parse(jsonData);\n if (parsed.data && parsed.name) {\n onDrop(parsed.name, parsed.data);\n }\n }\n } catch (error) {\n console.error('Failed to parse dropped GeoJSON:', error);\n }\n }, [onDrop]);\n \n return (\n <div\n className=\"relative flex-1 h-full\"\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n >\n {children}\n \n {isDragOver && (\n <div \n className={cn(\n \"absolute inset-0 z-50 flex items-center justify-center\",\n \"bg-primary/10 border-4 border-dashed border-primary rounded-lg\",\n \"pointer-events-none transition-all\"\n )}\n data-testid=\"map-drop-overlay\"\n >\n <div className=\"bg-background/95 rounded-lg p-6 shadow-lg flex flex-col items-center gap-3\">\n <Upload className=\"w-10 h-10 text-primary\" />\n <span className=\"text-lg font-medium\">Drop GeoJSON here</span>\n <span className=\"text-sm text-muted-foreground\">Add as new layer</span>\n </div>\n </div>\n )}\n </div>\n );\n}\n","import { useEffect, useRef, useCallback, useState } from 'react';\nimport maplibregl from 'maplibre-gl';\n\ninterface CategoryData {\n name: string;\n count: number;\n color: string;\n}\n\ninterface ClusterPieProps {\n map: maplibregl.Map;\n sourceId: string;\n layerId: string;\n categoryValues: string[];\n categoryColorMap: Record<string, string>;\n visible: boolean;\n}\n\nfunction createPieSVG(\n categories: CategoryData[],\n total: number,\n size: number = 44,\n onSliceHover?: (cat: CategoryData | null, event: MouseEvent) => void\n): HTMLDivElement {\n const container = document.createElement('div');\n container.style.width = `${size}px`;\n container.style.height = `${size}px`;\n container.style.cursor = 'pointer';\n \n const radius = size / 2;\n const innerRadius = radius * 0.5; // Donut style\n \n // Create SVG\n const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n svg.setAttribute('width', String(size));\n svg.setAttribute('height', String(size));\n svg.setAttribute('viewBox', `0 0 ${size} ${size}`);\n svg.style.display = 'block';\n \n // Add white background circle for better visibility\n const bgCircle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');\n bgCircle.setAttribute('cx', String(radius));\n bgCircle.setAttribute('cy', String(radius));\n bgCircle.setAttribute('r', String(radius));\n bgCircle.setAttribute('fill', 'white');\n svg.appendChild(bgCircle);\n \n // Draw pie slices\n let currentAngle = -90; // Start from top\n \n categories.forEach((cat) => {\n if (cat.count === 0) return;\n \n const sliceAngle = (cat.count / total) * 360;\n const startAngle = currentAngle;\n const endAngle = currentAngle + sliceAngle;\n \n // Convert to radians\n const startRad = (startAngle * Math.PI) / 180;\n const endRad = (endAngle * Math.PI) / 180;\n \n // Outer arc points\n const x1 = radius + radius * Math.cos(startRad);\n const y1 = radius + radius * Math.sin(startRad);\n const x2 = radius + radius * Math.cos(endRad);\n const y2 = radius + radius * Math.sin(endRad);\n \n // Inner arc points\n const x3 = radius + innerRadius * Math.cos(endRad);\n const y3 = radius + innerRadius * Math.sin(endRad);\n const x4 = radius + innerRadius * Math.cos(startRad);\n const y4 = radius + innerRadius * Math.sin(startRad);\n \n const largeArc = sliceAngle > 180 ? 1 : 0;\n \n // Create path for donut slice\n const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n const d = [\n `M ${x1} ${y1}`,\n `A ${radius} ${radius} 0 ${largeArc} 1 ${x2} ${y2}`,\n `L ${x3} ${y3}`,\n `A ${innerRadius} ${innerRadius} 0 ${largeArc} 0 ${x4} ${y4}`,\n 'Z'\n ].join(' ');\n \n path.setAttribute('d', d);\n path.setAttribute('fill', cat.color);\n path.setAttribute('stroke', 'white');\n path.setAttribute('stroke-width', '1');\n path.style.transition = 'opacity 0.15s';\n \n // Add hover effect\n path.addEventListener('mouseenter', (e) => {\n path.style.opacity = '0.8';\n if (onSliceHover) onSliceHover(cat, e as MouseEvent);\n });\n path.addEventListener('mouseleave', (e) => {\n path.style.opacity = '1';\n if (onSliceHover) onSliceHover(null, e as MouseEvent);\n });\n \n svg.appendChild(path);\n currentAngle = endAngle;\n });\n \n // Add center circle with count\n const centerCircle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');\n centerCircle.setAttribute('cx', String(radius));\n centerCircle.setAttribute('cy', String(radius));\n centerCircle.setAttribute('r', String(innerRadius - 2));\n centerCircle.setAttribute('fill', '#1f2937');\n svg.appendChild(centerCircle);\n \n // Add count text\n const text = document.createElementNS('http://www.w3.org/2000/svg', 'text');\n text.setAttribute('x', String(radius));\n text.setAttribute('y', String(radius));\n text.setAttribute('text-anchor', 'middle');\n text.setAttribute('dominant-baseline', 'central');\n text.setAttribute('fill', 'white');\n text.setAttribute('font-size', total >= 1000 ? '9' : total >= 100 ? '10' : '11');\n text.setAttribute('font-weight', 'bold');\n text.setAttribute('font-family', 'system-ui, sans-serif');\n text.textContent = total >= 1000 ? `${(total / 1000).toFixed(1)}k` : String(total);\n svg.appendChild(text);\n \n container.appendChild(svg);\n return container;\n}\n\n// Tooltip element (singleton)\nlet tooltipEl: HTMLDivElement | null = null;\n\nfunction showTooltip(cat: CategoryData, x: number, y: number) {\n if (!tooltipEl) {\n tooltipEl = document.createElement('div');\n tooltipEl.style.cssText = `\n position: fixed;\n background: rgba(0,0,0,0.85);\n color: white;\n padding: 6px 10px;\n border-radius: 4px;\n font-size: 12px;\n font-family: system-ui, sans-serif;\n pointer-events: none;\n z-index: 10000;\n white-space: nowrap;\n box-shadow: 0 2px 8px rgba(0,0,0,0.3);\n `;\n document.body.appendChild(tooltipEl);\n }\n \n tooltipEl.innerHTML = `\n <div style=\"display: flex; align-items: center; gap: 6px;\">\n <span style=\"width: 10px; height: 10px; border-radius: 2px; background: ${cat.color};\"></span>\n <span><strong>${cat.name}</strong>: ${cat.count}</span>\n </div>\n `;\n tooltipEl.style.left = `${x + 12}px`;\n tooltipEl.style.top = `${y - 10}px`;\n tooltipEl.style.display = 'block';\n}\n\nfunction hideTooltip() {\n if (tooltipEl) {\n tooltipEl.style.display = 'none';\n }\n}\n\nexport function ClusterPieManager(props: ClusterPieProps) {\n const { map, sourceId, layerId, categoryValues, categoryColorMap, visible } = props;\n const markersRef = useRef<Map<string, maplibregl.Marker>>(new Map());\n const updateScheduled = useRef(false);\n\n const updateMarkers = useCallback(() => {\n if (!map || !visible) {\n // Clear all markers when not visible\n markersRef.current.forEach(marker => marker.remove());\n markersRef.current.clear();\n return;\n }\n \n const source = map.getSource(sourceId) as maplibregl.GeoJSONSource | undefined;\n if (!source) return;\n \n // Query visible cluster features\n const clusters = map.querySourceFeatures(sourceId, {\n filter: ['has', 'point_count']\n });\n \n const visibleClusterIds = new Set<string>();\n \n clusters.forEach(feature => {\n const clusterId = feature.properties?.cluster_id;\n if (clusterId === undefined) return;\n \n const clusterKey = `${clusterId}`;\n visibleClusterIds.add(clusterKey);\n \n const coords = (feature.geometry as GeoJSON.Point).coordinates as [number, number];\n const pointCount = feature.properties?.point_count || 0;\n \n // Build category data from aggregated properties\n const categories: CategoryData[] = categoryValues.map((cat, i) => ({\n name: cat,\n count: feature.properties?.[`cat_${i}`] || 0,\n color: categoryColorMap[cat] || '#3b82f6'\n })).filter(c => c.count > 0);\n \n // Calculate size based on point count\n const size = pointCount < 100 ? 40 : pointCount < 750 ? 50 : 60;\n \n // Check if marker exists and update or create\n const existingMarker = markersRef.current.get(clusterKey);\n \n if (existingMarker) {\n // Update position\n existingMarker.setLngLat(coords);\n } else {\n // Create new marker with pie chart\n const el = createPieSVG(categories, pointCount, size, (cat, event) => {\n if (cat) {\n showTooltip(cat, event.clientX, event.clientY);\n } else {\n hideTooltip();\n }\n });\n \n // Add click handler for zoom\n el.addEventListener('click', () => {\n (source as any).getClusterExpansionZoom(clusterId, (err: any, zoom: number) => {\n if (!err) {\n map.easeTo({ center: coords, zoom: zoom + 0.5 });\n }\n });\n });\n \n const marker = new maplibregl.Marker({ element: el })\n .setLngLat(coords)\n .addTo(map);\n \n markersRef.current.set(clusterKey, marker);\n }\n });\n \n // Remove markers that are no longer visible\n markersRef.current.forEach((marker, key) => {\n if (!visibleClusterIds.has(key)) {\n marker.remove();\n markersRef.current.delete(key);\n }\n });\n }, [map, sourceId, categoryValues, categoryColorMap, visible]);\n\n useEffect(() => {\n if (!map) return;\n \n const scheduleUpdate = () => {\n if (updateScheduled.current) return;\n updateScheduled.current = true;\n requestAnimationFrame(() => {\n updateScheduled.current = false;\n updateMarkers();\n });\n };\n \n // Initial update\n scheduleUpdate();\n \n // Listen for map events\n map.on('moveend', scheduleUpdate);\n map.on('data', (e: maplibregl.MapDataEvent) => {\n if ((e as any).sourceId === sourceId) {\n scheduleUpdate();\n }\n });\n \n return () => {\n map.off('moveend', scheduleUpdate);\n // Clean up markers\n markersRef.current.forEach(marker => marker.remove());\n markersRef.current.clear();\n hideTooltip();\n };\n }, [map, sourceId, updateMarkers]);\n\n // Update when visibility changes\n useEffect(() => {\n if (!visible) {\n markersRef.current.forEach(marker => marker.remove());\n markersRef.current.clear();\n hideTooltip();\n } else {\n updateMarkers();\n }\n }, [visible, updateMarkers]);\n\n return null; // This is a side-effect only component\n}\n\n// Non-React version for use in effects\nexport function createClusterPieManager(\n map: maplibregl.Map,\n sourceId: string,\n categoryValues: string[],\n categoryColorMap: Record<string, string>\n): { update: () => void; destroy: () => void } {\n const markers = new Map<string, maplibregl.Marker>();\n let updateScheduled = false;\n\n function update() {\n const source = map.getSource(sourceId) as maplibregl.GeoJSONSource | undefined;\n if (!source) return;\n \n const clusters = map.querySourceFeatures(sourceId, {\n filter: ['has', 'point_count']\n });\n \n const visibleClusterIds = new Set<string>();\n \n clusters.forEach(feature => {\n const clusterId = feature.properties?.cluster_id;\n if (clusterId === undefined) return;\n \n const clusterKey = `${clusterId}`;\n visibleClusterIds.add(clusterKey);\n \n const coords = (feature.geometry as GeoJSON.Point).coordinates as [number, number];\n const pointCount = feature.properties?.point_count || 0;\n \n const categories: CategoryData[] = categoryValues.map((cat, i) => ({\n name: cat,\n count: feature.properties?.[`cat_${i}`] || 0,\n color: categoryColorMap[cat] || '#3b82f6'\n })).filter(c => c.count > 0);\n \n const size = pointCount < 100 ? 40 : pointCount < 750 ? 50 : 60;\n \n const existingMarker = markers.get(clusterKey);\n \n if (existingMarker) {\n existingMarker.setLngLat(coords);\n } else {\n const el = createPieSVG(categories, pointCount, size, (cat, event) => {\n if (cat) {\n showTooltip(cat, event.clientX, event.clientY);\n } else {\n hideTooltip();\n }\n });\n \n el.addEventListener('click', () => {\n (source as any).getClusterExpansionZoom(clusterId, (err: any, zoom: number) => {\n if (!err) {\n map.easeTo({ center: coords, zoom: zoom + 0.5 });\n }\n });\n });\n \n const marker = new maplibregl.Marker({ element: el })\n .setLngLat(coords)\n .addTo(map);\n \n markers.set(clusterKey, marker);\n }\n });\n \n markers.forEach((marker, key) => {\n if (!visibleClusterIds.has(key)) {\n marker.remove();\n markers.delete(key);\n }\n });\n }\n\n function scheduleUpdate() {\n if (updateScheduled) return;\n updateScheduled = true;\n requestAnimationFrame(() => {\n updateScheduled = false;\n update();\n });\n }\n\n function onData(e: maplibregl.MapDataEvent) {\n if ((e as any).sourceId === sourceId) {\n scheduleUpdate();\n }\n }\n\n map.on('moveend', scheduleUpdate);\n map.on('data', onData);\n scheduleUpdate();\n\n return {\n update: scheduleUpdate,\n destroy: () => {\n map.off('moveend', scheduleUpdate);\n map.off('data', onData);\n markers.forEach(marker => marker.remove());\n markers.clear();\n hideTooltip();\n }\n };\n}\n","import { useRef, useState, useEffect, useCallback, forwardRef, useImperativeHandle, useMemo } from 'react';\nimport maplibregl from 'maplibre-gl';\nimport MapboxDraw from '@mapbox/mapbox-gl-draw';\nimport * as turf from '@turf/turf';\nimport proj4 from 'proj4';\nimport * as THREE from 'three';\n\n// Define common CRS projections\nproj4.defs('EPSG:27700', '+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 +ellps=airy +towgs84=446.448,-125.157,542.06,0.15,0.247,0.842,-20.489 +units=m +no_defs');\nproj4.defs('EPSG:3857', '+proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs');\nproj4.defs('EPSG:32630', '+proj=utm +zone=30 +datum=WGS84 +units=m +no_defs'); // UTM Zone 30N\nproj4.defs('EPSG:32631', '+proj=utm +zone=31 +datum=WGS84 +units=m +no_defs'); // UTM Zone 31N\n\n// Detect CRS from GeoJSON and reproject to WGS84 if needed\nfunction detectAndReprojectGeoJSON(geojson: GeoJSON.FeatureCollection): { \n features: GeoJSON.FeatureCollection; \n reprojected: boolean; \n sourceCRS: string | null;\n} {\n // Check for CRS property in GeoJSON\n const crsProperty = (geojson as any).crs;\n let sourceCRS: string | null = null;\n \n if (crsProperty?.properties?.name) {\n // Parse CRS URN format like \"urn:ogc:def:crs:EPSG::27700\"\n const crsName = crsProperty.properties.name;\n const epsgMatch = crsName.match(/EPSG::?(\\d+)/i);\n if (epsgMatch) {\n sourceCRS = `EPSG:${epsgMatch[1]}`;\n }\n }\n \n // If no CRS found, check if coordinates look like WGS84\n if (!sourceCRS && geojson.features.length > 0) {\n const firstCoord = getFirstCoordinate(geojson.features[0].geometry);\n if (firstCoord) {\n const [x, y] = firstCoord;\n // WGS84 coords are -180 to 180 for lon, -90 to 90 for lat\n const looksLikeWGS84 = Math.abs(x) <= 180 && Math.abs(y) <= 90;\n if (looksLikeWGS84) {\n return { features: geojson, reprojected: false, sourceCRS: 'EPSG:4326' };\n }\n }\n }\n \n // If CRS is WGS84, no reprojection needed\n if (sourceCRS === 'EPSG:4326') {\n return { features: geojson, reprojected: false, sourceCRS };\n }\n \n // Try to reproject if we have a known CRS\n if (sourceCRS && proj4.defs(sourceCRS)) {\n try {\n const reprojectedFeatures = geojson.features.map(feature => ({\n ...feature,\n geometry: reprojectGeometry(feature.geometry, sourceCRS!)\n }));\n return {\n features: { ...geojson, type: 'FeatureCollection', features: reprojectedFeatures },\n reprojected: true,\n sourceCRS\n };\n } catch (e) {\n console.error('Reprojection failed:', e);\n }\n }\n \n return { features: geojson, reprojected: false, sourceCRS };\n}\n\nfunction getFirstCoordinate(geometry: GeoJSON.Geometry): [number, number] | null {\n if (!geometry) return null;\n switch (geometry.type) {\n case 'Point':\n return geometry.coordinates as [number, number];\n case 'MultiPoint':\n case 'LineString':\n return geometry.coordinates[0] as [number, number];\n case 'MultiLineString':\n case 'Polygon':\n return geometry.coordinates[0]?.[0] as [number, number];\n case 'MultiPolygon':\n return geometry.coordinates[0]?.[0]?.[0] as [number, number];\n default:\n return null;\n }\n}\n\nfunction reprojectGeometry(geometry: GeoJSON.Geometry, fromCRS: string): GeoJSON.Geometry {\n const transform = (coord: number[]): number[] => {\n const [x, y] = proj4(fromCRS, 'EPSG:4326', [coord[0], coord[1]]);\n return coord.length > 2 ? [x, y, ...coord.slice(2)] : [x, y];\n };\n \n const reprojectCoords = (coords: any): any => {\n if (typeof coords[0] === 'number') {\n return transform(coords);\n }\n return coords.map(reprojectCoords);\n };\n \n // Handle GeometryCollection separately\n if (geometry.type === 'GeometryCollection') {\n return {\n type: 'GeometryCollection',\n geometries: geometry.geometries.map(g => reprojectGeometry(g, fromCRS))\n };\n }\n \n // All other geometry types have coordinates\n const geomWithCoords = geometry as GeoJSON.Point | GeoJSON.MultiPoint | GeoJSON.LineString | GeoJSON.MultiLineString | GeoJSON.Polygon | GeoJSON.MultiPolygon;\n return {\n ...geomWithCoords,\n coordinates: reprojectCoords(geomWithCoords.coordinates)\n } as GeoJSON.Geometry;\n}\n\n// Custom read-only select mode that allows selection but prevents dragging\nconst ViewSelectMode = {\n ...MapboxDraw.modes.simple_select,\n \n // Override all drag handlers to prevent feature movement\n dragMove() {\n // No-op: prevent dragging\n },\n onDrag() {\n // No-op: prevent dragging\n },\n onDragStart() {\n // No-op: prevent drag start\n },\n onDragEnd() {\n // No-op: prevent drag end\n },\n dragFeature() {\n // No-op: prevent feature dragging\n },\n};\nimport { saveAs } from 'file-saver';\nimport 'maplibre-gl/dist/maplibre-gl.css';\nimport '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css';\n\n// Interface for 3D flight path data\ninterface FlightPath3D {\n id: string;\n coordinates: [number, number, number][]; // [lng, lat, altitude in meters]\n color: string;\n lineWidth: number;\n}\n\n// Create a Three.js custom layer for rendering 3D flight paths at altitude\n// Uses TubeGeometry for thick, visible lines since WebGL1 ignores linewidth\nfunction createFlightPath3DLayer(\n layerId: string,\n mapInstance: maplibregl.Map,\n flightPaths: FlightPath3D[]\n): maplibregl.CustomLayerInterface {\n let camera: THREE.Camera;\n let scene: THREE.Scene;\n let renderer: THREE.WebGLRenderer;\n let meshes: THREE.Mesh[] = [];\n\n return {\n id: layerId,\n type: 'custom' as const,\n renderingMode: '3d' as const,\n\n onAdd(map: maplibregl.Map, gl: WebGLRenderingContext) {\n camera = new THREE.Camera();\n scene = new THREE.Scene();\n\n // Create tube meshes for each flight path (thick, visible lines)\n flightPaths.forEach(path => {\n if (path.coordinates.length < 2) return;\n\n // Convert coordinates to Vector3 array for CatmullRomCurve3\n const points: THREE.Vector3[] = [];\n const altitudes: number[] = [];\n \n path.coordinates.forEach(coord => {\n const [lng, lat, alt = 0] = coord;\n const mercator = maplibregl.MercatorCoordinate.fromLngLat([lng, lat], alt);\n points.push(new THREE.Vector3(mercator.x, mercator.y, mercator.z));\n altitudes.push(alt);\n });\n\n // Calculate min/max altitude for color gradient\n const minAlt = Math.min(...altitudes);\n const maxAlt = Math.max(...altitudes);\n const altRange = maxAlt - minAlt || 1;\n\n // Create a smooth curve through the points\n const curve = new THREE.CatmullRomCurve3(points, false, 'catmullrom', 0.5);\n \n // Tube radius in Mercator units - thin line for drone flight visualization\n // Small radius for realistic drone path representation\n const tubeRadius = 0.000000075;\n const tubularSegments = Math.max(points.length * 4, 64);\n const radialSegments = 8;\n \n const geometry = new THREE.TubeGeometry(curve, tubularSegments, tubeRadius, radialSegments, false);\n \n // Create vertex colors based on altitude along the tube\n const positionAttr = geometry.attributes.position;\n const colors: number[] = [];\n \n for (let i = 0; i < positionAttr.count; i++) {\n // Approximate the altitude based on position along curve\n const segmentIndex = Math.floor(i / (radialSegments + 1));\n const t = segmentIndex / tubularSegments;\n const altIndex = Math.min(Math.floor(t * altitudes.length), altitudes.length - 1);\n const alt = altitudes[altIndex];\n const normalizedAlt = (alt - minAlt) / altRange;\n \n // Bright magenta (low) to bright cyan (high) gradient\n const color = new THREE.Color();\n color.setRGB(1 - normalizedAlt, normalizedAlt, 1);\n colors.push(color.r, color.g, color.b);\n }\n \n geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3));\n\n const material = new THREE.MeshBasicMaterial({\n vertexColors: true,\n side: THREE.DoubleSide,\n });\n\n const mesh = new THREE.Mesh(geometry, material);\n scene.add(mesh);\n meshes.push(mesh);\n });\n\n renderer = new THREE.WebGLRenderer({\n canvas: map.getCanvas(),\n context: gl,\n antialias: true,\n });\n\n renderer.autoClear = false;\n },\n\n render(_gl: WebGLRenderingContext, options: maplibregl.CustomRenderMethodInput) {\n const matrix = options.defaultProjectionData.mainMatrix;\n const m = new THREE.Matrix4().fromArray(Array.from(matrix as ArrayLike<number>));\n camera.projectionMatrix = m;\n renderer.resetState();\n renderer.render(scene, camera);\n mapInstance.triggerRepaint();\n },\n\n onRemove() {\n meshes.forEach(mesh => {\n scene.remove(mesh);\n mesh.geometry.dispose();\n (mesh.material as THREE.Material).dispose();\n });\n meshes = [];\n },\n };\n}\n\n// Helper to check if a LineString has altitude data (Z coordinates)\nfunction hasAltitudeData(feature: GeoJSON.Feature): boolean {\n if (feature.geometry.type === 'LineString') {\n const coords = feature.geometry.coordinates;\n return coords.some(c => c.length >= 3 && c[2] !== 0);\n }\n if (feature.geometry.type === 'MultiLineString') {\n const coords = feature.geometry.coordinates;\n return coords.some(line => line.some(c => c.length >= 3 && c[2] !== 0));\n }\n return false;\n}\n\n// Extract 3D flight paths from GeoJSON features\n// Handles both LineStrings with Z coordinates AND Point sequences with altitude\nfunction extract3DFlightPaths(features: GeoJSON.Feature[]): FlightPath3D[] {\n const paths: FlightPath3D[] = [];\n \n // First, handle explicit LineString/MultiLineString features\n features.forEach(feature => {\n if (feature.geometry.type === 'LineString' && hasAltitudeData(feature)) {\n paths.push({\n id: feature.id as string || `path-${paths.length}`,\n coordinates: feature.geometry.coordinates as [number, number, number][],\n color: (feature.properties?.stroke as string) || '#3b82f6',\n lineWidth: (feature.properties?.['stroke-width'] as number) || 3,\n });\n } else if (feature.geometry.type === 'MultiLineString') {\n feature.geometry.coordinates.forEach((line, idx) => {\n const has3D = line.some(c => c.length >= 3 && c[2] !== 0);\n if (has3D) {\n paths.push({\n id: `${feature.id || 'path'}-${idx}`,\n coordinates: line as [number, number, number][],\n color: (feature.properties?.stroke as string) || '#3b82f6',\n lineWidth: (feature.properties?.['stroke-width'] as number) || 3,\n });\n }\n });\n }\n });\n \n // Second, build flight paths from Point features with altitude data\n // Group points by TargetID (or use 'default' if not specified)\n const pointsByTarget = new Map<string, { \n coords: [number, number, number]; \n timestamp: number;\n properties: Record<string, unknown>;\n }[]>();\n \n features.forEach(feature => {\n if (feature.geometry.type === 'Point') {\n const coords = feature.geometry.coordinates;\n // Check if point has Z coordinate (altitude)\n if (coords.length >= 3 && coords[2] !== 0) {\n const targetId = (feature.properties?.TargetID as string) || 'default-points';\n const startDateStr = feature.properties?.startDate as string;\n const timestamp = startDateStr ? new Date(startDateStr).getTime() : 0;\n \n if (!pointsByTarget.has(targetId)) {\n pointsByTarget.set(targetId, []);\n }\n pointsByTarget.get(targetId)!.push({\n coords: coords as [number, number, number],\n timestamp,\n properties: feature.properties || {},\n });\n }\n }\n });\n \n // For each target, sort points by timestamp and create a flight path\n pointsByTarget.forEach((points, targetId) => {\n if (points.length < 2) return; // Need at least 2 points for a path\n \n // Sort by timestamp\n points.sort((a, b) => a.timestamp - b.timestamp);\n \n // Extract coordinates in order\n const coordinates = points.map(p => p.coords);\n \n paths.push({\n id: `points-path-${targetId}`,\n coordinates,\n color: '#3b82f6',\n lineWidth: 3,\n });\n });\n \n return paths;\n}\n\nimport { DrawingToolbar, DrawingMode, MeasureMode, SelectionMode } from './drawing-toolbar';\nimport { LayersPanel, Layer, TraceConfig, MapStyle, HeatmapConfig, ClusterConfig, VisualConfig, AutoLabelConfig, AltitudeDisplayMode } from './layers-panel';\nimport { PropertiesPanel } from './properties-panel';\nimport { StatusIndicator } from './status-indicator';\nimport { Timebar, TIMEBAR_HEIGHT, TIMEBAR_BOTTOM_OFFSET } from './timebar';\nimport { MapDropZone } from './map-drop-zone';\nimport { Button, Tooltip, Card } from 'antd';\nimport { useTimelineStore, normalizeTemporalProperties } from '@/lib/timeline-store';\nimport { useToast } from '@/hooks/use-toast';\nimport type { MapEditorHandle, MapEditorProps } from '@/lib/map-editor-api';\nimport { Clock, Layers, AlertTriangle } from 'lucide-react';\nimport { createClusterPieManager } from './cluster-pie-chart';\n\n// Simple base style with satellite raster layer (hidden by default)\n// Streets/terrain/dark layers are added dynamically after loading external styles\n// Default local glyphs URL - uses Noto Sans fonts packaged with the application\nconst DEFAULT_LOCAL_GLYPHS_URL = '/fonts/{fontstack}/{range}.pbf';\n\n// Create base style dynamically based on configuration\nfunction createBaseStyle(options: {\n glyphsUrl?: string;\n enableSatellite?: boolean;\n enableTerrain?: boolean;\n}): maplibregl.StyleSpecification {\n const sources: Record<string, maplibregl.SourceSpecification> = {};\n const layers: maplibregl.LayerSpecification[] = [\n {\n id: 'background',\n type: 'background',\n paint: {\n 'background-color': '#f0f0f0'\n }\n }\n ];\n\n if (options.enableSatellite !== false) {\n sources['satellite-tiles'] = {\n type: 'raster',\n tiles: ['https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}'],\n tileSize: 256,\n attribution: 'Esri, Maxar, Earthstar Geographics',\n };\n layers.push({\n id: 'satellite-layer',\n type: 'raster',\n source: 'satellite-tiles',\n minzoom: 0,\n maxzoom: 22,\n layout: { visibility: 'none' },\n });\n }\n\n if (options.enableTerrain !== false) {\n sources['terrain-dem'] = {\n type: 'raster-dem',\n tiles: ['https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png'],\n tileSize: 256,\n maxzoom: 15,\n encoding: 'terrarium',\n };\n }\n\n return {\n version: 8,\n sources,\n layers,\n glyphs: options.glyphsUrl || DEFAULT_LOCAL_GLYPHS_URL,\n };\n}\n\n// Layer prefixes for each basemap style (used to toggle visibility)\nconst BASEMAP_LAYER_PREFIXES: Record<MapStyle, string> = {\n streets: 'streets-',\n satellite: 'satellite-',\n dark: 'dark-',\n};\n\n// External style URLs to fetch and merge\nconst EXTERNAL_STYLE_URLS: Record<string, string> = {\n streets: 'https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json',\n dark: 'https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json',\n};\n\ninterface UndoState {\n features: GeoJSON.Feature[];\n layers: Layer[];\n selectedIds: string[];\n}\n\nexport const MapEditorCanvas = forwardRef<MapEditorHandle, MapEditorProps>(function MapEditorCanvas(\n {\n className,\n enableDrawing = true,\n enableLayers = true,\n enableTimeline = true,\n enableMeasurement = true,\n enableSelection = true,\n hiddenDrawingTools = [],\n hiddenSelectionTools = [],\n expandSelectionTools = false,\n showFilterTool = false,\n defaultSelectionMode = 'click',\n initialSelectionActive = true,\n showStatusPanel = true,\n onSelectionComplete,\n persistSelection = false,\n showDebugSidebar = false,\n initialCenter = [-74.006, 40.7128],\n initialZoom = 12,\n baseMapStyle = 'streets',\n customBasemaps,\n basemapOrder,\n initialDrawingMode,\n onFeatureSelect,\n onFeatureCreate,\n onFeatureUpdate,\n onFeatureDelete,\n onLayerChange,\n onActiveEditingLayerChange,\n onTimelineChange,\n onMapReady,\n onViewportChange,\n showClearFilter = false,\n onClearFilter,\n showGoToButton = false,\n onDropPoint,\n geocodingUrl,\n geocoderProvider,\n onSearchEngineRequest,\n onWorkspaceLoad,\n onWorkspaceSave,\n entityCardProvider,\n typePickerProvider,\n contextMenuProvider,\n featureSaveProvider,\n tooltipProvider,\n glyphsUrl,\n filterGeometry,\n enableSatellite = true,\n enableTerrain = true,\n enable3D = true,\n hideBasemapSwitcher = false,\n externalPersistence = false,\n enableKeyboardShortcuts = true,\n enableProperties = true,\n },\n ref\n) {\n const mapContainer = useRef<HTMLDivElement>(null);\n const map = useRef<maplibregl.Map | null>(null);\n const draw = useRef<MapboxDraw | null>(null);\n const fileInputRef = useRef<HTMLInputElement>(null);\n const hiddenFeatures = useRef<Map<string, GeoJSON.Feature[]>>(new Map());\n const tracePopupRef = useRef<maplibregl.Popup | null>(null);\n const tooltipElRef = useRef<HTMLDivElement | null>(null);\n const layersRef = useRef<Layer[]>([\n { id: 'default', name: 'Default Layer', visible: true, featureIds: [] }\n ]);\n const activeEditingLayerIdRef = useRef<string>('default');\n // Flag to distinguish API/import additions from user-drawn features\n const isApiAddingRef = useRef<boolean>(false);\n const isEditModeRef = useRef<boolean>(false);\n const originalGeometriesRef = useRef<Map<string, GeoJSON.Geometry>>(new Map());\n // Store features for read-only layers (bypasses MapboxDraw for performance)\n const readOnlyFeatures = useRef<Map<string, GeoJSON.Feature[]>>(new Map());\n // Track which basemap styles have been loaded and their layer IDs (for visibility toggling)\n // Note: satellite is only included if enableSatellite is true\n const loadedBasemaps = useRef<Set<string>>(new Set(enableSatellite ? ['satellite'] : []));\n const basemapLayerIds = useRef<Map<string, string[]>>(new Map(enableSatellite ? [['satellite', ['satellite-layer']]] : []));\n const loadingBasemaps = useRef<Set<string>>(new Set());\n // Custom basemap registry (id -> definition)\n const customBasemapRegistry = useRef<Map<string, import('@/lib/map-editor-api').BasemapDefinition>>(new Map());\n // Pie chart cluster managers (for category mode clustering with SVG pie charts)\n const clusterPieManagers = useRef<Map<string, { update: () => void; destroy: () => void }>>(new Map());\n // Ref to store handleMapStyleChange for use in imperative handle\n const handleMapStyleChangeRef = useRef<((style: MapStyle) => Promise<void>) | null>(null);\n // Track 3D flight path layer for altitude visualization\n const flightPath3DLayerId = useRef<string | null>(null);\n // Ref to store update3DFlightPaths for use in syncFeaturesToCustomLayers\n const update3DFlightPathsRef = useRef<(() => void) | null>(null);\n // Keep tooltipProvider in a ref so the mouseenter closure always sees the latest value\n const tooltipProviderRef = useRef(tooltipProvider);\n tooltipProviderRef.current = tooltipProvider;\n \n \n const [isMapLoaded, setIsMapLoaded] = useState(false);\n // Ref to track map loaded state synchronously (for use in imperative handle)\n const isMapLoadedRef = useRef(false);\n const [mapError, setMapError] = useState<string | null>(null);\n const [activeMode, setActiveMode] = useState<DrawingMode>('view_select');\n const [selectedFeatureIds, setSelectedFeatureIds] = useState<string[]>([]);\n const [featureCount, setFeatureCount] = useState(0);\n const [featureUpdateCounter, setFeatureUpdateCounter] = useState(0); // Trigger re-render when features update\n const [showProperties, setShowProperties] = useState(false);\n const [autoFocusLabel, setAutoFocusLabel] = useState(false);\n const [showLayers, setShowLayers] = useState(false);\n const [layers, setLayers] = useState<Layer[]>([\n { id: 'default', name: 'Default Layer', visible: true, featureIds: [] }\n ]);\n const [activeEditingLayerId, setActiveEditingLayerId] = useState<string>('default');\n const [undoStack, setUndoStack] = useState<UndoState[]>([]);\n const [redoStack, setRedoStack] = useState<UndoState[]>([]);\n const [isEditMode, setIsEditMode] = useState(false);\n const [currentMapStyle, setCurrentMapStyle] = useState<MapStyle>(baseMapStyle);\n const [measureMode, setMeasureMode] = useState<MeasureMode>('none');\n const [measurePoints, setMeasurePoints] = useState<[number, number][]>([]);\n const [measureResult, setMeasureResult] = useState<string | null>(null);\n const [is3DTerrainEnabled, setIs3DTerrainEnabled] = useState(false);\n const [selectionMode, setSelectionMode] = useState<SelectionMode>(defaultSelectionMode);\n const [isSelectionToolActive, setIsSelectionToolActive] = useState(initialSelectionActive);\n const filterActiveRef = useRef(false);\n const [selectionPoints, setSelectionPoints] = useState<[number, number][]>([]);\n const [selectionHoverPoint, setSelectionHoverPoint] = useState<[number, number] | null>(null);\n const [persistedSelectionPolygon, setPersistedSelectionPolygon] = useState<[number, number][] | null>(null);\n const isDrawingSelection = useRef(false);\n const isSelectingReadOnlyRef = useRef(false); // Track when selecting read-only to prevent selectionchange override\n const contextMenuFiredRef = useRef(false);\n const filterPolygonRef = useRef<SVGPolygonElement>(null);\n // Track pending feature kind for special tools (text, arrow, circle, rectangle)\n const pendingFeatureKindRef = useRef<'text' | 'arrow' | 'circle' | 'rectangle' | null>(null);\n // Track arrow feature IDs externally since MapboxDraw may not persist kind property reliably\n const arrowFeatureIdsRef = useRef<Set<string>>(new Set());\n // Circle drawing state (click center, drag radius)\n const [circleDrawCenter, setCircleDrawCenter] = useState<[number, number] | null>(null);\n const [circleDrawPreview, setCircleDrawPreview] = useState<[number, number][] | null>(null);\n const isDrawingCircle = useRef(false);\n // Rectangle drawing state (click corner, drag to opposite corner)\n const [rectangleDrawCorner, setRectangleDrawCorner] = useState<[number, number] | null>(null);\n const [rectangleDrawPreview, setRectangleDrawPreview] = useState<[number, number][] | null>(null);\n const isDrawingRectangle = useRef(false);\n const [autoLabelConfig, setAutoLabelConfig] = useState<AutoLabelConfig>({ enabled: true, threshold: 220 });\n // Start with high count so labels stay hidden until first viewport query completes\n const [visibleFeatureCount, setVisibleFeatureCount] = useState<number>(Infinity);\n const lastLabelVisibility = useRef<boolean>(false);\n // Suppress labels during bulk operations and map movements (STATE for re-render)\n const [labelsSuppressed, setLabelsSuppressed] = useState<boolean>(true);\n // Context menu state\n const [contextMenu, setContextMenu] = useState<{\n x: number;\n y: number;\n items: import('@/lib/map-editor-api').ContextMenuItem[];\n } | null>(null);\n \n const timelineStore = useTimelineStore();\n const { toast } = useToast();\n\n // Suppress non-critical MapLibre tile parsing errors that trigger the Vite error overlay\n useEffect(() => {\n const handleError = (event: ErrorEvent) => {\n const msg = event.message || '';\n // Suppress known non-critical errors from MapLibre\n if (msg.includes('unknown feature value') ||\n msg.includes('getSource') ||\n msg.includes('WebGL') ||\n msg.includes('style is not loaded') ||\n msg.includes('Map container') ||\n msg.includes('tile') ||\n msg.includes('already running') ||\n msg.includes('out of range') ||\n msg.includes('DEM data')) {\n event.preventDefault();\n event.stopPropagation();\n return true;\n }\n };\n \n const handleUnhandledRejection = (event: PromiseRejectionEvent) => {\n let message = '';\n try {\n message = event.reason?.message || String(event.reason);\n } catch {\n message = 'unknown';\n }\n // Suppress known non-critical errors\n if (message.includes('unknown feature value') ||\n message.includes('getSource') ||\n message.includes('WebGL') ||\n message.includes('style') ||\n message.includes('tile') ||\n message.includes('Map container') ||\n message.includes('already running') ||\n message.includes('out of range') ||\n message.includes('DEM data')) {\n event.preventDefault();\n return;\n }\n };\n \n // Catch all uncaught errors including non-Error throws\n const handleGlobalError = (event: Event) => {\n // Suppress all errors during map operations to prevent Vite overlay\n if (event instanceof ErrorEvent) {\n const msg = event.message || '';\n if (msg.includes('MapLibre') || msg.includes('maplibre') || msg.includes('map') ||\n msg.includes('tile') || msg.includes('WebGL') || msg.includes('getSource') ||\n msg.includes('style') || !event.message) {\n event.preventDefault();\n event.stopPropagation();\n return false;\n }\n }\n };\n \n window.addEventListener('error', handleError, true);\n window.addEventListener('error', handleGlobalError, true);\n window.addEventListener('unhandledrejection', handleUnhandledRejection, true);\n \n return () => {\n window.removeEventListener('error', handleError, true);\n window.removeEventListener('error', handleGlobalError, true);\n window.removeEventListener('unhandledrejection', handleUnhandledRejection, true);\n if (tooltipElRef.current) {\n try { tooltipElRef.current.parentElement?.removeChild(tooltipElRef.current); } catch {}\n tooltipElRef.current = null;\n }\n };\n }, []);\n\n const hasVisibleLayers = layers.some(l => l.visible);\n \n // Check if there's an editable layer selected (visible, not read-only, and explicitly selected)\n const hasEditableLayer = activeEditingLayerId !== '' && \n layers.some(l => l.id === activeEditingLayerId && l.visible && !l.readOnly);\n\n // Auto-exit edit mode when no editable layer is available\n useEffect(() => {\n if (isEditMode && !hasEditableLayer) {\n setIsEditMode(false);\n if (draw.current) {\n draw.current.changeMode('view_select');\n setActiveMode('view_select');\n }\n }\n }, [hasEditableLayer, isEditMode]);\n\n layersRef.current = layers;\n activeEditingLayerIdRef.current = activeEditingLayerId;\n isEditModeRef.current = isEditMode;\n\n // Helper to get all features (from MapboxDraw and read-only layers)\n const getAllFeatures = useCallback((): GeoJSON.Feature[] => {\n const drawFeatures = draw.current ? draw.current.getAll().features as GeoJSON.Feature[] : [];\n const readOnly: GeoJSON.Feature[] = [];\n readOnlyFeatures.current.forEach((features) => {\n readOnly.push(...features);\n });\n return [...drawFeatures, ...readOnly];\n }, []);\n \n const getSelectedFeatures = useCallback(() => {\n // Get selected features from both MapboxDraw and read-only storage\n const drawSelected = draw.current ? draw.current.getSelected().features as GeoJSON.Feature[] : [];\n \n // Also check if any selected IDs are from read-only features\n const readOnlySelected: GeoJSON.Feature[] = [];\n if (selectedFeatureIds.length > 0) {\n const selectedIdSet = new Set(selectedFeatureIds);\n readOnlyFeatures.current.forEach((features) => {\n features.forEach(f => {\n if (f.id && selectedIdSet.has(String(f.id))) {\n readOnlySelected.push(f);\n }\n });\n });\n }\n \n // Combine and deduplicate\n const allSelected = [...drawSelected, ...readOnlySelected];\n const seenIds = new Set<string>();\n return allSelected.filter(f => {\n const id = String(f.id);\n if (seenIds.has(id)) return false;\n seenIds.add(id);\n return true;\n });\n }, [selectedFeatureIds]);\n\n const selectedFeatures = getSelectedFeatures();\n\n // Helper to get a feature by ID from MapboxDraw or read-only storage\n const getFeatureById = useCallback((id: string): GeoJSON.Feature | null => {\n // Check MapboxDraw first\n if (draw.current) {\n const feature = draw.current.get(id);\n if (feature) return feature;\n }\n // Check read-only storage\n const entries = Array.from(readOnlyFeatures.current.entries());\n for (const [, features] of entries) {\n const found = features.find((f: GeoJSON.Feature) => String(f.id) === id);\n if (found) return found;\n }\n return null;\n }, []);\n\n // Centralized selection state helper that handles editable vs read-only features\n // and prevents MapboxDraw selectionchange from overwriting read-only selections\n const applySelectionState = useCallback((nextIds: string[], options?: { focusProperties?: boolean }) => {\n if (!isMapLoaded || !draw.current) {\n setSelectedFeatureIds(nextIds);\n if (options?.focusProperties) setShowProperties(nextIds.length > 0);\n // Always call onFeatureSelect to notify clearing\n onFeatureSelect?.(nextIds.length > 0 ? nextIds.map(id => getFeatureById(id)).filter(Boolean) as GeoJSON.Feature[] : []);\n return;\n }\n \n // Build set of editable IDs from layers (not draw.getAll() which excludes hidden features)\n const editableIdSet = new Set<string>();\n layersRef.current.forEach(layer => {\n if (!layer.readOnly) {\n layer.featureIds.forEach(id => editableIdSet.add(id));\n }\n });\n \n // Partition IDs into editable vs read-only\n const editableIds: string[] = [];\n const readOnlyIds: string[] = [];\n nextIds.forEach(id => (editableIdSet.has(id) ? editableIds : readOnlyIds).push(id));\n \n // Set guard if any read-only features are being selected\n if (readOnlyIds.length > 0) {\n isSelectingReadOnlyRef.current = true;\n }\n \n // Update MapboxDraw selection (only editable IDs that are currently visible in draw)\n const mode: DrawingMode = isEditModeRef.current ? 'simple_select' : 'view_select';\n // Filter to only IDs that exist in MapboxDraw right now\n const visibleEditableIds = editableIds.filter(id => {\n try { return !!draw.current!.get(id); } catch { return false; }\n });\n draw.current.changeMode(mode as string, { featureIds: visibleEditableIds });\n \n // Update React state with all IDs\n setSelectedFeatureIds(nextIds);\n selectedFeatureIdsRef.current = nextIds;\n if (options?.focusProperties) setShowProperties(nextIds.length > 0);\n \n // Get full feature objects for callback - always call to notify clearing\n const selectedFeaturesForCallback = nextIds.map(id => getFeatureById(id)).filter(Boolean) as GeoJSON.Feature[];\n onFeatureSelect?.(selectedFeaturesForCallback);\n \n // Trigger visual sync\n syncRef.current();\n \n // Clear guard after event loop to prevent race conditions\n if (readOnlyIds.length > 0) {\n queueMicrotask(() => { isSelectingReadOnlyRef.current = false; });\n }\n }, [isMapLoaded, getFeatureById, onFeatureSelect]);\n\n const saveStateForUndo = useCallback(() => {\n if (!draw.current) return;\n const currentState: UndoState = {\n features: draw.current.getAll().features as GeoJSON.Feature[],\n layers: JSON.parse(JSON.stringify(layers)),\n selectedIds: [...selectedFeatureIds],\n };\n setUndoStack(prev => [...prev.slice(-49), currentState]);\n setRedoStack([]);\n }, [layers, selectedFeatureIds]);\n\n const updateFeatureCount = useCallback(() => {\n // Count features from MapboxDraw (visible layers)\n const drawFeatureCount = draw.current ? draw.current.getAll().features.length : 0;\n // Count features from hidden layers\n let hiddenCount = 0;\n hiddenFeatures.current.forEach((features) => {\n hiddenCount += features.length;\n });\n // Count features from visible read-only layers\n let readOnlyCount = 0;\n readOnlyFeatures.current.forEach((features, layerId) => {\n const layer = layersRef.current.find(l => l.id === layerId);\n if (layer?.visible) {\n readOnlyCount += features.length;\n }\n });\n setFeatureCount(drawFeatureCount + hiddenCount + readOnlyCount);\n }, []);\n\n // Ref to track timeline visibility (declared early for use in sync function)\n const timelineVisibleIdsRef = useRef<Set<string> | null>(null);\n \n // Ref to always have the latest sync function available\n const syncRef = useRef<() => void>(() => {});\n\n // Generate consistent color from string value using Tableau 20 palette\n // This is a professionally designed palette for categorical data visualization\n const hashStringToColor = useCallback((str: string): string => {\n // Tableau 20 - balanced, perceptually distinct, colorblind-friendly\n const palette = [\n '#4e79a7', // steel blue\n '#f28e2b', // orange\n '#e15759', // red\n '#76b7b2', // teal\n '#59a14f', // green\n '#edc948', // yellow\n '#b07aa1', // purple\n '#ff9da7', // pink\n '#9c755f', // brown\n '#bab0ac', // gray\n '#5fa2ce', // light blue\n '#ffbe7d', // light orange\n '#ff9888', // salmon\n '#8cd17d', // light green\n '#b6992d', // olive\n '#f1ce63', // gold\n '#d4a6c8', // lavender\n '#86bcb6', // aqua\n '#d37295', // rose\n '#499894', // dark teal\n ];\n \n // Simple hash for consistent color assignment\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n hash = ((hash << 5) - hash) + str.charCodeAt(i);\n hash = hash & hash;\n }\n return palette[Math.abs(hash) % palette.length];\n }, []);\n\n // Compute color map for selected features (for timeline display)\n // This matches the color computation in syncFeaturesToCustomLayers for consistency\n const selectedFeatureColors = useMemo(() => {\n if (selectedFeatureIds.length === 0) return new Map<string, string>();\n \n const colorMap = new Map<string, string>();\n \n // Build feature lookup and layer lookup\n const featureToLayerMap = new Map<string, typeof layers[0]>();\n layers.forEach(layer => {\n layer.featureIds.forEach(fid => {\n featureToLayerMap.set(fid, layer);\n });\n });\n \n // Get all features for lookup\n const allFeats = getAllFeatures();\n const featById = new Map<string, GeoJSON.Feature>();\n allFeats.forEach(f => {\n if (f.id) featById.set(String(f.id), f);\n });\n \n // Compute trace point colors (same logic as syncFeaturesToCustomLayers)\n const tracePointColors = new Map<string, string>();\n layers.forEach(layer => {\n if (!layer.traceConfig?.enabled || !layer.visible) return;\n \n // Get visible point features with startDate from this layer\n const layerFeatures: GeoJSON.Feature[] = [];\n layer.featureIds.forEach(id => {\n const f = featById.get(id);\n if (!f || f.geometry.type !== 'Point' || !f.properties?.startDate) return;\n layerFeatures.push(f);\n });\n \n if (layerFeatures.length < 1) return;\n \n // Group by field if configured\n const groupByField = layer.traceConfig.groupByField;\n const groups = new Map<string, GeoJSON.Feature[]>();\n \n layerFeatures.forEach(f => {\n const key = groupByField && f.properties?.[groupByField] \n ? String(f.properties[groupByField]) \n : '__all__';\n if (!groups.has(key)) groups.set(key, []);\n groups.get(key)!.push(f);\n });\n \n // Generate colors for groups (same logic as trace line colors)\n const groupKeys = Array.from(groups.keys());\n groupKeys.forEach((key, index) => {\n const color = key === '__all__' \n ? '#3b82f6'\n : `hsl(${(index * 360 / groupKeys.length) % 360}, 70%, 50%)`;\n \n groups.get(key)!.forEach(f => {\n if (f.id) tracePointColors.set(String(f.id), color);\n });\n });\n });\n \n // Compute color for each selected feature\n selectedFeatureIds.forEach(fid => {\n const feature = featById.get(fid);\n const layer = featureToLayerMap.get(fid);\n const visualConfig = layer?.visualConfig;\n \n // Check if this is a trace point with assigned color\n if (tracePointColors.has(fid)) {\n colorMap.set(fid, tracePointColors.get(fid)!);\n return;\n }\n \n // Default color\n let color = (feature?.properties?.stroke as string) || '#3b82f6';\n \n // Apply layer color config\n const colorConfig = visualConfig?.color;\n if (colorConfig && feature) {\n if (colorConfig.mode === 'fixed' && colorConfig.fixedColor) {\n color = colorConfig.fixedColor;\n } else if (colorConfig.mode === 'field' && colorConfig.fieldName && feature.properties) {\n const fieldValue = feature.properties[colorConfig.fieldName];\n if (fieldValue !== undefined && fieldValue !== null) {\n color = hashStringToColor(String(fieldValue));\n }\n }\n }\n \n colorMap.set(fid, color);\n });\n \n return colorMap;\n }, [selectedFeatureIds, layers, getAllFeatures, hashStringToColor]);\n\n\n // Sync features to custom rendering layers (separate from MapboxDraw's internal layers)\n const syncFeaturesToCustomLayers = useCallback(() => {\n if (!map.current) return;\n \n const source = map.current.getSource('custom-features') as maplibregl.GeoJSONSource | undefined;\n if (!source) return;\n \n // Get editable features from MapboxDraw (if available)\n const drawFeatures = draw.current ? draw.current.getAll() : { type: 'FeatureCollection' as const, features: [] };\n const drawSelectedIds = draw.current ? draw.current.getSelectedIds() : [];\n const componentSelectedIds = selectedFeatureIdsRef.current;\n const selectedIds = Array.from(new Set([...drawSelectedIds, ...componentSelectedIds]));\n const visibleSet = timelineVisibleIdsRef.current;\n \n // Build combined feature collection from both MapboxDraw and read-only layers\n // Use layersRef.current for immediate access (avoids stale state after setLayers)\n const currentLayers = layersRef.current;\n const allFeatures: GeoJSON.Feature[] = [...drawFeatures.features];\n \n // Add read-only features\n readOnlyFeatures.current.forEach((features, layerId) => {\n const layer = currentLayers.find(l => l.id === layerId);\n if (layer?.visible) {\n allFeatures.push(...features);\n }\n });\n \n // Build O(1) lookup map: feature ID -> feature\n // Normalize all IDs to strings for consistent lookups\n const featureById = new Map<string, GeoJSON.Feature>();\n allFeatures.forEach(f => {\n if (f.id !== undefined && f.id !== null) {\n featureById.set(String(f.id), f);\n }\n });\n \n // Build lookup of feature ID -> layer for visual config\n const featureToLayer = new Map<string, Layer>();\n currentLayers.forEach(layer => {\n layer.featureIds.forEach(fid => featureToLayer.set(fid, layer));\n });\n \n // Pre-calculate min/max for size fields per visible layer only (using O(1) lookup)\n const sizeFieldRanges = new Map<string, { min: number; max: number }>();\n currentLayers.forEach(layer => {\n // Skip hidden layers - they shouldn't influence sizing of visible layers\n if (!layer.visible) return;\n \n const sizeConfig = layer.visualConfig?.size;\n if (sizeConfig?.mode === 'field' && sizeConfig.fieldName) {\n let min = Infinity, max = -Infinity;\n layer.featureIds.forEach(fid => {\n const feature = featureById.get(fid);\n if (feature?.properties) {\n const rawVal = feature.properties[sizeConfig.fieldName!];\n // Handle both numbers and numeric strings\n const val = typeof rawVal === 'number' ? rawVal : \n (typeof rawVal === 'string' && rawVal.trim() !== '' ? Number(rawVal) : NaN);\n if (isFinite(val)) {\n min = Math.min(min, val);\n max = Math.max(max, val);\n }\n }\n });\n if (isFinite(min) && isFinite(max)) {\n sizeFieldRanges.set(layer.id, { min, max });\n }\n }\n });\n \n // Compute trace point info for layers with traces enabled\n // - lastTracePointIds: last point in each group (will be shown with larger size)\n // - tracePointColors: color for ALL trace points (matches trace line color)\n // - tracePointIds: all points in trace layers (will show with small size, trace color)\n const lastTracePointIds = new Set<string>();\n const tracePointColors = new Map<string, string>();\n const lastTracePointLabels = new Map<string, string>();\n const tracePointIds = new Set<string>();\n \n currentLayers.forEach(layer => {\n if (!layer.traceConfig?.enabled || !layer.visible) return;\n \n // Get visible point features with startDate from this layer (O(1) lookup)\n const layerFeatures: GeoJSON.Feature[] = [];\n layer.featureIds.forEach(id => {\n const f = featureById.get(id);\n if (!f || f.geometry.type !== 'Point' || !f.properties?.startDate) return;\n if (visibleSet && f.id && !visibleSet.has(String(f.id))) return;\n layerFeatures.push(f);\n });\n \n if (layerFeatures.length < 1) return;\n \n // Group by field if configured\n const groupByField = layer.traceConfig.groupByField;\n const groups = new Map<string, GeoJSON.Feature[]>();\n \n layerFeatures.forEach(f => {\n const key = groupByField && f.properties?.[groupByField] \n ? String(f.properties[groupByField]) \n : '__all__';\n if (!groups.has(key)) groups.set(key, []);\n groups.get(key)!.push(f);\n });\n \n // Generate colors for groups (same logic as trace line colors)\n const groupKeys = Array.from(groups.keys());\n const groupColors = new Map<string, string>();\n groupKeys.forEach((key, index) => {\n if (key === '__all__') {\n groupColors.set(key, '#3b82f6');\n } else {\n const hue = (index * 360 / groupKeys.length) % 360;\n groupColors.set(key, `hsl(${hue}, 70%, 50%)`);\n }\n });\n \n // Find last point (chronologically) in each group, hide all others\n groups.forEach((groupFeatures, groupKey) => {\n const sorted = [...groupFeatures].sort((a, b) => {\n const dateA = new Date(a.properties?.startDate || 0).getTime();\n const dateB = new Date(b.properties?.startDate || 0).getTime();\n return dateA - dateB;\n });\n \n if (sorted.length > 0) {\n const groupColor = groupColors.get(groupKey) || '#3b82f6';\n \n // All points in trace mode get the trace line color\n sorted.forEach(point => {\n if (point.id) {\n tracePointIds.add(String(point.id));\n tracePointColors.set(String(point.id), groupColor);\n }\n });\n \n // Last point gets shown larger with label\n const lastPoint = sorted[sorted.length - 1];\n if (lastPoint.id) {\n lastTracePointIds.add(String(lastPoint.id));\n // Store the grouping field value as label (if grouping is enabled)\n if (groupByField && groupKey !== '__all__') {\n lastTracePointLabels.set(String(lastPoint.id), groupKey);\n }\n }\n }\n });\n });\n\n // Build feature collection with styling properties\n const sourceData: GeoJSON.FeatureCollection = {\n type: 'FeatureCollection',\n features: allFeatures.map(f => {\n // Normalize ID to string for consistent lookups across all maps/sets\n const featureId = String(f.id);\n const layer = featureToLayer.get(featureId);\n const visualConfig = layer?.visualConfig;\n \n // Check timeline visibility - if no filter active, show all; otherwise check set\n const isTimelineVisible = visibleSet === null || visibleSet.has(featureId);\n const baseOpacity = (f.properties?.['stroke-opacity'] as number) ?? 1;\n \n // Determine color based on visualConfig\n let strokeColor = (f.properties?.stroke as string) || '#3b82f6';\n const colorConfig = visualConfig?.color;\n if (colorConfig) {\n if (colorConfig.mode === 'fixed' && colorConfig.fixedColor) {\n strokeColor = colorConfig.fixedColor;\n } else if (colorConfig.mode === 'field' && colorConfig.fieldName && f.properties) {\n const fieldValue = f.properties[colorConfig.fieldName];\n if (fieldValue !== undefined && fieldValue !== null) {\n strokeColor = hashStringToColor(String(fieldValue));\n }\n }\n // mode === 'standard' uses default from feature properties\n }\n \n // Determine size based on visualConfig\n let strokeWidth = (f.properties?.['stroke-width'] as number) || 2;\n let pointRadius = Math.round(3 + strokeWidth); // Smaller default radius (must be integer)\n const sizeConfig = visualConfig?.size;\n if (sizeConfig) {\n if (sizeConfig.mode === 'override' && sizeConfig.overrideValue !== undefined) {\n // Override size: use directly\n strokeWidth = Math.max(1, Math.min(10, sizeConfig.overrideValue));\n pointRadius = Math.round(3 + strokeWidth);\n } else if (sizeConfig.mode === 'field' && sizeConfig.fieldName && layer) {\n const range = sizeFieldRanges.get(layer.id);\n if (range && f.properties) {\n const rawVal = f.properties[sizeConfig.fieldName];\n // Handle both numbers and numeric strings\n const val = typeof rawVal === 'number' ? rawVal : \n (typeof rawVal === 'string' && rawVal.trim() !== '' ? Number(rawVal) : NaN);\n if (isFinite(val)) {\n // Normalize to range with small minimum for better contrast\n // Min size: 2px stroke, 2px radius; Max size: 10px stroke, 18px radius\n const normalized = range.max > range.min \n ? (val - range.min) / (range.max - range.min)\n : 0.5;\n strokeWidth = 2 + normalized * 8; // 2-10\n pointRadius = Math.round(2 + normalized * 16); // 2-18\n }\n }\n }\n // mode === 'standard' uses default from feature properties\n }\n \n // Handle trace mode styling for points\n const isTracePoint = tracePointIds.has(featureId);\n const isLastTracePoint = lastTracePointIds.has(featureId);\n \n // Determine if this is a last trace point that should show a label\n const traceLabel = lastTracePointLabels.get(featureId);\n \n if (isTracePoint && f.geometry.type === 'Point') {\n // All trace points use the trace line color\n strokeColor = tracePointColors.get(featureId) || strokeColor;\n \n if (isLastTracePoint) {\n // Last trace point: larger size for visibility\n pointRadius = Math.max(pointRadius, 8);\n } else {\n // Non-last trace points: minimum 2px radius\n pointRadius = 2;\n }\n }\n \n // Determine label text based on visualConfig\n let labelText = (f.properties?.name as string) || '';\n const labelConfig = visualConfig?.label;\n if (labelConfig) {\n if (labelConfig.mode === 'fixed' && labelConfig.fixedText) {\n labelText = labelConfig.fixedText;\n } else if (labelConfig.mode === 'field' && labelConfig.fieldName && f.properties) {\n const fieldValue = f.properties[labelConfig.fieldName];\n labelText = fieldValue !== undefined && fieldValue !== null ? String(fieldValue) : '';\n }\n // mode === 'standard' uses default name from properties\n }\n \n // Override label for last trace points when grouping by field\n if (traceLabel) {\n labelText = traceLabel;\n }\n \n // Icon is stored as metadata (shown in properties panel) but not rendered as image overlay\n // The icon property can be any string identifier (e.g., 'map-pin', 'hospital')\n const featureIcon = (f.properties?.pointIcon || f.properties?.icon) as string | undefined;\n \n // Check if this point should be hidden because heatmap hideFeatures is enabled\n // Note: Trace points are now visible with small size, not hidden\n const isPoint = f.geometry.type === 'Point';\n const hideByHeatmap = isPoint && layer?.heatmapConfig?.enabled && layer?.heatmapConfig?.hideFeatures;\n const hideByCluster = isPoint && layer?.clusterConfig?.enabled === true && !layer?.clusterConfig?.showPointDots;\n const isSelected = selectedIds.includes(featureId);\n const hideByTrace = false; // Trace points now visible with small size\n \n // Check if flat (ground-level) line should be hidden when layer is set to '3d' only mode\n const isLine = f.geometry.type === 'LineString' || f.geometry.type === 'MultiLineString';\n const hideFlatFor3DOnly = isLine && layer?.hasAltitudeData && layer?.altitudeDisplayMode === '3d';\n \n // Sanitize properties for MapLibre (only primitives allowed)\n const sanitizedProps: Record<string, string | number | boolean | null> = {};\n if (f.properties) {\n Object.entries(f.properties).forEach(([key, value]) => {\n if (value === null || value === undefined) {\n sanitizedProps[key] = null;\n } else if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {\n sanitizedProps[key] = value;\n } else if (value instanceof Date) {\n sanitizedProps[key] = value.toISOString();\n } else {\n // Convert other types to string\n sanitizedProps[key] = String(value);\n }\n });\n }\n \n const isFeatureSelected = selectedIds.includes(featureId) ? 1 : 0;\n \n return {\n type: 'Feature' as const,\n id: featureId,\n geometry: f.geometry,\n properties: {\n // Preserve original properties for tooltip display (sanitized)\n ...sanitizedProps,\n // Override with computed visual properties\n id: featureId,\n name: labelText,\n isSelected: isFeatureSelected,\n isHiddenByHeatmap: hideByHeatmap ? true : false,\n isHiddenByCluster: hideByCluster ? 1 : 0,\n isHiddenByTrace: hideByTrace ? true : false,\n isTracePoint: isTracePoint ? true : false,\n isTraceLabel: traceLabel ? true : false,\n icon: featureIcon || '',\n stroke: strokeColor,\n 'stroke-width': strokeWidth,\n 'stroke-opacity': hideFlatFor3DOnly ? 0 : (isTimelineVisible ? baseOpacity : 0),\n fill: strokeColor,\n 'fill-opacity': hideFlatFor3DOnly ? 0 : (isTimelineVisible ? ((f.properties?.['fill-opacity'] as number) ?? 0.2) : 0),\n pointRadius: pointRadius,\n isHiddenFor3DOnly: hideFlatFor3DOnly ? 1 : 0,\n isTimelineHidden: isTimelineVisible ? 0 : 1,\n }\n };\n })\n };\n source.setData(sourceData);\n \n // Note: Label visibility is controlled by the fast-path useEffect that uses\n // viewport-aware feature counting. This allows labels to show when zoomed in\n // even if there are many features globally.\n \n // Compute and update trace lines for layers with traceConfig enabled\n const traceSource = map.current.getSource('trace-features') as maplibregl.GeoJSONSource | undefined;\n if (traceSource) {\n const traceSegments: GeoJSON.Feature[] = [];\n \n currentLayers.forEach(layer => {\n // Only process layers with traces enabled AND visible\n if (!layer.traceConfig?.enabled || !layer.visible) return;\n \n // Get point features from this layer that are timeline-visible and have startDate (O(1) lookup)\n const layerFeatures: GeoJSON.Feature[] = [];\n layer.featureIds.forEach(id => {\n const f = featureById.get(id);\n if (!f || f.geometry.type !== 'Point' || !f.properties?.startDate) return;\n if (visibleSet && f.id && !visibleSet.has(String(f.id))) return;\n layerFeatures.push(f);\n });\n \n if (layerFeatures.length < 2) return;\n \n // Group by field if configured\n const groupByField = layer.traceConfig.groupByField;\n const groups = new Map<string, GeoJSON.Feature[]>();\n \n layerFeatures.forEach(f => {\n const key = groupByField && f.properties?.[groupByField] \n ? String(f.properties[groupByField]) \n : '__all__';\n if (!groups.has(key)) groups.set(key, []);\n groups.get(key)!.push(f);\n });\n \n // Generate colors for groups\n const groupKeys = Array.from(groups.keys());\n const groupColors = new Map<string, string>();\n groupKeys.forEach((key, index) => {\n if (key === '__all__') {\n groupColors.set(key, '#3b82f6');\n } else {\n const hue = (index * 360 / groupKeys.length) % 360;\n groupColors.set(key, `hsl(${hue}, 70%, 50%)`);\n }\n });\n \n // Create trace segments for each group\n groups.forEach((groupFeatures, groupKey) => {\n const sorted = [...groupFeatures].sort((a, b) => {\n const dateA = new Date(a.properties?.startDate || 0).getTime();\n const dateB = new Date(b.properties?.startDate || 0).getTime();\n return dateA - dateB;\n });\n \n if (sorted.length < 2) return;\n \n for (let i = 0; i < sorted.length - 1; i++) {\n const from = sorted[i];\n const to = sorted[i + 1];\n const fromCoords = (from.geometry as GeoJSON.Point).coordinates;\n const toCoords = (to.geometry as GeoJSON.Point).coordinates;\n \n // Calculate distance\n const fromPoint = turf.point(fromCoords);\n const toPoint = turf.point(toCoords);\n const distanceKm = turf.distance(fromPoint, toPoint, { units: 'kilometers' });\n \n // Calculate duration and speed\n const fromTime = new Date(from.properties?.startDate || 0).getTime();\n const toTime = new Date(to.properties?.startDate || 0).getTime();\n const durationMs = toTime - fromTime;\n const durationHours = durationMs / (1000 * 60 * 60);\n const avgSpeedKmh = durationHours > 0 ? distanceKm / durationHours : 0;\n \n // Format duration\n let durationStr = '';\n if (durationMs < 60000) {\n durationStr = `${Math.round(durationMs / 1000)}s`;\n } else if (durationMs < 3600000) {\n durationStr = `${Math.round(durationMs / 60000)}m`;\n } else if (durationMs < 86400000) {\n durationStr = `${Math.floor(durationMs / 3600000)}h ${Math.round((durationMs % 3600000) / 60000)}m`;\n } else {\n durationStr = `${Math.floor(durationMs / 86400000)}d ${Math.round((durationMs % 86400000) / 3600000)}h`;\n }\n \n // Format distance\n const distanceStr = distanceKm < 1 ? `${Math.round(distanceKm * 1000)}m` : `${distanceKm.toFixed(2)}km`;\n \n // Format speed\n const speedStr = avgSpeedKmh < 1 ? `${(avgSpeedKmh * 1000).toFixed(0)}m/h` : `${avgSpeedKmh.toFixed(1)}km/h`;\n \n traceSegments.push({\n type: 'Feature',\n properties: {\n group: groupKey,\n color: groupColors.get(groupKey) || '#3b82f6',\n duration: durationStr,\n distance: distanceStr,\n avgSpeed: speedStr,\n fromName: from.properties?.name || '',\n toName: to.properties?.name || '',\n },\n geometry: {\n type: 'LineString',\n coordinates: [fromCoords, toCoords]\n },\n });\n }\n });\n });\n \n traceSource.setData({ type: 'FeatureCollection', features: traceSegments });\n }\n \n // Compute arrow head triangles for arrow features using screen-space projection\n const arrowHeadSource = map.current.getSource('arrow-heads') as maplibregl.GeoJSONSource | undefined;\n if (arrowHeadSource && map.current) {\n const arrowHeadTriangles: GeoJSON.Feature[] = [];\n const mapInstance = map.current;\n \n // Arrow head dimensions in pixels\n const headLength = 16; // Length from tip to base\n const headWidth = 10; // Half-width of the base\n \n sourceData.features.forEach(f => {\n // Check both the kind property and the external arrow ID set\n const isArrow = f.properties?.kind === 'arrow' || arrowFeatureIdsRef.current.has(String(f.id));\n if (f.geometry.type !== 'LineString' || !isArrow) return;\n \n const coords = f.geometry.coordinates as [number, number][];\n if (coords.length < 2) return;\n \n // Get last two points\n const end = coords[coords.length - 1];\n const prev = coords[coords.length - 2];\n \n // Project to screen coordinates\n const endScreen = mapInstance.project(end as [number, number]);\n const prevScreen = mapInstance.project(prev as [number, number]);\n \n // Compute direction vector in screen space (from prev to end)\n const dx = endScreen.x - prevScreen.x;\n const dy = endScreen.y - prevScreen.y;\n const len = Math.sqrt(dx * dx + dy * dy);\n \n if (len < 0.001) return; // Skip degenerate segments\n \n // Normalize direction vector\n const dirX = dx / len;\n const dirY = dy / len;\n \n // Perpendicular vector (90 degrees clockwise in screen space)\n const perpX = -dirY;\n const perpY = dirX;\n \n // Compute triangle vertices in screen space:\n // Tip is at the endpoint\n const tipScreen = { x: endScreen.x, y: endScreen.y };\n \n // Base vertices are behind the tip, offset perpendicular\n const baseLeftScreen = {\n x: endScreen.x - dirX * headLength - perpX * headWidth,\n y: endScreen.y - dirY * headLength - perpY * headWidth\n };\n const baseRightScreen = {\n x: endScreen.x - dirX * headLength + perpX * headWidth,\n y: endScreen.y - dirY * headLength + perpY * headWidth\n };\n \n // Unproject back to geographic coordinates\n const tipGeo = mapInstance.unproject([tipScreen.x, tipScreen.y]);\n const baseLeftGeo = mapInstance.unproject([baseLeftScreen.x, baseLeftScreen.y]);\n const baseRightGeo = mapInstance.unproject([baseRightScreen.x, baseRightScreen.y]);\n \n arrowHeadTriangles.push({\n type: 'Feature',\n geometry: {\n type: 'Polygon',\n coordinates: [[\n [tipGeo.lng, tipGeo.lat],\n [baseLeftGeo.lng, baseLeftGeo.lat],\n [baseRightGeo.lng, baseRightGeo.lat],\n [tipGeo.lng, tipGeo.lat] // Close the polygon\n ]]\n },\n properties: {\n ...f.properties,\n }\n });\n });\n \n arrowHeadSource.setData({ type: 'FeatureCollection', features: arrowHeadTriangles });\n }\n \n // Compute arrow label points (at midpoint of arrow lines)\n const arrowLabelSource = map.current.getSource('arrow-labels') as maplibregl.GeoJSONSource | undefined;\n if (arrowLabelSource) {\n const arrowLabelPoints: GeoJSON.Feature[] = [];\n \n sourceData.features.forEach(f => {\n // Check both the kind property and the external arrow ID set\n const isArrow = f.properties?.kind === 'arrow' || arrowFeatureIdsRef.current.has(String(f.id));\n if (f.geometry.type !== 'LineString' || !isArrow) return;\n \n // Only render label if name exists\n const name = f.properties?.name;\n if (!name) return;\n \n const coords = f.geometry.coordinates as [number, number][];\n if (coords.length < 2) return;\n \n // Calculate true midpoint of the line (average of all points weighted by segments)\n const start = coords[0];\n const end = coords[coords.length - 1];\n const midPoint: [number, number] = [\n (start[0] + end[0]) / 2,\n (start[1] + end[1]) / 2\n ];\n \n // Calculate bearing based on overall line direction (start to end)\n const dLng = end[0] - start[0];\n const dLat = end[1] - start[1];\n \n // atan2 gives angle from positive X axis (east) in radians\n // Convert to degrees: 0 = east, 90 = north, -90 = south, 180/-180 = west\n const angleFromEast = Math.atan2(dLat, dLng) * (180 / Math.PI);\n \n // MapLibre text-rotate is clockwise from horizontal (east-pointing text)\n // To align text with line: rotate by negative of angle from east\n // But we want text readable, so if line points left (west), flip 180\n let labelBearing = -angleFromEast;\n \n // Normalize to [-180, 180]\n labelBearing = ((labelBearing % 360) + 540) % 360 - 180;\n \n // If text would be upside down (pointing generally left), flip it\n if (labelBearing > 90) {\n labelBearing -= 180;\n } else if (labelBearing < -90) {\n labelBearing += 180;\n }\n \n arrowLabelPoints.push({\n type: 'Feature',\n geometry: {\n type: 'Point',\n coordinates: midPoint\n },\n properties: {\n ...f.properties,\n labelBearing: labelBearing,\n }\n });\n });\n \n arrowLabelSource.setData({ type: 'FeatureCollection', features: arrowLabelPoints });\n }\n \n // Update 3D flight paths to respect timeline filtering\n if (update3DFlightPathsRef?.current) {\n update3DFlightPathsRef.current();\n }\n \n // After sync, wait for map idle then count visible features\n // This handles new features being added - must wait for render to complete\n const m = map.current;\n if (m) {\n m.once('idle', () => {\n const countLayers = ['custom-point', 'custom-line', 'custom-polygon-fill'];\n const existing = countLayers.filter(id => m.getLayer(id));\n if (existing.length === 0) {\n setVisibleFeatureCount(0);\n setLabelsSuppressed(false);\n return;\n }\n const threshold = autoLabelConfig.enabled ? autoLabelConfig.threshold : 220;\n const rendered = m.queryRenderedFeatures(undefined, { layers: existing });\n const uniqueIds = new Set<string>();\n let count = 0;\n for (const f of rendered) {\n const fid = f.properties?.id || f.id;\n if (fid && !uniqueIds.has(String(fid))) {\n uniqueIds.add(String(fid));\n count++;\n if (count > threshold) break;\n }\n }\n setVisibleFeatureCount(count);\n setLabelsSuppressed(false);\n });\n }\n }, [layers, hashStringToColor, autoLabelConfig]);\n \n // Update 3D flight path layer for lines with altitude data\n const update3DFlightPaths = useCallback(() => {\n if (!map.current || !is3DTerrainEnabled) {\n // Remove 3D layer if terrain is disabled\n if (map.current && flightPath3DLayerId.current) {\n try {\n map.current.removeLayer(flightPath3DLayerId.current);\n } catch {}\n flightPath3DLayerId.current = null;\n }\n return;\n }\n \n const mapInstance = map.current;\n \n // Use the same timeline visible IDs set that ground features use\n const visibleSet = timelineVisibleIdsRef.current;\n \n // Helper to check if a feature is visible based on timeline\n const isFeatureVisibleInTimeline = (feature: GeoJSON.Feature): boolean => {\n // If no timeline filter is active, show all features\n if (visibleSet === null) return true;\n // Check if feature ID is in the visible set\n const featureId = String(feature.id);\n return visibleSet.has(featureId);\n };\n \n // Collect all features with altitude data from layers that have TRACE enabled\n // 3D tubes only appear when BOTH 3D terrain is on AND TRACE is enabled\n const allFeatures: GeoJSON.Feature[] = [];\n const currentLayers = layersRef.current;\n \n // Get editable features from MapboxDraw - only from layers with TRACE enabled\n if (draw.current) {\n const drawFeatures = draw.current.getAll().features.filter(feature => {\n if (!isFeatureVisibleInTimeline(feature)) return false;\n // Find which layer this feature belongs to\n const featureId = feature.id as string;\n const layer = currentLayers.find(l => l.featureIds.includes(featureId));\n // Only include if TRACE is enabled for this layer\n return layer?.traceConfig?.enabled === true;\n });\n allFeatures.push(...drawFeatures);\n }\n \n // Add read-only features (only from layers with TRACE enabled AND 3D altitude mode)\n readOnlyFeatures.current.forEach((features, layerId) => {\n const layer = currentLayers.find(l => l.id === layerId);\n // Only include features from layers with:\n // 1. TRACE enabled (required for connecting points into tubes)\n // 2. 3D altitude display enabled\n const altitudeMode = layer?.altitudeDisplayMode ?? 'both';\n const traceEnabled = layer?.traceConfig?.enabled === true;\n if (layer?.visible && traceEnabled && (altitudeMode === '3d' || altitudeMode === 'both')) {\n // Also filter by timeline visibility\n const visibleFeatures = features.filter(isFeatureVisibleInTimeline);\n allFeatures.push(...visibleFeatures);\n }\n });\n \n // Extract 3D flight paths (lines with Z coordinates, or points grouped by TargetID)\n const flightPaths = extract3DFlightPaths(allFeatures);\n \n if (flightPaths.length === 0) {\n // No 3D paths, remove layer if exists\n if (flightPath3DLayerId.current) {\n try {\n mapInstance.removeLayer(flightPath3DLayerId.current);\n } catch {}\n flightPath3DLayerId.current = null;\n }\n return;\n }\n \n // Remove existing layer\n if (flightPath3DLayerId.current) {\n try {\n mapInstance.removeLayer(flightPath3DLayerId.current);\n } catch {}\n }\n \n // Create new 3D layer\n const layerId = `flight-path-3d-${Date.now()}`;\n const layer = createFlightPath3DLayer(layerId, mapInstance, flightPaths);\n mapInstance.addLayer(layer);\n flightPath3DLayerId.current = layerId;\n \n }, [is3DTerrainEnabled]);\n \n // Keep syncRef and 3D update ref updated\n useEffect(() => {\n syncRef.current = syncFeaturesToCustomLayers;\n }, [syncFeaturesToCustomLayers]);\n \n // Keep update3DFlightPaths ref in sync so syncFeaturesToCustomLayers can call it\n useEffect(() => {\n update3DFlightPathsRef.current = update3DFlightPaths;\n }, [update3DFlightPaths]);\n \n // Update 3D flight paths when terrain is toggled, layers change, or timeline changes\n useEffect(() => {\n update3DFlightPaths();\n }, [update3DFlightPaths, layers, is3DTerrainEnabled, timelineStore.isEnabled, timelineStore.rangeStart, timelineStore.rangeEnd]);\n \n // Also call 3D update after features sync to pick up new flight path data\n useEffect(() => {\n if (map.current && is3DTerrainEnabled) {\n // Debounce to avoid multiple rapid updates\n const timer = setTimeout(() => {\n update3DFlightPathsRef.current?.();\n }, 100);\n return () => clearTimeout(timer);\n }\n }, [layers, is3DTerrainEnabled]);\n\n const updateTimelineStore = useCallback(() => {\n // Get features from MapboxDraw\n const drawFeatures = draw.current ? draw.current.getAll().features as GeoJSON.Feature[] : [];\n \n // Use layersRef.current for immediate access (avoids stale state after setLayers)\n const currentLayers = layersRef.current;\n \n // Combine with visible read-only features\n const allFeatures: GeoJSON.Feature[] = [...drawFeatures];\n readOnlyFeatures.current.forEach((features, layerId) => {\n const layer = currentLayers.find(l => l.id === layerId);\n if (layer?.visible) {\n allFeatures.push(...features);\n }\n });\n \n const temporalFeatures: { id: string; startDate: Date | null; endDate: Date | null; layerId: string }[] = [];\n const untimedIds: string[] = [];\n \n allFeatures.forEach(feature => {\n const { startDate, endDate } = normalizeTemporalProperties(feature.properties || {});\n const featureLayer = currentLayers.find(l => l.featureIds.includes(feature.id as string));\n \n if (startDate || endDate) {\n temporalFeatures.push({\n id: feature.id as string,\n startDate,\n endDate,\n layerId: featureLayer?.id || 'default',\n });\n } else {\n untimedIds.push(feature.id as string);\n }\n });\n \n timelineStore.setTemporalFeatures(temporalFeatures, untimedIds);\n }, [timelineStore]);\n\n useEffect(() => {\n if (!mapContainer.current || map.current) return;\n\n try {\n const baseStyle = createBaseStyle({\n glyphsUrl,\n enableSatellite,\n enableTerrain,\n });\n \n const mapInstance = new maplibregl.Map({\n container: mapContainer.current,\n style: baseStyle,\n center: initialCenter,\n zoom: initialZoom,\n attributionControl: false,\n boxZoom: false, // Disable default box zoom - we use shift+drag for selection instead\n maxPitch: 80, // Allow steep camera angles for 3D terrain viewing\n });\n\n mapInstance.addControl(new maplibregl.AttributionControl({\n compact: true,\n customAttribution: '© <a href=\"https://www.openstreetmap.org/copyright\" target=\"_blank\">OpenStreetMap</a> contributors',\n }), 'bottom-right');\n mapInstance.addControl(new maplibregl.NavigationControl(), 'bottom-right');\n mapInstance.addControl(new maplibregl.ScaleControl({ unit: 'metric' }), 'bottom-left');\n\n const drawInstance = new MapboxDraw({\n displayControlsDefault: false,\n controls: {},\n modes: {\n ...MapboxDraw.modes,\n view_select: ViewSelectMode,\n },\n // Make MapboxDraw's default styles transparent - we use custom layers for rendering\n // Only keep vertex handles visible for editing\n styles: [\n // Hide default polygon/line/point rendering - custom layers will show these\n { id: 'gl-draw-polygon-fill-inactive', type: 'fill', filter: ['all', ['==', 'active', 'false'], ['==', '$type', 'Polygon']], paint: { 'fill-opacity': 0 } },\n { id: 'gl-draw-polygon-fill-active', type: 'fill', filter: ['all', ['==', 'active', 'true'], ['==', '$type', 'Polygon']], paint: { 'fill-color': '#fbbf24', 'fill-opacity': 0.15 } },\n { id: 'gl-draw-polygon-stroke-inactive', type: 'line', filter: ['all', ['==', 'active', 'false'], ['==', '$type', 'Polygon']], paint: { 'line-opacity': 0 } },\n { id: 'gl-draw-polygon-stroke-active', type: 'line', filter: ['all', ['==', 'active', 'true'], ['==', '$type', 'Polygon']], paint: { 'line-color': '#f59e0b', 'line-width': 2, 'line-dasharray': [2, 2] } },\n { id: 'gl-draw-line-inactive', type: 'line', filter: ['all', ['==', 'active', 'false'], ['==', '$type', 'LineString']], paint: { 'line-opacity': 0 } },\n { id: 'gl-draw-line-active', type: 'line', filter: ['all', ['==', 'active', 'true'], ['==', '$type', 'LineString']], paint: { 'line-color': '#f59e0b', 'line-width': 2, 'line-dasharray': [2, 2] } },\n { id: 'gl-draw-point-inactive', type: 'circle', filter: ['all', ['==', 'active', 'false'], ['==', '$type', 'Point'], ['==', 'meta', 'feature']], paint: { 'circle-opacity': 0 } },\n { id: 'gl-draw-point-active', type: 'circle', filter: ['all', ['==', 'active', 'true'], ['==', '$type', 'Point'], ['==', 'meta', 'feature']], paint: { 'circle-opacity': 0 } },\n // Keep vertex handles visible for editing\n { id: 'gl-draw-polygon-and-line-vertex-inactive', type: 'circle', filter: ['all', ['==', 'meta', 'vertex'], ['==', '$type', 'Point'], ['!=', 'mode', 'static']], paint: { 'circle-radius': 5, 'circle-color': '#fff', 'circle-stroke-color': '#3b82f6', 'circle-stroke-width': 2 } },\n { id: 'gl-draw-polygon-and-line-vertex-active', type: 'circle', filter: ['all', ['==', 'meta', 'vertex'], ['==', '$type', 'Point'], ['==', 'active', 'true']], paint: { 'circle-radius': 6, 'circle-color': '#fff', 'circle-stroke-color': '#f59e0b', 'circle-stroke-width': 2 } },\n { id: 'gl-draw-polygon-midpoint', type: 'circle', filter: ['all', ['==', 'meta', 'midpoint'], ['==', '$type', 'Point']], paint: { 'circle-radius': 4, 'circle-color': '#3b82f6' } },\n ],\n });\n\n mapInstance.addControl(drawInstance as unknown as maplibregl.IControl);\n\n mapInstance.on('load', () => {\n map.current = mapInstance;\n draw.current = drawInstance;\n \n // Add custom source and layers for feature rendering with data-driven styling\n mapInstance.addSource('custom-features', {\n type: 'geojson',\n data: { type: 'FeatureCollection', features: [] }\n });\n \n // Custom polygon fill layer - preserves original styling\n mapInstance.addLayer({\n id: 'custom-polygon-fill',\n type: 'fill',\n source: 'custom-features',\n filter: ['==', '$type', 'Polygon'],\n paint: {\n 'fill-color': ['get', 'fill'],\n 'fill-opacity': ['get', 'fill-opacity']\n }\n });\n \n mapInstance.addLayer({\n id: 'custom-polygon-stroke',\n type: 'line',\n source: 'custom-features',\n filter: ['==', '$type', 'Polygon'],\n paint: {\n 'line-color': ['get', 'stroke'],\n 'line-width': ['get', 'stroke-width'],\n 'line-opacity': ['get', 'stroke-opacity']\n }\n });\n \n // Custom line layer - preserves original styling\n mapInstance.addLayer({\n id: 'custom-line',\n type: 'line',\n source: 'custom-features',\n filter: ['==', '$type', 'LineString'],\n paint: {\n 'line-color': ['get', 'stroke'],\n 'line-width': ['get', 'stroke-width'],\n 'line-opacity': ['get', 'stroke-opacity']\n }\n });\n \n // Shadow layer rendered beneath points for depth\n mapInstance.addLayer({\n id: 'custom-point-shadow',\n type: 'circle',\n source: 'custom-features',\n filter: ['==', '$type', 'Point'],\n paint: {\n 'circle-color': 'rgba(0, 0, 0, 0.2)',\n 'circle-radius': ['+', ['case',\n ['==', ['get', 'isHiddenByCluster'], 1], 0,\n ['coalesce', ['get', 'pointRadius'], 5]\n ], 1.5],\n 'circle-blur': 0.5,\n 'circle-opacity': ['case',\n ['==', ['get', 'isHiddenByCluster'], 1], 0,\n ['coalesce', ['get', 'stroke-opacity'], 1]\n ],\n 'circle-translate': [1, 1]\n }\n });\n\n // Custom point layer with data-driven selection styling\n mapInstance.addLayer({\n id: 'custom-point',\n type: 'circle',\n source: 'custom-features',\n filter: ['==', '$type', 'Point'],\n paint: {\n 'circle-color': ['coalesce', ['get', 'stroke'], '#3b82f6'],\n 'circle-radius': ['case', \n ['==', ['get', 'isHiddenByCluster'], 1], \n 0, \n ['coalesce', ['get', 'pointRadius'], 5]\n ],\n 'circle-opacity': ['case',\n ['==', ['get', 'isHiddenByCluster'], 1],\n 0,\n ['coalesce', ['get', 'stroke-opacity'], 1]\n ],\n 'circle-stroke-color': ['case', ['==', ['get', 'isSelected'], 1], '#06b6d4', '#555555'],\n 'circle-stroke-width': ['case', \n ['==', ['get', 'isHiddenByCluster'], 1], 0,\n ['==', ['get', 'isSelected'], 1], 3, \n 1.5\n ],\n 'circle-stroke-opacity': ['case', ['==', ['get', 'isHiddenByCluster'], 1], 0, 1]\n }\n });\n \n // Selection highlight for lines - bright cyan dashed overlay\n mapInstance.addLayer({\n id: 'custom-line-selection',\n type: 'line',\n source: 'custom-features',\n filter: ['all', ['==', '$type', 'LineString'], ['==', 'isSelected', 1]],\n paint: {\n 'line-color': '#06b6d4',\n 'line-width': ['+', ['get', 'stroke-width'], 4],\n 'line-dasharray': [4, 2]\n }\n });\n \n // Selection highlight for polygons - bright cyan dashed outline\n mapInstance.addLayer({\n id: 'custom-polygon-selection',\n type: 'line',\n source: 'custom-features',\n filter: ['all', ['==', '$type', 'Polygon'], ['==', 'isSelected', 1]],\n paint: {\n 'line-color': '#06b6d4',\n 'line-width': 4,\n 'line-dasharray': [4, 2]\n }\n });\n \n // Label layer for all features - shows 'name' property, or 'text' for text features\n // Trace labels are slightly bigger and bolder, hidden points have no labels\n // Arrow labels are handled separately by the custom-arrow-labels layer\n mapInstance.addLayer({\n id: 'custom-labels',\n type: 'symbol',\n source: 'custom-features',\n layout: {\n 'visibility': 'none',\n // Hide labels for trace points (except last point which has isTraceLabel), arrows handled separately\n 'text-field': ['case', \n ['==', ['get', 'isHiddenByTrace'], true], '',\n ['==', ['get', 'kind'], 'arrow'], '', // Arrows use custom-arrow-labels layer\n // Trace points: only show label if isTraceLabel is true (last point in group)\n ['all', ['==', ['get', 'isTracePoint'], true], ['!=', ['get', 'isTraceLabel'], true]], '',\n ['==', ['get', 'kind'], 'text'], ['coalesce', ['get', 'label'], ['get', 'text'], 'New Label'],\n ['coalesce', ['get', 'name'], '']\n ],\n // Text features use their fontSize property; trace labels 14px; others 12px\n 'text-size': ['case', \n ['==', ['get', 'kind'], 'text'], ['coalesce', ['get', 'fontSize'], 14],\n ['==', ['get', 'isTraceLabel'], true], 14, \n 12\n ],\n // Text features: center anchor; others: top anchor\n 'text-anchor': ['case', ['==', ['get', 'kind'], 'text'], 'center', 'top'],\n 'text-offset': ['case', ['==', ['get', 'kind'], 'text'], ['literal', [0, 0]], ['literal', [0, 0.8]]],\n 'text-allow-overlap': true,\n 'text-ignore-placement': false,\n 'text-optional': true,\n // Bold font for text features with fontWeight=bold, trace labels, others regular\n 'text-font': ['case', \n ['all', ['==', ['get', 'kind'], 'text'], ['==', ['get', 'fontWeight'], 'bold']], \n ['literal', ['Montserrat SemiBold', 'Noto Sans Regular']],\n ['==', ['get', 'isTraceLabel'], true], \n ['literal', ['Montserrat Medium', 'Noto Sans Regular']],\n ['literal', ['Montserrat Regular', 'Noto Sans Regular']]\n ],\n },\n paint: {\n // Text features use fontColor; others use default\n 'text-color': ['case', \n ['==', ['get', 'kind'], 'text'], ['coalesce', ['get', 'fontColor'], '#000000'],\n '#1f2937'\n ],\n 'text-halo-color': '#ffffff',\n // Thicker halo for trace labels and text features\n 'text-halo-width': ['case', \n ['==', ['get', 'kind'], 'text'], 2,\n ['==', ['get', 'isTraceLabel'], true], 2, \n 1.5\n ],\n 'text-opacity': ['*', 0.9, ['get', 'stroke-opacity']],\n }\n });\n \n // Arrow heads source - point features at arrow line endpoints\n mapInstance.addSource('arrow-heads', {\n type: 'geojson',\n data: { type: 'FeatureCollection', features: [] }\n });\n \n // Arrow head layer - triangle polygons computed in screen space for precise positioning\n mapInstance.addLayer({\n id: 'custom-arrow-heads',\n type: 'fill',\n source: 'arrow-heads',\n paint: {\n 'fill-color': ['coalesce', ['get', 'stroke'], '#3b82f6'],\n 'fill-opacity': ['coalesce', ['get', 'stroke-opacity'], 1],\n }\n });\n \n // Arrow labels source - positioned at midpoint of arrow lines\n mapInstance.addSource('arrow-labels', {\n type: 'geojson',\n data: { type: 'FeatureCollection', features: [] }\n });\n \n // Arrow labels layer - shows name alongside the arrow direction\n mapInstance.addLayer({\n id: 'custom-arrow-labels',\n type: 'symbol',\n source: 'arrow-labels',\n layout: {\n 'text-field': ['get', 'name'],\n 'text-size': 12,\n 'text-allow-overlap': false,\n 'text-ignore-placement': false,\n 'text-rotate': ['get', 'labelBearing'],\n 'text-rotation-alignment': 'map',\n 'text-keep-upright': true, // Always readable (not upside down)\n 'text-anchor': 'center',\n 'text-offset': [0, -1], // Offset above the line\n 'text-font': ['Montserrat Medium', 'Noto Sans Regular'],\n },\n paint: {\n 'text-color': ['coalesce', ['get', 'stroke'], '#3b82f6'],\n 'text-halo-color': '#ffffff',\n 'text-halo-width': 1.5,\n 'text-opacity': ['coalesce', ['get', 'stroke-opacity'], 1],\n }\n });\n \n // Add trace source and layer - traces are computed in syncFeaturesToCustomLayers\n mapInstance.addSource('trace-features', {\n type: 'geojson',\n data: { type: 'FeatureCollection', features: [] }\n });\n \n mapInstance.addLayer({\n id: 'trace-lines',\n type: 'line',\n source: 'trace-features',\n paint: {\n 'line-color': ['get', 'color'],\n 'line-width': 2,\n 'line-opacity': 0.7,\n },\n });\n \n // Tooltip rendered inside map container with position:absolute, clamped to container bounds\n if (tooltipElRef.current) {\n tooltipElRef.current.parentElement?.removeChild(tooltipElRef.current);\n }\n const tooltipEl = document.createElement('div');\n tooltipEl.className = 'feature-tooltip-fixed';\n tooltipEl.style.cssText = 'position:absolute;z-index:50;pointer-events:auto;display:none;max-width:320px;';\n mapInstance.getContainer().appendChild(tooltipEl);\n tooltipElRef.current = tooltipEl;\n \n let tooltipLngLat: maplibregl.LngLat | null = null;\n let tooltipHideTimeout: ReturnType<typeof setTimeout> | null = null;\n let tooltipShowTimeout: ReturnType<typeof setTimeout> | null = null;\n let isMouseOverPopup = false;\n let tooltipFeatures: GeoJSON.Feature[] = [];\n let tooltipPageIndex = 0;\n let tooltipLngLatForPagination: maplibregl.LngLat | null = null;\n \n const positionTooltip = () => {\n if (!tooltipLngLat || tooltipEl.style.display === 'none') return;\n const point = mapInstance.project(tooltipLngLat);\n const container = mapInstance.getContainer();\n const cw = container.clientWidth;\n const ch = container.clientHeight;\n \n tooltipEl.style.maxWidth = Math.min(320, cw - 24) + 'px';\n const tw = tooltipEl.offsetWidth || 200;\n const th = tooltipEl.offsetHeight || 80;\n const gap = 12;\n \n let left = point.x < cw / 2 ? point.x + gap : point.x - tw - gap;\n let top = point.y - th - gap;\n if (top < 4) top = point.y + gap;\n \n if (left + tw > cw - 4) left = cw - tw - 4;\n if (top + th > ch - 4) top = ch - th - 4;\n left = Math.max(4, left);\n top = Math.max(4, top);\n \n tooltipEl.style.left = left + 'px';\n tooltipEl.style.top = top + 'px';\n };\n \n const showTooltip = (lngLat: maplibregl.LngLat, html: string) => {\n tooltipEl.innerHTML = html;\n tooltipEl.style.display = 'block';\n tooltipLngLat = lngLat;\n requestAnimationFrame(() => positionTooltip());\n };\n \n const hideTooltip = () => {\n if (tooltipShowTimeout) { clearTimeout(tooltipShowTimeout); tooltipShowTimeout = null; }\n tooltipEl.style.display = 'none';\n tooltipLngLat = null;\n tooltipFeatures = [];\n tooltipPageIndex = 0;\n tooltipLngLatForPagination = null;\n };\n \n mapInstance.on('move', positionTooltip);\n \n const scheduleTooltipHide = () => {\n if (tooltipHideTimeout) clearTimeout(tooltipHideTimeout);\n tooltipHideTimeout = setTimeout(() => {\n if (!isMouseOverPopup) {\n hideTooltip();\n }\n }, 300);\n };\n \n const cancelTooltipHide = () => {\n if (tooltipHideTimeout) {\n clearTimeout(tooltipHideTimeout);\n tooltipHideTimeout = null;\n }\n };\n \n tooltipEl.addEventListener('mouseenter', () => {\n isMouseOverPopup = true;\n cancelTooltipHide();\n });\n tooltipEl.addEventListener('mouseleave', () => {\n isMouseOverPopup = false;\n scheduleTooltipHide();\n });\n tooltipEl.addEventListener('click', (ev) => {\n const target = (ev.target as HTMLElement).closest('[data-tooltip-nav]');\n if (!target) return;\n ev.stopPropagation();\n const dir = target.getAttribute('data-tooltip-nav');\n if (dir === 'prev' && tooltipPageIndex > 0) {\n tooltipPageIndex--;\n renderTooltipPage();\n } else if (dir === 'next' && tooltipPageIndex < tooltipFeatures.length - 1) {\n tooltipPageIndex++;\n renderTooltipPage();\n }\n });\n \n\n // Show tooltip on hover for custom layers\n const customLayers = ['custom-point', 'custom-line', 'custom-polygon-fill'];\n \n const buildBuiltinTooltipHtml = (feature: GeoJSON.Feature): string => {\n const props = feature.properties || {};\n const featureId = String(props.id || feature.id);\n const currentLayers = layersRef.current;\n const featureLayer = currentLayers.find(l => l.featureIds.includes(featureId));\n const visualConfig = featureLayer?.visualConfig;\n const highlightFields = new Set<string>();\n if (visualConfig?.size?.mode === 'field' && visualConfig.size.fieldName) highlightFields.add(visualConfig.size.fieldName);\n if (visualConfig?.color?.mode === 'field' && visualConfig.color.fieldName) highlightFields.add(visualConfig.color.fieldName);\n const excludeKeys = ['stroke','stroke-width','stroke-opacity','fill','fill-opacity','pointRadius','isSelected','kind','meta:type','circleCenter','circleRadius','icon','iconSize','pointIcon','pointIconSize','fontSize','fontColor','fontWeight','arrowSize','label','entityType'];\n const displayProps = Object.entries(props)\n .filter(([key, value]) => !excludeKeys.includes(key) && !key.startsWith('_') && !key.startsWith('isHidden') && !key.startsWith('isTrace') && !key.startsWith('isTimeline') && !key.startsWith('trace') && value != null && value !== '')\n .slice(0, 5);\n const name = props.name;\n let html = '<div class=\"text-sm space-y-0.5\">';\n if (name) html += `<div class=\"font-medium\">${name}</div>`;\n if (featureId) html += `<div class=\"text-xs text-muted-foreground\"><span class=\"opacity-70\">ID:</span> ${String(featureId).slice(0, 30)}</div>`;\n const otherProps = displayProps.filter(([k]) => k !== 'name' && k !== 'id');\n if (otherProps.length > 0) {\n html += '<div class=\"text-xs text-muted-foreground space-y-0.5\">';\n otherProps.forEach(([key, value]) => { html += `<div><span class=\"opacity-70\">${key}:</span> ${String(value).slice(0, 30)}</div>`; });\n html += '</div>';\n }\n if (highlightFields.size > 0) {\n html += '<div class=\"text-xs border-t border-border/50 mt-1 pt-1 space-y-0.5\">';\n highlightFields.forEach(fieldName => {\n const value = props[fieldName];\n if (value != null && value !== '') html += `<div class=\"flex justify-between gap-2\"><span class=\"opacity-70\">${fieldName}:</span> <span class=\"font-medium\">${String(value).slice(0, 20)}</span></div>`;\n });\n html += '</div>';\n }\n html += '</div>';\n return html;\n };\n \n const renderTooltipPage = () => {\n if (tooltipFeatures.length === 0 || !tooltipLngLatForPagination) return;\n const feature = tooltipFeatures[tooltipPageIndex];\n let html: string | null = null;\n \n if (tooltipProviderRef.current) {\n html = tooltipProviderRef.current(feature);\n } else {\n html = buildBuiltinTooltipHtml(feature);\n }\n \n if (!html) return;\n \n if (tooltipFeatures.length > 1) {\n const prevDisabled = tooltipPageIndex === 0;\n const nextDisabled = tooltipPageIndex === tooltipFeatures.length - 1;\n const btnBase = 'background:none;border-radius:4px;padding:1px 8px;font-size:12px;line-height:1.4;';\n const navHtml = `<div style=\"display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid #eee;padding:4px 0 6px;margin-bottom:4px;font-size:12px;color:#666;user-select:none\">`\n + `<button data-tooltip-nav=\"prev\" style=\"${btnBase}border:1px solid ${prevDisabled ? '#eee' : '#ddd'};cursor:${prevDisabled ? 'default' : 'pointer'};color:${prevDisabled ? '#ccc' : '#444'}\"${prevDisabled ? ' disabled' : ''}>‹</button>`\n + `<span>${tooltipPageIndex + 1} / ${tooltipFeatures.length}</span>`\n + `<button data-tooltip-nav=\"next\" style=\"${btnBase}border:1px solid ${nextDisabled ? '#eee' : '#ddd'};cursor:${nextDisabled ? 'default' : 'pointer'};color:${nextDisabled ? '#ccc' : '#444'}\"${nextDisabled ? ' disabled' : ''}>›</button>`\n + `</div>`;\n html = navHtml + html;\n }\n \n showTooltip(tooltipLngLatForPagination, html);\n };\n \n customLayers.forEach(layerId => {\n mapInstance.on('mouseenter', layerId, (e) => {\n mapInstance.getCanvas().style.cursor = 'pointer';\n if (tooltipShowTimeout) { clearTimeout(tooltipShowTimeout); tooltipShowTimeout = null; }\n if (tooltipHideTimeout) { clearTimeout(tooltipHideTimeout); tooltipHideTimeout = null; }\n\n if (!isMouseOverPopup) {\n tooltipEl.style.display = 'none';\n tooltipLngLat = null;\n }\n \n if (e.features && e.features.length > 0) {\n const coordinates = e.lngLat;\n\n tooltipShowTimeout = setTimeout(() => {\n tooltipShowTimeout = null;\n if (isDrawingSelection.current) return;\n const drawMode = draw.current?.getMode?.();\n const tooltipAllowedModes = ['simple_select', 'direct_select', 'view_select'];\n if (drawMode && !tooltipAllowedModes.includes(drawMode)) return;\n\n const hoveredFeature = e.features![0];\n const hoveredGeom = hoveredFeature.geometry;\n let hoveredCoords: [number, number] | null = null;\n if (hoveredGeom.type === 'Point') {\n hoveredCoords = hoveredGeom.coordinates as [number, number];\n }\n\n const seen = new Set<string>();\n const uniqueFeatures: GeoJSON.Feature[] = [];\n\n const addUnique = (f: GeoJSON.Feature | maplibregl.MapGeoJSONFeature) => {\n const fid = String((f.properties || {}).id || f.id || '');\n if (fid && seen.has(fid)) return;\n if (fid) seen.add(fid);\n uniqueFeatures.push({\n type: 'Feature',\n geometry: f.geometry as GeoJSON.Geometry,\n properties: { ...(f.properties || {}) },\n id: f.id,\n });\n };\n\n addUnique(hoveredFeature);\n\n if (hoveredCoords) {\n const allFeatures: GeoJSON.Feature[] = [];\n if (draw.current) {\n allFeatures.push(...draw.current.getAll().features);\n }\n readOnlyFeatures.current.forEach((features, lid) => {\n const layer = layersRef.current.find(l => l.id === lid);\n if (layer?.visible) allFeatures.push(...features);\n });\n const EPS = 1e-7;\n for (const cf of allFeatures) {\n if (cf.geometry?.type !== 'Point') continue;\n const cc = (cf.geometry as GeoJSON.Point).coordinates;\n if (Math.abs(cc[0] - hoveredCoords[0]) < EPS && Math.abs(cc[1] - hoveredCoords[1]) < EPS) {\n addUnique(cf);\n }\n }\n }\n\n if (uniqueFeatures.length === 0) {\n addUnique(hoveredFeature);\n }\n \n tooltipFeatures = uniqueFeatures;\n tooltipPageIndex = 0;\n tooltipLngLatForPagination = coordinates;\n \n renderTooltipPage();\n }, 250);\n }\n });\n \n mapInstance.on('mouseleave', layerId, () => {\n mapInstance.getCanvas().style.cursor = '';\n if (tooltipShowTimeout) { clearTimeout(tooltipShowTimeout); tooltipShowTimeout = null; }\n scheduleTooltipHide();\n });\n });\n \n // Trace line hover handlers\n mapInstance.on('mouseenter', 'trace-lines', (e) => {\n mapInstance.getCanvas().style.cursor = 'pointer';\n \n if (e.features && e.features.length > 0) {\n const props = e.features[0].properties || {};\n const duration = props.duration || '';\n const distance = props.distance || '';\n const avgSpeed = props.avgSpeed || '';\n const group = props.group !== '__all__' ? props.group : null;\n const fromName = props.fromName || '';\n const toName = props.toName || '';\n \n let html = '<div class=\"text-sm space-y-1\">';\n \n if (fromName || toName) {\n html += `<div class=\"font-medium text-xs text-muted-foreground\">${fromName || '?'} → ${toName || '?'}</div>`;\n }\n \n html += '<div class=\"space-y-0.5\">';\n html += `<div><span class=\"text-muted-foreground\">Duration:</span> <span class=\"font-medium\">${duration}</span></div>`;\n html += `<div><span class=\"text-muted-foreground\">Distance:</span> <span class=\"font-medium\">${distance}</span></div>`;\n html += `<div><span class=\"text-muted-foreground\">Avg Speed:</span> <span class=\"font-medium\">${avgSpeed}</span></div>`;\n html += '</div>';\n \n if (group) {\n html += `<div class=\"text-xs text-muted-foreground border-t border-border/50 mt-1 pt-1\">Group: ${group}</div>`;\n }\n \n html += '</div>';\n \n if (!tracePopupRef.current) {\n tracePopupRef.current = new maplibregl.Popup({\n closeButton: false,\n closeOnClick: false,\n className: 'feature-tooltip',\n anchor: 'bottom',\n offset: [0, -10]\n });\n }\n \n tracePopupRef.current\n .setLngLat(e.lngLat)\n .setHTML(html)\n .addTo(mapInstance);\n }\n });\n \n mapInstance.on('mouseleave', 'trace-lines', () => {\n mapInstance.getCanvas().style.cursor = '';\n if (tracePopupRef.current) {\n tracePopupRef.current.remove();\n }\n });\n \n setIsMapLoaded(true);\n isMapLoadedRef.current = true; // Set ref synchronously for imperative handle\n updateFeatureCount();\n \n // Apply initial drawing mode if specified\n if (initialDrawingMode && draw.current) {\n draw.current.changeMode(initialDrawingMode as string);\n setActiveMode(initialDrawingMode as DrawingMode);\n }\n \n // Notify parent that map is ready for programmatic control\n onMapReady?.();\n \n // Load the initial basemap style (streets by default)\n // This is async but we don't need to wait for it\n if (baseMapStyle !== 'satellite') {\n // For non-satellite styles, fetch and add layers\n // Check customBasemaps for a vector override first\n const customDef = customBasemaps?.[baseMapStyle];\n const styleUrl = (customDef?.type === 'vector' && typeof customDef.style === 'string') ? customDef.style : EXTERNAL_STYLE_URLS[baseMapStyle];\n if (styleUrl) {\n const prefix = BASEMAP_LAYER_PREFIXES[baseMapStyle] || `${baseMapStyle}-`;\n fetch(styleUrl)\n .then(res => res.json())\n .then((externalStyle: maplibregl.StyleSpecification) => {\n const addedLayerIds: string[] = [];\n\n // Resolve glyphs/sprite URLs from the external style so\n // the map can load fonts and icons served by the tileserver\n // instead of relying on bundled assets (which aren't\n // available when this component is consumed as a library).\n const resolveUrl = (url: string) => {\n if (/^https?:\\/\\//.test(url)) return url;\n try { return new URL(url, styleUrl).href; } catch { return url; }\n };\n if (externalStyle.glyphs) {\n mapInstance.setGlyphs(resolveUrl(externalStyle.glyphs as string));\n }\n if (externalStyle.sprite) {\n const spriteUrl = typeof externalStyle.sprite === 'string'\n ? resolveUrl(externalStyle.sprite)\n : externalStyle.sprite;\n mapInstance.setSprite(spriteUrl as any);\n }\n\n // Add sources\n if (externalStyle.sources) {\n for (const [sourceId, sourceSpec] of Object.entries(externalStyle.sources)) {\n const prefixedSourceId = `${prefix}${sourceId}`;\n if (!mapInstance.getSource(prefixedSourceId)) {\n mapInstance.addSource(prefixedSourceId, sourceSpec as maplibregl.SourceSpecification);\n }\n }\n }\n \n // Add layers (visible by default for initial style)\n if (externalStyle.layers) {\n for (const layer of externalStyle.layers) {\n const prefixedLayerId = `${prefix}${layer.id}`;\n if (!mapInstance.getLayer(prefixedLayerId)) {\n const newLayer = {\n ...layer,\n id: prefixedLayerId,\n layout: {\n ...(layer.layout || {}),\n visibility: 'visible' as const,\n },\n } as maplibregl.LayerSpecification;\n \n if ('source' in newLayer && typeof newLayer.source === 'string') {\n (newLayer as any).source = `${prefix}${newLayer.source}`;\n }\n \n try {\n const beforeLayer = mapInstance.getLayer('satellite-layer') ? 'satellite-layer'\n : (mapInstance.getLayer('custom-polygon-fill') ? 'custom-polygon-fill' : undefined);\n mapInstance.addLayer(newLayer, beforeLayer);\n addedLayerIds.push(prefixedLayerId);\n } catch (e) {\n // Continue on layer failures\n }\n }\n }\n }\n \n // Track loaded basemap\n basemapLayerIds.current.set(baseMapStyle, addedLayerIds);\n loadedBasemaps.current.add(baseMapStyle);\n })\n .catch(err => {\n console.error('Failed to load initial basemap:', err);\n });\n }\n } else {\n // Satellite is already in base style, just make it visible\n mapInstance.setLayoutProperty('satellite-layer', 'visibility', 'visible');\n }\n \n // Register custom basemaps from props\n if (customBasemaps) {\n for (const [id, definition] of Object.entries(customBasemaps)) {\n customBasemapRegistry.current.set(id, definition);\n \n if (definition.type === 'raster') {\n const sourceId = `custom-basemap-${id}`;\n const layerId = `custom-basemap-layer-${id}`;\n \n if (!mapInstance.getSource(sourceId)) {\n mapInstance.addSource(sourceId, {\n type: 'raster',\n tiles: definition.tiles,\n tileSize: definition.tileSize || 256,\n minzoom: definition.minzoom || 0,\n maxzoom: definition.maxzoom || 22,\n attribution: definition.attribution || '',\n });\n \n // Check if this custom basemap is the initial style\n const isInitialStyle = baseMapStyle === id;\n \n mapInstance.addLayer({\n id: layerId,\n type: 'raster',\n source: sourceId,\n layout: { visibility: isInitialStyle ? 'visible' : 'none' },\n }, 'satellite-layer');\n \n loadedBasemaps.current.add(id);\n basemapLayerIds.current.set(id, [layerId]);\n }\n } else if (definition.type === 'vector' && definition.style) {\n // Vector basemaps are loaded via the initial basemap loading code above\n // (which checks customBasemaps for style URL overrides).\n // Just mark it as a known basemap for the switcher.\n loadedBasemaps.current.add(id);\n }\n }\n }\n });\n\n // Track processed feature IDs to prevent duplicate handling\n const processedFeatureIds = new Set<string>();\n \n mapInstance.on('draw.create', (e: { features: GeoJSON.Feature[] }) => {\n const newFeatures = e.features.filter(f => {\n const id = f.id as string;\n if (processedFeatureIds.has(id)) return false;\n processedFeatureIds.add(id);\n // Clean up old IDs after a delay to prevent memory leak\n setTimeout(() => processedFeatureIds.delete(id), 1000);\n return true;\n });\n \n if (newFeatures.length === 0) return;\n \n // Check if this was a special tool (text or arrow) and add properties\n const pendingKind = pendingFeatureKindRef.current;\n if (pendingKind) {\n newFeatures.forEach(feature => {\n const fid = feature.id as string;\n const existingFeature = drawInstance.get(fid);\n if (existingFeature) {\n let newProps: Record<string, unknown> = { \n ...existingFeature.properties,\n kind: pendingKind \n };\n \n if (pendingKind === 'text') {\n // Default text properties\n newProps = {\n ...newProps,\n label: 'New Label',\n fontSize: 14,\n fontColor: '#000000',\n fontWeight: 'normal',\n };\n // Auto-focus the label input when text feature is created\n setTimeout(() => {\n setAutoFocusLabel(true);\n // Reset after a short delay so subsequent features don't auto-focus\n setTimeout(() => setAutoFocusLabel(false), 200);\n }, 0);\n } else if (pendingKind === 'arrow') {\n // Default arrow properties\n newProps = {\n ...newProps,\n arrowSize: 72,\n stroke: '#3b82f6',\n 'stroke-width': 2,\n };\n // Track this arrow ID externally for reliable detection\n arrowFeatureIdsRef.current.add(fid);\n }\n \n // Update the feature with new properties using setFeatureProperty\n Object.entries(newProps).forEach(([key, value]) => {\n drawInstance.setFeatureProperty(fid, key, value);\n });\n }\n });\n // Clear the pending kind\n pendingFeatureKindRef.current = null;\n }\n \n // Set default entityType for Point features (except text/arrow which have their own kind)\n newFeatures.forEach(feature => {\n const fid = feature.id as string;\n const existingFeature = drawInstance.get(fid);\n if (existingFeature && existingFeature.geometry.type === 'Point') {\n // Only set default entityType if not already set and not a special kind (text/arrow)\n const kind = existingFeature.properties?.kind;\n if (!existingFeature.properties?.entityType && kind !== 'text' && kind !== 'arrow') {\n drawInstance.setFeatureProperty(fid, 'entityType', 'os_geo_thing');\n }\n }\n });\n \n // Mark newly created features as unsaved only if they were user-drawn (not API/import)\n if (!isApiAddingRef.current) {\n newFeatures.forEach(feature => {\n const fid = feature.id as string;\n // Skip marking as unsaved when external persistence handles data\n if (!externalPersistence) {\n drawInstance.setFeatureProperty(fid, '_unsaved', true);\n }\n });\n }\n \n // Use ref to get current activeEditingLayerId (not stale closure value)\n const currentActiveEditingLayerId = activeEditingLayerIdRef.current;\n \n setLayers(prev => {\n // Find a valid target layer: must be visible and not read-only\n let targetLayer = prev.find(l => l.id === currentActiveEditingLayerId && l.visible && !l.readOnly);\n \n // If no valid active editing layer, find the first visible writable layer\n if (!targetLayer) {\n targetLayer = prev.find(l => l.visible && !l.readOnly);\n }\n \n // If still no valid layer, fall back to default even if it's not ideal\n if (!targetLayer) {\n targetLayer = prev.find(l => l.id === 'default');\n }\n \n if (!targetLayer) return prev; // Safety: no layers available\n \n return prev.map(layer => {\n if (layer.id === targetLayer!.id) {\n return {\n ...layer,\n featureIds: [...layer.featureIds, ...newFeatures.map(f => f.id as string)]\n };\n }\n return layer;\n });\n });\n updateFeatureCount();\n updateTimelineStore();\n saveStateForUndo();\n syncRef.current();\n \n // Reset to simple_select mode after creating any feature (so draw tools turn off)\n // Use setTimeout to avoid triggering another draw.create event\n setTimeout(() => {\n setActiveMode('simple_select');\n if (drawInstance.getMode() !== 'simple_select') {\n drawInstance.changeMode('simple_select');\n }\n }, 0);\n \n newFeatures.forEach(feature => {\n onFeatureCreate?.(feature);\n });\n });\n\n // Sync custom layers during drag for real-time visual feedback\n mapInstance.on('draw.render', () => {\n syncRef.current();\n });\n\n mapInstance.on('draw.update', (e: { features: GeoJSON.Feature[]; action?: string }) => {\n const activeLayerId = activeEditingLayerIdRef.current;\n const currentLayers = layersRef.current;\n const editMode = isEditModeRef.current;\n \n // Build feature-to-layer lookup\n const featureToLayerId = new Map<string, string>();\n currentLayers.forEach(layer => {\n layer.featureIds.forEach(fid => featureToLayerId.set(fid, layer.id));\n });\n \n // Check each updated feature - revert if not editable\n let hasRevertedFeatures = false;\n e.features.forEach(feature => {\n const fid = feature.id as string;\n const owningLayerId = featureToLayerId.get(fid);\n const owningLayer = currentLayers.find(l => l.id === owningLayerId);\n \n // Feature is NOT editable if:\n // 1. Edit mode is off, OR\n // 2. It belongs to a different layer than activeEditingLayerId, OR\n // 3. Its layer is read-only\n const isEditable = editMode && owningLayerId === activeLayerId && !owningLayer?.readOnly;\n \n if (!isEditable) {\n // Revert to original geometry\n const originalGeometry = originalGeometriesRef.current.get(fid);\n if (originalGeometry && drawInstance) {\n // Restore original geometry by updating the feature in draw\n const currentFeature = drawInstance.get(fid);\n if (currentFeature) {\n drawInstance.add({\n ...currentFeature,\n geometry: originalGeometry\n });\n hasRevertedFeatures = true;\n }\n }\n } else {\n // Feature was validly edited - update stored geometry\n originalGeometriesRef.current.set(fid, JSON.parse(JSON.stringify(feature.geometry)));\n // Mark feature as unsaved since geometry was modified via UI (skip when external persistence)\n if (!externalPersistence) {\n drawInstance.setFeatureProperty(fid, '_unsaved', true);\n }\n onFeatureUpdate?.(feature);\n // Trigger re-render to update properties panel with new coordinates\n setFeatureUpdateCounter(c => c + 1);\n }\n });\n \n // Sync custom layers on every update for visual feedback\n syncRef.current();\n \n // Only save undo state and update timeline when action is complete (not during vertex moves)\n // And only if we didn't revert all changes\n if (e.action === 'change_coordinates' && !hasRevertedFeatures) {\n updateTimelineStore();\n saveStateForUndo();\n }\n });\n\n mapInstance.on('draw.delete', (e: { features: GeoJSON.Feature[] }) => {\n const deletedIds = e.features.map(f => f.id as string);\n // Clean up arrow tracking\n deletedIds.forEach(id => arrowFeatureIdsRef.current.delete(id));\n \n setLayers(prev => prev.map(layer => ({\n ...layer,\n featureIds: layer.featureIds.filter(id => !deletedIds.includes(id))\n })));\n updateFeatureCount();\n updateTimelineStore();\n saveStateForUndo();\n syncRef.current();\n \n onFeatureDelete?.(deletedIds);\n });\n\n mapInstance.on('draw.selectionchange', (e: { features: GeoJSON.Feature[] }) => {\n // Skip if we're in the middle of selecting a read-only feature\n // (the clear operation triggers this event but we've already set our selection)\n if (isSelectingReadOnlyRef.current) {\n return;\n }\n \n const ids = e.features.map(f => f.id as string);\n \n // Capture original geometries for selected features (for edit protection)\n e.features.forEach(feature => {\n const fid = feature.id as string;\n if (!originalGeometriesRef.current.has(fid)) {\n originalGeometriesRef.current.set(fid, JSON.parse(JSON.stringify(feature.geometry)));\n }\n });\n \n // Clean up geometries for deselected features\n const currentIds = new Set(ids);\n originalGeometriesRef.current.forEach((_, key) => {\n if (!currentIds.has(key)) {\n originalGeometriesRef.current.delete(key);\n }\n });\n \n setSelectedFeatureIds(ids);\n setShowProperties(ids.length > 0);\n syncRef.current();\n \n onFeatureSelect?.(e.features);\n });\n \n // Also sync on mode change to ensure consistency\n mapInstance.on('draw.modechange', () => {\n syncRef.current();\n });\n \n // Click handler for selecting read-only features (not in MapboxDraw)\n // Supports toggle (click selected → deselect) and Ctrl/Cmd multi-select\n mapInstance.on('click', (e) => {\n if (e.originalEvent.button !== 0) return;\n if (contextMenuFiredRef.current) return;\n \n const isModifierKey = e.originalEvent.ctrlKey || e.originalEvent.metaKey;\n \n const features = mapInstance.queryRenderedFeatures(e.point, {\n layers: ['custom-polygon-fill', 'custom-line', 'custom-point']\n });\n \n if (features.length === 0) return;\n \n const hitFeature = features[0];\n const featureId = hitFeature.properties?.id;\n if (!featureId) return;\n \n let isReadOnly = false;\n readOnlyFeatures.current.forEach((layerFeatures) => {\n if (layerFeatures.some(f => String(f.id) === String(featureId))) {\n isReadOnly = true;\n }\n });\n \n if (!isReadOnly) {\n const currentMode = drawInstance.getMode();\n if (currentMode !== 'simple_select') return;\n return;\n }\n \n const fid = String(featureId);\n const currentSelection = selectedFeatureIdsRef.current;\n const isAlreadySelected = currentSelection.includes(fid);\n \n let nextIds: string[];\n if (isModifierKey) {\n nextIds = isAlreadySelected\n ? currentSelection.filter(id => id !== fid)\n : [...currentSelection, fid];\n } else {\n nextIds = isAlreadySelected\n ? currentSelection.filter(id => id !== fid)\n : [fid];\n }\n \n isSelectingReadOnlyRef.current = true;\n \n if (drawInstance.getSelected().features.length > 0) {\n drawInstance.changeMode('simple_select', { featureIds: [] });\n }\n \n setSelectedFeatureIds(nextIds);\n selectedFeatureIdsRef.current = nextIds;\n if (enableProperties) setShowProperties(nextIds.length > 0);\n syncRef.current();\n \n const selectedFeatures: GeoJSON.Feature[] = [];\n for (const id of nextIds) {\n readOnlyFeatures.current.forEach((layerFeatures) => {\n const found = layerFeatures.find(f => String(f.id) === id);\n if (found) selectedFeatures.push(found);\n });\n }\n onFeatureSelect?.(selectedFeatures);\n \n setTimeout(() => {\n isSelectingReadOnlyRef.current = false;\n }, 0);\n });\n\n mapInstance.on('error', (e) => {\n console.error('Map error:', e);\n });\n\n } catch (error) {\n console.error('Failed to initialize map:', error);\n setMapError(error instanceof Error ? error.message : 'Failed to initialize map');\n }\n\n return () => {\n if (map.current) {\n map.current.remove();\n map.current = null;\n draw.current = null;\n }\n };\n }, []);\n\n // Handle container resize - tell MapLibre to resize when container size changes\n useEffect(() => {\n if (!mapContainer.current || !map.current || !isMapLoaded) return;\n \n const container = mapContainer.current;\n const mapInstance = map.current;\n \n const resizeObserver = new ResizeObserver(() => {\n // Use requestAnimationFrame to batch resize calls and avoid WebGL errors\n requestAnimationFrame(() => {\n try {\n if (mapInstance && !mapInstance._removed) {\n mapInstance.resize();\n }\n } catch {\n // Ignore resize errors - map may be in transition\n }\n });\n });\n \n resizeObserver.observe(container);\n \n return () => {\n resizeObserver.disconnect();\n };\n }, [isMapLoaded]);\n\n // Project filter geometry coordinates onto the SVG overlay.\n // Uses state for initial render so React creates the element, then\n // imperative setAttribute on 'move' to avoid re-rendering 7k+ lines per frame.\n const [filterSvgPoints, setFilterSvgPoints] = useState<string>('');\n useEffect(() => {\n const mapInstance = map.current;\n if (!mapInstance || !isMapLoaded) return;\n if (!filterGeometry) {\n setFilterSvgPoints('');\n return;\n }\n\n const computePoints = (): string => {\n if (!map.current) return '';\n let coords: [number, number][] = [];\n if (filterGeometry.type === 'Polygon') {\n coords = filterGeometry.coordinates[0] as [number, number][];\n }\n if (coords.length === 0) return '';\n return coords.map(([lng, lat]) => {\n const pt = map.current!.project([lng, lat]);\n return `${pt.x},${pt.y}`;\n }).join(' ');\n };\n\n setFilterSvgPoints(computePoints());\n\n const onMove = () => {\n const pts = computePoints();\n if (pts) filterPolygonRef.current?.setAttribute('points', pts);\n };\n mapInstance.on('move', onMove);\n return () => { mapInstance.off('move', onMove); };\n }, [isMapLoaded, filterGeometry]);\n\n useEffect(() => {\n onLayerChange?.(layers);\n }, [layers, onLayerChange]);\n\n // Notify when active editing layer changes\n useEffect(() => {\n // Check if the current active layer can receive new features\n const layer = layers.find(l => l.id === activeEditingLayerId);\n const canAdd = !!layer && !layer.readOnly && layer.visible;\n onActiveEditingLayerChange?.(activeEditingLayerId || null, canAdd);\n }, [activeEditingLayerId, layers, onActiveEditingLayerChange]);\n\n useImperativeHandle(ref, () => ({\n flyTo: (coords: [number, number], zoom?: number) => {\n // Use ref for synchronous check (state may not have updated yet when called from onMapReady)\n if (!map.current || !isMapLoadedRef.current) return;\n map.current.flyTo({ center: coords, zoom: zoom ?? map.current.getZoom(), duration: 2000 });\n },\n \n fitToData: (layerIds?: string[]) => {\n if (!map.current || !isMapLoadedRef.current) return;\n \n const drawFeatures = draw.current ? draw.current.getAll().features : [];\n const readOnlyFeaturesList: GeoJSON.Feature[] = [];\n readOnlyFeatures.current.forEach((features) => {\n readOnlyFeaturesList.push(...features);\n });\n const allFeatures = [...drawFeatures, ...readOnlyFeaturesList];\n \n const currentLayers = layersRef.current;\n const targetLayerIds = layerIds ?? currentLayers.map(l => l.id);\n const targetFeatureIds = currentLayers\n .filter(l => targetLayerIds.includes(l.id))\n .flatMap(l => l.featureIds);\n \n const targetFeatures = allFeatures.filter(f => targetFeatureIds.includes(f.id as string));\n \n if (targetFeatures.length === 0) return;\n \n const fc = turf.featureCollection(targetFeatures);\n const bbox = turf.bbox(fc);\n map.current.fitBounds([[bbox[0], bbox[1]], [bbox[2], bbox[3]]], { padding: 50 });\n },\n \n centerOnFeature: (featureId: string) => {\n if (!map.current || !isMapLoaded) return;\n \n // First try MapboxDraw\n let feature = draw.current?.get(featureId);\n \n // If not found, check read-only features\n if (!feature) {\n readOnlyFeatures.current.forEach((features) => {\n const found = features.find(f => String(f.id) === featureId);\n if (found) feature = found as any;\n });\n }\n \n if (!feature) return;\n \n const center = turf.center(feature as turf.AllGeoJSON);\n map.current.flyTo({ center: center.geometry.coordinates as [number, number] });\n },\n \n listLayers: () => [...layersRef.current],\n \n addLayer: (name: string, geojson?: GeoJSON.FeatureCollection, options?: { readOnly?: boolean; skipFit?: boolean; fitPadding?: number }) => {\n if (!isMapLoadedRef.current) return '';\n \n // Evict any existing layers with the same name to prevent duplicates\n const dupes = layersRef.current.filter(l => l.name === name);\n for (const dupe of dupes) {\n if (draw.current && !dupe.readOnly) {\n dupe.featureIds.forEach(id => { try { draw.current!.delete(id); } catch {} });\n }\n readOnlyFeatures.current.delete(dupe.id);\n hiddenFeatures.current.delete(dupe.id);\n }\n if (dupes.length > 0) {\n const dupeIds = new Set(dupes.map(d => d.id));\n layersRef.current = layersRef.current.filter(l => !dupeIds.has(l.id));\n }\n \n const layerId = `layer-${Date.now()}`;\n const newLayer: Layer = {\n id: layerId,\n name,\n visible: true,\n featureIds: [],\n readOnly: options?.readOnly,\n };\n \n if (geojson) {\n if (options?.readOnly) {\n const featuresWithIds = geojson.features.map(f => {\n const id = f.id ? String(f.id) : crypto.randomUUID();\n return { ...f, id };\n });\n readOnlyFeatures.current.set(layerId, featuresWithIds);\n newLayer.featureIds = featuresWithIds.map(f => String(f.id));\n } else if (draw.current) {\n isApiAddingRef.current = true;\n try {\n const addedIds = geojson.features.map(f => {\n const ids = draw.current!.add(f);\n return ids[0];\n });\n newLayer.featureIds = addedIds;\n } finally {\n isApiAddingRef.current = false;\n }\n }\n }\n \n const updatedLayers = [...layersRef.current, newLayer];\n layersRef.current = updatedLayers;\n setLayers(updatedLayers);\n updateFeatureCount();\n updateTimelineStore();\n syncFeaturesToCustomLayers();\n \n // Fly to features if any (unless caller opted out)\n if (!options?.skipFit && geojson && geojson.features.length > 0 && map.current) {\n try {\n const bbox = turf.bbox(geojson);\n if (bbox.every(v => isFinite(v))) {\n map.current.fitBounds(\n [[bbox[0], bbox[1]], [bbox[2], bbox[3]]],\n { padding: options?.fitPadding ?? 50, maxZoom: 16, duration: 1000 }\n );\n }\n } catch {}\n }\n \n return newLayer.id;\n },\n \n removeLayer: (layerId: string) => {\n const layer = layersRef.current.find(l => l.id === layerId);\n if (!layer || !isMapLoadedRef.current) return false;\n \n if (draw.current && !layer.readOnly) {\n layer.featureIds.forEach(id => {\n try { draw.current!.delete(id); } catch {}\n });\n }\n \n readOnlyFeatures.current.delete(layerId);\n hiddenFeatures.current.delete(layerId);\n \n const updatedLayers = layersRef.current.filter(l => l.id !== layerId);\n layersRef.current = updatedLayers;\n setLayers(updatedLayers);\n updateFeatureCount();\n updateTimelineStore();\n requestAnimationFrame(() => {\n syncRef.current();\n });\n \n return true;\n },\n \n setLayerVisibility: (layerId: string, visible: boolean) => {\n const layer = layersRef.current.find(l => l.id === layerId);\n if (!layer || !isMapLoadedRef.current) return;\n \n if (layer.readOnly) {\n const nextLayers = layersRef.current.map(l => \n l.id === layerId ? { ...l, visible } : l\n );\n layersRef.current = nextLayers;\n setLayers(nextLayers);\n updateFeatureCount();\n updateTimelineStore();\n requestAnimationFrame(() => {\n syncRef.current();\n });\n return;\n }\n \n if (!draw.current) return;\n \n let nextLayers: Layer[];\n if (visible) {\n const hidden = hiddenFeatures.current.get(layerId) || [];\n const newIds: string[] = [];\n isApiAddingRef.current = true;\n try {\n hidden.forEach(f => {\n const ids = draw.current!.add(f);\n newIds.push(ids[0]);\n });\n } finally {\n isApiAddingRef.current = false;\n }\n hiddenFeatures.current.delete(layerId);\n \n nextLayers = layersRef.current.map(l => \n l.id === layerId ? { ...l, visible: true, featureIds: newIds } : l\n );\n } else {\n const features = layer.featureIds.map(id => draw.current!.get(id)).filter(Boolean) as GeoJSON.Feature[];\n hiddenFeatures.current.set(layerId, features);\n layer.featureIds.forEach(id => {\n try { draw.current!.delete(id); } catch {}\n });\n \n nextLayers = layersRef.current.map(l => \n l.id === layerId ? { ...l, visible: false, featureIds: [] } : l\n );\n }\n \n layersRef.current = nextLayers;\n setLayers(nextLayers);\n updateFeatureCount();\n updateTimelineStore();\n // Use syncRef to get latest sync function with updated layers\n requestAnimationFrame(() => {\n syncRef.current();\n });\n },\n \n addFeatures: (layerId: string, features: GeoJSON.Feature[]) => {\n // Use layersRef for synchronous access (state may not have updated yet when called from onMapReady)\n const layer = layersRef.current.find(l => l.id === layerId);\n if (!layer || !draw.current || !isMapLoadedRef.current) return [];\n \n const addedIds: string[] = [];\n \n // Mark as API adding so draw.create doesn't set _unsaved flag\n isApiAddingRef.current = true;\n try {\n features.forEach(f => {\n const { startDate, endDate } = normalizeTemporalProperties(f.properties || {});\n const normalizedFeature = {\n ...f,\n properties: {\n ...f.properties,\n startDate: startDate?.toISOString() || null,\n endDate: endDate?.toISOString() || null,\n }\n };\n const ids = draw.current!.add(normalizedFeature);\n addedIds.push(ids[0]);\n });\n } finally {\n isApiAddingRef.current = false;\n }\n \n setLayers(prev => prev.map(l => \n l.id === layerId ? { ...l, featureIds: [...l.featureIds, ...addedIds] } : l\n ));\n \n updateFeatureCount();\n updateTimelineStore();\n syncFeaturesToCustomLayers();\n \n return addedIds;\n },\n \n removeFeatures: (featureIds: string[]) => {\n if (!draw.current || !isMapLoaded) return;\n \n featureIds.forEach(id => {\n try { draw.current!.delete(id); } catch {}\n });\n \n setLayers(prev => prev.map(l => ({\n ...l,\n featureIds: l.featureIds.filter(id => !featureIds.includes(id))\n })));\n \n updateFeatureCount();\n updateTimelineStore();\n onFeatureDelete?.(featureIds);\n },\n \n selectFeatures: (featureIds: string[]) => {\n applySelectionState(featureIds, { focusProperties: true });\n },\n \n getSelectedFeatures,\n \n setEditMode: (enabled: boolean) => {\n // Always update the ref immediately so draw.update handler respects edit mode\n setIsEditMode(enabled);\n isEditModeRef.current = enabled;\n \n // Only change draw mode when DISABLING edit mode (to prevent accidental edits)\n // When enabling, keep the current mode (could be draw_point, draw_polygon, etc.)\n if (!enabled && draw.current) {\n draw.current.changeMode('view_select' as string);\n setActiveMode('view_select');\n }\n },\n \n isEditModeEnabled: () => isEditMode,\n \n setTimelineEnabled: (enabled: boolean) => {\n timelineStore.setEnabled(enabled);\n },\n \n setTimelineRange: (start: Date, end: Date) => {\n timelineStore.setRange(start, end);\n onTimelineChange?.(start, end);\n },\n \n exportGeoJSON: (layerIds?: string[]) => {\n const targetLayerIds = layerIds ?? layers.map(l => l.id);\n const allFeatures: GeoJSON.Feature[] = [];\n \n layers.filter(l => targetLayerIds.includes(l.id)).forEach(layer => {\n // Check if this is a read-only layer\n const readOnly = readOnlyFeatures.current.get(layer.id);\n if (readOnly) {\n allFeatures.push(...readOnly);\n } else if (layer.visible) {\n layer.featureIds.forEach(id => {\n const f = draw.current?.get(id);\n if (f) allFeatures.push(f as GeoJSON.Feature);\n });\n } else {\n const hidden = hiddenFeatures.current.get(layer.id) || [];\n allFeatures.push(...hidden);\n }\n });\n \n // Strip internal properties (prefixed with _) from exported features\n const cleanedFeatures = allFeatures.map(f => ({\n ...f,\n properties: Object.fromEntries(\n Object.entries(f.properties || {}).filter(([key]) => !key.startsWith('_'))\n ),\n }));\n \n return { type: 'FeatureCollection' as const, features: cleanedFeatures };\n },\n \n importGeoJSON: (layerId: string, geojson: GeoJSON.FeatureCollection) => {\n const layer = layers.find(l => l.id === layerId);\n if (!layer || !draw.current || !isMapLoaded) return [];\n \n const addedIds: string[] = [];\n \n // Mark as API adding so draw.create doesn't set _unsaved flag\n isApiAddingRef.current = true;\n try {\n geojson.features.forEach(f => {\n const { startDate, endDate } = normalizeTemporalProperties(f.properties || {});\n const normalizedFeature = {\n ...f,\n properties: {\n ...f.properties,\n startDate: startDate?.toISOString() || null,\n endDate: endDate?.toISOString() || null,\n }\n };\n const ids = draw.current!.add(normalizedFeature);\n addedIds.push(ids[0]);\n });\n } finally {\n isApiAddingRef.current = false;\n }\n \n setLayers(prev => prev.map(l => \n l.id === layerId ? { ...l, featureIds: [...l.featureIds, ...addedIds] } : l\n ));\n \n updateFeatureCount();\n updateTimelineStore();\n syncFeaturesToCustomLayers();\n \n return addedIds;\n },\n \n getActiveEditableLayerId: () => {\n // Return the active editing layer ID if it's not read-only, otherwise null\n if (!activeEditingLayerId) return null;\n const layer = layers.find(l => l.id === activeEditingLayerId);\n if (!layer || layer.readOnly) return null;\n return activeEditingLayerId;\n },\n \n canAddFeatures: () => {\n // Can add features if there's an active editable layer that is not read-only\n if (!activeEditingLayerId) return false;\n const layer = layers.find(l => l.id === activeEditingLayerId);\n return !!layer && !layer.readOnly && layer.visible;\n },\n \n // Basemap management methods\n \n registerBasemap: (id: string, definition: import('@/lib/map-editor-api').BasemapDefinition) => {\n if (!map.current) return;\n \n // Store in registry\n customBasemapRegistry.current.set(id, definition);\n \n // If raster, add the source and layer immediately (hidden)\n if (definition.type === 'raster') {\n const sourceId = `custom-basemap-${id}`;\n const layerId = `custom-basemap-layer-${id}`;\n \n if (!map.current.getSource(sourceId)) {\n map.current.addSource(sourceId, {\n type: 'raster',\n tiles: definition.tiles,\n tileSize: definition.tileSize || 256,\n minzoom: definition.minzoom || 0,\n maxzoom: definition.maxzoom || 22,\n attribution: definition.attribution || '',\n });\n \n // Add layer at the bottom (after background)\n map.current.addLayer({\n id: layerId,\n type: 'raster',\n source: sourceId,\n layout: { visibility: 'none' },\n }, 'satellite-layer'); // Insert before satellite layer\n \n loadedBasemaps.current.add(id);\n basemapLayerIds.current.set(id, [layerId]);\n }\n }\n // Vector basemaps will be loaded on-demand when selected\n },\n \n unregisterBasemap: (id: string) => {\n if (!map.current) return false;\n \n // Can't unregister built-in basemaps\n const builtIn = ['streets', 'satellite', 'dark'];\n if (builtIn.includes(id)) return false;\n \n // Remove from registry\n customBasemapRegistry.current.delete(id);\n \n // Remove layers and source\n const layerIds = basemapLayerIds.current.get(id) || [];\n for (const layerId of layerIds) {\n if (map.current.getLayer(layerId)) {\n map.current.removeLayer(layerId);\n }\n }\n \n const sourceId = `custom-basemap-${id}`;\n if (map.current.getSource(sourceId)) {\n map.current.removeSource(sourceId);\n }\n \n loadedBasemaps.current.delete(id);\n basemapLayerIds.current.delete(id);\n \n return true;\n },\n \n setBasemap: (id: string) => {\n handleMapStyleChangeRef.current?.(id as MapStyle);\n },\n \n getBasemap: () => {\n return currentMapStyle;\n },\n \n listBasemaps: () => {\n const builtIn = ['streets', 'satellite', 'dark'];\n const custom = Array.from(customBasemapRegistry.current.keys());\n return [...builtIn, ...custom];\n },\n \n setDrawingMode: (mode: 'simple_select' | 'draw_point' | 'draw_line_string' | 'draw_polygon') => {\n // Use ref for synchronous check (state may not have updated yet when called from onMapReady)\n if (!draw.current || !isMapLoadedRef.current) return;\n setActiveMode(mode as DrawingMode);\n draw.current.changeMode(mode as string);\n },\n \n getDrawingMode: () => {\n return activeMode;\n },\n \n updateReadOnlyLayer: (layerId: string, features: GeoJSON.Feature[]) => {\n const layer = layersRef.current.find(l => l.id === layerId);\n if (!layer || !layer.readOnly || !isMapLoadedRef.current) return false;\n \n const featuresWithIds = features.map(f => {\n const id = f.id ? String(f.id) : crypto.randomUUID();\n return { ...f, id };\n });\n readOnlyFeatures.current.set(layerId, featuresWithIds);\n \n const newFeatureIds = featuresWithIds.map(f => String(f.id));\n const updatedLayers = layersRef.current.map(l => \n l.id === layerId ? { ...l, featureIds: newFeatureIds } : l\n );\n layersRef.current = updatedLayers;\n setLayers(updatedLayers);\n updateFeatureCount();\n \n requestAnimationFrame(() => {\n syncRef.current();\n });\n \n return true;\n },\n \n setLayerData: (name: string, geojson: GeoJSON.FeatureCollection, options?: { fitPadding?: number }) => {\n if (!isMapLoadedRef.current) return '';\n\n const featuresWithIds = geojson.features.map(f => {\n const id = f.id ? String(f.id) : crypto.randomUUID();\n return { ...f, id };\n });\n const newFeatureIds = featuresWithIds.map(f => String(f.id));\n\n const layerId = `managed-${name}`;\n readOnlyFeatures.current.set(layerId, featuresWithIds);\n\n const newLayerObj: Layer = {\n id: layerId,\n name,\n visible: true,\n featureIds: newFeatureIds,\n readOnly: true,\n };\n\n // Eagerly update layersRef so sync functions see correct data\n const eagerCleaned = layersRef.current.filter(l => !(l.name === name && l.id !== layerId));\n const eagerIdx = eagerCleaned.findIndex(l => l.id === layerId);\n layersRef.current = eagerIdx >= 0\n ? eagerCleaned.map(l => l.id === layerId ? newLayerObj : l)\n : [...eagerCleaned, newLayerObj];\n\n // Functional update guarantees we operate on latest React state\n setLayers(prev => {\n const cleaned = prev.filter(l => {\n if (l.name === name && l.id !== layerId) {\n readOnlyFeatures.current.delete(l.id);\n hiddenFeatures.current.delete(l.id);\n if (draw.current && !l.readOnly) {\n l.featureIds.forEach(fid => { try { draw.current!.delete(fid); } catch {} });\n }\n return false;\n }\n return true;\n });\n const idx = cleaned.findIndex(l => l.id === layerId);\n const result = idx >= 0\n ? cleaned.map(l => l.id === layerId ? newLayerObj : l)\n : [...cleaned, newLayerObj];\n layersRef.current = result;\n return result;\n });\n\n updateFeatureCount();\n requestAnimationFrame(() => { syncRef.current(); });\n\n if (options?.fitPadding != null && geojson.features.length > 0 && map.current) {\n try {\n const bbox = turf.bbox(geojson);\n if (bbox.every(v => isFinite(v))) {\n map.current.fitBounds(\n [[bbox[0], bbox[1]], [bbox[2], bbox[3]]],\n { padding: options.fitPadding, maxZoom: 16, duration: 1000 }\n );\n }\n } catch {}\n }\n\n return layerId;\n },\n\n clearSelection: () => {\n setPersistedSelectionPolygon(null);\n setSelectionPoints([]);\n // Clear selected features\n setSelectedFeatureIds([]);\n applySelectionState([], { focusProperties: true });\n },\n \n // Viewport and state getters\n \n getViewport: (): import('@/lib/map-editor-api').ViewportInfo | null => {\n if (!map.current || !isMapLoaded) {\n return null;\n }\n \n const mapInstance = map.current;\n const center = mapInstance.getCenter();\n const zoom = mapInstance.getZoom();\n const bounds = mapInstance.getBounds();\n const rawBounds: [number, number, number, number] = [\n bounds.getWest(),\n bounds.getSouth(),\n bounds.getEast(),\n bounds.getNorth()\n ];\n \n return {\n center: [center.lng, center.lat],\n zoom,\n bounds: rawBounds,\n queryBounds: {\n minLng: Math.max(-180, Math.min(180, rawBounds[0])),\n maxLng: Math.max(-180, Math.min(180, rawBounds[2])),\n minLat: Math.max(-90, Math.min(90, rawBounds[1])),\n maxLat: Math.max(-90, Math.min(90, rawBounds[3])),\n },\n };\n },\n \n getLayerData: (layerId: string): GeoJSON.Feature[] => {\n const layer = layersRef.current.find(l => l.id === layerId);\n if (!layer) return [];\n \n const features: GeoJSON.Feature[] = [];\n \n // Check if this is a read-only layer\n const readOnly = readOnlyFeatures.current.get(layerId);\n if (readOnly) {\n // Clone read-only features to prevent mutation\n return readOnly.map(f => JSON.parse(JSON.stringify(f)));\n }\n \n // Editable layer - get from MapboxDraw or hidden storage\n if (layer.visible) {\n layer.featureIds.forEach(id => {\n const f = draw.current?.get(id);\n if (f) {\n // Clone and ensure consistent structure (same as exportGeoJSON)\n features.push(JSON.parse(JSON.stringify(f)));\n }\n });\n } else {\n const hidden = hiddenFeatures.current.get(layerId) || [];\n return hidden.map(f => JSON.parse(JSON.stringify(f)));\n }\n \n return features;\n },\n \n getTimelineRange: () => {\n return {\n start: timelineStore.rangeStart,\n end: timelineStore.rangeEnd,\n };\n },\n \n getMapUnsavedCount: () => {\n if (!draw.current) return 0;\n const allFeatures = draw.current.getAll().features;\n return allFeatures.filter(f => f.properties?._unsaved === true).length;\n },\n }), [layers, isEditMode, isMapLoaded, getSelectedFeatures, updateFeatureCount, updateTimelineStore, syncFeaturesToCustomLayers, timelineStore, onFeatureDelete, onTimelineChange, activeEditingLayerId, currentMapStyle, activeMode]);\n\n const handleModeChange = useCallback((mode: DrawingMode) => {\n if (!draw.current || !isMapLoaded) return;\n \n if (!hasVisibleLayers && mode !== 'simple_select' && mode !== 'view_select') {\n toast({\n title: \"No visible layers\",\n description: \"Show at least one layer to draw features\",\n variant: \"destructive\",\n });\n return;\n }\n \n // Handle special modes that map to underlying MapboxDraw modes\n if (mode === 'draw_text') {\n pendingFeatureKindRef.current = 'text';\n setActiveMode(mode);\n draw.current.changeMode('draw_point');\n return;\n } else if (mode === 'draw_arrow') {\n pendingFeatureKindRef.current = 'arrow';\n setActiveMode(mode);\n draw.current.changeMode('draw_line_string');\n return;\n } else if (mode === 'draw_circle') {\n // Circle uses custom handling (click center, drag radius)\n pendingFeatureKindRef.current = 'circle';\n setActiveMode(mode);\n // Put MapboxDraw in simple_select so it doesn't interfere\n draw.current.changeMode('simple_select');\n return;\n } else if (mode === 'draw_rectangle') {\n // Rectangle uses custom handling (click corner, drag to opposite corner)\n pendingFeatureKindRef.current = 'rectangle';\n setActiveMode(mode);\n // Put MapboxDraw in simple_select so it doesn't interfere\n draw.current.changeMode('simple_select');\n return;\n }\n \n // Clear pending kind for normal modes\n pendingFeatureKindRef.current = null;\n setActiveMode(mode);\n draw.current.changeMode(mode as string);\n }, [isMapLoaded, hasVisibleLayers, toast]);\n\n const handleUndo = useCallback(() => {\n if (undoStack.length === 0 || !draw.current) return;\n \n const currentState: UndoState = {\n features: draw.current.getAll().features as GeoJSON.Feature[],\n layers: JSON.parse(JSON.stringify(layers)),\n selectedIds: [...selectedFeatureIds],\n };\n \n const prevState = undoStack[undoStack.length - 1];\n \n // Set guard to prevent selectionchange from overwriting restored selection\n isSelectingReadOnlyRef.current = true;\n \n draw.current.deleteAll();\n // Mark as API adding so draw.create doesn't set _unsaved flag\n isApiAddingRef.current = true;\n try {\n prevState.features.forEach(f => draw.current!.add(f));\n } finally {\n isApiAddingRef.current = false;\n }\n setLayers(prevState.layers);\n \n // Use applySelectionState to properly handle restored selection\n applySelectionState(prevState.selectedIds, { focusProperties: false });\n \n setUndoStack(prev => prev.slice(0, -1));\n setRedoStack(prev => [...prev, currentState]);\n updateFeatureCount();\n updateTimelineStore();\n syncFeaturesToCustomLayers();\n }, [undoStack, layers, selectedFeatureIds, updateFeatureCount, updateTimelineStore, syncFeaturesToCustomLayers, applySelectionState]);\n\n const handleRedo = useCallback(() => {\n if (redoStack.length === 0 || !draw.current) return;\n \n const currentState: UndoState = {\n features: draw.current.getAll().features as GeoJSON.Feature[],\n layers: JSON.parse(JSON.stringify(layers)),\n selectedIds: [...selectedFeatureIds],\n };\n \n const nextState = redoStack[redoStack.length - 1];\n \n // Set guard to prevent selectionchange from overwriting restored selection\n isSelectingReadOnlyRef.current = true;\n \n draw.current.deleteAll();\n // Mark as API adding so draw.create doesn't set _unsaved flag\n isApiAddingRef.current = true;\n try {\n nextState.features.forEach(f => draw.current!.add(f));\n } finally {\n isApiAddingRef.current = false;\n }\n setLayers(nextState.layers);\n \n // Use applySelectionState to properly handle restored selection\n applySelectionState(nextState.selectedIds, { focusProperties: false });\n \n setRedoStack(prev => prev.slice(0, -1));\n setUndoStack(prev => [...prev, currentState]);\n updateFeatureCount();\n updateTimelineStore();\n syncFeaturesToCustomLayers();\n }, [redoStack, layers, selectedFeatureIds, updateFeatureCount, updateTimelineStore, syncFeaturesToCustomLayers, applySelectionState]);\n\n const handleClear = useCallback(() => {\n if (!draw.current) return;\n \n // Get active layer - only clear editable layers\n const activeLayer = layersRef.current.find(l => l.id === activeEditingLayerId);\n if (!activeLayer) {\n toast({\n title: \"No layer selected\",\n description: \"Select an editable layer to clear features\",\n variant: \"destructive\",\n });\n return;\n }\n \n if (activeLayer.readOnly) {\n toast({\n title: \"Cannot clear read-only layer\",\n description: \"This layer is locked and cannot be modified\",\n variant: \"destructive\",\n });\n return;\n }\n \n if (activeLayer.featureIds.length === 0) {\n toast({\n title: \"Layer is empty\",\n description: \"No features to clear\",\n });\n return;\n }\n \n saveStateForUndo();\n \n // Only delete features from the active layer\n activeLayer.featureIds.forEach(id => {\n arrowFeatureIdsRef.current.delete(id);\n try { draw.current!.delete(id); } catch {}\n });\n \n // Only clear featureIds for the active layer\n setLayers(prev => prev.map(l => \n l.id === activeEditingLayerId ? { ...l, featureIds: [] } : l\n ));\n \n setSelectedFeatureIds([]);\n setShowProperties(false);\n updateFeatureCount();\n updateTimelineStore();\n syncFeaturesToCustomLayers();\n \n toast({\n title: \"Layer cleared\",\n description: `Removed all features from \"${activeLayer.name}\"`,\n });\n }, [activeEditingLayerId, saveStateForUndo, updateFeatureCount, updateTimelineStore, syncFeaturesToCustomLayers, toast]);\n\n const handleDeleteSelected = useCallback(() => {\n if (!draw.current || selectedFeatureIds.length === 0) return;\n saveStateForUndo();\n \n selectedFeatureIds.forEach(id => {\n // Clean up arrow tracking\n arrowFeatureIdsRef.current.delete(id);\n try { draw.current!.delete(id); } catch {}\n });\n \n setLayers(prev => prev.map(l => ({\n ...l,\n featureIds: l.featureIds.filter(id => !selectedFeatureIds.includes(id))\n })));\n \n onFeatureDelete?.(selectedFeatureIds);\n setSelectedFeatureIds([]);\n setShowProperties(false);\n updateFeatureCount();\n updateTimelineStore();\n syncFeaturesToCustomLayers();\n }, [selectedFeatureIds, saveStateForUndo, updateFeatureCount, updateTimelineStore, syncFeaturesToCustomLayers, onFeatureDelete]);\n\n const handleToggleEditMode = useCallback(() => {\n setIsEditMode(prev => {\n const newMode = !prev;\n if (draw.current) {\n if (newMode) {\n draw.current.changeMode('simple_select');\n setActiveMode('simple_select');\n } else {\n draw.current.changeMode('view_select');\n setActiveMode('view_select');\n }\n }\n return newMode;\n });\n }, []);\n\n const handleToggleLayers = useCallback(() => {\n setShowLayers(prev => !prev);\n }, []);\n\n // Keyboard shortcuts scoped to the map container (requires focus)\n useEffect(() => {\n if (!isMapLoaded || !enableKeyboardShortcuts || !mapContainer.current) return;\n \n const container = mapContainer.current;\n \n const handleKeyDown = (e: KeyboardEvent) => {\n const target = e.target as HTMLElement;\n if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable) {\n return;\n }\n \n const key = e.key.toLowerCase();\n const isCtrlOrCmd = e.ctrlKey || e.metaKey;\n \n if (isCtrlOrCmd && key === 'z' && !e.shiftKey) {\n e.preventDefault();\n handleUndo();\n return;\n }\n if (isCtrlOrCmd && (key === 'y' || (key === 'z' && e.shiftKey))) {\n e.preventDefault();\n handleRedo();\n return;\n }\n \n if (key === 'e' && !isCtrlOrCmd && !e.altKey) {\n e.preventDefault();\n handleToggleEditMode();\n return;\n }\n \n if (!isEditMode) return;\n if (isCtrlOrCmd) return;\n \n switch (key) {\n case 'delete':\n case 'backspace':\n if (selectedFeatureIds.length > 0) {\n e.preventDefault();\n handleDeleteSelected();\n }\n break;\n case 'p':\n e.preventDefault();\n handleModeChange(activeMode === 'draw_point' ? 'simple_select' : 'draw_point');\n break;\n case 'l':\n e.preventDefault();\n handleModeChange(activeMode === 'draw_line_string' ? 'simple_select' : 'draw_line_string');\n break;\n case 'g':\n e.preventDefault();\n handleModeChange(activeMode === 'draw_polygon' ? 'simple_select' : 'draw_polygon');\n break;\n case 'b':\n e.preventDefault();\n handleModeChange(activeMode === 'draw_rectangle' ? 'simple_select' : 'draw_rectangle');\n break;\n case 't':\n e.preventDefault();\n handleModeChange(activeMode === 'draw_text' ? 'simple_select' : 'draw_text');\n break;\n case 'w':\n e.preventDefault();\n handleModeChange(activeMode === 'draw_arrow' ? 'simple_select' : 'draw_arrow');\n break;\n case 'c':\n e.preventDefault();\n handleModeChange(activeMode === 'draw_circle' ? 'simple_select' : 'draw_circle');\n break;\n case 'escape':\n handleModeChange('simple_select');\n break;\n }\n };\n \n container.addEventListener('keydown', handleKeyDown);\n return () => container.removeEventListener('keydown', handleKeyDown);\n }, [isMapLoaded, enableKeyboardShortcuts, isEditMode, activeMode, handleToggleEditMode, handleUndo, handleRedo, handleModeChange, selectedFeatureIds, handleDeleteSelected]);\n\n // Handle right-click context menu on features\n const handleFeatureContextMenu = useCallback((e: MouseEvent) => {\n contextMenuFiredRef.current = true;\n setTimeout(() => { contextMenuFiredRef.current = false; }, 0);\n \n if (!contextMenuProvider || !map.current) return;\n \n const mapInstance = map.current;\n \n // Query features at click point (including read-only layers)\n const point: [number, number] = [e.offsetX, e.offsetY];\n const clickedFeatures = mapInstance.queryRenderedFeatures(point, {\n layers: ['custom-point', 'custom-line', 'custom-polygon-fill']\n });\n \n // Use clicked feature for context menu without changing selection state\n let features: GeoJSON.Feature[] = [];\n \n if (clickedFeatures.length > 0) {\n const clickedId = String(clickedFeatures[0].properties?.id || clickedFeatures[0].id);\n let clickedFeature: GeoJSON.Feature | null = null;\n \n readOnlyFeatures.current.forEach((layerFeatures) => {\n const found = layerFeatures.find(f => String(f.id) === clickedId);\n if (found) clickedFeature = found;\n });\n \n if (!clickedFeature && draw.current) {\n const drawFeature = draw.current.get(clickedId);\n if (drawFeature) clickedFeature = drawFeature;\n }\n \n if (clickedFeature) {\n features = [clickedFeature];\n }\n }\n \n if (features.length === 0) return;\n \n e.preventDefault();\n \n // Get click coordinates in lng/lat\n const lngLat = mapInstance.unproject([e.offsetX, e.offsetY]);\n const clickCoords: [number, number] = [lngLat.lng, lngLat.lat];\n \n // Build feature-layer mapping\n const featureLayers: Record<string, { layerId: string; layerName: string }> = {};\n features.forEach(f => {\n const fid = String(f.id);\n // Find which layer this feature belongs to\n for (const layer of layersRef.current) {\n if (layer.featureIds.includes(fid)) {\n featureLayers[fid] = { layerId: layer.id, layerName: layer.name };\n break;\n }\n }\n });\n \n // Get viewport info\n const bounds = mapInstance.getBounds();\n const rawBounds: [number, number, number, number] = [\n bounds.getWest(),\n bounds.getSouth(),\n bounds.getEast(),\n bounds.getNorth()\n ];\n const queryBounds = {\n minLng: Math.max(-180, Math.min(180, rawBounds[0])),\n maxLng: Math.max(-180, Math.min(180, rawBounds[2])),\n minLat: Math.max(-90, Math.min(90, rawBounds[1])),\n maxLat: Math.max(-90, Math.min(90, rawBounds[3])),\n };\n const viewport: import('@/lib/map-editor-api').ViewportInfo = {\n center: [mapInstance.getCenter().lng, mapInstance.getCenter().lat],\n zoom: mapInstance.getZoom(),\n bounds: rawBounds,\n queryBounds,\n };\n \n // Build context and call provider\n const context: import('@/lib/map-editor-api').ContextMenuContext = {\n selectedFeatures: features,\n featureLayers,\n clickCoords,\n viewport,\n isEditMode,\n activeLayerId: activeEditingLayerIdRef.current,\n event: e,\n };\n \n const items = contextMenuProvider(context);\n if (!items || items.length === 0) return;\n \n // Show the context menu at the click position\n setContextMenu({\n x: e.clientX,\n y: e.clientY,\n items,\n });\n }, [contextMenuProvider, getSelectedFeatures, isEditMode, applySelectionState]);\n\n // Block right-click mousedown from reaching MapLibre/MapboxDraw to prevent selection\n useEffect(() => {\n if (!isMapLoaded || !map.current) return;\n \n const canvas = map.current.getCanvas();\n \n const blockRightMouseDown = (e: MouseEvent) => {\n if (e.button === 2) {\n e.stopPropagation();\n }\n };\n \n canvas.addEventListener('mousedown', blockRightMouseDown, true);\n \n return () => {\n canvas.removeEventListener('mousedown', blockRightMouseDown, true);\n };\n }, [isMapLoaded]);\n\n // Add right-click listener to map canvas\n useEffect(() => {\n if (!isMapLoaded || !map.current || !contextMenuProvider) return;\n \n const canvas = map.current.getCanvas();\n \n const handleContextMenu = (e: MouseEvent) => {\n handleFeatureContextMenu(e);\n };\n \n canvas.addEventListener('contextmenu', handleContextMenu);\n \n return () => {\n canvas.removeEventListener('contextmenu', handleContextMenu);\n };\n }, [isMapLoaded, contextMenuProvider, handleFeatureContextMenu]);\n\n // Close context menu when clicking elsewhere\n useEffect(() => {\n if (!contextMenu) return;\n \n const handleClick = () => {\n setContextMenu(null);\n };\n \n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n setContextMenu(null);\n }\n };\n \n // Delay adding listener so current click doesn't immediately close it\n const timeoutId = setTimeout(() => {\n window.addEventListener('click', handleClick);\n window.addEventListener('keydown', handleKeyDown);\n }, 0);\n \n return () => {\n clearTimeout(timeoutId);\n window.removeEventListener('click', handleClick);\n window.removeEventListener('keydown', handleKeyDown);\n };\n }, [contextMenu]);\n\n const handleCloseProperties = useCallback(() => {\n setShowProperties(false);\n if (draw.current) {\n const mode: DrawingMode = isEditMode ? 'simple_select' : 'view_select';\n draw.current.changeMode(mode as string, { featureIds: [] });\n }\n setSelectedFeatureIds([]);\n }, [isEditMode]);\n\n const handleUpdateProperties = useCallback((featureId: string, properties: Record<string, unknown>) => {\n if (!draw.current || !map.current) return;\n \n const feature = draw.current.get(featureId);\n if (!feature) return;\n \n saveStateForUndo();\n \n const { startDate, endDate } = normalizeTemporalProperties(properties);\n const normalizedProperties = {\n ...properties,\n startDate: startDate?.toISOString() || null,\n endDate: endDate?.toISOString() || null,\n };\n \n // Update properties using setFeatureProperty\n Object.entries(normalizedProperties).forEach(([key, value]) => {\n draw.current!.setFeatureProperty(featureId, key, value);\n });\n \n // Mark feature as unsaved since properties were modified via UI (skip when external persistence)\n if (!externalPersistence) {\n draw.current.setFeatureProperty(featureId, '_unsaved', true);\n }\n \n // Clear legacy 'text' property for text features to ensure 'label' is used\n if (properties.kind === 'text' || feature.properties?.kind === 'text') {\n draw.current!.setFeatureProperty(featureId, 'text', undefined);\n }\n \n // Sync to custom rendering layers\n syncFeaturesToCustomLayers();\n updateTimelineStore();\n \n const updated = draw.current.get(featureId);\n if (updated) {\n onFeatureUpdate?.(updated as GeoJSON.Feature);\n }\n }, [saveStateForUndo, updateTimelineStore, onFeatureUpdate, syncFeaturesToCustomLayers]);\n\n // Handler for updating point geometry (coordinates) from properties panel\n const handleUpdateGeometry = useCallback((featureId: string, geometry: GeoJSON.Geometry) => {\n if (!draw.current || !map.current) return;\n \n const feature = draw.current.get(featureId);\n if (!feature) return;\n \n // Only allow updating Point geometry\n if (feature.geometry.type !== 'Point' || geometry.type !== 'Point') return;\n \n saveStateForUndo();\n \n // Get all features, update the target one, and set them all back\n // This preserves layer bookkeeping and IDs\n const allFeatures = draw.current.getAll();\n const updatedFeatures = allFeatures.features.map(f => {\n if (f.id === featureId) {\n return { ...f, geometry };\n }\n return f;\n });\n \n // Set all features back - this updates in place\n draw.current.set({\n type: 'FeatureCollection',\n features: updatedFeatures,\n });\n \n // Mark feature as unsaved since geometry was modified via UI (skip when external persistence)\n if (!externalPersistence) {\n draw.current.setFeatureProperty(featureId, '_unsaved', true);\n }\n \n // Re-select the feature to maintain selection state\n draw.current.changeMode('simple_select', { featureIds: [featureId] });\n \n // Sync to custom rendering layers\n syncFeaturesToCustomLayers();\n \n const updated = draw.current.get(featureId);\n if (updated) {\n onFeatureUpdate?.(updated as GeoJSON.Feature);\n }\n }, [saveStateForUndo, onFeatureUpdate, syncFeaturesToCustomLayers]);\n\n // Handle feature saved - update feature with new ID and workspace metadata\n const handleFeatureSaved = useCallback((oldId: string, newId: string, metadata: { workspace: string; sourceName: string }) => {\n if (!draw.current) return;\n \n const feature = draw.current.get(oldId);\n if (!feature) return;\n \n // Update the feature in place with new metadata (clear _unsaved, add workspace info)\n draw.current.setFeatureProperty(oldId, '_unsaved', undefined);\n draw.current.setFeatureProperty(oldId, '_workspaceRecord', true);\n // Store workspace metadata both as internal (underscore) and visible properties\n draw.current.setFeatureProperty(oldId, '_workspace', metadata.workspace);\n draw.current.setFeatureProperty(oldId, '_sourceName', metadata.sourceName);\n // Also store as visible custom properties so they show in properties panel\n draw.current.setFeatureProperty(oldId, 'workspace', metadata.workspace);\n draw.current.setFeatureProperty(oldId, 'source_name', metadata.sourceName);\n \n // If the new ID is different from old ID, we need to replace the feature\n if (newId !== oldId) {\n const updatedFeature = draw.current.get(oldId);\n if (updatedFeature) {\n // Delete old feature\n draw.current.delete(oldId);\n \n // Add feature with new ID\n const newFeature = {\n ...updatedFeature,\n id: newId,\n };\n // Mark as API adding so draw.create doesn't set _unsaved flag\n isApiAddingRef.current = true;\n try {\n draw.current.add(newFeature);\n } finally {\n isApiAddingRef.current = false;\n }\n \n // Update layer bookkeeping\n setLayers(prev => prev.map(layer => ({\n ...layer,\n featureIds: layer.featureIds.map(fid => fid === oldId ? newId : fid),\n })));\n \n // Update selection to new ID in React state\n setSelectedFeatureIds(prev => prev.map(fid => fid === oldId ? newId : fid));\n \n // Also update MapboxDraw's internal selection to the new ID\n draw.current.changeMode('simple_select', { featureIds: [newId] });\n }\n }\n \n // Sync rendering\n syncFeaturesToCustomLayers();\n \n // Force a state update to trigger re-render with new properties\n setLayers(prev => [...prev]);\n }, [syncFeaturesToCustomLayers]);\n\n const handleAddLayer = useCallback((name: string) => {\n const newLayer: Layer = {\n id: `layer-${Date.now()}`,\n name,\n visible: true,\n featureIds: [],\n };\n setLayers(prev => [...prev, newLayer]);\n setActiveEditingLayerId(newLayer.id);\n }, []);\n\n const handleRemoveLayer = useCallback((layerId: string) => {\n if (layers.length <= 1) return;\n \n const layer = layers.find(l => l.id === layerId);\n if (!layer || !draw.current) return;\n \n saveStateForUndo();\n \n layer.featureIds.forEach(id => {\n try { draw.current!.delete(id); } catch {}\n });\n \n hiddenFeatures.current.delete(layerId);\n \n setLayers(prev => {\n const filtered = prev.filter(l => l.id !== layerId);\n if (activeEditingLayerId === layerId && filtered.length > 0) {\n setActiveEditingLayerId(filtered[0].id);\n }\n return filtered;\n });\n \n updateFeatureCount();\n updateTimelineStore();\n }, [layers, activeEditingLayerId, saveStateForUndo, updateFeatureCount, updateTimelineStore]);\n\n const handleRenameLayer = useCallback((layerId: string, newName: string) => {\n setLayers(prev => prev.map(l => \n l.id === layerId ? { ...l, name: newName } : l\n ));\n }, []);\n\n const handleToggleLayerVisibility = useCallback((layerId: string) => {\n const layer = layers.find(l => l.id === layerId);\n if (!layer) return;\n \n saveStateForUndo();\n \n let nextLayers: Layer[];\n \n // Handle read-only layers differently - no draw.current needed\n if (layer.readOnly) {\n nextLayers = layers.map(l => \n l.id === layerId ? { ...l, visible: !l.visible } : l\n );\n } else {\n if (!draw.current) return;\n \n if (layer.visible) {\n const features = layer.featureIds.map(id => draw.current!.get(id)).filter(Boolean) as GeoJSON.Feature[];\n hiddenFeatures.current.set(layerId, features);\n layer.featureIds.forEach(id => {\n try { draw.current!.delete(id); } catch {}\n });\n \n nextLayers = layers.map(l => \n l.id === layerId ? { ...l, visible: false, featureIds: [] } : l\n );\n } else {\n const features = hiddenFeatures.current.get(layerId) || [];\n const newIds: string[] = [];\n // Mark as API adding so draw.create doesn't set _unsaved flag\n isApiAddingRef.current = true;\n try {\n features.forEach(f => {\n const ids = draw.current!.add(f);\n newIds.push(ids[0]);\n });\n } finally {\n isApiAddingRef.current = false;\n }\n hiddenFeatures.current.delete(layerId);\n \n nextLayers = layers.map(l => \n l.id === layerId ? { ...l, visible: true, featureIds: newIds } : l\n );\n }\n }\n \n // Update ref BEFORE setLayers so sync functions see new data immediately\n layersRef.current = nextLayers;\n setLayers(nextLayers);\n updateFeatureCount();\n updateTimelineStore();\n \n // For read-only layers, trigger sync to update custom layers\n if (layer.readOnly) {\n requestAnimationFrame(() => {\n syncRef.current();\n });\n }\n }, [layers, saveStateForUndo, updateFeatureCount, updateTimelineStore]);\n\n const handleMoveFeatureToLayer = useCallback((featureId: string, targetLayerId: string) => {\n saveStateForUndo();\n setLayers(prev => prev.map(l => {\n if (l.featureIds.includes(featureId)) {\n return { ...l, featureIds: l.featureIds.filter(id => id !== featureId) };\n }\n if (l.id === targetLayerId) {\n return { ...l, featureIds: [...l.featureIds, featureId] };\n }\n return l;\n }));\n }, [saveStateForUndo]);\n\n const getFeatureCountForLayer = useCallback((layerId: string) => {\n const layer = layers.find(l => l.id === layerId);\n if (!layer) return 0;\n \n if (layer.visible) {\n return layer.featureIds.length;\n } else {\n return hiddenFeatures.current.get(layerId)?.length || 0;\n }\n }, [layers]);\n\n // Get count of unsaved features in a layer\n const getLayerUnsavedCount = useCallback((layerId: string) => {\n const layer = layers.find(l => l.id === layerId);\n if (!layer || !draw.current) return 0;\n \n let count = 0;\n if (layer.visible) {\n layer.featureIds.forEach(id => {\n const feature = draw.current!.get(id);\n if (feature?.properties?._unsaved) {\n count++;\n }\n });\n } else {\n const hidden = hiddenFeatures.current.get(layerId) || [];\n hidden.forEach(f => {\n if (f.properties?._unsaved) {\n count++;\n }\n });\n }\n return count;\n }, [layers]);\n\n // Get total count of unsaved features across all layers (for map-level indicator)\n const getMapUnsavedCount = useCallback(() => {\n let total = 0;\n layers.forEach(layer => {\n total += getLayerUnsavedCount(layer.id);\n });\n return total;\n }, [layers, getLayerUnsavedCount]);\n\n // Load a basemap style and add its layers to the map (prefixed to avoid conflicts)\n const loadBasemapStyle = useCallback(async (styleName: string): Promise<string[]> => {\n if (!map.current) return [];\n \n const mapInstance = map.current;\n const prefix = BASEMAP_LAYER_PREFIXES[styleName as MapStyle] || `${styleName}-`;\n const styleUrl = EXTERNAL_STYLE_URLS[styleName];\n \n if (!styleUrl) {\n console.warn(`No external style URL for: ${styleName}`);\n return [];\n }\n \n try {\n const response = await fetch(styleUrl);\n const externalStyle = await response.json() as maplibregl.StyleSpecification;\n \n const addedLayerIds: string[] = [];\n\n const resolveUrl = (url: string) => {\n if (/^https?:\\/\\//.test(url)) return url;\n try { return new URL(url, styleUrl).href; } catch { return url; }\n };\n if (externalStyle.glyphs) {\n mapInstance.setGlyphs(resolveUrl(externalStyle.glyphs as string));\n }\n if (externalStyle.sprite) {\n const spriteUrl = typeof externalStyle.sprite === 'string'\n ? resolveUrl(externalStyle.sprite)\n : externalStyle.sprite;\n mapInstance.setSprite(spriteUrl as any);\n }\n\n // Add all sources from the external style (prefixed)\n if (externalStyle.sources) {\n for (const [sourceId, sourceSpec] of Object.entries(externalStyle.sources)) {\n const prefixedSourceId = `${prefix}${sourceId}`;\n if (!mapInstance.getSource(prefixedSourceId)) {\n mapInstance.addSource(prefixedSourceId, sourceSpec as maplibregl.SourceSpecification);\n }\n }\n }\n \n // Add all layers from the external style (prefixed, hidden by default)\n // Insert BEFORE satellite-layer so they appear under it when satellite is visible\n if (externalStyle.layers) {\n for (const layer of externalStyle.layers) {\n const prefixedLayerId = `${prefix}${layer.id}`;\n \n if (!mapInstance.getLayer(prefixedLayerId)) {\n const newLayer = {\n ...layer,\n id: prefixedLayerId,\n layout: {\n ...(layer.layout || {}),\n visibility: 'none' as const, // Hidden by default\n },\n } as maplibregl.LayerSpecification;\n \n // Update source reference if it exists\n if ('source' in newLayer && typeof newLayer.source === 'string') {\n (newLayer as any).source = `${prefix}${newLayer.source}`;\n }\n \n try {\n const beforeLayer = mapInstance.getLayer('satellite-layer') ? 'satellite-layer'\n : (mapInstance.getLayer('custom-polygon-fill') ? 'custom-polygon-fill' : undefined);\n mapInstance.addLayer(newLayer, beforeLayer);\n addedLayerIds.push(prefixedLayerId);\n } catch (e) {\n console.warn(`Failed to add layer ${prefixedLayerId}:`, e);\n }\n }\n }\n }\n \n return addedLayerIds;\n } catch (e) {\n console.error(`Failed to load basemap style ${styleName}:`, e);\n return [];\n }\n }, []);\n\n // Toggle visibility of basemap layers\n const setBasemapVisibility = useCallback((styleName: string, visible: boolean) => {\n if (!map.current) return;\n \n const mapInstance = map.current;\n const layerIds = basemapLayerIds.current.get(styleName) || [];\n \n for (const layerId of layerIds) {\n if (mapInstance.getLayer(layerId)) {\n mapInstance.setLayoutProperty(layerId, 'visibility', visible ? 'visible' : 'none');\n }\n }\n }, []);\n\n const handleMapStyleChange = useCallback(async (style: MapStyle) => {\n if (!map.current) return;\n const mapInstance = map.current;\n \n // Hide all basemaps first\n basemapLayerIds.current.forEach((_, basemapName) => {\n setBasemapVisibility(basemapName, false);\n });\n \n // Check if this is a custom basemap from the registry\n const customDef = customBasemapRegistry.current.get(style);\n \n if (customDef) {\n // Handle custom basemap\n if (!loadedBasemaps.current.has(style)) {\n if (customDef.type === 'raster') {\n const sourceId = `custom-basemap-${style}`;\n const layerId = `custom-basemap-layer-${style}`;\n \n if (!mapInstance.getSource(sourceId)) {\n mapInstance.addSource(sourceId, {\n type: 'raster',\n tiles: customDef.tiles,\n tileSize: customDef.tileSize || 256,\n minzoom: customDef.minzoom || 0,\n maxzoom: customDef.maxzoom || 22,\n attribution: customDef.attribution || '',\n });\n \n mapInstance.addLayer({\n id: layerId,\n type: 'raster',\n source: sourceId,\n layout: { visibility: 'none' },\n }, 'satellite-layer');\n }\n \n loadedBasemaps.current.add(style);\n basemapLayerIds.current.set(style, [layerId]);\n }\n // TODO: Handle vector custom basemaps\n }\n } else if (!loadedBasemaps.current.has(style) && !loadingBasemaps.current.has(style)) {\n // Load built-in basemap if not already loaded\n loadingBasemaps.current.add(style);\n \n const layerIds = await loadBasemapStyle(style);\n basemapLayerIds.current.set(style, layerIds);\n loadedBasemaps.current.add(style);\n loadingBasemaps.current.delete(style);\n }\n \n // Show the selected basemap\n setBasemapVisibility(style, true);\n setCurrentMapStyle(style);\n }, [loadBasemapStyle, setBasemapVisibility]);\n \n // Keep ref updated for use in imperative handle\n handleMapStyleChangeRef.current = handleMapStyleChange;\n\n const handleUpdateTraceConfig = useCallback((layerId: string, config: TraceConfig) => {\n setLayers(prev => prev.map(l => \n l.id === layerId ? { ...l, traceConfig: config } : l\n ));\n }, []);\n\n const handleUpdateHeatmapConfig = useCallback((layerId: string, config: HeatmapConfig) => {\n setLayers(prev => prev.map(l => \n l.id === layerId ? { ...l, heatmapConfig: config } : l\n ));\n }, []);\n\n const handleUpdateClusterConfig = useCallback((layerId: string, config: ClusterConfig) => {\n setLayers(prev => prev.map(l => \n l.id === layerId ? { ...l, clusterConfig: config } : l\n ));\n }, []);\n\n const handleUpdateVisualConfig = useCallback((layerId: string, config: VisualConfig) => {\n setLayers(prev => prev.map(l => \n l.id === layerId ? { ...l, visualConfig: config } : l\n ));\n }, []);\n\n const handleUpdateAltitudeDisplayMode = useCallback((layerId: string, mode: AltitudeDisplayMode) => {\n setLayers(prev => prev.map(l => \n l.id === layerId ? { ...l, altitudeDisplayMode: mode } : l\n ));\n }, []);\n\n const handleUpdateAutoLabelConfig = useCallback((config: AutoLabelConfig) => {\n setAutoLabelConfig(config);\n }, []);\n\n // Count visible features using MapLibre's queryRenderedFeatures\n // This uses MapLibre's internal spatial index - efficient and accurate\n const LABEL_THRESHOLD = 500;\n \n const countVisibleFeaturesInViewport = useCallback(() => {\n if (!map.current || !isMapLoaded) return;\n \n const customLayers = ['custom-point', 'custom-line', 'custom-polygon-fill'];\n const existingLayers = customLayers.filter(id => map.current!.getLayer(id));\n \n if (existingLayers.length === 0) {\n setVisibleFeatureCount(0);\n return;\n }\n \n // queryRenderedFeatures returns features currently visible on screen\n const rendered = map.current.queryRenderedFeatures(undefined, { layers: existingLayers });\n \n // Dedupe by feature ID (same feature can appear from multiple tiles)\n const uniqueIds = new Set<string>();\n for (const f of rendered) {\n const fid = f.properties?.id || f.id;\n if (fid) uniqueIds.add(String(fid));\n }\n \n setVisibleFeatureCount(uniqueIds.size);\n }, [isMapLoaded]);\n\n // Listen to map move/zoom to update visible feature count (debounced)\n useEffect(() => {\n if (!map.current || !isMapLoaded) return;\n \n const mapInstance = map.current;\n let debounceTimer: ReturnType<typeof setTimeout> | null = null;\n \n const handleMoveEnd = () => {\n // Debounce to avoid rapid-fire updates during continuous panning\n if (debounceTimer) clearTimeout(debounceTimer);\n debounceTimer = setTimeout(() => {\n countVisibleFeaturesInViewport();\n }, 300); // 300ms debounce for smoother interaction\n };\n \n mapInstance.on('moveend', handleMoveEnd);\n mapInstance.on('zoomend', handleMoveEnd);\n \n // Initial count\n countVisibleFeaturesInViewport();\n \n return () => {\n if (debounceTimer) clearTimeout(debounceTimer);\n try {\n mapInstance.off('moveend', handleMoveEnd);\n mapInstance.off('zoomend', handleMoveEnd);\n } catch {\n // Map may already be destroyed\n }\n };\n }, [isMapLoaded, countVisibleFeaturesInViewport]);\n\n // Also update count when features change\n useEffect(() => {\n countVisibleFeaturesInViewport();\n }, [featureCount, countVisibleFeaturesInViewport]);\n\n // Sync arrow heads on every map move (screen-space computed features need continuous updates)\n useEffect(() => {\n if (!map.current || !isMapLoaded) return;\n \n const mapInstance = map.current;\n \n const handleMove = () => {\n // Use syncRef to get current sync function\n if (syncRef.current) {\n syncRef.current();\n }\n };\n \n mapInstance.on('move', handleMove);\n \n return () => {\n try {\n mapInstance.off('move', handleMove);\n } catch {\n // Map may already be destroyed\n }\n };\n }, [isMapLoaded]);\n\n // Fire onViewportChange callback when map viewport changes\n useEffect(() => {\n if (!map.current || !isMapLoaded || !onViewportChange) return;\n \n const mapInstance = map.current;\n \n const emitViewportChange = () => {\n if (!mapInstance) return;\n \n const center = mapInstance.getCenter();\n const zoom = mapInstance.getZoom();\n const bounds = mapInstance.getBounds();\n \n // Get raw bounds\n const rawBounds: [number, number, number, number] = [\n bounds.getWest(),\n bounds.getSouth(),\n bounds.getEast(),\n bounds.getNorth()\n ];\n \n // Normalize query bounds - clamp latitude to valid range, handle longitude wrapping\n const queryBounds = {\n minLng: Math.max(-180, Math.min(180, rawBounds[0])),\n maxLng: Math.max(-180, Math.min(180, rawBounds[2])),\n minLat: Math.max(-90, Math.min(90, rawBounds[1])),\n maxLat: Math.max(-90, Math.min(90, rawBounds[3]))\n };\n \n onViewportChange({\n center: [center.lng, center.lat],\n zoom,\n bounds: rawBounds,\n queryBounds\n });\n };\n \n mapInstance.on('moveend', emitViewportChange);\n mapInstance.on('zoomend', emitViewportChange);\n \n // Fire initial viewport\n emitViewportChange();\n \n return () => {\n try {\n mapInstance.off('moveend', emitViewportChange);\n mapInstance.off('zoomend', emitViewportChange);\n } catch {\n // Map may already be destroyed\n }\n };\n }, [isMapLoaded, onViewportChange]);\n\n // Viewport feature counting - OPTIMIZED: stop counting once threshold exceeded\n // Only counts on actual viewport changes (zoom level or center changes)\n useEffect(() => {\n if (!map.current || !isMapLoaded) return;\n \n const mapInstance = map.current;\n let lastCenter = mapInstance.getCenter();\n let lastZoom = mapInstance.getZoom();\n \n const updateViewportCount = () => {\n const layers = ['custom-point', 'custom-line', 'custom-polygon-fill'];\n const existing = layers.filter(id => mapInstance.getLayer(id));\n if (existing.length === 0) {\n setVisibleFeatureCount(0);\n setLabelsSuppressed(false);\n return;\n }\n \n // Get threshold for early exit optimization\n const threshold = autoLabelConfig.enabled ? autoLabelConfig.threshold : 220;\n \n // Query features but stop counting once we exceed threshold\n const rendered = mapInstance.queryRenderedFeatures(undefined, { layers: existing });\n const uniqueIds = new Set<string>();\n let count = 0;\n \n for (const f of rendered) {\n const fid = f.properties?.id || f.id;\n if (fid && !uniqueIds.has(String(fid))) {\n uniqueIds.add(String(fid));\n count++;\n if (count > threshold) {\n setVisibleFeatureCount(count);\n setLabelsSuppressed(false);\n return;\n }\n }\n }\n \n setVisibleFeatureCount(count);\n setLabelsSuppressed(false);\n };\n \n const onMapMovement = () => {\n // Only update if viewport actually changed (not just click-hold-release)\n const center = mapInstance.getCenter();\n const zoom = mapInstance.getZoom();\n const centerMoved = Math.abs(center.lng - lastCenter.lng) > 0.0001 || \n Math.abs(center.lat - lastCenter.lat) > 0.0001;\n const zoomChanged = Math.abs(zoom - lastZoom) > 0.01;\n \n if (centerMoved || zoomChanged) {\n lastCenter = center;\n lastZoom = zoom;\n // Small delay to batch rapid movements\n requestAnimationFrame(() => {\n if (mapInstance.loaded()) {\n updateViewportCount();\n }\n });\n }\n };\n \n // Listen for map movements\n mapInstance.on('moveend', onMapMovement);\n \n // Initial count after first idle\n mapInstance.once('idle', updateViewportCount);\n \n return () => {\n try {\n mapInstance.off('moveend', onMapMovement);\n } catch {\n // Map may be destroyed\n }\n };\n }, [isMapLoaded, autoLabelConfig.threshold, autoLabelConfig.enabled]);\n\n // Update label visibility directly without rebuilding all data\n // This is the fast path for pan/zoom - just toggle layer visibility\n const DEFAULT_LABEL_THRESHOLD = 220;\n useEffect(() => {\n if (!map.current || !isMapLoaded) return;\n \n const labelLayer = map.current.getLayer('custom-labels');\n if (!labelLayer) return;\n \n // Use viewport count with threshold (configurable or default 220)\n const threshold = autoLabelConfig.enabled ? autoLabelConfig.threshold : DEFAULT_LABEL_THRESHOLD;\n // Don't show labels while suppressed (during bulk operations)\n const shouldShowLabels = !labelsSuppressed && visibleFeatureCount < threshold;\n \n // Only update if visibility changed\n if (lastLabelVisibility.current !== shouldShowLabels) {\n lastLabelVisibility.current = shouldShowLabels;\n map.current.setLayoutProperty('custom-labels', 'visibility', shouldShowLabels ? 'visible' : 'none');\n }\n }, [autoLabelConfig, visibleFeatureCount, isMapLoaded, labelsSuppressed]);\n\n const getLayerFields = useCallback((layerId: string): { name: string; isNumeric: boolean }[] => {\n const layer = layers.find(l => l.id === layerId);\n if (!layer) return [];\n\n const fieldsMap = new Map<string, boolean>();\n const excludedFields = new Set(['name', 'startDate', 'endDate', 'opacity']);\n const MAX_SAMPLES = 10000; // Limit for performance with large datasets\n\n // Get features from appropriate source\n let features: (GeoJSON.Feature | undefined)[] = [];\n if (layer.readOnly) {\n // Read-only layer: get from readOnlyFeatures storage\n features = readOnlyFeatures.current.get(layerId) || [];\n } else if (layer.visible) {\n // Editable visible layer: get from MapboxDraw\n features = draw.current ? layer.featureIds.map(id => draw.current!.get(id)) : [];\n } else {\n // Editable hidden layer: get from hiddenFeatures\n features = hiddenFeatures.current.get(layerId) || [];\n }\n\n // Sample up to MAX_SAMPLES for field scanning\n const sampleFeatures = features.slice(0, MAX_SAMPLES);\n \n sampleFeatures.forEach(f => {\n if (f && f.properties) {\n Object.entries(f.properties).forEach(([key, value]) => {\n if (!excludedFields.has(key)) {\n // Check if value is a number or a numeric string\n const isNumeric = typeof value === 'number' || \n (typeof value === 'string' && value.trim() !== '' && !isNaN(Number(value)));\n if (!fieldsMap.has(key)) {\n fieldsMap.set(key, isNumeric);\n } else if (isNumeric && !fieldsMap.get(key)) {\n fieldsMap.set(key, true);\n }\n }\n });\n }\n });\n\n return Array.from(fieldsMap.entries())\n .map(([name, isNumeric]) => ({ name, isNumeric }))\n .sort((a, b) => a.name.localeCompare(b.name));\n }, [layers]);\n\n const handleFitToLayerFeatures = useCallback((layerId: string) => {\n const layer = layers.find(l => l.id === layerId);\n if (!layer || !map.current) return;\n \n let features: GeoJSON.Feature[];\n \n if (!layer.visible) {\n // Hidden layers - use hiddenFeatures storage\n features = hiddenFeatures.current.get(layerId) || [];\n } else if (layer.readOnly) {\n // Visible read-only layers - use readOnlyFeatures storage\n features = readOnlyFeatures.current.get(layerId) || [];\n } else {\n // Visible editable layers - use MapboxDraw\n features = layer.featureIds.map(id => draw.current?.get(id)).filter(Boolean) as GeoJSON.Feature[];\n }\n \n if (features.length === 0) return;\n \n const featureCollection: GeoJSON.FeatureCollection = {\n type: 'FeatureCollection',\n features: features,\n };\n \n const bounds = turf.bbox(featureCollection);\n if (bounds.some(v => !isFinite(v))) return;\n \n map.current.fitBounds(\n [[bounds[0], bounds[1]], [bounds[2], bounds[3]]],\n { padding: 50, maxZoom: 18 }\n );\n }, [layers]);\n\n const hasPointFeatures = useCallback((layerId: string): boolean => {\n const layer = layers.find(l => l.id === layerId);\n if (!layer) return false;\n \n if (layer.visible) {\n if (layer.readOnly) {\n // Read-only layers store features in readOnlyFeatures ref\n const roFeatures = readOnlyFeatures.current.get(layerId) || [];\n return roFeatures.some(f => f.geometry?.type === 'Point');\n } else {\n // Editable layers use MapboxDraw\n if (!draw.current) return false;\n for (const id of layer.featureIds) {\n const feature = draw.current.get(id);\n if (feature?.geometry?.type === 'Point') return true;\n }\n return false;\n }\n } else {\n // Hidden layers (any type)\n const hidden = hiddenFeatures.current.get(layerId) || [];\n return hidden.some(f => f.geometry?.type === 'Point');\n }\n }, [layers]);\n\n const getAvailableTraceFields = useCallback((layerId: string): string[] => {\n const layer = layers.find(l => l.id === layerId);\n if (!layer) return [];\n\n const fieldsSet = new Set<string>();\n const excludedFields = new Set(['name', 'startDate', 'endDate', 'opacity']);\n const MAX_SAMPLES = 10000; // Limit for performance with large datasets\n\n // Get features from appropriate source\n let features: (GeoJSON.Feature | undefined)[] = [];\n if (layer.readOnly) {\n // Read-only layer: get from readOnlyFeatures storage\n features = readOnlyFeatures.current.get(layerId) || [];\n } else if (layer.visible) {\n // Editable visible layer: get from MapboxDraw\n features = draw.current ? layer.featureIds.map(id => draw.current!.get(id)) : [];\n } else {\n // Editable hidden layer: get from hiddenFeatures\n features = hiddenFeatures.current.get(layerId) || [];\n }\n\n // Sample up to MAX_SAMPLES for field scanning\n const sampleFeatures = features.slice(0, MAX_SAMPLES);\n\n sampleFeatures.forEach(f => {\n if (f && f.properties) {\n Object.entries(f.properties).forEach(([key, value]) => {\n if (!excludedFields.has(key) && (typeof value === 'string' || typeof value === 'number')) {\n fieldsSet.add(key);\n }\n });\n }\n });\n\n return Array.from(fieldsSet).sort();\n }, [layers]);\n\n const handleMeasureModeChange = useCallback((mode: MeasureMode) => {\n setMeasureMode(mode);\n setMeasurePoints([]);\n setMeasureResult(null);\n \n if (mode !== 'none' && draw.current) {\n const selectMode: DrawingMode = isEditMode ? 'simple_select' : 'view_select';\n draw.current.changeMode(selectMode as string);\n setActiveMode(selectMode);\n }\n }, [isEditMode]);\n\n // Toggle 3D terrain on/off\n const handleToggle3DTerrain = useCallback(() => {\n if (!map.current) return;\n \n // Don't allow 3D if terrain is disabled\n if (!enableTerrain || !enable3D) {\n toast({\n title: '3D Terrain Unavailable',\n description: 'Terrain features are disabled for this configuration.',\n variant: 'destructive',\n });\n return;\n }\n \n const newState = !is3DTerrainEnabled;\n setIs3DTerrainEnabled(newState);\n \n const mapInstance = map.current;\n \n if (newState) {\n // Enable 3D terrain with exaggeration for visible effect\n mapInstance.setTerrain({ source: 'terrain-dem', exaggeration: 1.5 });\n \n // Add hillshade layer for better terrain visualization if not already present\n if (!mapInstance.getLayer('terrain-hillshade')) {\n // Find a good insertion point (before first symbol layer or at end)\n const layers = mapInstance.getStyle().layers || [];\n let beforeId: string | undefined;\n for (const layer of layers) {\n if (layer.type === 'symbol') {\n beforeId = layer.id;\n break;\n }\n }\n \n mapInstance.addLayer({\n id: 'terrain-hillshade',\n type: 'hillshade',\n source: 'terrain-dem',\n paint: {\n 'hillshade-exaggeration': 0.5,\n 'hillshade-shadow-color': '#000000',\n 'hillshade-highlight-color': '#ffffff',\n }\n }, beforeId);\n } else {\n mapInstance.setLayoutProperty('terrain-hillshade', 'visibility', 'visible');\n }\n \n toast({\n title: '3D Terrain Enabled',\n description: 'Tilt the map (right-click + drag or Ctrl + drag) to see the 3D effect.',\n });\n } else {\n // Disable 3D terrain\n mapInstance.setTerrain(null);\n \n // Hide hillshade layer\n if (mapInstance.getLayer('terrain-hillshade')) {\n mapInstance.setLayoutProperty('terrain-hillshade', 'visibility', 'none');\n }\n }\n }, [is3DTerrainEnabled, enableTerrain, enable3D, toast]);\n\n const handleSelectionModeChange = useCallback((mode: SelectionMode) => {\n setSelectionMode(mode);\n setSelectionPoints([]);\n setSelectionHoverPoint(null);\n isDrawingSelection.current = false;\n }, []);\n\n // Ref to track selection points for polygon selection (avoids stale closure in dblclick handler)\n const selectionPointsRef = useRef<[number, number][]>([]);\n useEffect(() => {\n selectionPointsRef.current = selectionPoints;\n }, [selectionPoints]);\n\n // Ref to track selected feature IDs for shift-merge selection (avoids stale closure)\n const selectedFeatureIdsRef = useRef<string[]>([]);\n useEffect(() => {\n selectedFeatureIdsRef.current = selectedFeatureIds;\n }, [selectedFeatureIds]);\n\n // Rectangle and Lasso selection mouse handlers\n useEffect(() => {\n // Only require map.current for cursor/pan control - draw.current is only needed for feature queries\n if (!map.current || !isMapLoaded) {\n return;\n }\n if (selectionMode === 'click' || !isSelectionToolActive) {\n // Ensure navigation is enabled when in click mode or selection tool not active\n if (map.current) {\n map.current.dragPan.enable();\n map.current.getCanvas().style.cursor = '';\n }\n return;\n }\n \n const mapInstance = map.current;\n const canvas = mapInstance.getCanvas();\n \n // Disable map panning when in rectangle/polygon selection mode AND tool is active\n mapInstance.dragPan.disable();\n \n // Change cursor\n console.log('[Selection Effect] Setting crosshair cursor');\n canvas.style.cursor = 'crosshair';\n \n let startPoint: { x: number; y: number } | null = null;\n \n const handleMouseDown = (e: MouseEvent) => {\n if (e.button !== 0) return; // Only left click\n \n if (selectionMode === 'rectangle' || selectionMode === 'circle') {\n startPoint = { x: e.offsetX, y: e.offsetY };\n isDrawingSelection.current = true;\n const lngLat = mapInstance.unproject([e.offsetX, e.offsetY]);\n setSelectionPoints([[lngLat.lng, lngLat.lat]]);\n }\n };\n \n const handleMouseMove = (e: MouseEvent) => {\n if (selectionMode === 'rectangle' && isDrawingSelection.current && startPoint) {\n const startLngLat = mapInstance.unproject([startPoint.x, startPoint.y]);\n const currentLngLat = mapInstance.unproject([e.offsetX, e.offsetY]);\n \n // Normalize coordinates to handle any drag direction\n const minLng = Math.min(startLngLat.lng, currentLngLat.lng);\n const maxLng = Math.max(startLngLat.lng, currentLngLat.lng);\n const minLat = Math.min(startLngLat.lat, currentLngLat.lat);\n const maxLat = Math.max(startLngLat.lat, currentLngLat.lat);\n \n // Create rectangle from normalized corners\n setSelectionPoints([\n [minLng, maxLat], // top-left\n [maxLng, maxLat], // top-right\n [maxLng, minLat], // bottom-right\n [minLng, minLat], // bottom-left\n [minLng, maxLat], // close polygon\n ]);\n } else if (selectionMode === 'circle' && isDrawingSelection.current && startPoint) {\n const centerLngLat = mapInstance.unproject([startPoint.x, startPoint.y]);\n const edgeLngLat = mapInstance.unproject([e.offsetX, e.offsetY]);\n \n // Calculate radius in kilometers using turf\n const center = turf.point([centerLngLat.lng, centerLngLat.lat]);\n const edge = turf.point([edgeLngLat.lng, edgeLngLat.lat]);\n const radiusKm = turf.distance(center, edge, { units: 'kilometers' });\n \n // Create circle polygon using turf (64 points for smooth circle)\n if (radiusKm > 0) {\n const circle = turf.circle([centerLngLat.lng, centerLngLat.lat], radiusKm, { steps: 64, units: 'kilometers' });\n const coords = circle.geometry.coordinates[0] as [number, number][];\n setSelectionPoints(coords);\n }\n } else if (selectionMode === 'polygon') {\n // Track hover position for rubber-band preview\n const lngLat = mapInstance.unproject([e.offsetX, e.offsetY]);\n setSelectionHoverPoint([lngLat.lng, lngLat.lat]);\n }\n };\n \n const handleMouseUp = (e: MouseEvent) => {\n if (selectionMode === 'rectangle' && isDrawingSelection.current && startPoint) {\n isDrawingSelection.current = false;\n \n const MIN_DRAG_PX = 32;\n const dx = Math.abs(e.offsetX - startPoint.x);\n const dy = Math.abs(e.offsetY - startPoint.y);\n if (dx < MIN_DRAG_PX || dy < MIN_DRAG_PX) {\n startPoint = null;\n setSelectionPoints([]);\n return;\n }\n \n const startLngLat = mapInstance.unproject([startPoint.x, startPoint.y]);\n const endLngLat = mapInstance.unproject([e.offsetX, e.offsetY]);\n \n // Normalize coordinates to handle any drag direction\n const minLng = Math.min(startLngLat.lng, endLngLat.lng);\n const maxLng = Math.max(startLngLat.lng, endLngLat.lng);\n const minLat = Math.min(startLngLat.lat, endLngLat.lat);\n const maxLat = Math.max(startLngLat.lat, endLngLat.lat);\n \n // Create selection polygon with proper winding\n const selectionPolygon = turf.polygon([[\n [minLng, maxLat], // top-left\n [maxLng, maxLat], // top-right\n [maxLng, minLat], // bottom-right\n [minLng, minLat], // bottom-left\n [minLng, maxLat], // close polygon\n ]]);\n \n // Find all features within the selection (including read-only)\n const drawFeatures = draw.current ? draw.current.getAll().features : [];\n const readOnlyFeaturesList: GeoJSON.Feature[] = [];\n readOnlyFeatures.current.forEach((features, layerId) => {\n const layer = layersRef.current.find(l => l.id === layerId);\n if (layer?.visible) readOnlyFeaturesList.push(...features);\n });\n const allFeatures = [...drawFeatures, ...readOnlyFeaturesList];\n \n const selectedIds: string[] = [];\n \n allFeatures.forEach(feature => {\n try {\n const geom = feature.geometry;\n let isInside = false;\n \n if (geom.type === 'Point') {\n isInside = turf.booleanPointInPolygon(geom.coordinates as [number, number], selectionPolygon);\n } else if (geom.type === 'LineString' || geom.type === 'Polygon' || geom.type === 'MultiPoint' || geom.type === 'MultiLineString' || geom.type === 'MultiPolygon') {\n isInside = turf.booleanIntersects(feature as GeoJSON.Feature, selectionPolygon);\n }\n \n if (isInside && feature.id) {\n selectedIds.push(String(feature.id));\n }\n } catch (err) {\n // Skip features that cause errors\n }\n });\n \n // Merge with existing selection when shift is held\n const finalIds = e.shiftKey \n ? Array.from(new Set([...selectedFeatureIdsRef.current, ...selectedIds]))\n : selectedIds;\n applySelectionState(finalIds, { focusProperties: true });\n \n const isFilterAction = filterActiveRef.current || !showFilterTool;\n if (onSelectionComplete && isFilterAction) {\n onSelectionComplete(selectionPolygon.geometry);\n }\n \n // Deactivate selection tool after completion (return to pan mode)\n setIsSelectionToolActive(false);\n \n if (persistSelection && isFilterAction) {\n setPersistedSelectionPolygon([\n [minLng, maxLat],\n [maxLng, maxLat],\n [maxLng, minLat],\n [minLng, minLat],\n [minLng, maxLat],\n ]);\n }\n \n startPoint = null;\n setSelectionPoints([]);\n } else if (selectionMode === 'circle' && isDrawingSelection.current && startPoint) {\n isDrawingSelection.current = false;\n \n const centerLngLat = mapInstance.unproject([startPoint.x, startPoint.y]);\n const edgeLngLat = mapInstance.unproject([e.offsetX, e.offsetY]);\n \n // Calculate radius in kilometers using turf\n const center = turf.point([centerLngLat.lng, centerLngLat.lat]);\n const edge = turf.point([edgeLngLat.lng, edgeLngLat.lat]);\n const radiusKm = turf.distance(center, edge, { units: 'kilometers' });\n \n if (radiusKm > 0) {\n // Create selection circle polygon using turf\n const selectionPolygon = turf.circle([centerLngLat.lng, centerLngLat.lat], radiusKm, { steps: 64, units: 'kilometers' });\n \n // Find all features within the selection (including read-only)\n const drawFeatures = draw.current ? draw.current.getAll().features : [];\n const readOnlyFeaturesList: GeoJSON.Feature[] = [];\n readOnlyFeatures.current.forEach((features, layerId) => {\n const layer = layersRef.current.find(l => l.id === layerId);\n if (layer?.visible) readOnlyFeaturesList.push(...features);\n });\n const allFeatures = [...drawFeatures, ...readOnlyFeaturesList];\n \n const selectedIds: string[] = [];\n \n allFeatures.forEach(feature => {\n try {\n const geom = feature.geometry;\n let isInside = false;\n \n if (geom.type === 'Point') {\n isInside = turf.booleanPointInPolygon(geom.coordinates as [number, number], selectionPolygon);\n } else if (geom.type === 'LineString' || geom.type === 'Polygon' || geom.type === 'MultiPoint' || geom.type === 'MultiLineString' || geom.type === 'MultiPolygon') {\n isInside = turf.booleanIntersects(feature as GeoJSON.Feature, selectionPolygon);\n }\n \n if (isInside && feature.id) {\n selectedIds.push(String(feature.id));\n }\n } catch (err) {\n // Skip features that cause errors\n }\n });\n \n // Merge with existing selection when shift is held\n const finalIds = e.shiftKey \n ? Array.from(new Set([...selectedFeatureIdsRef.current, ...selectedIds]))\n : selectedIds;\n applySelectionState(finalIds, { focusProperties: true });\n \n const isFilterAction = filterActiveRef.current || !showFilterTool;\n if (onSelectionComplete && isFilterAction) {\n onSelectionComplete(selectionPolygon.geometry);\n }\n \n // Deactivate selection tool after completion (return to pan mode)\n setIsSelectionToolActive(false);\n \n if (persistSelection && isFilterAction) {\n setPersistedSelectionPolygon(selectionPolygon.geometry.coordinates[0] as [number, number][]);\n }\n }\n \n startPoint = null;\n setSelectionPoints([]);\n }\n };\n \n const handleClick = (e: MouseEvent) => {\n if (selectionMode === 'polygon') {\n const lngLat = mapInstance.unproject([e.offsetX, e.offsetY]);\n setSelectionPoints(prev => [...prev, [lngLat.lng, lngLat.lat]]);\n }\n };\n \n const handleDblClick = (e: MouseEvent) => {\n if (selectionMode === 'polygon') {\n e.preventDefault();\n e.stopPropagation();\n \n // Use ref to get current selection points (avoid stale closure)\n const currentPoints = selectionPointsRef.current;\n \n // Need at least 3 points for a valid polygon\n if (currentPoints.length < 3) {\n setSelectionPoints([]);\n return;\n }\n \n // Close the polygon and find features (including read-only)\n const closedPoints = [...currentPoints, currentPoints[0]];\n const selectionPolygon = turf.polygon([closedPoints]);\n \n const drawFeatures = draw.current ? draw.current.getAll().features : [];\n const readOnlyFeaturesList: GeoJSON.Feature[] = [];\n readOnlyFeatures.current.forEach((features, layerId) => {\n const layer = layersRef.current.find(l => l.id === layerId);\n if (layer?.visible) readOnlyFeaturesList.push(...features);\n });\n const allFeatures = [...drawFeatures, ...readOnlyFeaturesList];\n \n const selectedIds: string[] = [];\n \n allFeatures.forEach(feature => {\n try {\n const geom = feature.geometry;\n let isInside = false;\n \n if (geom.type === 'Point') {\n isInside = turf.booleanPointInPolygon(geom.coordinates as [number, number], selectionPolygon);\n } else if (geom.type === 'LineString' || geom.type === 'Polygon' || geom.type === 'MultiPoint' || geom.type === 'MultiLineString' || geom.type === 'MultiPolygon') {\n isInside = turf.booleanIntersects(feature as GeoJSON.Feature, selectionPolygon);\n }\n \n if (isInside && feature.id) {\n selectedIds.push(String(feature.id));\n }\n } catch (err) {\n // Skip features that cause errors\n }\n });\n \n // Merge with existing selection when shift is held\n const finalIds = e.shiftKey \n ? Array.from(new Set([...selectedFeatureIdsRef.current, ...selectedIds]))\n : selectedIds;\n applySelectionState(finalIds, { focusProperties: true });\n \n const isFilterAction = filterActiveRef.current || !showFilterTool;\n if (onSelectionComplete && isFilterAction) {\n onSelectionComplete(selectionPolygon.geometry);\n }\n \n // Deactivate selection tool after completion (return to pan mode)\n setIsSelectionToolActive(false);\n \n if (persistSelection && isFilterAction) {\n setPersistedSelectionPolygon(closedPoints);\n }\n \n setSelectionPoints([]);\n setSelectionHoverPoint(null);\n }\n };\n \n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n isDrawingSelection.current = false;\n setSelectionPoints([]);\n setSelectionHoverPoint(null);\n startPoint = null;\n }\n };\n \n const handleContextMenu = (e: MouseEvent) => {\n e.preventDefault();\n isDrawingSelection.current = false;\n setSelectionPoints([]);\n setSelectionHoverPoint(null);\n startPoint = null;\n };\n \n const handleMouseLeave = () => {\n setSelectionHoverPoint(null);\n };\n \n // Add listeners\n canvas.addEventListener('mousedown', handleMouseDown);\n canvas.addEventListener('mousemove', handleMouseMove);\n canvas.addEventListener('mouseup', handleMouseUp);\n canvas.addEventListener('click', handleClick);\n canvas.addEventListener('dblclick', handleDblClick);\n canvas.addEventListener('mouseleave', handleMouseLeave);\n window.addEventListener('keydown', handleKeyDown);\n canvas.addEventListener('contextmenu', handleContextMenu);\n \n return () => {\n // Re-enable map navigation\n if (map.current) {\n map.current.dragPan.enable();\n map.current.getCanvas().style.cursor = '';\n }\n setSelectionHoverPoint(null);\n \n canvas.removeEventListener('mousedown', handleMouseDown);\n canvas.removeEventListener('mousemove', handleMouseMove);\n canvas.removeEventListener('mouseup', handleMouseUp);\n canvas.removeEventListener('click', handleClick);\n canvas.removeEventListener('dblclick', handleDblClick);\n canvas.removeEventListener('mouseleave', handleMouseLeave);\n window.removeEventListener('keydown', handleKeyDown);\n canvas.removeEventListener('contextmenu', handleContextMenu);\n };\n }, [selectionMode, isMapLoaded, onFeatureSelect, onSelectionComplete, persistSelection, isSelectionToolActive]);\n\n // Shift+Drag rectangle selection (works in click selection mode)\n const shiftSelectionRef = useRef<{ \n isActive: boolean; \n startPoint: { x: number; y: number } | null \n }>({ isActive: false, startPoint: null });\n \n useEffect(() => {\n if (!map.current || !isMapLoaded || !draw.current) return;\n // Only active in click selection mode - other modes have their own handlers\n if (selectionMode !== 'click') return;\n \n const mapInstance = map.current;\n const canvas = mapInstance.getCanvas();\n \n const handleShiftMouseDown = (e: MouseEvent) => {\n if (e.button !== 0 || !e.shiftKey) return;\n \n // Start shift+drag selection\n shiftSelectionRef.current = {\n isActive: true,\n startPoint: { x: e.offsetX, y: e.offsetY }\n };\n \n // Disable panning during shift selection\n mapInstance.dragPan.disable();\n canvas.style.cursor = 'crosshair';\n \n const lngLat = mapInstance.unproject([e.offsetX, e.offsetY]);\n setSelectionPoints([[lngLat.lng, lngLat.lat]]);\n \n e.preventDefault();\n e.stopPropagation();\n };\n \n const handleShiftMouseMove = (e: MouseEvent) => {\n if (!shiftSelectionRef.current.isActive || !shiftSelectionRef.current.startPoint) return;\n \n const startPoint = shiftSelectionRef.current.startPoint;\n const startLngLat = mapInstance.unproject([startPoint.x, startPoint.y]);\n const currentLngLat = mapInstance.unproject([e.offsetX, e.offsetY]);\n \n // Normalize coordinates\n const minLng = Math.min(startLngLat.lng, currentLngLat.lng);\n const maxLng = Math.max(startLngLat.lng, currentLngLat.lng);\n const minLat = Math.min(startLngLat.lat, currentLngLat.lat);\n const maxLat = Math.max(startLngLat.lat, currentLngLat.lat);\n \n setSelectionPoints([\n [minLng, maxLat],\n [maxLng, maxLat],\n [maxLng, minLat],\n [minLng, minLat],\n [minLng, maxLat],\n ]);\n };\n \n const handleShiftMouseUp = (e: MouseEvent) => {\n if (!shiftSelectionRef.current.isActive || !shiftSelectionRef.current.startPoint) return;\n \n const startPoint = shiftSelectionRef.current.startPoint;\n const startLngLat = mapInstance.unproject([startPoint.x, startPoint.y]);\n const endLngLat = mapInstance.unproject([e.offsetX, e.offsetY]);\n \n // Normalize coordinates\n const minLng = Math.min(startLngLat.lng, endLngLat.lng);\n const maxLng = Math.max(startLngLat.lng, endLngLat.lng);\n const minLat = Math.min(startLngLat.lat, endLngLat.lat);\n const maxLat = Math.max(startLngLat.lat, endLngLat.lat);\n \n // Create selection polygon\n const selectionPolygon = turf.polygon([[\n [minLng, maxLat],\n [maxLng, maxLat],\n [maxLng, minLat],\n [minLng, minLat],\n [minLng, maxLat],\n ]]);\n \n // Find all features within the selection (including read-only)\n const drawFeatures = draw.current ? draw.current.getAll().features : [];\n const readOnlyFeaturesList: GeoJSON.Feature[] = [];\n readOnlyFeatures.current.forEach((features, layerId) => {\n const layer = layersRef.current.find(l => l.id === layerId);\n if (layer?.visible) readOnlyFeaturesList.push(...features);\n });\n const allFeatures = [...drawFeatures, ...readOnlyFeaturesList];\n \n const selectedIds: string[] = [];\n \n allFeatures.forEach(feature => {\n try {\n const geom = feature.geometry;\n let isInside = false;\n \n if (geom.type === 'Point') {\n isInside = turf.booleanPointInPolygon(geom.coordinates as [number, number], selectionPolygon);\n } else if (geom.type === 'LineString' || geom.type === 'Polygon' || geom.type === 'MultiPoint' || geom.type === 'MultiLineString' || geom.type === 'MultiPolygon') {\n isInside = turf.booleanIntersects(feature as GeoJSON.Feature, selectionPolygon);\n }\n \n if (isInside && feature.id) {\n selectedIds.push(String(feature.id));\n }\n } catch {}\n });\n \n // Merge with existing selection when shift is held\n const mergedIds = Array.from(new Set([...selectedFeatureIdsRef.current, ...selectedIds]));\n applySelectionState(mergedIds, { focusProperties: true });\n \n // Reset state\n shiftSelectionRef.current = { isActive: false, startPoint: null };\n setSelectionPoints([]);\n mapInstance.dragPan.enable();\n canvas.style.cursor = '';\n };\n \n const handleKeyUp = (e: KeyboardEvent) => {\n // Cancel if shift is released during selection\n if (e.key === 'Shift' && shiftSelectionRef.current.isActive) {\n shiftSelectionRef.current = { isActive: false, startPoint: null };\n setSelectionPoints([]);\n mapInstance.dragPan.enable();\n canvas.style.cursor = '';\n }\n };\n \n canvas.addEventListener('mousedown', handleShiftMouseDown);\n canvas.addEventListener('mousemove', handleShiftMouseMove);\n canvas.addEventListener('mouseup', handleShiftMouseUp);\n window.addEventListener('keyup', handleKeyUp);\n \n return () => {\n canvas.removeEventListener('mousedown', handleShiftMouseDown);\n canvas.removeEventListener('mousemove', handleShiftMouseMove);\n canvas.removeEventListener('mouseup', handleShiftMouseUp);\n window.removeEventListener('keyup', handleKeyUp);\n \n // Ensure panning is re-enabled\n if (map.current) {\n map.current.dragPan.enable();\n }\n };\n }, [selectionMode, isMapLoaded, onFeatureSelect, onSelectionComplete, persistSelection, isSelectionToolActive]);\n\n // Manage MapLibre layer for persisted selection (so it zooms with the map)\n useEffect(() => {\n if (!map.current || !isMapLoaded) return;\n \n const mapInstance = map.current;\n const sourceId = 'persisted-selection-source';\n const fillLayerId = 'persisted-selection-fill';\n const lineLayerId = 'persisted-selection-line';\n \n // Create empty GeoJSON for when there's no selection\n const emptyGeojson: GeoJSON.FeatureCollection = {\n type: 'FeatureCollection',\n features: []\n };\n \n // Create GeoJSON polygon if we have a valid selection\n const geojson: GeoJSON.FeatureCollection = \n (persistedSelectionPolygon && persistedSelectionPolygon.length >= 4)\n ? {\n type: 'FeatureCollection',\n features: [{\n type: 'Feature',\n properties: {},\n geometry: {\n type: 'Polygon',\n coordinates: [persistedSelectionPolygon]\n }\n }]\n }\n : emptyGeojson;\n \n // Check if source already exists\n const existingSource = mapInstance.getSource(sourceId) as maplibregl.GeoJSONSource | undefined;\n \n if (existingSource) {\n // Update existing source data\n existingSource.setData(geojson);\n } else {\n // Add source and layers for the first time\n mapInstance.addSource(sourceId, {\n type: 'geojson',\n data: geojson\n });\n \n // Add fill layer\n mapInstance.addLayer({\n id: fillLayerId,\n type: 'fill',\n source: sourceId,\n paint: {\n 'fill-color': '#3B82F6',\n 'fill-opacity': 0.2\n }\n });\n \n // Add line layer\n mapInstance.addLayer({\n id: lineLayerId,\n type: 'line',\n source: sourceId,\n paint: {\n 'line-color': '#3B82F6',\n 'line-width': 2\n }\n });\n }\n \n return () => {\n // Cleanup on unmount only - check map still exists\n try {\n if (mapInstance && mapInstance.getLayer && mapInstance.getLayer(lineLayerId)) {\n mapInstance.removeLayer(lineLayerId);\n }\n if (mapInstance && mapInstance.getLayer && mapInstance.getLayer(fillLayerId)) {\n mapInstance.removeLayer(fillLayerId);\n }\n if (mapInstance && mapInstance.getSource && mapInstance.getSource(sourceId)) {\n mapInstance.removeSource(sourceId);\n }\n } catch (e) {\n // Map may have been destroyed, ignore cleanup errors\n }\n };\n }, [persistedSelectionPolygon, isMapLoaded]);\n\n // Circle drawing mode (click center, drag radius)\n useEffect(() => {\n if (!map.current || !isMapLoaded || !draw.current) return;\n if (activeMode !== 'draw_circle') {\n // Reset circle drawing state when leaving circle mode\n setCircleDrawCenter(null);\n setCircleDrawPreview(null);\n isDrawingCircle.current = false;\n return;\n }\n \n const mapInstance = map.current;\n const drawInstance = draw.current;\n const canvas = mapInstance.getCanvas();\n \n // Disable map panning during circle drawing\n mapInstance.dragPan.disable();\n canvas.style.cursor = 'crosshair';\n \n let centerPoint: { x: number; y: number; lngLat: [number, number] } | null = null;\n \n const handleMouseDown = (e: MouseEvent) => {\n if (e.button !== 0) return;\n \n const lngLat = mapInstance.unproject([e.offsetX, e.offsetY]);\n centerPoint = { \n x: e.offsetX, \n y: e.offsetY, \n lngLat: [lngLat.lng, lngLat.lat] \n };\n isDrawingCircle.current = true;\n setCircleDrawCenter([lngLat.lng, lngLat.lat]);\n };\n \n const handleMouseMove = (e: MouseEvent) => {\n if (!isDrawingCircle.current || !centerPoint) return;\n \n const edgeLngLat = mapInstance.unproject([e.offsetX, e.offsetY]);\n \n // Calculate radius using turf\n const center = turf.point(centerPoint.lngLat);\n const edge = turf.point([edgeLngLat.lng, edgeLngLat.lat]);\n const radiusKm = turf.distance(center, edge, { units: 'kilometers' });\n \n if (radiusKm > 0.001) { // Minimum 1 meter\n const circle = turf.circle(centerPoint.lngLat, radiusKm, { steps: 64, units: 'kilometers' });\n const coords = circle.geometry.coordinates[0] as [number, number][];\n setCircleDrawPreview(coords);\n }\n };\n \n const handleMouseUp = (e: MouseEvent) => {\n if (!isDrawingCircle.current || !centerPoint) return;\n \n const edgeLngLat = mapInstance.unproject([e.offsetX, e.offsetY]);\n \n // Calculate final radius\n const center = turf.point(centerPoint.lngLat);\n const edge = turf.point([edgeLngLat.lng, edgeLngLat.lat]);\n const radiusKm = turf.distance(center, edge, { units: 'kilometers' });\n \n if (radiusKm > 0.001) { // Minimum 1 meter\n // Create circle polygon\n const circle = turf.circle(centerPoint.lngLat, radiusKm, { steps: 64, units: 'kilometers' });\n \n // Add to MapboxDraw\n const featureId = crypto.randomUUID();\n const circleFeature: GeoJSON.Feature<GeoJSON.Polygon> = {\n type: 'Feature',\n id: featureId,\n properties: {\n kind: 'circle',\n circleCenter: centerPoint.lngLat,\n circleRadius: radiusKm * 1000 // Store in meters\n },\n geometry: circle.geometry\n };\n \n // Add to draw\n drawInstance.add(circleFeature);\n \n // Add to active layer\n const currentActiveEditingLayerId = activeEditingLayerIdRef.current;\n setLayers(prev => {\n let targetLayer = prev.find(l => l.id === currentActiveEditingLayerId && l.visible && !l.readOnly);\n if (!targetLayer) {\n targetLayer = prev.find(l => l.visible && !l.readOnly);\n }\n if (!targetLayer) return prev;\n \n return prev.map(layer => \n layer.id === targetLayer!.id \n ? { ...layer, featureIds: [...layer.featureIds, featureId] }\n : layer\n );\n });\n \n // Sync to custom layers\n syncFeaturesToCustomLayers();\n \n // Update feature count\n const newCount = drawInstance.getAll().features.length;\n setFeatureCount(newCount);\n \n // Save undo state\n setUndoStack(prev => [...prev, {\n features: drawInstance.getAll().features as GeoJSON.Feature[],\n selectedIds: [featureId],\n layers: layersRef.current\n }]);\n setRedoStack([]);\n \n // Select the new feature and reset to pan mode\n drawInstance.changeMode('simple_select', { featureIds: [featureId] });\n setActiveMode('simple_select');\n setSelectedFeatureIds([featureId]);\n if (enableProperties) setShowProperties(true);\n \n // Callback\n if (onFeatureCreate) {\n onFeatureCreate(circleFeature);\n }\n }\n \n // Reset\n centerPoint = null;\n isDrawingCircle.current = false;\n setCircleDrawCenter(null);\n setCircleDrawPreview(null);\n };\n \n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n centerPoint = null;\n isDrawingCircle.current = false;\n setCircleDrawCenter(null);\n setCircleDrawPreview(null);\n setActiveMode('simple_select');\n }\n };\n \n canvas.addEventListener('mousedown', handleMouseDown);\n canvas.addEventListener('mousemove', handleMouseMove);\n canvas.addEventListener('mouseup', handleMouseUp);\n window.addEventListener('keydown', handleKeyDown);\n \n return () => {\n canvas.removeEventListener('mousedown', handleMouseDown);\n canvas.removeEventListener('mousemove', handleMouseMove);\n canvas.removeEventListener('mouseup', handleMouseUp);\n window.removeEventListener('keydown', handleKeyDown);\n \n // Re-enable panning\n if (map.current) {\n map.current.dragPan.enable();\n map.current.getCanvas().style.cursor = '';\n }\n };\n }, [activeMode, isMapLoaded, onFeatureCreate]);\n\n // Rectangle drawing mode (click corner, drag to opposite corner)\n useEffect(() => {\n if (!map.current || !isMapLoaded || !draw.current) return;\n if (activeMode !== 'draw_rectangle') {\n // Reset rectangle drawing state when leaving rectangle mode\n setRectangleDrawCorner(null);\n setRectangleDrawPreview(null);\n isDrawingRectangle.current = false;\n return;\n }\n \n const mapInstance = map.current;\n const drawInstance = draw.current;\n const canvas = mapInstance.getCanvas();\n \n // Disable map panning during rectangle drawing\n mapInstance.dragPan.disable();\n canvas.style.cursor = 'crosshair';\n \n let cornerPoint: { lngLat: [number, number] } | null = null;\n \n const handleMouseDown = (e: MouseEvent) => {\n if (e.button !== 0) return;\n \n const lngLat = mapInstance.unproject([e.offsetX, e.offsetY]);\n cornerPoint = { lngLat: [lngLat.lng, lngLat.lat] };\n isDrawingRectangle.current = true;\n setRectangleDrawCorner([lngLat.lng, lngLat.lat]);\n };\n \n const handleMouseMove = (e: MouseEvent) => {\n if (!isDrawingRectangle.current || !cornerPoint) return;\n \n const oppositeCorner = mapInstance.unproject([e.offsetX, e.offsetY]);\n const [x1, y1] = cornerPoint.lngLat;\n const [x2, y2] = [oppositeCorner.lng, oppositeCorner.lat];\n \n // Create rectangle coordinates (4 corners + closing point)\n const rectCoords: [number, number][] = [\n [x1, y1], // top-left\n [x2, y1], // top-right\n [x2, y2], // bottom-right\n [x1, y2], // bottom-left\n [x1, y1], // close polygon\n ];\n \n setRectangleDrawPreview(rectCoords);\n };\n \n const handleMouseUp = (e: MouseEvent) => {\n if (!isDrawingRectangle.current || !cornerPoint) return;\n \n const oppositeCorner = mapInstance.unproject([e.offsetX, e.offsetY]);\n const [x1, y1] = cornerPoint.lngLat;\n const [x2, y2] = [oppositeCorner.lng, oppositeCorner.lat];\n \n // Check if rectangle has meaningful size\n const width = Math.abs(x2 - x1);\n const height = Math.abs(y2 - y1);\n \n if (width > 0.00001 && height > 0.00001) {\n // Create rectangle polygon\n const rectCoords: [number, number][] = [\n [x1, y1],\n [x2, y1],\n [x2, y2],\n [x1, y2],\n [x1, y1],\n ];\n \n const featureId = crypto.randomUUID();\n const rectFeature: GeoJSON.Feature<GeoJSON.Polygon> = {\n type: 'Feature',\n id: featureId,\n properties: {\n kind: 'rectangle',\n },\n geometry: {\n type: 'Polygon',\n coordinates: [rectCoords],\n },\n };\n \n // Add to draw\n drawInstance.add(rectFeature);\n \n // Add to active layer\n const currentActiveEditingLayerId = activeEditingLayerIdRef.current;\n setLayers(prev => {\n let targetLayer = prev.find(l => l.id === currentActiveEditingLayerId && l.visible && !l.readOnly);\n if (!targetLayer) {\n targetLayer = prev.find(l => l.visible && !l.readOnly);\n }\n if (!targetLayer) return prev;\n \n return prev.map(layer => \n layer.id === targetLayer!.id \n ? { ...layer, featureIds: [...layer.featureIds, featureId] }\n : layer\n );\n });\n \n // Sync to custom layers\n syncFeaturesToCustomLayers();\n \n // Update feature count\n const newCount = drawInstance.getAll().features.length;\n setFeatureCount(newCount);\n \n // Save undo state\n setUndoStack(prev => [...prev, {\n features: drawInstance.getAll().features as GeoJSON.Feature[],\n selectedIds: [featureId],\n layers: layersRef.current\n }]);\n setRedoStack([]);\n \n // Select the new feature and reset to pan mode\n drawInstance.changeMode('simple_select', { featureIds: [featureId] });\n setActiveMode('simple_select');\n setSelectedFeatureIds([featureId]);\n if (enableProperties) setShowProperties(true);\n \n // Callback\n if (onFeatureCreate) {\n onFeatureCreate(rectFeature);\n }\n }\n \n // Reset\n cornerPoint = null;\n isDrawingRectangle.current = false;\n setRectangleDrawCorner(null);\n setRectangleDrawPreview(null);\n };\n \n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n cornerPoint = null;\n isDrawingRectangle.current = false;\n setRectangleDrawCorner(null);\n setRectangleDrawPreview(null);\n setActiveMode('simple_select');\n }\n };\n \n canvas.addEventListener('mousedown', handleMouseDown);\n canvas.addEventListener('mousemove', handleMouseMove);\n canvas.addEventListener('mouseup', handleMouseUp);\n window.addEventListener('keydown', handleKeyDown);\n \n return () => {\n canvas.removeEventListener('mousedown', handleMouseDown);\n canvas.removeEventListener('mousemove', handleMouseMove);\n canvas.removeEventListener('mouseup', handleMouseUp);\n window.removeEventListener('keydown', handleKeyDown);\n \n // Re-enable panning\n if (map.current) {\n map.current.dragPan.enable();\n map.current.getCanvas().style.cursor = '';\n }\n };\n }, [activeMode, isMapLoaded, onFeatureCreate]);\n\n // Measurement mode mouse handlers\n const measurePointsRef = useRef<[number, number][]>([]);\n useEffect(() => {\n measurePointsRef.current = measurePoints;\n }, [measurePoints]);\n\n useEffect(() => {\n if (!map.current || !isMapLoaded || measureMode === 'none') return;\n \n const mapInstance = map.current;\n const canvas = mapInstance.getCanvas();\n \n // Set cursor to crosshair for measurement\n canvas.style.cursor = 'crosshair';\n \n const handleClick = (e: MouseEvent) => {\n const lngLat = mapInstance.unproject([e.offsetX, e.offsetY]);\n const newPoint: [number, number] = [lngLat.lng, lngLat.lat];\n \n setMeasurePoints(prev => {\n const updated = [...prev, newPoint];\n \n // Calculate result based on mode\n if (measureMode === 'distance' && updated.length >= 2) {\n const line = turf.lineString(updated);\n const distance = turf.length(line, { units: 'kilometers' });\n if (distance < 1) {\n setMeasureResult(`${(distance * 1000).toFixed(1)} m`);\n } else {\n setMeasureResult(`${distance.toFixed(2)} km`);\n }\n } else if (measureMode === 'area' && updated.length >= 3) {\n const closed = [...updated, updated[0]];\n const polygon = turf.polygon([closed]);\n const area = turf.area(polygon);\n if (area < 10000) {\n setMeasureResult(`${area.toFixed(1)} m²`);\n } else if (area < 1000000) {\n setMeasureResult(`${(area / 10000).toFixed(2)} ha`);\n } else {\n setMeasureResult(`${(area / 1000000).toFixed(2)} km²`);\n }\n }\n \n return updated;\n });\n };\n \n const handleDblClick = (e: MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n // Clear measurement on double-click\n setMeasurePoints([]);\n setMeasureResult(null);\n };\n \n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n setMeasurePoints([]);\n setMeasureResult(null);\n }\n };\n \n canvas.addEventListener('click', handleClick);\n canvas.addEventListener('dblclick', handleDblClick);\n window.addEventListener('keydown', handleKeyDown);\n \n return () => {\n canvas.style.cursor = '';\n canvas.removeEventListener('click', handleClick);\n canvas.removeEventListener('dblclick', handleDblClick);\n window.removeEventListener('keydown', handleKeyDown);\n };\n }, [measureMode, isMapLoaded]);\n\n // Render measurement overlay on the map\n useEffect(() => {\n if (!map.current || !isMapLoaded) return;\n \n const mapInstance = map.current;\n const sourceId = 'measure-overlay';\n const lineLayerId = 'measure-line';\n const pointsLayerId = 'measure-points';\n \n // Add source if it doesn't exist\n if (!mapInstance.getSource(sourceId)) {\n mapInstance.addSource(sourceId, {\n type: 'geojson',\n data: { type: 'FeatureCollection', features: [] }\n });\n \n mapInstance.addLayer({\n id: lineLayerId,\n type: 'line',\n source: sourceId,\n filter: ['==', '$type', 'LineString'],\n paint: {\n 'line-color': '#ef4444',\n 'line-width': 2,\n 'line-dasharray': [4, 2]\n }\n });\n \n mapInstance.addLayer({\n id: pointsLayerId,\n type: 'circle',\n source: sourceId,\n filter: ['==', '$type', 'Point'],\n paint: {\n 'circle-radius': 5,\n 'circle-color': '#ef4444',\n 'circle-stroke-color': '#fff',\n 'circle-stroke-width': 2\n }\n });\n }\n \n // Update the source data based on measurePoints\n const features: GeoJSON.Feature[] = [];\n \n if (measurePoints.length > 0) {\n // Add points\n measurePoints.forEach((pt, i) => {\n features.push({\n type: 'Feature',\n properties: { index: i },\n geometry: { type: 'Point', coordinates: pt }\n });\n });\n \n // Add line if we have 2+ points\n if (measurePoints.length >= 2) {\n if (measureMode === 'area' && measurePoints.length >= 3) {\n // Close the polygon for area mode\n features.push({\n type: 'Feature',\n properties: {},\n geometry: { type: 'LineString', coordinates: [...measurePoints, measurePoints[0]] }\n });\n } else {\n features.push({\n type: 'Feature',\n properties: {},\n geometry: { type: 'LineString', coordinates: measurePoints }\n });\n }\n }\n }\n \n const source = mapInstance.getSource(sourceId) as maplibregl.GeoJSONSource | undefined;\n if (source) {\n source.setData({ type: 'FeatureCollection', features });\n }\n }, [measurePoints, measureMode, isMapLoaded]);\n\n const handleSaveLayerGeoJSON = useCallback((layerId: string) => {\n const layer = layers.find(l => l.id === layerId);\n if (!layer || !draw.current) return;\n \n const features: GeoJSON.Feature[] = [];\n \n if (layer.visible) {\n layer.featureIds.forEach(id => {\n const f = draw.current!.get(id);\n if (f) features.push(f as GeoJSON.Feature);\n });\n } else {\n const hidden = hiddenFeatures.current.get(layerId) || [];\n features.push(...hidden);\n }\n \n // Include layer metadata in the export\n const layerMetadata: Record<string, unknown> = {\n name: layer.name,\n };\n if (layer.traceConfig) layerMetadata.traceConfig = layer.traceConfig;\n if (layer.heatmapConfig) layerMetadata.heatmapConfig = layer.heatmapConfig;\n if (layer.visualConfig) layerMetadata.visualConfig = layer.visualConfig;\n \n // Strip internal properties (prefixed with _) from exported features\n const cleanedFeatures = features.map(f => ({\n ...f,\n properties: Object.fromEntries(\n Object.entries(f.properties || {}).filter(([key]) => !key.startsWith('_'))\n ),\n }));\n \n const geojson = {\n type: 'FeatureCollection' as const,\n features: cleanedFeatures,\n properties: {\n layerMetadata,\n },\n };\n \n const blob = new Blob([JSON.stringify(geojson, null, 2)], { type: 'application/json' });\n saveAs(blob, `${layer.name.replace(/[^a-z0-9]/gi, '_')}.geojson`);\n }, [layers]);\n\n const handleLoadLayerGeoJSON = useCallback((layerId: string) => {\n const input = fileInputRef.current;\n if (!input) return;\n \n input.dataset.targetLayer = layerId;\n input.dataset.createNewLayer = '';\n input.click();\n }, []);\n\n const handleLoadNewLayerGeoJSON = useCallback(() => {\n const input = fileInputRef.current;\n if (!input) return;\n \n input.dataset.targetLayer = '';\n input.dataset.createNewLayer = 'true';\n input.click();\n }, []);\n\n const handleSaveAllGeoJSON = useCallback(() => {\n if (!draw.current) return;\n \n const allFeatures: GeoJSON.Feature[] = [];\n const layersMetadata: Record<string, unknown>[] = [];\n \n layers.forEach(layer => {\n // Collect features with layer ID added to properties\n if (layer.visible) {\n layer.featureIds.forEach(id => {\n const f = draw.current!.get(id);\n if (f) {\n const featureWithLayer = {\n ...f,\n properties: {\n ...f.properties,\n _layerId: layer.id,\n },\n };\n allFeatures.push(featureWithLayer as GeoJSON.Feature);\n }\n });\n } else {\n const hidden = hiddenFeatures.current.get(layer.id) || [];\n hidden.forEach(f => {\n const featureWithLayer = {\n ...f,\n properties: {\n ...f.properties,\n _layerId: layer.id,\n },\n };\n allFeatures.push(featureWithLayer as GeoJSON.Feature);\n });\n }\n \n // Collect layer metadata\n const layerMeta: Record<string, unknown> = {\n id: layer.id,\n name: layer.name,\n };\n if (layer.traceConfig) layerMeta.traceConfig = layer.traceConfig;\n if (layer.heatmapConfig) layerMeta.heatmapConfig = layer.heatmapConfig;\n if (layer.visualConfig) layerMeta.visualConfig = layer.visualConfig;\n layersMetadata.push(layerMeta);\n });\n \n // Strip internal properties (prefixed with _) from exported features, except _layerId which is used for restore\n const cleanedFeatures = allFeatures.map(f => ({\n ...f,\n properties: Object.fromEntries(\n Object.entries(f.properties || {}).filter(([key]) => !key.startsWith('_') || key === '_layerId')\n ),\n }));\n \n const geojson = {\n type: 'FeatureCollection' as const,\n features: cleanedFeatures,\n properties: {\n layers: layersMetadata,\n },\n };\n \n const blob = new Blob([JSON.stringify(geojson, null, 2)], { type: 'application/json' });\n saveAs(blob, 'map_export.geojson');\n }, [layers]);\n\n // Handler for \"Search and add...\" button in New Layer row\n // Uses same pattern as addLayer + addFeatures in imperative handle\n const handleSearchAndAddToNewLayer = useCallback(async () => {\n if (!onSearchEngineRequest || !map.current || !draw.current) return;\n \n const mapInstance = map.current;\n const center = mapInstance.getCenter();\n const zoom = mapInstance.getZoom();\n const bounds = mapInstance.getBounds();\n \n const rawBounds: [number, number, number, number] = [\n bounds.getWest(),\n bounds.getSouth(),\n bounds.getEast(),\n bounds.getNorth()\n ];\n \n const queryBounds = {\n minLng: Math.max(-180, Math.min(180, rawBounds[0])),\n maxLng: Math.max(-180, Math.min(180, rawBounds[2])),\n minLat: Math.max(-90, Math.min(90, rawBounds[1])),\n maxLat: Math.max(-90, Math.min(90, rawBounds[3]))\n };\n \n const viewport = {\n center: [center.lng, center.lat] as [number, number],\n zoom,\n bounds: rawBounds,\n queryBounds,\n };\n \n try {\n const result = await onSearchEngineRequest({\n viewport,\n activeLayerId: null, // Creating new layer\n });\n \n if (result && result.features && result.features.length > 0) {\n saveStateForUndo();\n \n // Auto-generate layer name based on feature count\n const layerName = `${result.features.length} workspace features`;\n const newLayerId = `layer-${Date.now()}`;\n \n // Add features using same pattern as addFeatures in imperative handle\n const addedIds: string[] = [];\n // Mark as API adding so draw.create doesn't set _unsaved flag\n isApiAddingRef.current = true;\n try {\n result.features.forEach(f => {\n const { startDate, endDate } = normalizeTemporalProperties(f.properties || {});\n const normalizedFeature = {\n ...f,\n properties: {\n ...f.properties,\n startDate: startDate?.toISOString() || null,\n endDate: endDate?.toISOString() || null,\n }\n };\n const ids = draw.current!.add(normalizedFeature);\n addedIds.push(ids[0]);\n });\n } finally {\n isApiAddingRef.current = false;\n }\n \n // Create new layer with the added feature IDs\n const newLayer: Layer = {\n id: newLayerId,\n name: layerName,\n visible: true,\n featureIds: addedIds,\n };\n \n // Update layers state \n layersRef.current = [...layersRef.current, newLayer];\n setLayers(layersRef.current);\n setActiveEditingLayerId(newLayerId);\n \n updateFeatureCount();\n updateTimelineStore();\n syncFeaturesToCustomLayers();\n \n toast({\n title: 'Layer created',\n description: `Added ${result.features.length} features to \"${layerName}\"`,\n });\n }\n } catch (error) {\n toast({\n title: 'Search failed',\n description: error instanceof Error ? error.message : 'Failed to search data source',\n variant: 'destructive',\n });\n }\n }, [onSearchEngineRequest, saveStateForUndo, updateFeatureCount, updateTimelineStore, syncFeaturesToCustomLayers, toast]);\n\n // Handler for workspace load (external file picker)\n // Uses same pattern as addFeatures in imperative handle\n const handleWorkspaceLoad = useCallback(async (layerId: string) => {\n if (!onWorkspaceLoad || !draw.current) return;\n \n const layer = layersRef.current.find(l => l.id === layerId);\n if (!layer) return;\n \n try {\n const result = await onWorkspaceLoad(layerId);\n if (result && result.features && result.features.length > 0) {\n saveStateForUndo();\n \n // Add features using same pattern as addFeatures in imperative handle\n const addedIds: string[] = [];\n // Mark as API adding so draw.create doesn't set _unsaved flag\n isApiAddingRef.current = true;\n try {\n result.features.forEach(f => {\n const { startDate, endDate } = normalizeTemporalProperties(f.properties || {});\n const normalizedFeature = {\n ...f,\n properties: {\n ...f.properties,\n startDate: startDate?.toISOString() || null,\n endDate: endDate?.toISOString() || null,\n }\n };\n const ids = draw.current!.add(normalizedFeature);\n addedIds.push(ids[0]);\n });\n } finally {\n isApiAddingRef.current = false;\n }\n \n // Update layer with new features\n layersRef.current = layersRef.current.map(l =>\n l.id === layerId ? { ...l, featureIds: [...l.featureIds, ...addedIds] } : l\n );\n setLayers(layersRef.current);\n \n updateFeatureCount();\n updateTimelineStore();\n syncFeaturesToCustomLayers();\n \n toast({\n title: 'Features loaded',\n description: `Added ${result.features.length} features to \"${layer.name}\"`,\n });\n }\n } catch (error) {\n toast({\n title: 'Load failed',\n description: error instanceof Error ? error.message : 'Failed to load from workspace',\n variant: 'destructive',\n });\n }\n }, [onWorkspaceLoad, saveStateForUndo, updateFeatureCount, updateTimelineStore, syncFeaturesToCustomLayers, toast]);\n\n // Handler for workspace save (external file saver)\n const handleWorkspaceSave = useCallback(async (layerId: string) => {\n if (!onWorkspaceSave) return;\n \n const layer = layersRef.current.find(l => l.id === layerId);\n if (!layer) return;\n \n // Collect features from the layer (same pattern as handleSaveLayerGeoJSON)\n const features: GeoJSON.Feature[] = [];\n if (layer.visible && draw.current) {\n layer.featureIds.forEach(id => {\n const f = draw.current!.get(id);\n if (f) features.push(f as GeoJSON.Feature);\n });\n } else {\n const hidden = hiddenFeatures.current.get(layerId) || [];\n features.push(...hidden);\n }\n \n // Also check read-only features\n const roFeatures = readOnlyFeatures.current.get(layerId);\n if (roFeatures) {\n features.push(...roFeatures);\n }\n \n // Strip internal properties (prefixed with _) from exported features\n const cleanedFeatures = features.map(f => ({\n ...f,\n properties: Object.fromEntries(\n Object.entries(f.properties || {}).filter(([key]) => !key.startsWith('_'))\n ),\n }));\n \n const geojson: GeoJSON.FeatureCollection = {\n type: 'FeatureCollection',\n features: cleanedFeatures,\n };\n \n try {\n await onWorkspaceSave(layerId, geojson);\n \n // Clear _unsaved flag on all features in this layer after successful save\n if (layer.visible && draw.current) {\n layer.featureIds.forEach(id => {\n const feature = draw.current!.get(id);\n if (feature?.properties?._unsaved) {\n draw.current!.setFeatureProperty(id, '_unsaved', undefined);\n }\n });\n } else {\n // Update hidden features\n const hidden = hiddenFeatures.current.get(layerId) || [];\n const updatedHidden = hidden.map(f => ({\n ...f,\n properties: {\n ...f.properties,\n _unsaved: undefined,\n },\n }));\n hiddenFeatures.current.set(layerId, updatedHidden);\n }\n \n // Force re-render to update unsaved counts\n setLayers(prev => [...prev]);\n \n toast({\n title: 'Saved',\n description: `Saved ${features.length} features to workspace`,\n });\n } catch (error) {\n // Only show error toast if it's not a user cancellation\n const errorMessage = error instanceof Error ? error.message : 'Failed to save to workspace';\n if (!errorMessage.includes('cancelled')) {\n toast({\n title: 'Save failed',\n description: errorMessage,\n variant: 'destructive',\n });\n }\n }\n }, [onWorkspaceSave, toast]);\n\n const handleFitToFeatures = useCallback(() => {\n if (!map.current || !draw.current) return;\n \n // Collect all features (visible and hidden)\n const allFeatures: GeoJSON.Feature[] = [];\n \n layers.forEach(layer => {\n if (layer.visible) {\n layer.featureIds.forEach(id => {\n const f = draw.current!.get(id);\n if (f) allFeatures.push(f as GeoJSON.Feature);\n });\n } else {\n const hidden = hiddenFeatures.current.get(layer.id) || [];\n allFeatures.push(...hidden);\n }\n });\n \n if (allFeatures.length === 0) {\n toast({\n title: \"No features\",\n description: \"There are no features to fit to\",\n });\n return;\n }\n \n const fc: GeoJSON.FeatureCollection = {\n type: 'FeatureCollection',\n features: allFeatures,\n };\n \n const bbox = turf.bbox(fc);\n map.current.fitBounds([[bbox[0], bbox[1]], [bbox[2], bbox[3]]], { \n padding: 80,\n maxZoom: 16,\n });\n }, [layers, toast]);\n\n const handleFileChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file || !draw.current) return;\n \n // Get target layer from dataset or active editing layer\n const requestedTargetLayerId = e.target.dataset.targetLayer || activeEditingLayerId;\n const createNewLayer = e.target.dataset.createNewLayer === 'true';\n \n // Clear the flags\n delete e.target.dataset.createNewLayer;\n \n const reader = new FileReader();\n reader.onload = (event) => {\n try {\n const rawGeojson = JSON.parse(event.target?.result as string) as GeoJSON.FeatureCollection & { \n properties?: { \n layerMetadata?: {\n name?: string;\n traceConfig?: TraceConfig;\n heatmapConfig?: HeatmapConfig;\n visualConfig?: VisualConfig;\n };\n };\n };\n \n if (rawGeojson.type !== 'FeatureCollection' || !Array.isArray(rawGeojson.features)) {\n throw new Error('Invalid GeoJSON format');\n }\n \n if (rawGeojson.features.length === 0) {\n toast({\n title: \"Empty GeoJSON\",\n description: \"The file contains no features\",\n variant: \"destructive\",\n });\n return;\n }\n \n // Detect CRS and reproject to WGS84 if needed\n const { features: geojson, reprojected, sourceCRS } = detectAndReprojectGeoJSON(rawGeojson);\n \n saveStateForUndo();\n \n // Extract layer metadata if present\n const layerMetadata = rawGeojson.properties?.layerMetadata;\n \n // Normalize features\n const normalizedFeatures = geojson.features.map(f => {\n const { startDate, endDate } = normalizeTemporalProperties(f.properties || {});\n return {\n ...f,\n properties: {\n ...f.properties,\n startDate: startDate?.toISOString() || null,\n endDate: endDate?.toISOString() || null,\n }\n };\n });\n \n if (createNewLayer) {\n // Create a new READ-ONLY layer from the file for performance\n const fileName = file.name.replace(/\\.geojson$|\\.json$/i, '');\n const layerId = `layer-${Date.now()}`;\n \n const newLayer: Layer = {\n id: layerId,\n name: layerMetadata?.name || fileName,\n visible: true,\n featureIds: [],\n readOnly: true, // High-performance mode by default\n ...(layerMetadata?.traceConfig && { traceConfig: layerMetadata.traceConfig }),\n ...(layerMetadata?.heatmapConfig && { heatmapConfig: layerMetadata.heatmapConfig }),\n ...(layerMetadata?.visualConfig && { visualConfig: layerMetadata.visualConfig }),\n };\n \n // Assign unique IDs and store in read-only storage\n const addedIds: string[] = [];\n const featuresWithIds: GeoJSON.Feature[] = [];\n normalizedFeatures.forEach(f => {\n const featureId = f.id ? String(f.id) : crypto.randomUUID();\n const normalizedFeature = { ...f, id: featureId };\n featuresWithIds.push(normalizedFeature);\n addedIds.push(featureId);\n });\n \n // Store in read-only features ref (not MapboxDraw)\n readOnlyFeatures.current.set(layerId, featuresWithIds);\n newLayer.featureIds = addedIds;\n \n setLayers(prev => [...prev, newLayer]);\n // Don't set active editing layer for read-only layers\n updateFeatureCount();\n updateTimelineStore();\n syncFeaturesToCustomLayers();\n \n // Fly to the new features\n if (map.current && geojson.features.length > 0) {\n try {\n const bbox = turf.bbox(geojson);\n if (bbox && bbox.every(v => isFinite(v))) {\n map.current.fitBounds(\n [[bbox[0], bbox[1]], [bbox[2], bbox[3]]],\n { padding: 50, maxZoom: 16, duration: 1000 }\n );\n }\n } catch (e) {\n // Silently fail if bbox calculation fails\n }\n }\n \n const reprojectMsg = reprojected ? ` (reprojected from ${sourceCRS})` : '';\n toast({\n title: \"Layer created\",\n description: `Created \"${newLayer.name}\" with ${addedIds.length} features${reprojectMsg} (high-performance mode)`,\n });\n return;\n }\n \n // Find the target layer - must be visible and not read-only for loading\n let targetLayer = layers.find(l => l.id === requestedTargetLayerId && !l.readOnly);\n \n // If no valid target, find first visible writable layer\n if (!targetLayer) {\n targetLayer = layers.find(l => l.visible && !l.readOnly);\n }\n \n // If still no valid layer, fall back to default\n if (!targetLayer) {\n targetLayer = layers.find(l => l.id === 'default');\n }\n \n if (targetLayer?.visible) {\n // Layer is visible - add to MapboxDraw\n const addedIds: string[] = [];\n // Mark as API adding so draw.create doesn't set _unsaved flag\n isApiAddingRef.current = true;\n try {\n normalizedFeatures.forEach(f => {\n const ids = draw.current!.add(f);\n addedIds.push(ids[0]);\n });\n } finally {\n isApiAddingRef.current = false;\n }\n \n const targetId = targetLayer.id;\n setLayers(prev => prev.map(l => {\n if (l.id !== targetId) return l;\n // Apply layer metadata if present\n return {\n ...l,\n featureIds: [...l.featureIds, ...addedIds],\n ...(layerMetadata?.traceConfig && { traceConfig: layerMetadata.traceConfig }),\n ...(layerMetadata?.heatmapConfig && { heatmapConfig: layerMetadata.heatmapConfig }),\n ...(layerMetadata?.visualConfig && { visualConfig: layerMetadata.visualConfig }),\n };\n }));\n } else if (targetLayer) {\n // Layer is hidden - add to hiddenFeatures\n const featuresWithIds = normalizedFeatures.map(f => ({\n ...f,\n id: f.id || `feature-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,\n })) as GeoJSON.Feature[];\n \n const targetId = targetLayer.id;\n const addedIds = featuresWithIds.map(f => f.id as string);\n const existing = hiddenFeatures.current.get(targetId) || [];\n hiddenFeatures.current.set(targetId, [...existing, ...featuresWithIds]);\n \n setLayers(prev => prev.map(l => {\n if (l.id !== targetId) return l;\n // Apply layer metadata if present\n return {\n ...l,\n featureIds: [...l.featureIds, ...addedIds],\n ...(layerMetadata?.traceConfig && { traceConfig: layerMetadata.traceConfig }),\n ...(layerMetadata?.heatmapConfig && { heatmapConfig: layerMetadata.heatmapConfig }),\n ...(layerMetadata?.visualConfig && { visualConfig: layerMetadata.visualConfig }),\n };\n }));\n }\n \n updateFeatureCount();\n updateTimelineStore();\n syncFeaturesToCustomLayers();\n \n const reprojectMsg = reprojected ? ` (reprojected from ${sourceCRS})` : '';\n toast({\n title: \"GeoJSON loaded\",\n description: `Added ${normalizedFeatures.length} features${reprojectMsg}${!targetLayer?.visible ? ' (layer hidden)' : ''}`,\n });\n } catch (error) {\n toast({\n title: \"Failed to load GeoJSON\",\n description: error instanceof Error ? error.message : 'Invalid file',\n variant: \"destructive\",\n });\n }\n };\n reader.readAsText(file);\n \n e.target.value = '';\n }, [layers, activeEditingLayerId, saveStateForUndo, updateFeatureCount, updateTimelineStore, syncFeaturesToCustomLayers, toast]);\n\n const handleDropGeoJSON = useCallback((name: string, data: GeoJSON.FeatureCollection & {\n properties?: {\n layerMetadata?: {\n name?: string;\n traceConfig?: TraceConfig;\n heatmapConfig?: HeatmapConfig;\n visualConfig?: VisualConfig;\n };\n };\n }) => {\n if (!map.current) return;\n \n // Detect CRS and reproject to WGS84 if needed\n const { features: reprojectedData, reprojected, sourceCRS } = detectAndReprojectGeoJSON(data);\n \n saveStateForUndo();\n \n // Extract layer metadata if present\n const layerMetadata = data.properties?.layerMetadata;\n const layerId = `layer-${Date.now()}`;\n \n // Check if any features have altitude data\n const layerHasAltitudeData = reprojectedData.features.some(f => hasAltitudeData(f));\n \n const newLayer: Layer = {\n id: layerId,\n name: layerMetadata?.name || name,\n visible: true,\n featureIds: [],\n readOnly: true, // Dropped layers are read-only for performance\n ...(layerMetadata?.traceConfig && { traceConfig: layerMetadata.traceConfig }),\n ...(layerMetadata?.heatmapConfig && { heatmapConfig: layerMetadata.heatmapConfig }),\n ...(layerMetadata?.visualConfig && { visualConfig: layerMetadata.visualConfig }),\n ...(layerHasAltitudeData && { hasAltitudeData: true, altitudeDisplayMode: 'both' as AltitudeDisplayMode }),\n };\n \n // Store features in readOnlyFeatures ref (bypasses MapboxDraw for performance)\n const normalizedFeatures: GeoJSON.Feature[] = [];\n const addedIds: string[] = [];\n \n reprojectedData.features.forEach((f, index) => {\n const { startDate, endDate } = normalizeTemporalProperties(f.properties || {});\n // Generate unique ID for each feature\n const featureId = f.id !== undefined && f.id !== null \n ? String(f.id) \n : `${layerId}-f${index}`;\n \n const normalizedFeature: GeoJSON.Feature = {\n ...f,\n id: featureId,\n properties: {\n ...f.properties,\n startDate: startDate?.toISOString() || null,\n endDate: endDate?.toISOString() || null,\n }\n };\n normalizedFeatures.push(normalizedFeature);\n addedIds.push(featureId);\n });\n \n // Store in read-only features ref (not MapboxDraw)\n readOnlyFeatures.current.set(layerId, normalizedFeatures);\n newLayer.featureIds = addedIds;\n \n // Build the new layers array and update ref BEFORE calling update functions\n // This ensures updateTimelineStore/syncFeaturesToCustomLayers see the new layer immediately\n const nextLayers = [...layersRef.current, newLayer];\n layersRef.current = nextLayers;\n setLayers(nextLayers);\n \n // Don't set active editing layer for read-only dropped layers\n updateFeatureCount();\n updateTimelineStore();\n syncFeaturesToCustomLayers();\n \n // Fly to the new features\n if (reprojectedData.features.length > 0) {\n try {\n const bbox = turf.bbox(reprojectedData);\n if (bbox && bbox.every(v => isFinite(v))) {\n map.current.fitBounds(\n [[bbox[0], bbox[1]], [bbox[2], bbox[3]]],\n { padding: 50, maxZoom: 16, duration: 1000 }\n );\n }\n } catch (e) {\n // Silently fail if bbox calculation fails\n }\n }\n \n const reprojectMsg = reprojected ? ` (reprojected from ${sourceCRS})` : '';\n toast({\n title: \"Layer added\",\n description: `Created \"${newLayer.name}\" with ${addedIds.length} features${reprojectMsg} (read-only)`,\n });\n }, [saveStateForUndo, updateFeatureCount, updateTimelineStore, syncFeaturesToCustomLayers, toast]);\n\n const handleTimelineFilterChange = useCallback((visibleIds: string[], hiddenIds: string[], untimedIds: string[]) => {\n if (!draw.current || !map.current) return;\n \n // Store visible IDs for custom layer sync\n timelineVisibleIdsRef.current = new Set([...visibleIds, ...untimedIds]);\n \n // Sync custom layers with timeline visibility (also updates traces)\n syncFeaturesToCustomLayers();\n }, [syncFeaturesToCustomLayers]);\n\n // Track previous timeline enabled state to detect open/close transitions\n const prevTimelineEnabledRef = useRef(timelineStore.isEnabled);\n \n // Effect to handle timeline open/close\n useEffect(() => {\n const wasEnabled = prevTimelineEnabledRef.current;\n const isNowEnabled = timelineStore.isEnabled;\n prevTimelineEnabledRef.current = isNowEnabled;\n \n if (!isNowEnabled || !timelineStore.hasTemporalData) {\n // Clear the filter - show all features\n timelineVisibleIdsRef.current = null;\n syncFeaturesToCustomLayers();\n } else if (!wasEnabled && isNowEnabled) {\n // Timeline just opened - refresh timeline data to ensure it's up to date\n updateTimelineStore();\n }\n }, [timelineStore.isEnabled, timelineStore.hasTemporalData, syncFeaturesToCustomLayers, updateTimelineStore]);\n\n // Effect to render heatmap layers for layers with heatmapConfig enabled\n useEffect(() => {\n if (!map.current || !draw.current || !isMapLoaded) return;\n\n const mapInstance = map.current;\n const drawInstance = draw.current;\n\n const rebuildHeatmaps = () => {\n if (!mapInstance.isStyleLoaded()) {\n mapInstance.once('idle', rebuildHeatmaps);\n return;\n }\n\n // Clean up old heatmap sources/layers\n layers.forEach(layer => {\n const sourceId = `heatmap-source-${layer.id}`;\n const heatmapLayerId = `heatmap-layer-${layer.id}`;\n\n try {\n if (mapInstance.getLayer(heatmapLayerId)) {\n mapInstance.removeLayer(heatmapLayerId);\n }\n if (mapInstance.getSource(sourceId)) {\n mapInstance.removeSource(sourceId);\n }\n } catch {}\n });\n\n // Build heatmaps for layers with heatmapConfig enabled\n layers.forEach(layer => {\n if (!layer.heatmapConfig?.enabled) return;\n\n const sourceId = `heatmap-source-${layer.id}`;\n const heatmapLayerId = `heatmap-layer-${layer.id}`;\n\n // Get point features for this layer (from draw, read-only storage, or hidden storage)\n let pointFeatures: GeoJSON.Feature[] = [];\n if (layer.visible) {\n if (layer.readOnly) {\n // Read-only layers store features in readOnlyFeatures ref\n const roFeatures = readOnlyFeatures.current.get(layer.id) || [];\n pointFeatures = roFeatures.filter(f => f.geometry?.type === 'Point');\n } else {\n // Editable layers use MapboxDraw\n layer.featureIds.forEach(id => {\n const f = drawInstance.get(id);\n if (f && f.geometry?.type === 'Point') {\n pointFeatures.push(f);\n }\n });\n }\n } else {\n const hidden = hiddenFeatures.current.get(layer.id) || [];\n pointFeatures = hidden.filter(f => f.geometry?.type === 'Point');\n }\n\n if (pointFeatures.length === 0) return;\n\n const { intensity, radius } = layer.heatmapConfig;\n\n try {\n mapInstance.addSource(sourceId, {\n type: 'geojson',\n data: { type: 'FeatureCollection', features: pointFeatures },\n });\n\n mapInstance.addLayer({\n id: heatmapLayerId,\n type: 'heatmap',\n source: sourceId,\n paint: {\n 'heatmap-weight': 1,\n 'heatmap-intensity': [\n 'interpolate', ['linear'], ['zoom'],\n 0, intensity * 0.5,\n 9, intensity * 3\n ],\n 'heatmap-color': [\n 'interpolate', ['linear'], ['heatmap-density'],\n 0, 'rgba(33,102,172,0)',\n 0.2, 'rgb(103,169,207)',\n 0.4, 'rgb(209,229,240)',\n 0.6, 'rgb(253,219,199)',\n 0.8, 'rgb(239,138,98)',\n 1, 'rgb(178,24,43)'\n ],\n 'heatmap-radius': [\n 'interpolate', ['linear'], ['zoom'],\n 0, radius / 2,\n 9, radius * 1.5\n ],\n 'heatmap-opacity': 0.8,\n },\n });\n } catch {}\n });\n };\n\n rebuildHeatmaps();\n\n const handleStyleLoad = () => {\n mapInstance.once('idle', rebuildHeatmaps);\n };\n mapInstance.on('style.load', handleStyleLoad);\n\n return () => {\n try {\n mapInstance.off('style.load', handleStyleLoad);\n } catch {\n // Map may already be destroyed\n }\n };\n }, [isMapLoaded, layers, currentMapStyle]);\n\n // Effect to render cluster layers for layers with clusterConfig enabled\n useEffect(() => {\n if (!map.current || !draw.current || !isMapLoaded) return;\n\n const mapInstance = map.current;\n const drawInstance = draw.current;\n\n const rebuildClusters = () => {\n if (!mapInstance.isStyleLoaded()) {\n mapInstance.once('idle', rebuildClusters);\n return;\n }\n\n // Clean up old cluster sources/layers and pie managers\n layers.forEach(layer => {\n const sourceId = `cluster-source-${layer.id}`;\n const clustersLayerId = `clusters-${layer.id}`;\n const clusterCountLayerId = `cluster-count-${layer.id}`;\n const unclusteredLayerId = `unclustered-point-${layer.id}`;\n\n // Destroy any existing pie manager for this layer\n const existingPieManager = clusterPieManagers.current.get(layer.id);\n if (existingPieManager) {\n existingPieManager.destroy();\n clusterPieManagers.current.delete(layer.id);\n }\n\n try {\n if (mapInstance.getLayer(clusterCountLayerId)) {\n mapInstance.removeLayer(clusterCountLayerId);\n }\n if (mapInstance.getLayer(clustersLayerId)) {\n mapInstance.removeLayer(clustersLayerId);\n }\n if (mapInstance.getLayer(unclusteredLayerId)) {\n mapInstance.removeLayer(unclusteredLayerId);\n }\n if (mapInstance.getSource(sourceId)) {\n mapInstance.removeSource(sourceId);\n }\n } catch {}\n });\n\n // Build clusters for layers with clusterConfig enabled AND visible\n layers.forEach(layer => {\n if (!layer.clusterConfig?.enabled || !layer.visible) return;\n\n const sourceId = `cluster-source-${layer.id}`;\n const clustersLayerId = `clusters-${layer.id}`;\n const clusterCountLayerId = `cluster-count-${layer.id}`;\n const unclusteredLayerId = `unclustered-point-${layer.id}`;\n\n // Get point features for this layer (from draw, read-only storage, or hidden storage)\n let pointFeatures: GeoJSON.Feature[] = [];\n if (layer.visible) {\n if (layer.readOnly) {\n const roFeatures = readOnlyFeatures.current.get(layer.id) || [];\n pointFeatures = roFeatures.filter(f => f.geometry?.type === 'Point');\n } else {\n layer.featureIds.forEach(id => {\n const f = drawInstance.get(id);\n if (f && f.geometry?.type === 'Point') {\n pointFeatures.push(f);\n }\n });\n }\n } else {\n const hidden = hiddenFeatures.current.get(layer.id) || [];\n pointFeatures = hidden.filter(f => f.geometry?.type === 'Point');\n }\n\n if (pointFeatures.length === 0) return;\n\n const groupByField = layer.clusterConfig?.groupByField;\n \n // Category color palette for pie charts\n const categoryColors = [\n '#3b82f6', '#ef4444', '#22c55e', '#f59e0b', '#8b5cf6', \n '#ec4899', '#06b6d4', '#f97316', '#84cc16', '#6366f1',\n '#14b8a6', '#d946ef', '#0ea5e9', '#a855f7', '#10b981',\n ];\n\n try {\n // Get layer color for styling (use visual config color or default)\n const layerColor = layer.visualConfig?.color?.fixedColor || '#3b82f6';\n \n // Build cluster properties for category aggregation if groupByField is set\n let clusterProperties: Record<string, any> = {};\n let categoryValues: string[] = [];\n let categoryColorMap: Record<string, string> = {};\n \n if (groupByField) {\n // Collect unique category values from features\n const uniqueCategories = new Set<string>();\n pointFeatures.forEach(f => {\n const val = f.properties?.[groupByField];\n if (val !== undefined && val !== null) {\n uniqueCategories.add(String(val));\n }\n });\n categoryValues = Array.from(uniqueCategories).slice(0, 15); // Limit to 15 categories\n \n // Assign colors to categories\n categoryValues.forEach((cat, i) => {\n categoryColorMap[cat] = categoryColors[i % categoryColors.length];\n // Create aggregation expression for this category\n clusterProperties[`cat_${i}`] = [\n '+',\n ['case', ['==', ['get', groupByField], cat], 1, 0]\n ];\n });\n }\n\n // Create cluster source with automatic clustering\n mapInstance.addSource(sourceId, {\n type: 'geojson',\n data: { type: 'FeatureCollection', features: pointFeatures },\n cluster: true,\n clusterMaxZoom: 14,\n clusterRadius: 50,\n ...(Object.keys(clusterProperties).length > 0 ? { clusterProperties } : {}),\n });\n\n if (groupByField && categoryValues.length > 0) {\n // CATEGORY MODE: Use DOM-based SVG pie chart markers\n // Create pie chart manager for this layer\n const pieManager = createClusterPieManager(\n mapInstance,\n sourceId,\n categoryValues,\n categoryColorMap\n );\n clusterPieManagers.current.set(layer.id, pieManager);\n \n // Note: No circle layers needed - pie charts are rendered as DOM markers\n // The pie manager handles cluster visualization with interactive pie slices\n \n } else {\n // SIMPLE COUNT MODE: Colored circles with count\n\n // Cluster circles layer\n mapInstance.addLayer({\n id: clustersLayerId,\n type: 'circle',\n source: sourceId,\n filter: ['has', 'point_count'],\n paint: {\n 'circle-color': [\n 'step',\n ['get', 'point_count'],\n layerColor, // color for count < 100\n 100, '#f59e0b', // yellow for count >= 100\n 750, '#ef4444', // red for count >= 750\n ],\n 'circle-radius': [\n 'step',\n ['get', 'point_count'],\n 20, // 20px for count < 100\n 100, 30, // 30px for count >= 100\n 750, 40, // 40px for count >= 750\n ],\n 'circle-stroke-width': 2,\n 'circle-stroke-color': '#ffffff',\n },\n });\n\n // Cluster count labels\n mapInstance.addLayer({\n id: clusterCountLayerId,\n type: 'symbol',\n source: sourceId,\n filter: ['has', 'point_count'],\n layout: {\n 'text-field': ['get', 'point_count_abbreviated'],\n 'text-font': ['Open Sans Bold', 'Arial Unicode MS Bold'],\n 'text-size': 12,\n },\n paint: {\n 'text-color': '#ffffff',\n },\n });\n }\n\n // Unclustered point layer (for individual points when zoomed in)\n const unclusteredColor = groupByField \n ? ['match', ['get', groupByField], \n ...categoryValues.flatMap(cat => [cat, categoryColorMap[cat] || layerColor]),\n layerColor\n ]\n : layerColor;\n \n mapInstance.addLayer({\n id: unclusteredLayerId,\n type: 'circle',\n source: sourceId,\n filter: ['!', ['has', 'point_count']],\n paint: {\n 'circle-color': unclusteredColor as any,\n 'circle-radius': 6,\n 'circle-stroke-width': 1,\n 'circle-stroke-color': '#ffffff',\n },\n });\n\n // Add click handler for expanding clusters\n mapInstance.on('click', clustersLayerId, async (e) => {\n const features = mapInstance.queryRenderedFeatures(e.point, {\n layers: [clustersLayerId],\n });\n if (!features.length) return;\n\n const clusterId = features[0].properties?.cluster_id;\n const source = mapInstance.getSource(sourceId) as maplibregl.GeoJSONSource;\n \n try {\n const zoom = await source.getClusterExpansionZoom(clusterId);\n const geometry = features[0].geometry;\n if (geometry.type === 'Point') {\n mapInstance.easeTo({\n center: geometry.coordinates as [number, number],\n zoom: zoom ?? 10,\n });\n }\n } catch {\n // Cluster may have been removed\n }\n });\n\n // Change cursor on cluster hover\n mapInstance.on('mouseenter', clustersLayerId, () => {\n mapInstance.getCanvas().style.cursor = 'pointer';\n });\n mapInstance.on('mouseleave', clustersLayerId, () => {\n mapInstance.getCanvas().style.cursor = '';\n });\n } catch (e) {\n console.warn('Error creating cluster layer:', e);\n }\n });\n };\n\n rebuildClusters();\n\n const handleStyleLoad = () => {\n mapInstance.once('idle', rebuildClusters);\n };\n mapInstance.on('style.load', handleStyleLoad);\n\n return () => {\n try {\n mapInstance.off('style.load', handleStyleLoad);\n } catch {\n // Map may already be destroyed\n }\n };\n }, [isMapLoaded, layers, currentMapStyle]);\n\n if (mapError) {\n return (\n <div className={`flex items-center justify-center h-full bg-muted/30 ${className || ''}`} data-testid=\"map-error\">\n <Card className=\"max-w-md\">\n <div className=\"p-4 border-b border-border\">\n <div className=\"flex items-center gap-3\">\n <div className=\"p-2 rounded-full bg-destructive/10\">\n <AlertTriangle className=\"w-6 h-6 text-destructive\" />\n </div>\n <div>\n <h3 className=\"text-lg font-semibold\">Map Initialization Failed</h3>\n <p className=\"text-sm text-muted-foreground\">Unable to load the interactive map</p>\n </div>\n </div>\n </div>\n <div className=\"p-4 space-y-4\">\n <p className=\"text-sm text-muted-foreground\">{mapError}</p>\n <Button type=\"primary\" onClick={() => window.location.reload()} className=\"w-full\" data-testid=\"button-reload\">\n Refresh Page\n </Button>\n </div>\n </Card>\n </div>\n );\n }\n\n return (\n <MapDropZone onDrop={handleDropGeoJSON}>\n <div className={`map-container w-full h-full min-w-0 relative ${className || ''}`} data-testid=\"map-editor-canvas\">\n <div \n ref={mapContainer} \n className={`w-full h-full ${activeMode.startsWith('draw_') ? 'cursor-crosshair' : ''}`}\n data-testid=\"map-canvas\"\n tabIndex={enableKeyboardShortcuts ? 0 : undefined}\n style={{ outline: 'none' }}\n />\n {/* Filter geometry overlay – dashed SVG like the selection rectangle */}\n {filterSvgPoints && (\n <svg\n className=\"absolute inset-0 w-full h-full pointer-events-none z-[99]\"\n data-testid=\"filter-overlay\"\n >\n <polygon\n ref={filterPolygonRef}\n points={filterSvgPoints}\n fill=\"rgba(0, 0, 0, 0.03)\"\n stroke=\"#555\"\n strokeWidth=\"1.5\"\n strokeDasharray=\"6,3\"\n strokeOpacity=\"0.6\"\n />\n </svg>\n )}\n\n {/* Selection overlay for rectangle selection preview (rectangle mode or shift+drag in click mode) */}\n {selectionPoints.length >= 4 && (selectionMode === 'rectangle' || selectionMode === 'click') && map.current && (\n <svg \n className=\"absolute inset-0 w-full h-full pointer-events-none z-[100]\"\n data-testid=\"selection-overlay\"\n >\n <polygon\n points={selectionPoints.map(([lng, lat]) => {\n const point = map.current!.project([lng, lat]);\n return `${point.x},${point.y}`;\n }).join(' ')}\n fill=\"rgba(59, 130, 246, 0.15)\"\n stroke=\"rgb(59, 130, 246)\"\n strokeWidth=\"2\"\n strokeDasharray=\"6,3\"\n />\n </svg>\n )}\n\n {/* Polygon selection with rubber-band preview */}\n {selectionMode === 'polygon' && map.current && (selectionPoints.length >= 1 || selectionHoverPoint) && (\n <svg \n className=\"absolute inset-0 w-full h-full pointer-events-none z-[100]\"\n data-testid=\"polygon-points-overlay\"\n >\n {/* Lines between clicked points */}\n {selectionPoints.length >= 2 && selectionPoints.map(([lng, lat], i) => {\n if (i === 0) return null;\n const prevPoint = map.current!.project([selectionPoints[i - 1][0], selectionPoints[i - 1][1]]);\n const currPoint = map.current!.project([lng, lat]);\n return (\n <line\n key={`line-${i}`}\n x1={prevPoint.x}\n y1={prevPoint.y}\n x2={currPoint.x}\n y2={currPoint.y}\n stroke=\"rgb(59, 130, 246)\"\n strokeWidth=\"2\"\n />\n );\n })}\n \n {/* Rubber-band line from last point to hover position */}\n {selectionPoints.length >= 1 && selectionHoverPoint && (\n <line\n x1={map.current!.project([selectionPoints[selectionPoints.length - 1][0], selectionPoints[selectionPoints.length - 1][1]]).x}\n y1={map.current!.project([selectionPoints[selectionPoints.length - 1][0], selectionPoints[selectionPoints.length - 1][1]]).y}\n x2={map.current!.project(selectionHoverPoint).x}\n y2={map.current!.project(selectionHoverPoint).y}\n stroke=\"rgb(59, 130, 246)\"\n strokeWidth=\"2\"\n strokeDasharray=\"6,3\"\n />\n )}\n \n {/* Closing preview line from hover to first point (when 3+ points) */}\n {selectionPoints.length >= 3 && selectionHoverPoint && (\n <line\n x1={map.current!.project(selectionHoverPoint).x}\n y1={map.current!.project(selectionHoverPoint).y}\n x2={map.current!.project([selectionPoints[0][0], selectionPoints[0][1]]).x}\n y2={map.current!.project([selectionPoints[0][0], selectionPoints[0][1]]).y}\n stroke=\"rgb(59, 130, 246)\"\n strokeWidth=\"2\"\n strokeDasharray=\"6,3\"\n opacity=\"0.5\"\n />\n )}\n \n {/* Point markers at each clicked vertex */}\n {selectionPoints.map(([lng, lat], i) => {\n const point = map.current!.project([lng, lat]);\n return (\n <circle\n key={`point-${i}`}\n cx={point.x}\n cy={point.y}\n r=\"5\"\n fill=\"rgb(59, 130, 246)\"\n stroke=\"white\"\n strokeWidth=\"2\"\n />\n );\n })}\n \n {/* Hover point indicator */}\n {selectionHoverPoint && (\n <circle\n cx={map.current!.project(selectionHoverPoint).x}\n cy={map.current!.project(selectionHoverPoint).y}\n r=\"4\"\n fill=\"rgba(59, 130, 246, 0.5)\"\n stroke=\"white\"\n strokeWidth=\"1\"\n />\n )}\n </svg>\n )}\n\n {/* Circle selection overlay */}\n {selectionMode === 'circle' && selectionPoints.length >= 4 && map.current && (\n <svg \n className=\"absolute inset-0 w-full h-full pointer-events-none z-[100]\"\n data-testid=\"circle-selection-overlay\"\n >\n <polygon\n points={selectionPoints.map(([lng, lat]) => {\n const point = map.current!.project([lng, lat]);\n return `${point.x},${point.y}`;\n }).join(' ')}\n fill=\"rgba(59, 130, 246, 0.15)\"\n stroke=\"rgb(59, 130, 246)\"\n strokeWidth=\"2\"\n strokeDasharray=\"6,3\"\n />\n </svg>\n )}\n\n {/* Persisted selection is rendered via MapLibre layer for proper zoom behavior */}\n\n {/* Circle drawing preview */}\n {activeMode === 'draw_circle' && circleDrawPreview && circleDrawPreview.length >= 4 && map.current && (\n <svg \n className=\"absolute inset-0 w-full h-full pointer-events-none z-[100]\"\n data-testid=\"circle-draw-preview\"\n >\n <polygon\n points={circleDrawPreview.map(([lng, lat]) => {\n const point = map.current!.project([lng, lat]);\n return `${point.x},${point.y}`;\n }).join(' ')}\n fill=\"rgba(34, 197, 94, 0.15)\"\n stroke=\"rgb(34, 197, 94)\"\n strokeWidth=\"2\"\n strokeDasharray=\"6,3\"\n />\n {/* Center point indicator */}\n {circleDrawCenter && (\n <circle\n cx={map.current!.project(circleDrawCenter).x}\n cy={map.current!.project(circleDrawCenter).y}\n r=\"6\"\n fill=\"rgb(34, 197, 94)\"\n stroke=\"white\"\n strokeWidth=\"2\"\n />\n )}\n </svg>\n )}\n\n {/* Rectangle drawing preview */}\n {activeMode === 'draw_rectangle' && rectangleDrawPreview && rectangleDrawPreview.length >= 4 && map.current && (\n <svg \n className=\"absolute inset-0 w-full h-full pointer-events-none z-[100]\"\n data-testid=\"rectangle-draw-preview\"\n >\n <polygon\n points={rectangleDrawPreview.map(([lng, lat]) => {\n const point = map.current!.project([lng, lat]);\n return `${point.x},${point.y}`;\n }).join(' ')}\n fill=\"rgba(34, 197, 94, 0.15)\"\n stroke=\"rgb(34, 197, 94)\"\n strokeWidth=\"2\"\n strokeDasharray=\"6,3\"\n />\n {/* Corner point indicator */}\n {rectangleDrawCorner && (\n <circle\n cx={map.current!.project(rectangleDrawCorner).x}\n cy={map.current!.project(rectangleDrawCorner).y}\n r=\"5\"\n fill=\"rgb(34, 197, 94)\"\n stroke=\"white\"\n strokeWidth=\"2\"\n />\n )}\n </svg>\n )}\n\n {(enableDrawing || enableSelection) && (\n <DrawingToolbar\n activeMode={activeMode}\n onModeChange={handleModeChange}\n onClear={handleClear}\n onDeleteSelected={handleDeleteSelected}\n onUndo={handleUndo}\n onRedo={handleRedo}\n featureCount={featureCount}\n selectedCount={selectedFeatureIds.length}\n canUndo={undoStack.length > 0}\n canRedo={redoStack.length > 0}\n disabled={!isMapLoaded}\n isEditMode={isEditMode}\n onToggleEditMode={handleToggleEditMode}\n hasVisibleLayers={hasVisibleLayers}\n hasEditableLayer={hasEditableLayer}\n measureMode={measureMode}\n onMeasureModeChange={handleMeasureModeChange}\n selectionMode={selectionMode}\n onSelectionModeChange={handleSelectionModeChange}\n isSelectionToolActive={isSelectionToolActive}\n onSelectionToolActiveChange={setIsSelectionToolActive}\n enableMeasurement={enableMeasurement}\n enableSelection={enableSelection}\n hiddenDrawingTools={hiddenDrawingTools}\n hiddenSelectionTools={hiddenSelectionTools}\n expandSelectionTools={expandSelectionTools}\n showFilterTool={showFilterTool}\n selectionOnly={!enableDrawing && enableSelection}\n showShortcutHints={enableKeyboardShortcuts}\n onGoTo={(coords, zoom) => {\n if (map.current) {\n const currentZoom = map.current.getZoom();\n map.current.flyTo({ center: coords, zoom: zoom ?? Math.max(currentZoom, 10), duration: 2000 });\n }\n }}\n showClearFilter={showClearFilter}\n onClearFilter={onClearFilter}\n onFilterActiveChange={(active: boolean) => { filterActiveRef.current = active; }}\n showGoToButton={showGoToButton}\n onDropPoint={onDropPoint}\n geocodingUrl={geocodingUrl}\n geocoderProvider={geocoderProvider}\n onSearchEngineRequest={onSearchEngineRequest ? async () => {\n // Get current viewport info and call the external search engine\n if (!map.current) {\n console.error('Map not ready');\n return;\n }\n \n const mapInstance = map.current;\n const center = mapInstance.getCenter();\n const zoom = mapInstance.getZoom();\n const bounds = mapInstance.getBounds();\n \n const rawBounds: [number, number, number, number] = [\n bounds.getWest(),\n bounds.getSouth(),\n bounds.getEast(),\n bounds.getNorth()\n ];\n \n const queryBounds = {\n minLng: Math.max(-180, Math.min(180, rawBounds[0])),\n maxLng: Math.max(-180, Math.min(180, rawBounds[2])),\n minLat: Math.max(-90, Math.min(90, rawBounds[1])),\n maxLat: Math.max(-90, Math.min(90, rawBounds[3]))\n };\n \n const viewport = {\n center: [center.lng, center.lat] as [number, number],\n zoom,\n bounds: rawBounds,\n queryBounds\n };\n \n const activeLayerId = activeEditingLayerIdRef.current;\n \n try {\n const result = await onSearchEngineRequest({\n viewport,\n activeLayerId,\n });\n \n // If we got features back, add them to the active layer using proper helper\n if (result && result.features && result.features.length > 0 && activeLayerId) {\n const layer = layersRef.current.find(l => l.id === activeLayerId);\n if (layer && !layer.readOnly && draw.current && isMapLoaded) {\n const addedIds: string[] = [];\n \n // Mark as API adding so draw.create doesn't set _unsaved flag\n isApiAddingRef.current = true;\n try {\n result.features.forEach(f => {\n // Normalize temporal properties like addFeatures helper does\n const { startDate, endDate } = normalizeTemporalProperties(f.properties || {});\n const normalizedFeature = {\n ...f,\n properties: {\n ...f.properties,\n startDate: startDate?.toISOString() || null,\n endDate: endDate?.toISOString() || null,\n }\n };\n const ids = draw.current!.add(normalizedFeature);\n addedIds.push(ids[0]);\n });\n } finally {\n isApiAddingRef.current = false;\n }\n \n // Update layers properly with ref pattern\n const nextLayers = layersRef.current.map(l => \n l.id === activeLayerId ? { ...l, featureIds: [...l.featureIds, ...addedIds] } : l\n );\n layersRef.current = nextLayers;\n setLayers(nextLayers);\n \n updateFeatureCount();\n updateTimelineStore();\n syncFeaturesToCustomLayers();\n \n // Fire create callback for each added feature\n addedIds.forEach(id => {\n const feature = draw.current?.get(id);\n if (feature) {\n onFeatureCreate?.(feature as GeoJSON.Feature);\n }\n });\n }\n }\n } catch (error) {\n console.error('Search engine error:', error);\n }\n } : undefined}\n />\n )}\n\n {enableMeasurement && measureMode !== 'none' && (\n <div \n className=\"absolute top-4 left-16 z-10 bg-background/90 floating-panel rounded-lg shadow-lg border border-border px-4 py-2\"\n data-testid=\"measure-result-panel\"\n >\n <div className=\"flex items-center gap-3\">\n <span className=\"text-xs text-muted-foreground\">\n {measureMode === 'distance' ? 'Distance:' : 'Area:'}\n </span>\n <span className=\"font-mono text-sm font-medium\" data-testid=\"text-measure-result\">\n {measureResult || (measureMode === 'distance' ? 'Click points to measure' : 'Click 3+ points')}\n </span>\n <span className=\"text-xs text-muted-foreground\">\n (double-click to clear)\n </span>\n </div>\n </div>\n )}\n\n {/* Timeline toggle - moves above timebar when open */}\n {enableTimeline && timelineStore.hasTemporalData && (\n <div \n className=\"absolute left-4 z-[200] transition-all\"\n style={{ bottom: timelineStore.isEnabled ? TIMEBAR_HEIGHT + TIMEBAR_BOTTOM_OFFSET + 8 : 48 }}\n >\n <Tooltip title=\"Timeline\" placement=\"right\">\n <Button\n type=\"default\"\n icon={<Clock className=\"w-5 h-5\" />}\n onClick={() => timelineStore.setEnabled(!timelineStore.isEnabled)}\n disabled={!isMapLoaded}\n className={`!w-10 !h-10 !min-w-0 !p-0 bg-background shadow-lg ${timelineStore.isEnabled ? 'bg-primary/10' : ''}`}\n aria-label=\"Toggle timeline\"\n aria-pressed={timelineStore.isEnabled}\n data-testid=\"button-toggle-timeline\"\n />\n </Tooltip>\n </div>\n )}\n\n {/* Layers toggle - top right */}\n {enableLayers && (\n <div className=\"absolute top-4 right-4 z-[200] flex items-center gap-2\">\n {getMapUnsavedCount() > 0 && (\n <div \n className=\"px-2 py-1 bg-orange-500 text-white text-xs font-medium rounded-md shadow-lg\"\n data-testid=\"badge-unsaved-count\"\n >\n {getMapUnsavedCount()} unsaved\n </div>\n )}\n <Tooltip title=\"Layers\" placement=\"left\">\n <Button\n type=\"default\"\n icon={<Layers className=\"w-6 h-6\" />}\n onClick={handleToggleLayers}\n disabled={!isMapLoaded}\n className={`!w-11 !h-11 !min-w-0 !p-0 bg-background shadow-lg ${showLayers ? 'bg-primary/10' : ''}`}\n aria-label=\"Toggle layers panel\"\n aria-pressed={showLayers}\n data-testid=\"button-toggle-layers\"\n />\n </Tooltip>\n </div>\n )}\n\n \n {enableLayers && showLayers && (\n <LayersPanel\n layers={layers}\n onAddLayer={handleAddLayer}\n onRemoveLayer={handleRemoveLayer}\n onRenameLayer={handleRenameLayer}\n onToggleLayerVisibility={handleToggleLayerVisibility}\n onMoveFeatureToLayer={handleMoveFeatureToLayer}\n selectedFeatureIds={selectedFeatureIds}\n getFeatureCount={getFeatureCountForLayer}\n getLayerUnsavedCount={getLayerUnsavedCount}\n getMapUnsavedCount={getMapUnsavedCount}\n activeEditingLayerId={activeEditingLayerId}\n onSetActiveEditingLayer={setActiveEditingLayerId}\n onSaveLayerGeoJSON={handleSaveLayerGeoJSON}\n onLoadLayerGeoJSON={handleLoadLayerGeoJSON}\n onLoadNewLayerGeoJSON={handleLoadNewLayerGeoJSON}\n onSaveAllGeoJSON={handleSaveAllGeoJSON}\n onSearchAndAddToNewLayer={onSearchEngineRequest ? handleSearchAndAddToNewLayer : undefined}\n onWorkspaceLoad={onWorkspaceLoad ? handleWorkspaceLoad : undefined}\n onWorkspaceSave={onWorkspaceSave ? handleWorkspaceSave : undefined}\n onFitToFeatures={handleFitToFeatures}\n currentMapStyle={currentMapStyle}\n onMapStyleChange={handleMapStyleChange}\n onUpdateTraceConfig={handleUpdateTraceConfig}\n getAvailableTraceFields={getAvailableTraceFields}\n onUpdateHeatmapConfig={handleUpdateHeatmapConfig}\n onUpdateClusterConfig={handleUpdateClusterConfig}\n hasPointFeatures={hasPointFeatures}\n onUpdateVisualConfig={handleUpdateVisualConfig}\n getLayerFields={getLayerFields}\n onFitToLayerFeatures={handleFitToLayerFeatures}\n autoLabelConfig={autoLabelConfig}\n onUpdateAutoLabelConfig={handleUpdateAutoLabelConfig}\n visibleFeatureCount={visibleFeatureCount}\n is3DTerrainEnabled={is3DTerrainEnabled}\n onToggle3DTerrain={handleToggle3DTerrain}\n onUpdateAltitudeDisplayMode={handleUpdateAltitudeDisplayMode}\n hideSatellite={!enableSatellite}\n hideTerrain={!enableTerrain}\n hideBasemapSwitcher={hideBasemapSwitcher}\n externalPersistence={externalPersistence}\n />\n )}\n\n {showProperties && selectedFeatures.length > 0 && (() => {\n // Find the layer name for the first selected feature\n const firstFeatureId = selectedFeatures[0]?.id as string;\n const featureLayer = layers.find(l => l.featureIds.includes(firstFeatureId));\n const layerName = featureLayer?.name;\n const layerId = featureLayer?.id;\n \n return (\n <PropertiesPanel\n selectedFeatures={selectedFeatures.map(f => ({\n id: f.id as string,\n type: f.type,\n properties: f.properties || {},\n geometry: f.geometry,\n }))}\n onUpdateProperties={handleUpdateProperties}\n onUpdateGeometry={handleUpdateGeometry}\n onClose={handleCloseProperties}\n isEditMode={isEditMode}\n layerName={layerName}\n layerId={layerId}\n autoFocusLabel={autoFocusLabel}\n entityCardProvider={entityCardProvider}\n typePickerProvider={typePickerProvider}\n featureSaveProvider={featureSaveProvider}\n onFeatureSaved={handleFeatureSaved}\n />\n );\n })()}\n\n {showStatusPanel && (\n <StatusIndicator\n activeMode={activeMode}\n featureCount={featureCount}\n selectedCount={selectedFeatureIds.length}\n selectionMode={selectionMode}\n />\n )}\n\n {enableTimeline && timelineStore.isEnabled && (\n <Timebar \n onFilterChange={handleTimelineFilterChange} \n selectedFeatureIds={selectedFeatureIds}\n selectedFeatureColors={selectedFeatureColors}\n />\n )}\n\n {/* Custom context menu */}\n {contextMenu && (\n <div\n className=\"fixed z-[9999] min-w-[160px] rounded-md border bg-popover p-1 shadow-md\"\n style={{ left: contextMenu.x, top: contextMenu.y }}\n data-testid=\"context-menu\"\n >\n {contextMenu.items.map((item) => (\n <button\n key={item.id}\n className={`flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-sm hover-elevate active-elevate-2 ${\n item.disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'\n } ${item.destructive ? 'text-destructive' : ''}`}\n disabled={item.disabled}\n onClick={() => {\n if (!item.disabled) {\n item.onSelect();\n setContextMenu(null);\n }\n }}\n data-testid={`context-menu-item-${item.id}`}\n >\n {item.label}\n </button>\n ))}\n </div>\n )}\n\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\".geojson,.json\"\n onChange={handleFileChange}\n className=\"hidden\"\n data-testid=\"input-file-geojson\"\n />\n </div>\n </MapDropZone>\n );\n});\n","import { Download, Upload } from 'lucide-react';\nimport { Button, Tooltip } from 'antd';\n\ninterface ActionPanelProps {\n onSave: () => void;\n onLoad: () => void;\n disabled?: boolean;\n}\n\nexport function ActionPanel({ onSave, onLoad, disabled }: ActionPanelProps) {\n return (\n <div \n className=\"absolute top-4 right-4 z-10 flex items-center gap-2 p-2 bg-background/80 floating-panel rounded-lg shadow-lg border border-border\"\n role=\"group\"\n aria-label=\"File actions\"\n data-testid=\"panel-actions\"\n >\n <Tooltip \n title={\n <div className=\"flex items-center gap-2\">\n <span>Download features as GeoJSON</span>\n <kbd className=\"px-1.5 py-0.5 text-xs font-mono bg-white/20 rounded\">S</kbd>\n </div>\n }\n >\n <Button\n type=\"default\"\n onClick={onSave}\n disabled={disabled}\n className=\"gap-2 flex items-center\"\n aria-label=\"Save as GeoJSON\"\n data-testid=\"button-save-geojson\"\n >\n <Download className=\"w-4 h-4\" />\n <span className=\"text-sm font-medium\">Save GeoJSON</span>\n </Button>\n </Tooltip>\n \n <Tooltip title=\"Import features from GeoJSON file\">\n <Button\n type=\"default\"\n onClick={onLoad}\n disabled={disabled}\n className=\"gap-2 flex items-center\"\n aria-label=\"Load GeoJSON file\"\n data-testid=\"button-load-geojson\"\n >\n <Upload className=\"w-4 h-4\" />\n <span className=\"text-sm font-medium\">Load GeoJSON</span>\n </Button>\n </Tooltip>\n </div>\n );\n}\n","import { useState, useCallback } from 'react';\nimport { Plus, FileJson, GripVertical, TestTube, Upload, Plane, Users, Phone, Car, AlertCircle, Check, Loader2 } from 'lucide-react';\nimport { Button, Card, Divider, Modal, DatePicker, Table, Tag } from 'antd';\nimport type { ColumnsType } from 'antd/es/table';\nimport dayjs from 'dayjs';\nimport { cn } from '@/lib/utils';\nimport * as toGeoJSON from '@mapbox/togeojson';\n\n// Mock entity data for the import wizard demonstration\ninterface PositionIdentifier {\n type: 'phone' | 'vehicle' | 'device';\n value: string;\n}\n\ninterface MockEntity {\n id: string;\n name: string;\n type: 'person' | 'phone' | 'vehicle';\n identifiers: PositionIdentifier[];\n}\n\nconst MOCK_ENTITIES: MockEntity[] = [\n { id: '1', name: 'John Smith', type: 'person', identifiers: [{ type: 'phone', value: '+1-555-0101' }, { type: 'vehicle', value: 'ABC-1234' }] },\n { id: '2', name: 'Jane Doe', type: 'person', identifiers: [{ type: 'phone', value: '+1-555-0102' }] },\n { id: '3', name: 'Bob Wilson', type: 'person', identifiers: [] },\n { id: '4', name: 'Alice Brown', type: 'person', identifiers: [{ type: 'vehicle', value: 'XYZ-5678' }, { type: 'vehicle', value: 'DEF-9012' }] },\n { id: '5', name: '+1-555-0200', type: 'phone', identifiers: [{ type: 'phone', value: '+1-555-0200' }] },\n { id: '6', name: '+1-555-0201', type: 'phone', identifiers: [{ type: 'phone', value: '+1-555-0201' }] },\n { id: '7', name: 'Vehicle GHI-3456', type: 'vehicle', identifiers: [{ type: 'vehicle', value: 'GHI-3456' }] },\n { id: '8', name: 'Carol White', type: 'person', identifiers: [{ type: 'phone', value: '+1-555-0103' }, { type: 'device', value: 'IMEI-123456' }] },\n { id: '9', name: 'David Lee', type: 'person', identifiers: [] },\n { id: '10', name: 'Emma Garcia', type: 'person', identifiers: [{ type: 'phone', value: '+1-555-0104' }] },\n { id: '11', name: 'Frank Miller', type: 'person', identifiers: [{ type: 'vehicle', value: 'JKL-7890' }] },\n];\n\ninterface ImportWizardProps {\n open: boolean;\n onClose: () => void;\n onImportComplete: (summary: string) => void;\n}\n\nfunction ImportWizard({ open, onClose, onImportComplete }: ImportWizardProps) {\n const [fromDate, setFromDate] = useState<dayjs.Dayjs | null>(dayjs().subtract(10, 'day'));\n const [toDate, setToDate] = useState<dayjs.Dayjs | null>(dayjs());\n const [isValidating, setIsValidating] = useState(false);\n const [validationResult, setValidationResult] = useState<{\n totalPositions: number;\n entitiesWithData: number;\n entitiesWithoutData: number;\n } | null>(null);\n\n const handleSetToNow = () => {\n setToDate(dayjs());\n };\n\n const handleValidate = async () => {\n setIsValidating(true);\n setValidationResult(null);\n \n // Simulate async validation\n await new Promise(resolve => setTimeout(resolve, 1500));\n \n // Generate mock validation result\n const entitiesWithIdentifiers = MOCK_ENTITIES.filter(e => e.identifiers.length > 0);\n const entitiesWithoutIdentifiers = MOCK_ENTITIES.filter(e => e.identifiers.length === 0);\n const totalPositions = entitiesWithIdentifiers.reduce((sum, e) => {\n // Random number of positions per identifier\n return sum + e.identifiers.length * Math.floor(Math.random() * 50 + 10);\n }, 0);\n \n setValidationResult({\n totalPositions,\n entitiesWithData: entitiesWithIdentifiers.length,\n entitiesWithoutData: entitiesWithoutIdentifiers.length,\n });\n setIsValidating(false);\n };\n\n const handleInsert = () => {\n if (!validationResult) return;\n \n const summary = `${validationResult.totalPositions} positions added from ${validationResult.entitiesWithData} entities, ${validationResult.entitiesWithoutData} entities had no positions`;\n onImportComplete(summary);\n \n // Reset state\n setValidationResult(null);\n setFromDate(dayjs().subtract(10, 'day'));\n setToDate(dayjs());\n onClose();\n };\n\n const handleCancel = () => {\n setValidationResult(null);\n setIsValidating(false);\n onClose();\n };\n\n const columns: ColumnsType<MockEntity> = [\n {\n title: 'Entity',\n dataIndex: 'name',\n key: 'name',\n render: (name: string, record: MockEntity) => (\n <div className=\"flex items-center gap-2\">\n {record.type === 'person' && <Users className=\"w-4 h-4 text-muted-foreground\" />}\n {record.type === 'phone' && <Phone className=\"w-4 h-4 text-blue-500\" />}\n {record.type === 'vehicle' && <Car className=\"w-4 h-4 text-green-500\" />}\n <span>{name}</span>\n </div>\n ),\n },\n {\n title: 'Position Identifiers',\n dataIndex: 'identifiers',\n key: 'identifiers',\n render: (identifiers: PositionIdentifier[], record: MockEntity) => {\n // For phones, they ARE the identifier\n if (record.type === 'phone') {\n return (\n <Tag color=\"blue\" className=\"flex items-center gap-1 w-fit\">\n <Phone className=\"w-3 h-3\" />\n Self (Phone)\n </Tag>\n );\n }\n \n if (identifiers.length === 0) {\n return (\n <span className=\"text-amber-600 dark:text-amber-400 flex items-center gap-1 text-sm\">\n <AlertCircle className=\"w-4 h-4\" />\n No position identifiers available\n </span>\n );\n }\n \n return (\n <div className=\"flex flex-wrap gap-1\">\n {identifiers.map((id, idx) => (\n <Tag \n key={idx} \n color={id.type === 'phone' ? 'blue' : id.type === 'vehicle' ? 'green' : 'purple'}\n className=\"flex items-center gap-1\"\n >\n {id.type === 'phone' && <Phone className=\"w-3 h-3\" />}\n {id.type === 'vehicle' && <Car className=\"w-3 h-3\" />}\n {id.value}\n </Tag>\n ))}\n </div>\n );\n },\n },\n ];\n\n return (\n <Modal\n open={open}\n onCancel={handleCancel}\n title={\n <div className=\"flex items-center gap-2\">\n <Users className=\"w-5 h-5 text-primary\" />\n Import non os_geo_thing Wizard\n </div>\n }\n width={700}\n footer={null}\n data-testid=\"dialog-import-wizard\"\n >\n <div className=\"space-y-4\">\n <p className=\"text-sm text-muted-foreground\">\n This wizard demonstrates importing position data for entities that are not of type os_geo_thing. \n Select a time range and validate to see available positions.\n </p>\n \n {/* Entity List */}\n <div>\n <h4 className=\"font-medium text-sm mb-2\">Entities ({MOCK_ENTITIES.length})</h4>\n <Table\n dataSource={MOCK_ENTITIES}\n columns={columns}\n rowKey=\"id\"\n size=\"small\"\n pagination={{ pageSize: 5 }}\n className=\"border rounded-md\"\n data-testid=\"table-entities\"\n />\n </div>\n \n {/* Time Range Picker */}\n <div className=\"bg-muted/30 p-3 rounded-md\">\n <h4 className=\"font-medium text-sm mb-2\">Time Range</h4>\n <div className=\"flex items-center gap-2 flex-wrap\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm text-muted-foreground\">From:</span>\n <DatePicker\n value={fromDate}\n onChange={setFromDate}\n size=\"small\"\n format=\"YYYY-MM-DD\"\n data-testid=\"datepicker-from\"\n />\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm text-muted-foreground\">To:</span>\n <DatePicker\n value={toDate}\n onChange={setToDate}\n size=\"small\"\n format=\"YYYY-MM-DD\"\n data-testid=\"datepicker-to\"\n />\n </div>\n <Button\n type=\"default\"\n size=\"small\"\n onClick={handleSetToNow}\n data-testid=\"button-set-to-now\"\n >\n Set to Now\n </Button>\n </div>\n </div>\n \n {/* Validation Result */}\n {validationResult && (\n <div className=\"bg-green-50 dark:bg-green-950/30 border border-green-200 dark:border-green-800 p-3 rounded-md\">\n <div className=\"flex items-center gap-2 text-green-700 dark:text-green-400\">\n <Check className=\"w-5 h-5\" />\n <span className=\"font-medium\">Validation Complete</span>\n </div>\n <p className=\"text-sm text-green-600 dark:text-green-400 mt-1\">\n <strong>{validationResult.totalPositions}</strong> positions available from{' '}\n <strong>{validationResult.entitiesWithData}</strong> entities\n {validationResult.entitiesWithoutData > 0 && (\n <span className=\"text-amber-600 dark:text-amber-400\">\n {' '}({validationResult.entitiesWithoutData} entities had no positions)\n </span>\n )}\n </p>\n </div>\n )}\n \n {/* Action Buttons */}\n <div className=\"flex justify-end gap-2 pt-2 border-t\">\n <Button onClick={handleCancel} data-testid=\"button-cancel-wizard\">\n Cancel\n </Button>\n {!validationResult ? (\n <Button\n type=\"primary\"\n onClick={handleValidate}\n disabled={isValidating || !fromDate || !toDate}\n data-testid=\"button-validate\"\n >\n {isValidating ? (\n <>\n <Loader2 className=\"w-4 h-4 mr-2 animate-spin\" />\n Validating...\n </>\n ) : (\n 'Validate'\n )}\n </Button>\n ) : (\n <Button\n type=\"primary\"\n onClick={handleInsert}\n data-testid=\"button-insert\"\n >\n <Check className=\"w-4 h-4 mr-2\" />\n Insert {validationResult.totalPositions} Positions\n </Button>\n )}\n </div>\n </div>\n </Modal>\n );\n}\n\nconst CITY_NAMES = [\n 'Paris', 'London', 'Tokyo', 'Milan', 'Cairo', 'Sydney', 'Berlin', 'Madrid',\n 'Rome', 'Vienna', 'Prague', 'Dublin', 'Oslo', 'Helsinki', 'Lisbon', 'Athens',\n 'Budapest', 'Warsaw', 'Moscow', 'Beijing', 'Seoul', 'Mumbai', 'Singapore'\n];\n\nfunction generateRandomName(): string {\n const city = CITY_NAMES[Math.floor(Math.random() * CITY_NAMES.length)];\n const number = Math.floor(Math.random() * 10000);\n return `${city} ${number}`;\n}\n\nfunction generateRandomDate(start: Date, end: Date): Date {\n return new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime()));\n}\n\nfunction generateRandomPoint(): GeoJSON.Feature {\n const lng = (Math.random() * 360) - 180;\n const lat = (Math.random() * 170) - 85;\n const name = generateRandomName();\n \n const hasTemporal = Math.random() < 0.2;\n \n let properties: Record<string, unknown> = { name };\n \n if (hasTemporal) {\n const baseDate = new Date(2020, 0, 1);\n const endDate = new Date(2024, 11, 31);\n const startDate = generateRandomDate(baseDate, endDate);\n const featureEndDate = generateRandomDate(startDate, new Date(endDate.getTime() + 365 * 24 * 60 * 60 * 1000));\n \n properties = {\n ...properties,\n startDate: startDate.toISOString(),\n endDate: featureEndDate.toISOString(),\n };\n }\n \n return {\n type: 'Feature',\n properties,\n geometry: {\n type: 'Point',\n coordinates: [lng, lat],\n },\n };\n}\n\nfunction generateSequentialPoints(): GeoJSON.Feature[] {\n const baseDate = new Date();\n const baseLng = 0;\n const baseLat = 20;\n \n return Array.from({ length: 10 }, (_, i) => {\n const date = new Date(baseDate.getTime() + i * 24 * 60 * 60 * 1000); // +1 day each\n const lng = baseLng + i * 10; // 10 degrees east each (~1000km at equator)\n \n return {\n type: 'Feature' as const,\n properties: {\n name: `Point ${i + 1}`,\n startDate: date.toISOString(),\n },\n geometry: {\n type: 'Point' as const,\n coordinates: [lng, baseLat],\n },\n };\n });\n}\n\nfunction generateNYCPoints(count: number): GeoJSON.FeatureCollection {\n // NYC area bounds: roughly -74.3 to -73.7 lng, 40.5 to 40.9 lat\n const nycCenter = { lng: -74.006, lat: 40.7128 };\n const spread = 0.15; // ~15km radius\n \n // 12 types with weighted distribution for realistic NYC data\n const types = [\n { name: 'bus stop', weight: 0.18 },\n { name: 'retail', weight: 0.15 },\n { name: 'restaurant', weight: 0.14 },\n { name: 'office', weight: 0.12 },\n { name: 'residential', weight: 0.10 },\n { name: 'school', weight: 0.08 },\n { name: 'park', weight: 0.06 },\n { name: 'subway', weight: 0.05 },\n { name: 'hotel', weight: 0.04 },\n { name: 'museum', weight: 0.03 },\n { name: 'hospital', weight: 0.03 },\n { name: 'theater', weight: 0.02 },\n ];\n \n const getRandomType = () => {\n const r = Math.random();\n let cumulative = 0;\n for (const t of types) {\n cumulative += t.weight;\n if (r < cumulative) return t.name;\n }\n return types[0].name;\n };\n \n // Max occupancy ranges by type\n const getMaxOccupancy = (type: string) => {\n switch (type) {\n case 'hospital': return Math.floor(Math.random() * 9000) + 1000; // 1000-10000\n case 'residential': return Math.floor(Math.random() * 500) + 50; // 50-550\n case 'office': return Math.floor(Math.random() * 2000) + 100; // 100-2100\n case 'school': return Math.floor(Math.random() * 1500) + 200; // 200-1700\n case 'hotel': return Math.floor(Math.random() * 800) + 100; // 100-900\n case 'theater': return Math.floor(Math.random() * 2000) + 200; // 200-2200\n case 'museum': return Math.floor(Math.random() * 1000) + 100; // 100-1100\n case 'restaurant': return Math.floor(Math.random() * 200) + 20; // 20-220\n case 'retail': return Math.floor(Math.random() * 400) + 10; // 10-410\n case 'park': return Math.floor(Math.random() * 5000) + 100; // 100-5100\n case 'subway': return Math.floor(Math.random() * 500) + 50; // 50-550\n case 'bus stop': return Math.floor(Math.random() * 45) + 5; // 5-50\n default: return Math.floor(Math.random() * 100) + 5;\n }\n };\n \n const features: GeoJSON.Feature[] = Array.from({ length: count }, (_, i) => {\n // Random position within NYC area with gaussian-ish distribution (more density at center)\n const angle = Math.random() * Math.PI * 2;\n const distance = Math.random() * Math.random() * spread; // Squared for center concentration\n const lng = nycCenter.lng + Math.cos(angle) * distance;\n const lat = nycCenter.lat + Math.sin(angle) * distance * 0.7; // Adjust for lat/lng ratio\n \n const type = getRandomType();\n const maxOccupancy = getMaxOccupancy(type);\n \n return {\n type: 'Feature' as const,\n properties: {\n name: `NYC Point ${i + 1}`,\n type,\n maxOccupancy,\n },\n geometry: {\n type: 'Point' as const,\n coordinates: [lng, lat],\n },\n };\n });\n \n return {\n type: 'FeatureCollection',\n features,\n };\n}\n\nfunction generatePeopleTraces(): GeoJSON.Feature[] {\n // NYC bounds for movement\n const nycCenter = { lng: -74.006, lat: 40.7128 };\n const features: GeoJSON.Feature[] = [];\n \n // 5 people, 6 hours, 1 point per 10 minutes = 36 points per person\n const numPeople = 5;\n const durationHours = 6;\n const intervalMinutes = 10;\n const pointsPerPerson = (durationHours * 60) / intervalMinutes; // 36\n \n const baseDate = new Date();\n baseDate.setHours(8, 0, 0, 0); // Start at 8 AM\n \n for (let person = 0; person < numPeople; person++) {\n const targetId = `Person-${person + 1}`;\n \n // Random starting position within NYC\n let currentLng = nycCenter.lng + (Math.random() - 0.5) * 0.1;\n let currentLat = nycCenter.lat + (Math.random() - 0.5) * 0.08;\n \n for (let i = 0; i < pointsPerPerson; i++) {\n const timestamp = new Date(baseDate.getTime() + i * intervalMinutes * 60 * 1000);\n \n // Add feature\n features.push({\n type: 'Feature',\n properties: {\n name: `${targetId} - ${i + 1}`,\n TargetID: targetId,\n startDate: timestamp.toISOString(),\n },\n geometry: {\n type: 'Point',\n coordinates: [currentLng, currentLat],\n },\n });\n \n // Move for next point (walking speed ~0.001 degrees per 10 min, ~100m)\n const walkSpeed = 0.001 + Math.random() * 0.001;\n const angle = Math.random() * Math.PI * 2;\n currentLng += Math.cos(angle) * walkSpeed;\n currentLat += Math.sin(angle) * walkSpeed * 0.7;\n \n // Keep within NYC bounds\n currentLng = Math.max(nycCenter.lng - 0.1, Math.min(nycCenter.lng + 0.1, currentLng));\n currentLat = Math.max(nycCenter.lat - 0.08, Math.min(nycCenter.lat + 0.08, currentLat));\n }\n }\n \n return features;\n}\n\n/**\n * Generate a sample drone flight path over NYC with altitude data\n * This simulates a drone survey flight as timestamped GPS points.\n * Enable TRACE feature in layer menu to see flight path as connected line.\n * Each point has its own timestamp for timeline filtering.\n */\nfunction generateDroneFlightOverNYC(): GeoJSON.FeatureCollection {\n // Flight waypoints with altitude in meters\n const waypoints = [\n { lng: -73.9654, lat: 40.7829, alt: 50, name: 'Takeoff - Central Park' },\n { lng: -73.9654, lat: 40.7829, alt: 120, name: 'Climb to survey altitude' },\n { lng: -73.9810, lat: 40.7614, alt: 120, name: 'Times Square flyover' },\n { lng: -73.9857, lat: 40.7484, alt: 150, name: 'Empire State Building' },\n { lng: -73.9776, lat: 40.7527, alt: 180, name: 'Grand Central area' },\n { lng: -73.9712, lat: 40.7580, alt: 160, name: 'Rockefeller Center' },\n { lng: -73.9632, lat: 40.7794, alt: 140, name: 'Upper East Side' },\n { lng: -73.9654, lat: 40.7851, alt: 100, name: 'Central Park North' },\n { lng: -73.9654, lat: 40.7829, alt: 60, name: 'Return to start' },\n { lng: -73.9654, lat: 40.7829, alt: 0, name: 'Landing' },\n ];\n \n const baseTime = new Date();\n baseTime.setHours(14, 0, 0, 0); // 2 PM flight\n const flightDurationMs = 25 * 60 * 1000; // 25 minutes total flight\n \n // Generate interpolated points along the flight path\n // Each point is a separate feature with its own timestamp\n const features: GeoJSON.Feature[] = [];\n let pointIndex = 0;\n const totalSegments = waypoints.length - 1;\n const pointsPerSegment = 10;\n const totalPoints = totalSegments * pointsPerSegment + 1;\n const timePerPoint = flightDurationMs / totalPoints;\n \n for (let i = 0; i < waypoints.length - 1; i++) {\n const from = waypoints[i];\n const to = waypoints[i + 1];\n \n for (let j = 0; j < pointsPerSegment; j++) {\n const t = j / pointsPerSegment;\n const lng = from.lng + (to.lng - from.lng) * t;\n const lat = from.lat + (to.lat - from.lat) * t;\n const alt = from.alt + (to.alt - from.alt) * t;\n // Add some noise to altitude for realism\n const noise = (Math.random() - 0.5) * 5;\n const finalAlt = Math.max(0, alt + noise);\n \n const timestamp = new Date(baseTime.getTime() + pointIndex * timePerPoint);\n const isWaypoint = j === 0;\n \n features.push({\n type: 'Feature',\n properties: {\n name: isWaypoint ? from.name : `Flight point ${pointIndex + 1}`,\n altitude: Math.round(finalAlt),\n startDate: timestamp.toISOString(),\n TargetID: 'DJI-001',\n },\n geometry: {\n type: 'Point',\n coordinates: [lng, lat, finalAlt],\n },\n });\n \n pointIndex++;\n }\n }\n \n // Add final landing point\n const last = waypoints[waypoints.length - 1];\n features.push({\n type: 'Feature',\n properties: {\n name: last.name,\n altitude: last.alt,\n startDate: new Date(baseTime.getTime() + flightDurationMs).toISOString(),\n TargetID: 'DJI-001',\n },\n geometry: {\n type: 'Point',\n coordinates: [last.lng, last.lat, last.alt],\n },\n });\n \n return {\n type: 'FeatureCollection',\n features,\n };\n}\n\n/**\n * Parse KML file content to GeoJSON using @mapbox/togeojson\n */\nexport function parseKMLToGeoJSON(kmlContent: string): GeoJSON.FeatureCollection | null {\n try {\n const parser = new DOMParser();\n const kmlDoc = parser.parseFromString(kmlContent, 'application/xml');\n \n // Check for parse errors\n const parseError = kmlDoc.querySelector('parsererror');\n if (parseError) {\n console.error('KML parse error:', parseError.textContent);\n return null;\n }\n \n // Convert KML to GeoJSON\n const geoJSON = toGeoJSON.kml(kmlDoc);\n return geoJSON as GeoJSON.FeatureCollection;\n } catch (error) {\n console.error('Error parsing KML:', error);\n return null;\n }\n}\n\n// Sample drone flight data\nconst SAMPLE_DRONE_FLIGHT = {\n id: 'sample-drone-flight',\n name: 'NYC Drone Flight',\n description: 'Enable TRACE to see flight path',\n getData: generateDroneFlightOverNYC,\n};\n\nconst SAMPLE_GEOJSON_ITEMS = [\n {\n id: 'sample-cities',\n name: 'World Cities',\n description: '5 major cities with dates',\n data: {\n type: 'FeatureCollection',\n features: [\n {\n type: 'Feature',\n properties: { name: 'New York', startDate: '2023-01-15', endDate: '2023-06-30' },\n geometry: { type: 'Point', coordinates: [-74.006, 40.7128] }\n },\n {\n type: 'Feature',\n properties: { name: 'Los Angeles', startDate: '2023-03-01' },\n geometry: { type: 'Point', coordinates: [-118.2437, 34.0522] }\n },\n {\n type: 'Feature',\n properties: { name: 'Chicago' },\n geometry: { type: 'Point', coordinates: [-87.6298, 41.8781] }\n },\n {\n type: 'Feature',\n properties: { name: 'Houston', startDate: '2022-12-01', endDate: '2023-12-01' },\n geometry: { type: 'Point', coordinates: [-95.3698, 29.7604] }\n },\n {\n type: 'Feature',\n properties: { name: 'Phoenix' },\n geometry: { type: 'Point', coordinates: [-112.074, 33.4484] }\n }\n ]\n } as GeoJSON.FeatureCollection\n },\n {\n id: 'sample-route',\n name: 'Sample Route',\n description: 'Points with timestamps and phone',\n data: {\n type: 'FeatureCollection',\n features: [\n {\n type: 'Feature',\n properties: { name: 'Stop 1', startDate: '2023-01-01T08:00:00Z', phone: '+1-555-0100' },\n geometry: { type: 'Point', coordinates: [-122.4194, 37.7749] }\n },\n {\n type: 'Feature',\n properties: { name: 'Stop 2', startDate: '2023-01-01T10:30:00Z', phone: '+1-555-0100' },\n geometry: { type: 'Point', coordinates: [-118.2437, 34.0522] }\n },\n {\n type: 'Feature',\n properties: { name: 'Stop 3', startDate: '2023-01-01T14:00:00Z', phone: '+1-555-0100' },\n geometry: { type: 'Point', coordinates: [-112.074, 33.4484] }\n },\n {\n type: 'Feature',\n properties: { name: 'Stop 4', startDate: '2023-01-02T09:00:00Z', phone: '+1-555-0100' },\n geometry: { type: 'Point', coordinates: [-104.9903, 39.7392] }\n },\n {\n type: 'Feature',\n properties: { name: 'Stop 5', startDate: '2023-01-02T16:00:00Z', phone: '+1-555-0100' },\n geometry: { type: 'Point', coordinates: [-95.3698, 29.7604] }\n }\n ]\n } as GeoJSON.FeatureCollection\n },\n {\n id: 'sample-region',\n name: 'Sample Region',\n description: 'A polygon without dates',\n data: {\n type: 'FeatureCollection',\n features: [\n {\n type: 'Feature',\n properties: { name: 'Western Region' },\n geometry: {\n type: 'Polygon',\n coordinates: [[\n [-125, 48],\n [-125, 32],\n [-110, 32],\n [-110, 48],\n [-125, 48]\n ]]\n }\n }\n ]\n } as GeoJSON.FeatureCollection\n }\n];\n\ninterface DraggableGeoJSONProps {\n item: typeof SAMPLE_GEOJSON_ITEMS[0];\n}\n\nfunction DraggableGeoJSON({ item }: DraggableGeoJSONProps) {\n const handleDragStart = (e: React.DragEvent) => {\n e.dataTransfer.setData('application/json', JSON.stringify({\n name: item.name,\n data: item.data\n }));\n e.dataTransfer.effectAllowed = 'copy';\n };\n \n return (\n <Card\n draggable\n onDragStart={handleDragStart}\n className=\"pl-[10px] pr-[10px] pt-[1px] pb-[1px] cursor-grab active:cursor-grabbing hover-elevate\"\n data-testid={`draggable-geojson-${item.id}`}\n >\n <div className=\"flex items-start gap-2\">\n <GripVertical className=\"w-4 h-4 text-muted-foreground mt-0.5 flex-shrink-0\" />\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <FileJson className=\"w-4 h-4 text-primary\" />\n <span className=\"font-medium text-sm truncate\">{item.name}</span>\n </div>\n <p className=\"text-xs text-muted-foreground mt-1\">{item.description}</p>\n </div>\n </div>\n </Card>\n );\n}\n\ninterface DraggableDroneFlightProps {\n item: typeof SAMPLE_DRONE_FLIGHT;\n}\n\nfunction DraggableDroneFlight({ item }: DraggableDroneFlightProps) {\n const handleDragStart = (e: React.DragEvent) => {\n const data = item.getData();\n e.dataTransfer.setData('application/json', JSON.stringify({\n name: item.name,\n data: data\n }));\n e.dataTransfer.effectAllowed = 'copy';\n };\n \n return (\n <Card\n draggable\n onDragStart={handleDragStart}\n className=\"p-3 cursor-grab active:cursor-grabbing hover-elevate border-primary/30\"\n data-testid={`draggable-drone-flight-${item.id}`}\n >\n <div className=\"flex items-start gap-2\">\n <GripVertical className=\"w-4 h-4 text-muted-foreground mt-0.5 flex-shrink-0\" />\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <Plane className=\"w-4 h-4 text-primary\" />\n <span className=\"font-medium text-sm truncate\">{item.name}</span>\n </div>\n <p className=\"text-xs text-muted-foreground mt-1\">{item.description}</p>\n </div>\n </div>\n </Card>\n );\n}\n\ninterface DebugSidebarProps {\n onAddRandomPoints: (features: GeoJSON.Feature[]) => void;\n onImportKML?: (name: string, geojson: GeoJSON.FeatureCollection) => void;\n canAddFeatures?: boolean;\n className?: string;\n onCloseMap?: () => void;\n}\n\nexport function DebugSidebar({ onAddRandomPoints, onImportKML, canAddFeatures = true, className, onCloseMap }: DebugSidebarProps) {\n const [isGenerating, setIsGenerating] = useState(false);\n const [isDragOver, setIsDragOver] = useState(false);\n const [wizardOpen, setWizardOpen] = useState(false);\n const [importSummary, setImportSummary] = useState<string | null>(null);\n \n // Handle KML file drop\n const handleKMLDrop = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n setIsDragOver(false);\n \n const files = e.dataTransfer.files;\n if (files.length === 0) return;\n \n const file = files[0];\n const isKML = file.name.toLowerCase().endsWith('.kml') || \n file.name.toLowerCase().endsWith('.kmz');\n \n if (!isKML) {\n console.warn('Please drop a KML file');\n return;\n }\n \n const reader = new FileReader();\n reader.onload = (event) => {\n const content = event.target?.result as string;\n const geojson = parseKMLToGeoJSON(content);\n \n if (geojson && onImportKML) {\n // Use filename without extension as layer name\n const layerName = file.name.replace(/\\.(kml|kmz)$/i, '');\n onImportKML(layerName, geojson);\n }\n };\n reader.readAsText(file);\n }, [onImportKML]);\n \n const handleDragOver = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n setIsDragOver(true);\n }, []);\n \n const handleDragLeave = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n setIsDragOver(false);\n }, []);\n \n const handleGeneratePoints = () => {\n setIsGenerating(true);\n const points = Array.from({ length: 10 }, () => generateRandomPoint());\n onAddRandomPoints(points);\n setTimeout(() => setIsGenerating(false), 500);\n };\n \n const handleGenerateSequential = () => {\n setIsGenerating(true);\n const points = generateSequentialPoints();\n onAddRandomPoints(points);\n setTimeout(() => setIsGenerating(false), 500);\n };\n\n const handleGenerateNYC = () => {\n setIsGenerating(true);\n const nycData = generateNYCPoints(1000);\n onAddRandomPoints(nycData.features);\n setTimeout(() => setIsGenerating(false), 500);\n };\n\n const handleGeneratePeopleTraces = () => {\n setIsGenerating(true);\n const traces = generatePeopleTraces();\n onAddRandomPoints(traces);\n setTimeout(() => setIsGenerating(false), 500);\n };\n \n return (\n <div\n className={cn(\n \"h-full w-72 bg-sidebar border-r border-border flex flex-col min-h-0\",\n className\n )}\n data-testid=\"debug-sidebar\"\n >\n <div className=\"flex items-center gap-2 p-4 border-b border-border flex-shrink-0\">\n <TestTube className=\"w-5 h-5 text-primary\" />\n <h2 className=\"font-semibold flex-1\">Debug Panel</h2>\n {onCloseMap && (\n <Button\n type=\"default\"\n size=\"small\"\n danger\n onClick={onCloseMap}\n data-testid=\"button-close-map\"\n >\n Close Map\n </Button>\n )}\n </div>\n \n <div className=\"flex-1 min-h-0 overflow-auto\">\n <div className=\"p-4 space-y-4\">\n <div>\n <h3 className=\"text-sm font-medium mb-2\">Test Data</h3>\n {!canAddFeatures && (\n <p className=\"text-xs text-amber-600 dark:text-amber-400 mb-2\">\n Select an editable layer to add test data\n </p>\n )}\n <div className=\"space-y-2\">\n <Button\n type=\"default\"\n size=\"small\"\n onClick={handleGeneratePoints}\n disabled={isGenerating || !canAddFeatures}\n className=\"w-full flex items-center justify-center\"\n data-testid=\"button-add-random-points\"\n >\n <Plus className=\"w-4 h-4 mr-2\" />\n {isGenerating ? 'Adding...' : 'Add 10 Random Points'}\n </Button>\n <Button\n type=\"default\"\n size=\"small\"\n onClick={handleGenerateSequential}\n disabled={isGenerating || !canAddFeatures}\n className=\"w-full flex items-center justify-center\"\n data-testid=\"button-add-sequential-points\"\n >\n <Plus className=\"w-4 h-4 mr-2\" />\n Add 10 Sequential Points\n </Button>\n <Button\n type=\"default\"\n size=\"small\"\n onClick={handleGenerateNYC}\n disabled={isGenerating || !canAddFeatures}\n className=\"w-full flex items-center justify-center\"\n data-testid=\"button-add-nyc-points\"\n >\n <Plus className=\"w-4 h-4 mr-2\" />\n Add 1000 NYC Points\n </Button>\n <Button\n type=\"default\"\n size=\"small\"\n onClick={handleGeneratePeopleTraces}\n disabled={isGenerating || !canAddFeatures}\n className=\"w-full flex items-center justify-center\"\n data-testid=\"button-add-people-traces\"\n >\n <Plus className=\"w-4 h-4 mr-2\" />\n Add People Traces\n </Button>\n <Button\n type=\"default\"\n size=\"small\"\n onClick={() => {\n setIsGenerating(true);\n const data = generateNYCPoints(100000);\n onAddRandomPoints(data.features);\n setTimeout(() => setIsGenerating(false), 500);\n }}\n disabled={isGenerating || !canAddFeatures}\n className=\"w-full flex items-center justify-center\"\n data-testid=\"button-add-100k-points\"\n >\n <Plus className=\"w-4 h-4 mr-2\" />\n Add 100k NYC Points\n </Button>\n </div>\n <p className=\"text-xs text-muted-foreground mt-2\">\n Sequential: 10 points going east, 1 day apart. NYC: points clustered around Manhattan. People: 5 people moving for 6 hours. 100k: Performance test.\n </p>\n </div>\n \n <Divider className=\"!my-3\" />\n \n <div>\n <h3 className=\"text-sm font-medium mb-2\">Drag to Map</h3>\n <p className=\"text-xs text-muted-foreground mb-3\">\n Drag these samples onto the map to add them as new layers\n </p>\n <div className=\"space-y-2\">\n <DraggableDroneFlight item={SAMPLE_DRONE_FLIGHT} />\n {SAMPLE_GEOJSON_ITEMS.map(item => (\n <DraggableGeoJSON key={item.id} item={item} />\n ))}\n </div>\n </div>\n \n <Divider className=\"!my-3\" />\n \n <div>\n <h3 className=\"text-sm font-medium mb-2\">Import Wizard Demo</h3>\n <p className=\"text-xs text-muted-foreground mb-2\">\n Demonstrates importing positions for non-os_geo_thing entities\n </p>\n <Button\n type=\"default\"\n size=\"small\"\n onClick={() => setWizardOpen(true)}\n className=\"w-full flex items-center justify-center\"\n data-testid=\"button-open-import-wizard\"\n >\n <Users className=\"w-4 h-4 mr-2\" />\n Import non os_geo_thing Wizard\n </Button>\n {importSummary && (\n <div className=\"mt-2 p-2 bg-green-50 dark:bg-green-950/30 border border-green-200 dark:border-green-800 rounded-md\">\n <p className=\"text-xs text-green-700 dark:text-green-400\">\n {importSummary}\n </p>\n </div>\n )}\n </div>\n \n <Divider className=\"!my-3\" />\n \n <div>\n <h3 className=\"text-sm font-medium mb-2\">Import KML</h3>\n <p className=\"text-xs text-muted-foreground mb-2\">\n Drop a KML file to import drone flight logs or GPS tracks\n </p>\n <div\n onDrop={handleKMLDrop}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n className={cn(\n \"border-2 border-dashed rounded-md p-4 text-center transition-colors\",\n isDragOver \n ? \"border-primary bg-primary/10\" \n : \"border-muted-foreground/30\"\n )}\n data-testid=\"kml-drop-zone\"\n >\n <Upload className={cn(\n \"w-8 h-8 mx-auto mb-2\",\n isDragOver ? \"text-primary\" : \"text-muted-foreground\"\n )} />\n <p className=\"text-sm text-muted-foreground\">\n {isDragOver ? \"Drop KML file here\" : \"Drop .kml file\"}\n </p>\n </div>\n </div>\n </div>\n </div>\n \n {/* Import Wizard Modal */}\n <ImportWizard\n open={wizardOpen}\n onClose={() => setWizardOpen(false)}\n onImportComplete={(summary) => {\n setImportSummary(summary);\n // Clear summary after 10 seconds\n setTimeout(() => setImportSummary(null), 10000);\n }}\n />\n </div>\n );\n}\n"],"names":["PRESET_COLORS","Map","Tag","_a","_b","_c","_d","CalendarIcon","totalRange","MapEditorCanvas","layer","layerId","tooltipEl","showTooltip","hideTooltip","selectedFeatures","nextLayers","layers","e","reprojectMsg"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../client/src/lib/utils.ts","../client/src/hooks/toast-context.ts","../client/src/hooks/use-toast.ts","../client/src/components/drawing-toolbar.tsx","../client/src/components/color-picker-popover.tsx","../client/src/components/icon-picker.tsx","../client/src/components/layers-panel.tsx","../client/src/components/properties-panel.tsx","../client/src/components/status-indicator.tsx","../client/src/lib/timeline-store.ts","../client/src/components/timebar.tsx","../client/src/components/map-drop-zone.tsx","../client/src/components/cluster-pie-chart.tsx","../client/src/components/map-editor-canvas.tsx","../client/src/components/action-panel.tsx","../client/src/components/debug-sidebar.tsx"],"sourcesContent":["import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","import { createContext } from 'react';\n\nexport type ToastFn = (options: { title?: string; description?: string; variant?: 'default' | 'destructive' }) => void;\n\nexport const ToastContext = createContext<ToastFn | null>(null);\n","import { useContext } from \"react\";\nimport { App, message as staticMessage } from \"antd\";\nimport { ToastContext } from \"./toast-context\";\n\nexport function useToast() {\n const externalToast = useContext(ToastContext);\n\n if (externalToast) {\n return { toast: externalToast };\n }\n\n let message: ReturnType<typeof App.useApp>['message'] | null = null;\n try {\n const app = App.useApp();\n message = app.message;\n } catch {\n // App.useApp() fails when no antd <App> provider is in the tree\n // (common when consumed as an npm package with a separate antd bundle)\n }\n\n const toast = ({ title, description, variant }: { title?: string; description?: string; variant?: 'default' | 'destructive' }) => {\n const content = description ? `${title ? title + ': ' : ''}${description}` : title;\n const msg = message ?? staticMessage;\n if (variant === 'destructive') {\n msg.error(content);\n } else {\n msg.success(content);\n }\n };\n\n return { toast };\n}\n\nexport { useToast as toast };\n","import { useState, useRef, useEffect } from 'react';\nimport { MapPin, Minus, Pentagon, Trash2, X, Undo2, Redo2, MousePointer2, Pencil, Ruler, Move, ChevronDown, Square, Hexagon, Type, MoveRight, Circle, Navigation, MoreVertical, Search, Loader2, Plus, Database, Filter } from 'lucide-react';\nimport { Button, Tooltip, Dropdown, Modal, Input, Divider, Tabs } from 'antd';\nimport type { MenuProps } from 'antd';\nimport { cn } from '@/lib/utils';\nimport { useToast } from '@/hooks/use-toast';\nimport type { SearchEngineParams, GeocoderProvider, GeocoderResult } from '@/lib/map-editor-api';\n\nexport type DrawingMode = 'simple_select' | 'view_select' | 'draw_point' | 'draw_line_string' | 'draw_polygon' | 'draw_rectangle' | 'direct_select' | 'draw_text' | 'draw_arrow' | 'draw_circle';\nexport type MeasureMode = 'none' | 'distance' | 'area';\nexport type SelectionMode = 'click' | 'rectangle' | 'polygon' | 'circle';\n\ninterface DrawingToolbarProps {\n activeMode: DrawingMode;\n onModeChange: (mode: DrawingMode) => void;\n onClear: () => void;\n onDeleteSelected: () => void;\n onUndo: () => void;\n onRedo: () => void;\n featureCount: number;\n selectedCount: number;\n canUndo: boolean;\n canRedo: boolean;\n disabled?: boolean;\n isEditMode: boolean;\n onToggleEditMode: () => void;\n hasVisibleLayers: boolean;\n hasEditableLayer: boolean;\n measureMode: MeasureMode;\n onMeasureModeChange: (mode: MeasureMode) => void;\n selectionMode: SelectionMode;\n onSelectionModeChange: (mode: SelectionMode) => void;\n enableMeasurement?: boolean;\n enableSelection?: boolean;\n hiddenDrawingTools?: ('point' | 'line' | 'polygon' | 'text' | 'arrow' | 'circle')[];\n hiddenSelectionTools?: ('click' | 'rectangle' | 'polygon' | 'circle')[];\n selectionOnly?: boolean;\n onGoTo?: (coords: [number, number], zoom?: number) => void;\n onDropPoint?: (coords: [number, number], name?: string) => void;\n showGoToButton?: boolean;\n isSelectionToolActive?: boolean;\n onSelectionToolActiveChange?: (active: boolean) => void;\n showClearFilter?: boolean;\n onClearFilter?: () => void;\n /** Notifies the parent when the filter tool is toggled on or off */\n onFilterActiveChange?: (active: boolean) => void;\n /** Callback to invoke the external search engine - when provided, shows \"+\" add menu */\n onSearchEngineRequest?: () => Promise<void>;\n /** Whether the search engine request is currently in progress */\n isSearchEngineLoading?: boolean;\n /** Custom geocoding URL - should accept ?q={query} parameter and return Nominatim-compatible JSON */\n geocodingUrl?: string;\n /** Custom geocoder provider function - use instead of geocodingUrl when geocoding is an internal API */\n geocoderProvider?: GeocoderProvider;\n /** Whether to show keyboard shortcut hints in tooltips and menus. Default: true. */\n showShortcutHints?: boolean;\n /** When true, render each selection tool as a separate button instead of a dropdown */\n expandSelectionTools?: boolean;\n /** Show a dedicated Filter button that activates rectangle selection for geo-filtering */\n showFilterTool?: boolean;\n}\n\ninterface ToolButtonProps {\n mode: DrawingMode;\n activeMode: DrawingMode;\n onModeChange: (mode: DrawingMode) => void;\n icon: React.ReactNode;\n label: string;\n shortcut: string;\n disabled?: boolean;\n showShortcutHint?: boolean;\n}\n\nfunction ToolButton({ mode, activeMode, onModeChange, icon, label, shortcut, disabled, showShortcutHint = true }: ToolButtonProps) {\n const isActive = activeMode === mode;\n \n const handleClick = () => {\n if (isActive) {\n onModeChange('simple_select');\n } else {\n onModeChange(mode);\n }\n };\n \n return (\n <Tooltip \n title={showShortcutHint\n ? <span className=\"flex items-center gap-2\">{label}<kbd className=\"px-1.5 py-0.5 text-xs font-mono bg-black/20 rounded\">{shortcut}</kbd></span>\n : label\n } \n placement=\"right\"\n >\n <Button\n type=\"text\"\n onClick={handleClick}\n disabled={disabled}\n className={cn(\n \"relative transition-all duration-150 flex items-center justify-center !w-9 !h-9 !min-w-0 !p-0\",\n isActive && \"tool-active bg-primary/10\"\n )}\n aria-label={label}\n aria-pressed={isActive}\n data-testid={`button-tool-${mode.replace('draw_', '').replace('_string', '')}`}\n icon={icon}\n />\n </Tooltip>\n );\n}\n\nconst SELECTION_MODES = [\n { id: 'click' as SelectionMode, label: 'Click Select', icon: MousePointer2, shortcut: 'V' },\n { id: 'rectangle' as SelectionMode, label: 'Rectangle Select', icon: Square, shortcut: 'R' },\n { id: 'polygon' as SelectionMode, label: 'Polygon Select', icon: Hexagon, shortcut: 'S' },\n { id: 'circle' as SelectionMode, label: 'Circle Select', icon: Circle, shortcut: 'O' },\n];\n\nexport function DrawingToolbar({ \n activeMode, \n onModeChange, \n onClear, \n onDeleteSelected, \n onUndo, \n onRedo, \n featureCount, \n selectedCount, \n canUndo, \n canRedo, \n disabled,\n isEditMode,\n onToggleEditMode,\n hasVisibleLayers,\n hasEditableLayer,\n measureMode,\n onMeasureModeChange,\n selectionMode,\n onSelectionModeChange,\n enableMeasurement = true,\n enableSelection = true,\n hiddenDrawingTools = [],\n hiddenSelectionTools = [],\n selectionOnly = false,\n onGoTo,\n onDropPoint,\n showGoToButton = false,\n isSelectionToolActive = true,\n onSelectionToolActiveChange,\n showClearFilter = false,\n onClearFilter,\n onFilterActiveChange,\n onSearchEngineRequest,\n geocodingUrl = 'https://nominatim.openstreetmap.org/search',\n geocoderProvider,\n showShortcutHints = true,\n expandSelectionTools = false,\n showFilterTool = false,\n}: DrawingToolbarProps) {\n const { toast } = useToast();\n const [goToDialogOpen, setGoToDialogOpen] = useState(false);\n const [goToLat, setGoToLat] = useState('');\n const [goToLng, setGoToLng] = useState('');\n const [goToAddress, setGoToAddress] = useState('');\n const [isSearching, setIsSearching] = useState(false);\n const [filterActive, setFilterActive] = useState(false);\n const [isCompact, setIsCompact] = useState(false);\n const toolbarRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n onFilterActiveChange?.(filterActive);\n }, [filterActive, onFilterActiveChange]);\n const rafIdRef = useRef<number | null>(null);\n const isCompactRef = useRef(false);\n \n useEffect(() => {\n const HYSTERESIS_MARGIN = 20;\n const BOTTOM_MARGIN = 80;\n \n const checkOverflow = () => {\n if (rafIdRef.current !== null) {\n cancelAnimationFrame(rafIdRef.current);\n }\n \n rafIdRef.current = requestAnimationFrame(() => {\n if (!toolbarRef.current) return;\n \n const toolbar = toolbarRef.current;\n const toolbarRect = toolbar.getBoundingClientRect();\n const viewportHeight = window.innerHeight;\n \n const timeButton = toolbar.querySelector('[data-testid=\"button-timeline-toggle\"]');\n \n let toolbarBottom: number;\n if (isCompactRef.current) {\n const estimatedExpandedHeight = toolbarRect.height + 260;\n toolbarBottom = toolbarRect.top + estimatedExpandedHeight;\n } else {\n toolbarBottom = toolbarRect.bottom;\n }\n \n let threshold: number;\n if (timeButton) {\n const timeButtonRect = timeButton.getBoundingClientRect();\n threshold = timeButtonRect.top;\n } else {\n threshold = viewportHeight - BOTTOM_MARGIN;\n }\n \n let shouldBeCompact: boolean;\n if (isCompactRef.current) {\n shouldBeCompact = toolbarBottom > (threshold - HYSTERESIS_MARGIN);\n } else {\n shouldBeCompact = toolbarRect.bottom > threshold;\n }\n \n if (shouldBeCompact !== isCompactRef.current) {\n isCompactRef.current = shouldBeCompact;\n setIsCompact(shouldBeCompact);\n }\n });\n };\n \n checkOverflow();\n \n const resizeObserver = new ResizeObserver(() => {\n checkOverflow();\n });\n \n if (toolbarRef.current) {\n resizeObserver.observe(toolbarRef.current);\n }\n \n window.addEventListener('resize', checkOverflow);\n \n return () => {\n if (rafIdRef.current !== null) {\n cancelAnimationFrame(rafIdRef.current);\n }\n resizeObserver.disconnect();\n window.removeEventListener('resize', checkOverflow);\n };\n }, [isEditMode, enableMeasurement, enableSelection, selectionOnly]);\n \n const drawingDisabled = disabled || !hasVisibleLayers;\n \n const visibleSelectionModes = SELECTION_MODES.filter(\n mode => !hiddenSelectionTools.includes(mode.id)\n );\n \n const handleGoTo = () => {\n const lat = parseFloat(goToLat.trim());\n const lng = parseFloat(goToLng.trim());\n \n if (isNaN(lat) || isNaN(lng)) {\n toast({ title: 'Invalid coordinates', description: 'Please enter valid latitude and longitude values', variant: 'destructive' });\n return;\n }\n \n if (lat < -90 || lat > 90) {\n toast({ title: 'Invalid latitude', description: 'Latitude must be between -90 and 90', variant: 'destructive' });\n return;\n }\n \n if (lng < -180 || lng > 180) {\n toast({ title: 'Invalid longitude', description: 'Longitude must be between -180 and 180', variant: 'destructive' });\n return;\n }\n \n if (onDropPoint) {\n onDropPoint([lng, lat]);\n } else {\n onGoTo?.([lng, lat]);\n }\n setGoToDialogOpen(false);\n setGoToLat('');\n setGoToLng('');\n };\n\n const handleAddressSearch = async () => {\n if (!goToAddress.trim()) return;\n \n setIsSearching(true);\n try {\n let result: GeocoderResult | null = null;\n \n // Use geocoderProvider if available, otherwise fall back to URL-based geocoding\n if (geocoderProvider) {\n result = await geocoderProvider(goToAddress.trim());\n } else {\n const response = await fetch(\n `${geocodingUrl}?format=json&q=${encodeURIComponent(goToAddress)}&limit=1`\n );\n \n if (!response.ok) throw new Error('Search failed');\n \n const results = await response.json();\n \n if (results.length > 0) {\n const { lon, lat, display_name } = results[0];\n result = {\n lon: parseFloat(lon),\n lat: parseFloat(lat),\n displayName: display_name\n };\n }\n }\n \n if (!result) {\n toast({\n title: 'Location not found',\n description: 'Try a different search term',\n variant: 'destructive'\n });\n return;\n }\n \n const coords: [number, number] = [result.lon, result.lat];\n const shortName = result.displayName.split(',').slice(0, 2).join(',');\n \n if (onDropPoint) {\n onDropPoint(coords, shortName);\n } else {\n onGoTo?.(coords);\n }\n \n setGoToDialogOpen(false);\n setGoToAddress('');\n \n toast({\n title: 'Location found',\n description: shortName\n });\n } catch (error) {\n toast({\n title: 'Search error',\n description: 'Could not search for location. Check your connection.',\n variant: 'destructive'\n });\n } finally {\n setIsSearching(false);\n }\n };\n\n const handleClearAll = () => {\n Modal.confirm({\n title: 'Clear all features?',\n content: `This will remove all ${featureCount} feature${featureCount !== 1 ? 's' : ''} from the map. This action cannot be undone.`,\n okText: 'Clear all',\n okButtonProps: { danger: true },\n cancelText: 'Cancel',\n onOk: onClear,\n });\n };\n\n const getSelectionMenuItems = (): MenuProps['items'] => {\n const items: MenuProps['items'] = visibleSelectionModes.map((mode) => {\n const Icon = mode.icon;\n const isThisModeActive = isSelectionToolActive && selectionMode === mode.id;\n return {\n key: mode.id,\n label: (\n <span className=\"flex items-center gap-2\">\n <Icon className=\"w-4 h-4\" />\n {mode.label}\n </span>\n ),\n className: isThisModeActive ? 'bg-primary/10' : '',\n onClick: () => {\n if (isEditMode) {\n onToggleEditMode();\n }\n setFilterActive(false);\n if (selectionMode === mode.id && isSelectionToolActive) {\n onSelectionToolActiveChange?.(false);\n } else {\n onSelectionModeChange(mode.id);\n onSelectionToolActiveChange?.(true);\n }\n onModeChange('simple_select');\n },\n };\n });\n \n return items;\n };\n\n const getMoreMenuItems = (): MenuProps['items'] => {\n const items: MenuProps['items'] = [];\n \n if (!hiddenDrawingTools.includes('text')) {\n items.push({\n key: 'text',\n label: (\n <div className=\"flex items-center justify-between w-full\">\n <span className=\"flex items-center gap-2\">\n <Type className=\"w-4 h-4\" />\n Add Text\n </span>\n {showShortcutHints && <kbd className=\"px-1.5 py-0.5 text-xs font-mono bg-black/10 dark:bg-white/10 rounded\">T</kbd>}\n </div>\n ),\n disabled: drawingDisabled,\n className: activeMode === 'draw_text' ? 'bg-primary/10' : '',\n onClick: () => onModeChange(activeMode === 'draw_text' ? 'simple_select' : 'draw_text'),\n });\n }\n \n if (!hiddenDrawingTools.includes('arrow')) {\n items.push({\n key: 'arrow',\n label: (\n <div className=\"flex items-center justify-between w-full\">\n <span className=\"flex items-center gap-2\">\n <MoveRight className=\"w-4 h-4\" />\n Draw Arrow\n </span>\n {showShortcutHints && <kbd className=\"px-1.5 py-0.5 text-xs font-mono bg-black/10 dark:bg-white/10 rounded\">W</kbd>}\n </div>\n ),\n disabled: drawingDisabled,\n className: activeMode === 'draw_arrow' ? 'bg-primary/10' : '',\n onClick: () => onModeChange(activeMode === 'draw_arrow' ? 'simple_select' : 'draw_arrow'),\n });\n }\n \n if (!hiddenDrawingTools.includes('circle')) {\n items.push({\n key: 'circle',\n label: (\n <div className=\"flex items-center justify-between w-full\">\n <span className=\"flex items-center gap-2\">\n <Circle className=\"w-4 h-4\" />\n Draw Circle\n </span>\n {showShortcutHints && <kbd className=\"px-1.5 py-0.5 text-xs font-mono bg-black/10 dark:bg-white/10 rounded\">C</kbd>}\n </div>\n ),\n disabled: drawingDisabled,\n className: activeMode === 'draw_circle' ? 'bg-primary/10' : '',\n onClick: () => onModeChange(activeMode === 'draw_circle' ? 'simple_select' : 'draw_circle'),\n });\n }\n \n items.push({ type: 'divider' });\n \n items.push({\n key: 'undo',\n label: (\n <div className=\"flex items-center justify-between w-full\">\n <span className=\"flex items-center gap-2\">\n <Undo2 className=\"w-4 h-4\" />\n Undo\n </span>\n {showShortcutHints && <kbd className=\"px-1.5 py-0.5 text-xs font-mono bg-black/10 dark:bg-white/10 rounded\">Ctrl+Z</kbd>}\n </div>\n ),\n disabled: disabled || !canUndo,\n onClick: onUndo,\n });\n \n items.push({\n key: 'redo',\n label: (\n <div className=\"flex items-center justify-between w-full\">\n <span className=\"flex items-center gap-2\">\n <Redo2 className=\"w-4 h-4\" />\n Redo\n </span>\n {showShortcutHints && <kbd className=\"px-1.5 py-0.5 text-xs font-mono bg-black/10 dark:bg-white/10 rounded\">Ctrl+Y</kbd>}\n </div>\n ),\n disabled: disabled || !canRedo,\n onClick: onRedo,\n });\n \n items.push({ type: 'divider' });\n \n items.push({\n key: 'delete',\n label: (\n <div className=\"flex items-center justify-between w-full text-red-500\">\n <span className=\"flex items-center gap-2\">\n <X className=\"w-4 h-4\" />\n Delete selected ({selectedCount})\n </span>\n {showShortcutHints && <kbd className=\"px-1.5 py-0.5 text-xs font-mono bg-black/10 dark:bg-white/10 rounded\">Del</kbd>}\n </div>\n ),\n disabled: disabled || selectedCount === 0,\n onClick: onDeleteSelected,\n });\n \n items.push({\n key: 'clear',\n label: (\n <div className=\"flex items-center gap-2 text-red-500\">\n <Trash2 className=\"w-4 h-4\" />\n Clear all ({featureCount})\n </div>\n ),\n disabled: disabled || featureCount === 0,\n onClick: handleClearAll,\n });\n \n return items;\n };\n\n const compactOverflowItems = isEditMode && isCompact && !selectionOnly ? (\n <Tooltip title=\"More tools\" placement=\"right\">\n <Dropdown\n menu={{ items: getMoreMenuItems() }}\n trigger={['click']}\n placement=\"bottomRight\"\n >\n <Button\n type=\"text\"\n className=\"relative flex items-center justify-center !w-9 !h-9 !min-w-0 !p-0\"\n aria-label=\"More tools\"\n data-testid=\"button-more-tools\"\n icon={<MoreVertical className=\"w-5 h-5\" />}\n />\n </Dropdown>\n </Tooltip>\n ) : null;\n\n return (\n <div \n ref={toolbarRef}\n className=\"absolute top-4 left-4 z-10 flex flex-col gap-0.5 p-1 bg-background/80 floating-panel rounded-lg shadow-lg border border-border pl-[2px] pr-[2px] pt-[2px] pb-[2px]\"\n role=\"toolbar\"\n aria-label=\"Drawing tools\"\n data-testid=\"toolbar-drawing\"\n >\n {enableSelection && (\n <>\n {expandSelectionTools ? (\n <>\n {visibleSelectionModes.map((mode) => {\n const Icon = mode.icon;\n const isThisModeActive = isSelectionToolActive && selectionMode === mode.id;\n return (\n <Tooltip key={mode.id} title={mode.label} placement=\"right\">\n <Button\n type=\"text\"\n disabled={disabled}\n onClick={() => {\n if (isEditMode) onToggleEditMode();\n if (selectionMode === mode.id && isSelectionToolActive) {\n onSelectionToolActiveChange?.(false);\n } else {\n onSelectionModeChange(mode.id);\n onSelectionToolActiveChange?.(true);\n }\n onModeChange('simple_select');\n }}\n className={cn(\n \"relative transition-all duration-150 flex items-center justify-center !w-9 !h-9 !min-w-0 !p-0\",\n isThisModeActive && \"tool-active bg-primary/10\"\n )}\n aria-label={mode.label}\n data-testid={`button-select-${mode.id}`}\n icon={<Icon className=\"w-5 h-5\" />}\n />\n </Tooltip>\n );\n })}\n </>\n ) : (\n <div className=\"relative flex items-center\">\n <Tooltip title={`${selectionMode.charAt(0).toUpperCase() + selectionMode.slice(1)} Select`} placement=\"right\">\n <Button\n type=\"text\"\n disabled={disabled}\n onClick={() => {\n if (isEditMode) onToggleEditMode();\n if (isSelectionToolActive && !filterActive) {\n onSelectionToolActiveChange?.(false);\n } else {\n setFilterActive(false);\n onSelectionToolActiveChange?.(true);\n }\n onModeChange('simple_select');\n }}\n className={cn(\n \"relative transition-all duration-150 flex items-center justify-center !w-9 !h-9 !min-w-0 !p-0\",\n isSelectionToolActive && selectionMode !== 'click' && !filterActive && \"tool-active bg-primary/10\"\n )}\n aria-label=\"Select Tool\"\n data-testid=\"button-select-tool\"\n >\n {selectionMode === 'click' && <MousePointer2 className=\"w-5 h-5\" />}\n {selectionMode === 'rectangle' && <Square className=\"w-5 h-5\" />}\n {selectionMode === 'polygon' && <Hexagon className=\"w-5 h-5\" />}\n {selectionMode === 'circle' && <Circle className=\"w-5 h-5\" />}\n </Button>\n </Tooltip>\n <Dropdown\n menu={{ items: getSelectionMenuItems() }}\n trigger={['click']}\n placement=\"bottomRight\"\n >\n <button\n disabled={disabled}\n className=\"absolute -bottom-1 -right-1 w-4 h-4 flex items-center justify-center rounded-sm bg-background/80 hover:bg-accent cursor-pointer border-0 p-0\"\n aria-label=\"Switch selection mode\"\n data-testid=\"button-select-mode-switch\"\n onClick={(e) => e.stopPropagation()}\n >\n <ChevronDown className=\"w-3 h-3 opacity-70\" />\n </button>\n </Dropdown>\n </div>\n )}\n \n {showFilterTool && (\n <Tooltip title=\"Filter Area\" placement=\"right\">\n <Button\n type=\"text\"\n disabled={disabled}\n onClick={() => {\n if (isEditMode) onToggleEditMode();\n if (filterActive && isSelectionToolActive) {\n setFilterActive(false);\n onSelectionToolActiveChange?.(false);\n } else {\n setFilterActive(true);\n onSelectionModeChange('rectangle');\n onSelectionToolActiveChange?.(true);\n }\n onModeChange('simple_select');\n }}\n className={cn(\n \"relative transition-all duration-150 flex items-center justify-center !w-9 !h-9 !min-w-0 !p-0\",\n isSelectionToolActive && filterActive && \"tool-active bg-primary/10\"\n )}\n aria-label=\"Filter Area\"\n data-testid=\"button-filter-tool\"\n icon={<Filter className=\"w-5 h-5\" />}\n />\n </Tooltip>\n )}\n\n {showClearFilter && (\n <Tooltip title=\"Clear Filter\" placement=\"right\">\n <Button\n type=\"text\"\n onClick={onClearFilter}\n disabled={disabled}\n className=\"relative transition-all duration-150 text-red-500 hover:text-red-500 flex items-center justify-center !w-9 !h-9 !min-w-0 !p-0\"\n aria-label=\"Clear Filter\"\n data-testid=\"button-clear-filter-toolbar\"\n icon={<X className=\"w-5 h-5\" />}\n />\n </Tooltip>\n )}\n \n <Divider className=\"!my-0.5 !min-w-0\" />\n </>\n )}\n \n {enableMeasurement && (\n <>\n <Tooltip \n title={<span className=\"flex items-center gap-2\">Measure Distance<kbd className=\"px-1.5 py-0.5 text-xs font-mono bg-black/20 rounded\">M</kbd></span>} \n placement=\"right\"\n >\n <Button\n type=\"text\"\n onClick={() => onMeasureModeChange(measureMode === 'distance' ? 'none' : 'distance')}\n disabled={disabled}\n className={cn(\n \"relative transition-all duration-150 flex items-center justify-center !w-9 !h-9 !min-w-0 !p-0\",\n measureMode === 'distance' && \"tool-active bg-primary/10\"\n )}\n aria-label=\"Measure Distance\"\n aria-pressed={measureMode === 'distance'}\n data-testid=\"button-measure-distance\"\n icon={<Ruler className=\"w-5 h-5\" />}\n />\n </Tooltip>\n \n <Tooltip \n title={<span className=\"flex items-center gap-2\">Measure Area<kbd className=\"px-1.5 py-0.5 text-xs font-mono bg-black/20 rounded\">A</kbd></span>} \n placement=\"right\"\n >\n <Button\n type=\"text\"\n onClick={() => onMeasureModeChange(measureMode === 'area' ? 'none' : 'area')}\n disabled={disabled}\n className={cn(\n \"relative transition-all duration-150 flex items-center justify-center !w-9 !h-9 !min-w-0 !p-0\",\n measureMode === 'area' && \"tool-active bg-primary/10\"\n )}\n aria-label=\"Measure Area\"\n aria-pressed={measureMode === 'area'}\n data-testid=\"button-measure-area\"\n icon={<Move className=\"w-5 h-5\" />}\n />\n </Tooltip>\n\n <Divider className=\"!my-0.5 !min-w-0\" />\n </>\n )}\n\n {onGoTo && (\n <>\n <Tooltip \n title=\"Go To\" \n placement=\"right\"\n >\n <Button\n type=\"text\"\n onClick={() => setGoToDialogOpen(true)}\n disabled={disabled}\n className=\"relative transition-all duration-150 flex items-center justify-center !w-9 !h-9 !min-w-0 !p-0\"\n aria-label=\"Go To\"\n data-testid=\"button-goto-address\"\n icon={<Navigation className=\"w-5 h-5\" />}\n />\n </Tooltip>\n {!enableMeasurement && <Divider className=\"!my-0.5 !min-w-0\" />}\n </>\n )}\n \n {!selectionOnly && (\n <Tooltip \n title={\n !hasEditableLayer && !isEditMode ? (\n <div className=\"flex flex-col gap-1 max-w-48\">\n <span className=\"text-amber-500 font-medium\">No editable layer</span>\n <span className=\"text-xs\">Select an editable layer with the pencil icon to enable editing</span>\n </div>\n ) : showShortcutHints ? (\n <span className=\"flex items-center gap-2\">Edit Mode<kbd className=\"px-1.5 py-0.5 text-xs font-mono bg-black/20 rounded\">E</kbd></span>\n ) : (\n \"Edit Mode\"\n )\n } \n placement=\"right\"\n >\n <Button\n type=\"text\"\n onClick={onToggleEditMode}\n disabled={disabled || (!isEditMode && !hasEditableLayer)}\n className={cn(\n \"relative transition-all duration-150 flex items-center justify-center !w-9 !h-9 !min-w-0 !p-0\",\n isEditMode && \"tool-active bg-primary/10\"\n )}\n aria-label=\"Edit Mode\"\n aria-pressed={isEditMode}\n data-testid=\"button-edit-mode\"\n icon={<Pencil className=\"w-5 h-5\" />}\n />\n </Tooltip>\n )}\n \n {isEditMode && !selectionOnly && (\n <>\n <Divider className=\"!my-0.5 !min-w-0\" />\n \n {/* Database Search button - shown when search engine is available */}\n {onSearchEngineRequest && (\n <Tooltip title=\"Search Database\" placement=\"right\">\n <Button\n type=\"text\"\n onClick={onSearchEngineRequest}\n disabled={drawingDisabled}\n className=\"relative transition-all duration-150 flex items-center justify-center !w-9 !h-9 !min-w-0 !p-0\"\n aria-label=\"Search Database\"\n data-testid=\"button-search-database\"\n icon={\n <div className=\"relative w-5 h-5\">\n <Database className=\"w-5 h-5\" />\n <Search className=\"w-3 h-3 absolute -bottom-0.5 right-[-4px] stroke-[2.5]\" />\n </div>\n }\n />\n </Tooltip>\n )}\n \n {/* Drop Point button */}\n {!hiddenDrawingTools.includes('point') && (\n <ToolButton\n mode=\"draw_point\"\n activeMode={activeMode}\n onModeChange={onModeChange}\n icon={<MapPin className=\"w-5 h-5\" />}\n label=\"Drop Point\"\n shortcut=\"P\"\n disabled={drawingDisabled}\n showShortcutHint={showShortcutHints}\n />\n )}\n \n {!hiddenDrawingTools.includes('line') && (\n <ToolButton\n mode=\"draw_line_string\"\n activeMode={activeMode}\n onModeChange={onModeChange}\n icon={<Minus className=\"w-5 h-5\" />}\n label=\"Draw Line\"\n shortcut=\"L\"\n disabled={drawingDisabled}\n showShortcutHint={showShortcutHints}\n />\n )}\n \n {!hiddenDrawingTools.includes('polygon') && (\n <Dropdown\n menu={{\n items: [\n {\n key: 'polygon',\n label: (\n <span className=\"flex items-center gap-2\">\n <Pentagon className=\"w-4 h-4\" />\n Draw Polygon\n {showShortcutHints && <kbd className=\"ml-auto px-1.5 py-0.5 text-xs font-mono bg-black/10 dark:bg-white/10 rounded\">G</kbd>}\n </span>\n ),\n onClick: () => onModeChange('draw_polygon'),\n },\n {\n key: 'rectangle',\n label: (\n <span className=\"flex items-center gap-2\">\n <Square className=\"w-4 h-4\" />\n Draw Rectangle\n {showShortcutHints && <kbd className=\"ml-auto px-1.5 py-0.5 text-xs font-mono bg-black/10 dark:bg-white/10 rounded\">B</kbd>}\n </span>\n ),\n onClick: () => onModeChange('draw_rectangle'),\n },\n ],\n }}\n trigger={['click']}\n placement=\"bottomRight\"\n disabled={drawingDisabled}\n >\n <Tooltip \n title={showShortcutHints\n ? <span className=\"flex items-center gap-2\">Draw Polygon/Rectangle<kbd className=\"px-1.5 py-0.5 text-xs font-mono bg-black/20 rounded\">G</kbd></span>\n : \"Draw Polygon/Rectangle\"\n } \n placement=\"right\"\n >\n <Button\n type=\"text\"\n disabled={drawingDisabled}\n className={cn(\n \"relative transition-all duration-150 flex items-center justify-center !w-9 !h-9 !min-w-0 !p-0\",\n (activeMode === 'draw_polygon' || activeMode === 'draw_rectangle') && \"tool-active bg-primary/10\"\n )}\n aria-label=\"Draw Polygon or Rectangle\"\n data-testid=\"button-tool-polygon-menu\"\n icon={\n <div className=\"relative\">\n {activeMode === 'draw_rectangle' ? <Square className=\"w-5 h-5\" /> : <Pentagon className=\"w-5 h-5\" />}\n <ChevronDown className=\"w-2.5 h-2.5 absolute -bottom-0.5 -right-1\" />\n </div>\n }\n />\n </Tooltip>\n </Dropdown>\n )}\n \n {!isCompact && (\n <>\n <Divider className=\"!my-0.5 !min-w-0\" />\n \n {!hiddenDrawingTools.includes('text') && (\n <ToolButton\n mode=\"draw_text\"\n activeMode={activeMode}\n onModeChange={onModeChange}\n icon={<Type className=\"w-5 h-5\" />}\n label=\"Add Text\"\n shortcut=\"T\"\n disabled={drawingDisabled}\n showShortcutHint={showShortcutHints}\n />\n )}\n \n {!hiddenDrawingTools.includes('arrow') && (\n <ToolButton\n mode=\"draw_arrow\"\n activeMode={activeMode}\n onModeChange={onModeChange}\n icon={<MoveRight className=\"w-5 h-5\" />}\n label=\"Draw Arrow\"\n shortcut=\"W\"\n disabled={drawingDisabled}\n showShortcutHint={showShortcutHints}\n />\n )}\n \n {!hiddenDrawingTools.includes('circle') && (\n <ToolButton\n mode=\"draw_circle\"\n activeMode={activeMode}\n onModeChange={onModeChange}\n icon={<Circle className=\"w-5 h-5\" />}\n label=\"Draw Circle\"\n shortcut=\"C\"\n disabled={drawingDisabled}\n showShortcutHint={showShortcutHints}\n />\n )}\n \n <Divider className=\"!my-0.5 !min-w-0\" />\n \n <Tooltip \n title={showShortcutHints\n ? <span className=\"flex items-center gap-2\">Undo<kbd className=\"px-1.5 py-0.5 text-xs font-mono bg-black/20 rounded\">Ctrl+Z</kbd></span>\n : \"Undo\"\n } \n placement=\"right\"\n >\n <Button\n type=\"text\"\n onClick={onUndo}\n disabled={disabled || !canUndo}\n aria-label=\"Undo\"\n data-testid=\"button-undo\"\n className=\"flex items-center justify-center !w-9 !h-9 !min-w-0 !p-0\"\n icon={<Undo2 className=\"w-5 h-5\" />}\n />\n </Tooltip>\n \n <Tooltip \n title={showShortcutHints\n ? <span className=\"flex items-center gap-2\">Redo<kbd className=\"px-1.5 py-0.5 text-xs font-mono bg-black/20 rounded\">Ctrl+Y</kbd></span>\n : \"Redo\"\n } \n placement=\"right\"\n >\n <Button\n type=\"text\"\n onClick={onRedo}\n disabled={disabled || !canRedo}\n aria-label=\"Redo\"\n data-testid=\"button-redo\"\n className=\"flex items-center justify-center !w-9 !h-9 !min-w-0 !p-0\"\n icon={<Redo2 className=\"w-5 h-5\" />}\n />\n </Tooltip>\n \n <Tooltip \n title={showShortcutHints\n ? <span className=\"flex items-center gap-2\">Delete selected ({selectedCount})<kbd className=\"px-1.5 py-0.5 text-xs font-mono bg-black/20 rounded\">Del</kbd></span>\n : `Delete selected (${selectedCount})`\n } \n placement=\"right\"\n >\n <Button\n type=\"text\"\n onClick={onDeleteSelected}\n disabled={disabled || selectedCount === 0}\n className=\"text-red-500 hover:text-red-500 flex items-center justify-center !w-9 !h-9 !min-w-0 !p-0\"\n aria-label=\"Delete selected features\"\n data-testid=\"button-delete-selected\"\n icon={<X className=\"w-5 h-5\" />}\n />\n </Tooltip>\n \n <Tooltip title=\"Clear all features\" placement=\"right\">\n <Button\n type=\"text\"\n onClick={handleClearAll}\n disabled={disabled || featureCount === 0}\n className=\"text-red-500 hover:text-red-500 flex items-center justify-center !w-9 !h-9 !min-w-0 !p-0\"\n aria-label=\"Clear all features\"\n data-testid=\"button-clear-all\"\n icon={<Trash2 className=\"w-5 h-5\" />}\n />\n </Tooltip>\n </>\n )}\n \n {compactOverflowItems}\n </>\n )}\n \n <Modal\n open={goToDialogOpen}\n onCancel={() => setGoToDialogOpen(false)}\n title={onDropPoint ? \"Drop Point at Location\" : \"Go To Location\"}\n footer={null}\n width={400}\n >\n <Tabs\n defaultActiveKey=\"address\"\n items={[\n {\n key: 'address',\n label: 'Search Address',\n children: (\n <div className=\"space-y-4 pt-2\">\n <p className=\"text-muted-foreground text-sm\">\n Search for a place to {onDropPoint ? 'drop a point there' : 'navigate there'}.\n </p>\n <div className=\"flex gap-2\">\n <Input\n placeholder=\"e.g. Paris, France or 123 Main St\"\n value={goToAddress}\n onChange={(e) => setGoToAddress(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleAddressSearch();\n }}\n disabled={isSearching}\n data-testid=\"input-goto-address\"\n />\n <Button\n type=\"primary\"\n onClick={handleAddressSearch}\n disabled={isSearching || !goToAddress.trim()}\n data-testid=\"button-search-address\"\n icon={isSearching ? <Loader2 className=\"w-4 h-4 animate-spin\" /> : <Search className=\"w-4 h-4\" />}\n />\n </div>\n </div>\n ),\n },\n {\n key: 'coordinates',\n label: 'Coordinates',\n children: (\n <div className=\"space-y-4 pt-2\">\n <p className=\"text-muted-foreground text-sm\">\n Enter coordinates to {onDropPoint ? 'drop a point' : 'navigate'} to a specific location.\n </p>\n <div className=\"grid grid-cols-2 gap-3\">\n <div className=\"space-y-2\">\n <label htmlFor=\"goto-lat\" className=\"text-sm font-medium\">Latitude</label>\n <Input\n id=\"goto-lat\"\n type=\"number\"\n step=\"any\"\n placeholder=\"-90 to 90\"\n value={goToLat}\n onChange={(e) => setGoToLat(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleGoTo();\n }}\n data-testid=\"input-goto-lat\"\n />\n </div>\n <div className=\"space-y-2\">\n <label htmlFor=\"goto-lng\" className=\"text-sm font-medium\">Longitude</label>\n <Input\n id=\"goto-lng\"\n type=\"number\"\n step=\"any\"\n placeholder=\"-180 to 180\"\n value={goToLng}\n onChange={(e) => setGoToLng(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleGoTo();\n }}\n data-testid=\"input-goto-lng\"\n />\n </div>\n </div>\n <div className=\"flex justify-end gap-2 pt-2\">\n <Button onClick={() => setGoToDialogOpen(false)} data-testid=\"button-goto-cancel\">\n Cancel\n </Button>\n <Button type=\"primary\" onClick={handleGoTo} data-testid=\"button-goto-navigate\">\n {onDropPoint ? 'Drop Point' : 'Go To'}\n </Button>\n </div>\n </div>\n ),\n },\n ]}\n />\n </Modal>\n </div>\n );\n}\n","import { Button, Popover, Input } from 'antd';\n\nconst PRESET_COLORS = [\n '#3b82f6', \n '#ef4444', \n '#22c55e', \n '#f59e0b', \n '#8b5cf6', \n '#06b6d4', \n '#ec4899', \n '#6366f1', \n '#14b8a6', \n '#f97316', \n];\n\ninterface ColorPickerPopoverProps {\n value: string;\n onChange: (color: string) => void;\n testId?: string;\n}\n\nexport function ColorPickerPopover({ value, onChange, testId }: ColorPickerPopoverProps) {\n const popoverContent = (\n <div>\n <div className=\"grid grid-cols-5 gap-1\">\n {PRESET_COLORS.map((color) => (\n <button\n key={color}\n type=\"button\"\n className=\"w-6 h-6 rounded-sm border border-border hover:scale-110 transition-transform\"\n style={{ backgroundColor: color }}\n onClick={() => onChange(color)}\n data-testid={testId ? `button-${testId}-${color.replace('#', '')}` : undefined}\n />\n ))}\n </div>\n <div className=\"mt-2 flex items-center gap-2\">\n <input\n type=\"color\"\n value={value}\n onChange={(e) => onChange(e.target.value)}\n className=\"h-7 w-10 p-0 border-0 cursor-pointer\"\n data-testid={testId ? `input-${testId}-picker` : undefined}\n />\n <Input\n type=\"text\"\n value={value}\n onChange={(e) => onChange(e.target.value)}\n className=\"!h-7 flex-1 text-xs font-mono\"\n data-testid={testId ? `input-${testId}` : undefined}\n />\n </div>\n </div>\n );\n\n return (\n <Popover \n content={popoverContent} \n trigger=\"click\"\n placement=\"bottomLeft\"\n overlayClassName=\"z-[10001]\"\n >\n <Button \n type=\"default\"\n size=\"small\"\n className=\"!h-7 !w-16 !p-1\"\n data-testid={testId ? `button-${testId}` : undefined}\n >\n <span \n className=\"w-full h-full rounded-sm block\"\n style={{ backgroundColor: value }}\n />\n </Button>\n </Popover>\n );\n}\n\nexport { PRESET_COLORS };\n","import { useState, useMemo, useCallback } from 'react';\nimport { Button, Modal, Input } from 'antd';\nimport { \n MapPin, Home, Building2, Store, Factory, Warehouse, Church,\n Hospital, School, GraduationCap, Library, Landmark, Castle,\n Car, Bus, Train, Plane, Ship, Bike, Fuel,\n Utensils, Coffee, Beer, Wine, Pizza, IceCream,\n Trees, Mountain, Waves, Sun, Cloud, Umbrella,\n Heart, Star, Flag, AlertTriangle, Info, HelpCircle,\n Camera, Music, Film, Gamepad2, Trophy, Medal,\n Briefcase, Wrench, Hammer, Scissors, Paintbrush, Palette,\n ShoppingCart, Gift, Package, CreditCard, Wallet,\n Phone, Mail, Globe, Wifi, Radio, Tv,\n User, Users, Baby, Dog, Cat, Bird,\n Flower2, Leaf, Apple, Carrot, Egg,\n Tent, Compass, Anchor, Navigation,\n CrossIcon, PlusCircle, MinusCircle, CheckCircle, XCircle,\n Clock, Calendar, Bookmark, Tag, Zap, Flame,\n Lock, Key, Shield, Eye, Search,\n Circle, Square, Triangle, Hexagon, Octagon, Pentagon,\n ArrowUp, ArrowDown, ArrowLeft, ArrowRight,\n type LucideIcon\n} from 'lucide-react';\n\ninterface IconDef {\n id: string;\n name: string;\n icon: LucideIcon;\n category: string;\n}\n\nconst ICONS: IconDef[] = [\n // Location & Places\n { id: 'map-pin', name: 'Map Pin', icon: MapPin, category: 'places' },\n { id: 'home', name: 'Home', icon: Home, category: 'places' },\n { id: 'building', name: 'Building', icon: Building2, category: 'places' },\n { id: 'store', name: 'Store', icon: Store, category: 'places' },\n { id: 'factory', name: 'Factory', icon: Factory, category: 'places' },\n { id: 'warehouse', name: 'Warehouse', icon: Warehouse, category: 'places' },\n { id: 'church', name: 'Church', icon: Church, category: 'places' },\n { id: 'hospital', name: 'Hospital', icon: Hospital, category: 'places' },\n { id: 'school', name: 'School', icon: School, category: 'places' },\n { id: 'graduation', name: 'University', icon: GraduationCap, category: 'places' },\n { id: 'library', name: 'Library', icon: Library, category: 'places' },\n { id: 'landmark', name: 'Landmark', icon: Landmark, category: 'places' },\n { id: 'castle', name: 'Castle', icon: Castle, category: 'places' },\n \n // Transport\n { id: 'car', name: 'Car', icon: Car, category: 'transport' },\n { id: 'bus', name: 'Bus', icon: Bus, category: 'transport' },\n { id: 'train', name: 'Train', icon: Train, category: 'transport' },\n { id: 'plane', name: 'Plane', icon: Plane, category: 'transport' },\n { id: 'ship', name: 'Ship', icon: Ship, category: 'transport' },\n { id: 'bike', name: 'Bike', icon: Bike, category: 'transport' },\n { id: 'fuel', name: 'Gas Station', icon: Fuel, category: 'transport' },\n \n // Food & Drink\n { id: 'utensils', name: 'Restaurant', icon: Utensils, category: 'food' },\n { id: 'coffee', name: 'Coffee', icon: Coffee, category: 'food' },\n { id: 'beer', name: 'Bar', icon: Beer, category: 'food' },\n { id: 'wine', name: 'Wine', icon: Wine, category: 'food' },\n { id: 'pizza', name: 'Pizza', icon: Pizza, category: 'food' },\n { id: 'ice-cream', name: 'Ice Cream', icon: IceCream, category: 'food' },\n \n // Nature\n { id: 'trees', name: 'Forest', icon: Trees, category: 'nature' },\n { id: 'mountain', name: 'Mountain', icon: Mountain, category: 'nature' },\n { id: 'waves', name: 'Water', icon: Waves, category: 'nature' },\n { id: 'sun', name: 'Sun', icon: Sun, category: 'nature' },\n { id: 'cloud', name: 'Cloud', icon: Cloud, category: 'nature' },\n { id: 'umbrella', name: 'Umbrella', icon: Umbrella, category: 'nature' },\n { id: 'flower', name: 'Flower', icon: Flower2, category: 'nature' },\n { id: 'leaf', name: 'Leaf', icon: Leaf, category: 'nature' },\n \n // Symbols\n { id: 'heart', name: 'Heart', icon: Heart, category: 'symbols' },\n { id: 'star', name: 'Star', icon: Star, category: 'symbols' },\n { id: 'flag', name: 'Flag', icon: Flag, category: 'symbols' },\n { id: 'alert', name: 'Warning', icon: AlertTriangle, category: 'symbols' },\n { id: 'info', name: 'Info', icon: Info, category: 'symbols' },\n { id: 'help', name: 'Help', icon: HelpCircle, category: 'symbols' },\n { id: 'check', name: 'Check', icon: CheckCircle, category: 'symbols' },\n { id: 'x', name: 'X', icon: XCircle, category: 'symbols' },\n { id: 'plus', name: 'Plus', icon: PlusCircle, category: 'symbols' },\n { id: 'minus', name: 'Minus', icon: MinusCircle, category: 'symbols' },\n { id: 'zap', name: 'Zap', icon: Zap, category: 'symbols' },\n { id: 'flame', name: 'Flame', icon: Flame, category: 'symbols' },\n \n // Activities\n { id: 'camera', name: 'Camera', icon: Camera, category: 'activities' },\n { id: 'music', name: 'Music', icon: Music, category: 'activities' },\n { id: 'film', name: 'Cinema', icon: Film, category: 'activities' },\n { id: 'gamepad', name: 'Gaming', icon: Gamepad2, category: 'activities' },\n { id: 'trophy', name: 'Trophy', icon: Trophy, category: 'activities' },\n { id: 'medal', name: 'Medal', icon: Medal, category: 'activities' },\n { id: 'tent', name: 'Camping', icon: Tent, category: 'activities' },\n { id: 'compass', name: 'Compass', icon: Compass, category: 'activities' },\n \n // Work & Tools\n { id: 'briefcase', name: 'Office', icon: Briefcase, category: 'work' },\n { id: 'wrench', name: 'Repair', icon: Wrench, category: 'work' },\n { id: 'hammer', name: 'Construction', icon: Hammer, category: 'work' },\n { id: 'scissors', name: 'Scissors', icon: Scissors, category: 'work' },\n { id: 'paintbrush', name: 'Art', icon: Paintbrush, category: 'work' },\n { id: 'palette', name: 'Palette', icon: Palette, category: 'work' },\n \n // Shopping\n { id: 'cart', name: 'Shopping', icon: ShoppingCart, category: 'shopping' },\n { id: 'gift', name: 'Gift', icon: Gift, category: 'shopping' },\n { id: 'package', name: 'Package', icon: Package, category: 'shopping' },\n { id: 'credit-card', name: 'Payment', icon: CreditCard, category: 'shopping' },\n { id: 'wallet', name: 'Wallet', icon: Wallet, category: 'shopping' },\n \n // Communication\n { id: 'phone', name: 'Phone', icon: Phone, category: 'communication' },\n { id: 'mail', name: 'Mail', icon: Mail, category: 'communication' },\n { id: 'globe', name: 'Web', icon: Globe, category: 'communication' },\n { id: 'wifi', name: 'WiFi', icon: Wifi, category: 'communication' },\n { id: 'radio', name: 'Radio', icon: Radio, category: 'communication' },\n { id: 'tv', name: 'TV', icon: Tv, category: 'communication' },\n \n // People & Animals\n { id: 'user', name: 'Person', icon: User, category: 'people' },\n { id: 'users', name: 'Group', icon: Users, category: 'people' },\n { id: 'baby', name: 'Baby', icon: Baby, category: 'people' },\n { id: 'dog', name: 'Dog', icon: Dog, category: 'people' },\n { id: 'cat', name: 'Cat', icon: Cat, category: 'people' },\n { id: 'bird', name: 'Bird', icon: Bird, category: 'people' },\n \n // Food Items\n { id: 'apple', name: 'Apple', icon: Apple, category: 'food' },\n { id: 'carrot', name: 'Carrot', icon: Carrot, category: 'food' },\n { id: 'egg', name: 'Egg', icon: Egg, category: 'food' },\n \n // Maritime\n { id: 'anchor', name: 'Anchor', icon: Anchor, category: 'maritime' },\n { id: 'navigation', name: 'Navigation', icon: Navigation, category: 'maritime' },\n \n // Security\n { id: 'lock', name: 'Lock', icon: Lock, category: 'security' },\n { id: 'key', name: 'Key', icon: Key, category: 'security' },\n { id: 'shield', name: 'Shield', icon: Shield, category: 'security' },\n { id: 'eye', name: 'Eye', icon: Eye, category: 'security' },\n { id: 'search', name: 'Search', icon: Search, category: 'security' },\n \n // Time\n { id: 'clock', name: 'Clock', icon: Clock, category: 'time' },\n { id: 'calendar', name: 'Calendar', icon: Calendar, category: 'time' },\n { id: 'bookmark', name: 'Bookmark', icon: Bookmark, category: 'time' },\n { id: 'tag', name: 'Tag', icon: Tag, category: 'time' },\n \n // Shapes\n { id: 'circle', name: 'Circle', icon: Circle, category: 'shapes' },\n { id: 'square', name: 'Square', icon: Square, category: 'shapes' },\n { id: 'triangle', name: 'Triangle', icon: Triangle, category: 'shapes' },\n { id: 'hexagon', name: 'Hexagon', icon: Hexagon, category: 'shapes' },\n { id: 'octagon', name: 'Octagon', icon: Octagon, category: 'shapes' },\n { id: 'pentagon', name: 'Pentagon', icon: Pentagon, category: 'shapes' },\n \n // Arrows\n { id: 'arrow-up', name: 'Arrow Up', icon: ArrowUp, category: 'arrows' },\n { id: 'arrow-down', name: 'Arrow Down', icon: ArrowDown, category: 'arrows' },\n { id: 'arrow-left', name: 'Arrow Left', icon: ArrowLeft, category: 'arrows' },\n { id: 'arrow-right', name: 'Arrow Right', icon: ArrowRight, category: 'arrows' },\n];\n\nconst CATEGORIES = [\n { id: 'places', label: 'Places' },\n { id: 'transport', label: 'Transport' },\n { id: 'food', label: 'Food' },\n { id: 'nature', label: 'Nature' },\n { id: 'symbols', label: 'Symbols' },\n { id: 'activities', label: 'Activities' },\n { id: 'work', label: 'Work' },\n { id: 'shopping', label: 'Shopping' },\n { id: 'communication', label: 'Communication' },\n { id: 'people', label: 'People' },\n { id: 'maritime', label: 'Maritime' },\n { id: 'security', label: 'Security' },\n { id: 'time', label: 'Time' },\n { id: 'shapes', label: 'Shapes' },\n { id: 'arrows', label: 'Arrows' },\n];\n\n// Map of icon IDs to their components for rendering on the map\nconst ICON_MAP = new Map<string, LucideIcon>(ICONS.map(i => [i.id, i.icon]));\n\ninterface IconPickerProps {\n value: string;\n onChange: (icon: string) => void;\n disabled?: boolean;\n}\n\nexport function IconPicker({ value, onChange, disabled = false }: IconPickerProps) {\n const [open, setOpen] = useState(false);\n const [search, setSearch] = useState('');\n const [activeCategory, setActiveCategory] = useState<string | null>(null);\n\n const filteredIcons = useMemo(() => {\n let result = ICONS;\n \n if (activeCategory) {\n result = result.filter(i => i.category === activeCategory);\n }\n \n if (search.trim()) {\n const searchLower = search.toLowerCase().trim();\n result = result.filter(i => \n i.name.toLowerCase().includes(searchLower) ||\n i.id.toLowerCase().includes(searchLower) ||\n i.category.toLowerCase().includes(searchLower)\n );\n }\n \n return result;\n }, [activeCategory, search]);\n\n const handleSelect = useCallback((iconId: string) => {\n onChange(iconId);\n setOpen(false);\n }, [onChange]);\n\n const selectedIcon = useMemo(() => {\n return ICONS.find(i => i.id === value);\n }, [value]);\n\n const SelectedIconComponent = selectedIcon?.icon;\n\n return (\n <>\n <Button\n type=\"default\"\n size=\"small\"\n disabled={disabled}\n onClick={() => setOpen(true)}\n className=\"!w-10 !h-8 !p-0 overflow-hidden\"\n data-testid=\"button-icon-picker\"\n >\n {SelectedIconComponent ? (\n <SelectedIconComponent className=\"w-5 h-5\" />\n ) : (\n <MapPin className=\"w-4 h-4 text-muted-foreground\" />\n )}\n </Button>\n \n <Modal\n open={open}\n onCancel={() => setOpen(false)}\n title=\"Select Icon\"\n footer={null}\n width={600}\n className=\"icon-picker-modal\"\n styles={{ body: { maxHeight: '70vh', display: 'flex', flexDirection: 'column', padding: 0 } }}\n data-testid=\"dialog-icon-picker\"\n >\n <div className=\"px-4 pb-2 space-y-2 shrink-0 pt-2\">\n <Input\n placeholder=\"Search icons...\"\n value={search}\n onChange={(e) => {\n setSearch(e.target.value);\n if (e.target.value) setActiveCategory(null);\n }}\n className=\"h-9\"\n data-testid=\"input-icon-search\"\n autoFocus\n />\n \n <div className=\"overflow-x-auto whitespace-nowrap\">\n <div className=\"flex gap-1 pb-2\">\n <Button\n type={activeCategory === null && !search ? \"primary\" : \"text\"}\n size=\"small\"\n className=\"!h-7 text-xs !px-3 shrink-0\"\n onClick={() => { setActiveCategory(null); setSearch(''); }}\n data-testid=\"button-category-all\"\n >\n All ({ICONS.length})\n </Button>\n {CATEGORIES.map(cat => {\n const count = ICONS.filter(i => i.category === cat.id).length;\n return (\n <Button\n key={cat.id}\n type={activeCategory === cat.id ? \"primary\" : \"text\"}\n size=\"small\"\n className=\"!h-7 text-xs !px-3 shrink-0\"\n onClick={() => { setActiveCategory(cat.id); setSearch(''); }}\n data-testid={`button-category-${cat.id}`}\n >\n {cat.label} ({count})\n </Button>\n );\n })}\n </div>\n </div>\n </div>\n \n <div \n className=\"flex-1 overflow-y-auto px-4 pb-4 min-h-0\"\n style={{ maxHeight: '400px' }}\n >\n <div className=\"grid grid-cols-8 sm:grid-cols-10 md:grid-cols-12 gap-1\">\n {filteredIcons.map((iconDef) => {\n const IconComponent = iconDef.icon;\n return (\n <Button\n key={iconDef.id}\n type={value === iconDef.id ? \"primary\" : \"text\"}\n size=\"small\"\n className=\"!w-10 !h-10 !p-1\"\n onClick={() => handleSelect(iconDef.id)}\n title={iconDef.name}\n data-testid={`button-icon-${iconDef.id}`}\n >\n <IconComponent className=\"w-5 h-5\" />\n </Button>\n );\n })}\n </div>\n {filteredIcons.length === 0 && (\n <div className=\"text-center text-muted-foreground text-sm py-12\">\n No icons found for \"{search}\"\n </div>\n )}\n </div>\n \n <div className=\"px-4 py-3 border-t shrink-0 flex items-center justify-between gap-2\">\n {selectedIcon ? (\n <div className=\"flex items-center gap-2 text-sm text-muted-foreground min-w-0\">\n {SelectedIconComponent && <SelectedIconComponent className=\"w-5 h-5 shrink-0\" />}\n <span className=\"truncate\">{selectedIcon.name}</span>\n </div>\n ) : (\n <span className=\"text-sm text-muted-foreground\">No icon selected</span>\n )}\n <div className=\"flex gap-2 shrink-0\">\n {value && (\n <Button\n type=\"default\"\n size=\"small\"\n onClick={() => { onChange(''); setOpen(false); }}\n data-testid=\"button-clear-icon\"\n >\n Clear\n </Button>\n )}\n <Button\n type=\"text\"\n size=\"small\"\n onClick={() => setOpen(false)}\n data-testid=\"button-close-icon-picker\"\n >\n Cancel\n </Button>\n </div>\n </div>\n </Modal>\n </>\n );\n}\n\n// Export utilities for rendering icons on the map\nexport function getIconComponent(iconId: string): LucideIcon | null {\n return ICON_MAP.get(iconId) || null;\n}\n\nexport function isValidIconId(value: string): boolean {\n return ICON_MAP.has(value);\n}\n\nexport { ICONS, ICON_MAP };\nexport type { IconDef };\n","import { useState, useCallback } from 'react';\nimport { Layers, Eye, EyeOff, Plus, Trash2, ChevronDown, ChevronRight, Pencil, MoreHorizontal, Download, Upload, Map, Satellite, Focus, Type, Lock, FolderOpen, Smile, Box, Database, Search } from 'lucide-react';\nimport { Button, Input, Divider, Dropdown, Modal, Select, Switch, Slider, Tooltip, Tag } from 'antd';\nimport { ColorPickerPopover } from '@/components/color-picker-popover';\nimport { IconPicker } from '@/components/icon-picker';\n\nexport type BuiltInMapStyle = 'streets' | 'satellite' | 'dark';\nexport type MapStyle = BuiltInMapStyle | (string & {});\n\nexport const MAP_STYLES: { id: MapStyle; name: string; icon: typeof Map }[] = [\n { id: 'streets', name: 'Streets', icon: Map },\n { id: 'satellite', name: 'Satellite', icon: Satellite },\n { id: 'dark', name: 'Dark', icon: Map },\n];\n\nexport interface TraceConfig {\n enabled: boolean;\n groupByField: string | null;\n}\n\nexport interface HeatmapConfig {\n enabled: boolean;\n intensity: number;\n radius: number;\n hideFeatures?: boolean;\n}\n\nexport interface ClusterConfig {\n enabled: boolean;\n groupByField: string | null;\n showPointDots?: boolean;\n}\n\nexport type LabelMode = 'standard' | 'field' | 'fixed';\nexport type SizeMode = 'standard' | 'field' | 'override';\nexport type ColorMode = 'standard' | 'field' | 'fixed';\n\nexport interface LabelConfig {\n mode: LabelMode;\n fieldName?: string;\n fixedText?: string;\n}\n\nexport interface SizeConfig {\n mode: SizeMode;\n fieldName?: string;\n overrideValue?: number;\n}\n\nexport interface ColorConfig {\n mode: ColorMode;\n fieldName?: string;\n fixedColor?: string;\n}\n\nexport interface IconConfig {\n enabled: boolean;\n icon: string;\n size: number;\n}\n\nexport interface VisualConfig {\n label?: LabelConfig;\n size?: SizeConfig;\n color?: ColorConfig;\n icon?: IconConfig;\n}\n\nexport type AltitudeDisplayMode = '3d' | 'flat' | 'both';\n\nexport interface Layer {\n id: string;\n name: string;\n visible: boolean;\n featureIds: string[];\n readOnly?: boolean;\n traceConfig?: TraceConfig;\n heatmapConfig?: HeatmapConfig;\n clusterConfig?: ClusterConfig;\n visualConfig?: VisualConfig;\n altitudeDisplayMode?: AltitudeDisplayMode;\n hasAltitudeData?: boolean;\n}\n\nexport interface AutoLabelConfig {\n enabled: boolean;\n threshold: number;\n}\n\ninterface LayersPanelProps {\n layers: Layer[];\n onAddLayer: (name: string) => void;\n onRemoveLayer: (layerId: string) => void;\n onRenameLayer: (layerId: string, name: string) => void;\n onToggleLayerVisibility: (layerId: string) => void;\n onMoveFeatureToLayer: (featureId: string, layerId: string) => void;\n selectedFeatureIds: string[];\n getFeatureCount: (layerId: string) => number;\n /** Get count of unsaved features in a layer (for displaying unsaved badge) */\n getLayerUnsavedCount?: (layerId: string) => number;\n /** Get total count of unsaved features across all layers (for map-level indicator) */\n getMapUnsavedCount?: () => number;\n activeEditingLayerId: string;\n onSetActiveEditingLayer: (layerId: string) => void;\n onSaveLayerGeoJSON: (layerId: string) => void;\n onLoadLayerGeoJSON: (layerId: string) => void;\n onLoadNewLayerGeoJSON: () => void;\n onSaveAllGeoJSON: () => void;\n onSearchAndAddToNewLayer?: () => Promise<void>;\n onWorkspaceLoad?: (layerId: string) => Promise<void>;\n onWorkspaceSave?: (layerId: string) => Promise<void>;\n onFitToFeatures?: () => void;\n onFitToLayerFeatures?: (layerId: string) => void;\n currentMapStyle: MapStyle;\n onMapStyleChange: (style: MapStyle) => void;\n onUpdateTraceConfig: (layerId: string, config: TraceConfig) => void;\n getAvailableTraceFields: (layerId: string) => string[];\n getLayerFields?: (layerId: string) => { name: string; isNumeric: boolean }[];\n onUpdateHeatmapConfig?: (layerId: string, config: HeatmapConfig) => void;\n onUpdateClusterConfig?: (layerId: string, config: ClusterConfig) => void;\n onUpdateVisualConfig?: (layerId: string, config: VisualConfig) => void;\n hasPointFeatures?: (layerId: string) => boolean;\n autoLabelConfig?: AutoLabelConfig;\n onUpdateAutoLabelConfig?: (config: AutoLabelConfig) => void;\n visibleFeatureCount?: number;\n is3DTerrainEnabled?: boolean;\n onToggle3DTerrain?: () => void;\n onUpdateAltitudeDisplayMode?: (layerId: string, mode: AltitudeDisplayMode) => void;\n /** Hide satellite basemap option (for air-gapped deployments) */\n hideSatellite?: boolean;\n /** Hide terrain basemap and 3D toggle (for air-gapped deployments) */\n hideTerrain?: boolean;\n /** Hide the entire basemap style switcher (for air-gapped deployments with only a local tile server) */\n hideBasemapSwitcher?: boolean;\n /** When true, hide unsaved badges (persistence is handled externally) */\n externalPersistence?: boolean;\n}\n\nexport function LayersPanel({\n layers,\n onAddLayer,\n onRemoveLayer,\n onRenameLayer,\n onToggleLayerVisibility,\n onMoveFeatureToLayer,\n selectedFeatureIds,\n getFeatureCount,\n getLayerUnsavedCount,\n getMapUnsavedCount,\n activeEditingLayerId,\n onSetActiveEditingLayer,\n onSaveLayerGeoJSON,\n onLoadLayerGeoJSON,\n onLoadNewLayerGeoJSON,\n onSaveAllGeoJSON,\n onSearchAndAddToNewLayer,\n onWorkspaceLoad,\n onWorkspaceSave,\n onFitToFeatures,\n onFitToLayerFeatures,\n currentMapStyle,\n onMapStyleChange,\n onUpdateTraceConfig,\n getAvailableTraceFields,\n getLayerFields,\n onUpdateHeatmapConfig,\n onUpdateClusterConfig,\n onUpdateVisualConfig,\n hasPointFeatures,\n autoLabelConfig,\n onUpdateAutoLabelConfig,\n visibleFeatureCount,\n is3DTerrainEnabled = false,\n onToggle3DTerrain,\n onUpdateAltitudeDisplayMode,\n hideSatellite = false,\n hideTerrain = false,\n hideBasemapSwitcher = false,\n externalPersistence = false,\n}: LayersPanelProps) {\n const [newLayerName, setNewLayerName] = useState('');\n const [editingLayerId, setEditingLayerId] = useState<string | null>(null);\n const [editingName, setEditingName] = useState('');\n const [expandedLayers, setExpandedLayers] = useState<Set<string>>(new Set());\n\n const handleAddLayer = useCallback(() => {\n if (!newLayerName.trim()) return;\n onAddLayer(newLayerName.trim());\n setNewLayerName('');\n }, [newLayerName, onAddLayer]);\n\n const handleStartEdit = useCallback((layer: Layer) => {\n setEditingLayerId(layer.id);\n setEditingName(layer.name);\n }, []);\n\n const handleSaveEdit = useCallback(() => {\n if (editingLayerId && editingName.trim()) {\n onRenameLayer(editingLayerId, editingName.trim());\n }\n setEditingLayerId(null);\n setEditingName('');\n }, [editingLayerId, editingName, onRenameLayer]);\n\n const handleCancelEdit = useCallback(() => {\n setEditingLayerId(null);\n setEditingName('');\n }, []);\n\n const toggleExpanded = useCallback((layerId: string) => {\n setExpandedLayers(prev => {\n const next = new Set(prev);\n if (next.has(layerId)) {\n next.delete(layerId);\n } else {\n next.add(layerId);\n }\n return next;\n });\n }, []);\n\n const handleMoveSelectedToLayer = useCallback((layerId: string) => {\n selectedFeatureIds.forEach(featureId => {\n onMoveFeatureToLayer(featureId, layerId);\n });\n }, [selectedFeatureIds, onMoveFeatureToLayer]);\n\n const handleDeleteLayer = useCallback((layer: Layer) => {\n Modal.confirm({\n title: `Delete layer \"${layer.name}\"?`,\n content: 'This will delete the layer. Features in this layer will be moved to the default layer.',\n okText: 'Delete',\n okButtonProps: { danger: true },\n cancelText: 'Cancel',\n onOk: () => onRemoveLayer(layer.id),\n });\n }, [onRemoveLayer]);\n\n return (\n <div \n className=\"absolute top-16 right-4 z-10 w-[420px] bg-background/95 floating-panel rounded-lg shadow-lg border border-border max-h-[calc(100vh-5rem)] flex flex-col overflow-hidden\"\n data-testid=\"panel-layers\"\n >\n {/* Map Styles Section */}\n <div className=\"p-2 border-b border-border shrink-0\">\n <div className=\"flex items-center gap-1.5 mb-1.5\">\n <Map className=\"w-4 h-4 text-muted-foreground\" />\n <h3 className=\"text-sm font-semibold flex-1\">Map Options</h3>\n <Dropdown\n trigger={['click']}\n placement=\"bottomRight\"\n menu={{\n items: [\n {\n key: 'auto-labels',\n label: (\n <div className=\"px-1.5 py-1.5\" onClick={(e) => e.stopPropagation()}>\n <div className=\"flex items-center justify-between gap-1.5 mb-1.5\">\n <div className=\"flex items-center gap-1.5\">\n <Type className=\"w-4 h-4 text-muted-foreground\" />\n <span className=\"text-sm\">Auto-show labels</span>\n </div>\n <Switch\n size=\"small\"\n checked={autoLabelConfig?.enabled ?? false}\n onChange={(checked) => onUpdateAutoLabelConfig?.({ \n enabled: checked, \n threshold: autoLabelConfig?.threshold ?? 100 \n })}\n data-testid=\"switch-auto-labels\"\n />\n </div>\n {autoLabelConfig?.enabled && (\n <div className=\"ml-5 space-y-1\">\n <div className=\"flex items-center gap-1.5\">\n <span className=\"text-xs text-muted-foreground\">When features on screen</span>\n <span className=\"text-xs font-medium\">< {autoLabelConfig.threshold}</span>\n </div>\n <Slider\n value={autoLabelConfig.threshold}\n min={10}\n max={500}\n step={10}\n onChange={(value) => onUpdateAutoLabelConfig?.({ \n ...autoLabelConfig, \n threshold: value \n })}\n className=\"w-full\"\n data-testid=\"slider-auto-label-threshold\"\n />\n {visibleFeatureCount !== undefined && (\n <div className=\"text-xs text-muted-foreground\">\n Visible: <span className=\"font-medium\">{visibleFeatureCount}</span>\n {visibleFeatureCount < autoLabelConfig.threshold ? (\n <span className=\"text-green-600 dark:text-green-400 ml-1\">(shown)</span>\n ) : (\n <span className=\"text-amber-600 dark:text-amber-400 ml-1\">(hidden)</span>\n )}\n </div>\n )}\n </div>\n )}\n </div>\n ),\n },\n { type: 'divider' },\n {\n key: 'load-all',\n icon: <Upload className=\"w-[18px] h-[18px]\" />,\n label: 'Load Entire Map from GeoJSON',\n onClick: onLoadNewLayerGeoJSON,\n },\n {\n key: 'save-all',\n icon: <Download className=\"w-[18px] h-[18px]\" />,\n label: 'Save Entire Map as GeoJSON',\n onClick: onSaveAllGeoJSON,\n },\n ...(onWorkspaceLoad || onWorkspaceSave ? [{ type: 'divider' as const }] : []),\n ...(onWorkspaceLoad ? [{\n key: 'workspace-load-all',\n icon: <FolderOpen className=\"w-[18px] h-[18px]\" />,\n label: 'Load All from Workspace...',\n onClick: () => {\n // Load to active layer or first layer if available\n const targetLayerId = activeEditingLayerId || (layers.length > 0 ? layers[0].id : null);\n if (targetLayerId) {\n onWorkspaceLoad(targetLayerId);\n }\n },\n }] : []),\n ...(onWorkspaceSave ? [{\n key: 'workspace-save-all',\n icon: <FolderOpen className=\"w-[18px] h-[18px]\" />,\n label: 'Save All to Workspace...',\n onClick: () => {\n // Save from active layer or first layer if available\n const targetLayerId = activeEditingLayerId || (layers.length > 0 ? layers[0].id : null);\n if (targetLayerId) {\n onWorkspaceSave(targetLayerId);\n }\n },\n }] : []),\n ...(onFitToFeatures ? [\n { type: 'divider' as const },\n {\n key: 'fit-all',\n icon: <Focus className=\"w-[18px] h-[18px]\" />,\n label: 'Fit Map to All Features',\n onClick: onFitToFeatures,\n },\n ] : []),\n ],\n }}\n >\n <Button \n type=\"text\" \n icon={<MoreHorizontal className=\"w-[18px] h-[18px]\" />}\n className=\"!w-7 !h-7 !min-w-0 !p-0\"\n data-testid=\"button-global-settings-menu\"\n />\n </Dropdown>\n </div>\n {!hideBasemapSwitcher && (\n <div className=\"flex items-center gap-1.5\">\n <div className=\"grid grid-cols-3 gap-1 flex-1\">\n {MAP_STYLES\n .filter((style) => {\n if (hideSatellite && style.id === 'satellite') return false;\n return true;\n })\n .map((style) => {\n const Icon = style.icon;\n const isActive = currentMapStyle === style.id;\n return (\n <Button\n key={style.id}\n type={isActive ? \"primary\" : \"default\"}\n size=\"small\"\n onClick={() => onMapStyleChange(style.id)}\n className={`flex flex-col items-center gap-1 !h-auto !py-2 w-full ${isActive ? '' : 'bg-background'}`}\n data-testid={`button-map-style-${style.id}`}\n >\n <Icon className=\"w-[18px] h-[18px]\" />\n <span className=\"text-sm\">{style.name}</span>\n </Button>\n );\n })}\n </div>\n {onToggle3DTerrain && !hideTerrain && (\n <Button\n type=\"default\"\n size=\"small\"\n onClick={onToggle3DTerrain}\n className={`flex flex-col items-center gap-0.5 !h-auto !py-1.5 !px-2 !rounded-full transition-all shrink-0 ${\n is3DTerrainEnabled \n ? '!bg-primary !text-primary-foreground !border-primary shadow-md' \n : '!bg-muted/50 !border-dashed !border-muted-foreground/40'\n }`}\n data-testid=\"button-3d-terrain\"\n >\n <Box className=\"w-4 h-4\" />\n <span className=\"text-xs font-medium\">3D</span>\n </Button>\n )}\n </div>\n )}\n </div>\n {/* Layers Section */}\n <div className=\"flex items-center gap-1.5 px-2 py-1.5 border-b border-border shrink-0\">\n <Layers className=\"w-4 h-4 text-muted-foreground\" />\n <h3 className=\"text-sm font-semibold flex-1\">Layers</h3>\n <Tag className=\"text-xs px-1.5 py-0\">{layers.length}</Tag>\n </div>\n <div className=\"flex-1 min-h-0 overflow-y-auto\">\n <div className=\"p-1.5 space-y-0.5 pr-2\">\n {layers.map((layer) => {\n const featureCount = getFeatureCount(layer.id);\n const isExpanded = expandedLayers.has(layer.id);\n const isEditing = editingLayerId === layer.id;\n const isDefault = layer.id === 'default';\n const isActiveEditing = layer.id === activeEditingLayerId;\n \n return (\n <div key={layer.id}>\n <div \n className={`flex items-center gap-1 px-[5px] py-[5px] rounded-md hover-elevate group min-w-0 ${isActiveEditing ? 'bg-primary/10 border border-primary/30' : ''}`}\n data-testid={`layer-item-${layer.id}`}\n >\n {/* Left control cluster - tighter spacing */}\n <div className=\"flex items-center gap-0 shrink-0\">\n <Button \n type=\"text\" \n icon={isExpanded ? <ChevronDown className=\"w-3.5 h-3.5\" /> : <ChevronRight className=\"w-3.5 h-3.5\" />}\n onClick={() => toggleExpanded(layer.id)}\n className=\"!w-6 !h-7 !min-w-0 !p-0\"\n />\n \n <Button\n type=\"text\"\n icon={layer.visible ? <Eye className=\"w-4 h-4\" /> : <EyeOff className=\"w-4 h-4 text-muted-foreground\" />}\n onClick={() => onToggleLayerVisibility(layer.id)}\n className=\"!w-6 !h-7 !min-w-0 !p-0\"\n data-testid={`button-toggle-visibility-${layer.id}`}\n />\n \n {layer.readOnly ? (\n <Tooltip title={<><p className=\"font-medium\">High-Performance Mode</p><p className=\"text-sm text-muted-foreground\">View-only, optimized for large datasets</p></>}>\n <div className=\"h-7 w-6 flex items-center justify-center relative\">\n <Lock className=\"w-4 h-4 text-muted-foreground\" />\n <span className=\"absolute -top-0.5 -right-0.5 w-2.5 h-2.5 bg-green-500 rounded-full\" />\n </div>\n </Tooltip>\n ) : (\n <Tooltip title={isActiveEditing ? \"This is the layer being edited\" : \"Click to edit this layer\"}>\n <Button\n type=\"text\"\n icon={<Pencil className={`w-4 h-4 ${isActiveEditing ? 'text-primary' : ''}`} />}\n onClick={() => {\n if (!layer.visible) return;\n if (isActiveEditing) {\n onSetActiveEditingLayer('');\n } else {\n onSetActiveEditingLayer(layer.id);\n }\n }}\n disabled={!layer.visible}\n className={`!w-6 !h-7 !min-w-0 !p-0 ${isActiveEditing ? 'ring-2 ring-primary ring-offset-1 ring-offset-background' : ''}`}\n data-testid={`button-set-active-${layer.id}`}\n />\n </Tooltip>\n )}\n </div>\n \n {/* Layer name - uses all remaining space */}\n {isEditing ? (\n <Input\n value={editingName}\n onChange={(e) => setEditingName(e.target.value)}\n onBlur={handleSaveEdit}\n onKeyDown={(e) => {\n if (e.key === 'Enter') handleSaveEdit();\n if (e.key === 'Escape') handleCancelEdit();\n }}\n className=\"!h-7 text-sm flex-1 min-w-0\"\n autoFocus\n data-testid={`input-edit-layer-${layer.id}`}\n />\n ) : (\n <div className=\"flex items-center gap-1.5 flex-1 min-w-0\">\n <Tooltip title={layer.name}>\n <button\n onClick={() => handleStartEdit(layer)}\n className=\"text-left text-base truncate px-1 min-w-0\"\n data-testid={`button-layer-name-${layer.id}`}\n >\n {layer.name}\n </button>\n </Tooltip>\n {!externalPersistence && getLayerUnsavedCount && getLayerUnsavedCount(layer.id) > 0 && (\n <Tag color=\"orange\" className=\"!text-[10px] !px-1 !py-0 !leading-4 !border-0 shrink-0\">\n {getLayerUnsavedCount(layer.id)} unsaved\n </Tag>\n )}\n </div>\n )}\n \n {/* Right side - feature count and menu */}\n <div className=\"flex items-center gap-1 shrink-0\">\n <Tag className=\"text-sm\">{featureCount}</Tag>\n \n <Dropdown\n trigger={['click']}\n placement=\"bottomRight\"\n menu={{\n items: [\n {\n key: 'load-desktop',\n icon: <Upload className=\"w-[18px] h-[18px]\" />,\n label: 'Load GeoJSON from desktop',\n onClick: () => onLoadLayerGeoJSON(layer.id),\n },\n {\n key: 'save-desktop',\n icon: <Download className=\"w-[18px] h-[18px]\" />,\n label: 'Save GeoJSON to desktop',\n onClick: () => onSaveLayerGeoJSON(layer.id),\n },\n ...(onWorkspaceLoad || onWorkspaceSave ? [{ type: 'divider' as const }] : []),\n ...(onWorkspaceLoad ? [{\n key: 'load-workspace',\n icon: <FolderOpen className=\"w-[18px] h-[18px]\" />,\n label: 'Load from workspace',\n onClick: () => onWorkspaceLoad(layer.id),\n }] : []),\n ...(onWorkspaceSave ? [{\n key: 'save-workspace',\n icon: <FolderOpen className=\"w-[18px] h-[18px]\" />,\n label: 'Save to workspace',\n onClick: () => onWorkspaceSave(layer.id),\n }] : []),\n ...(onFitToLayerFeatures && featureCount > 0 ? [\n { type: 'divider' as const },\n {\n key: 'fit',\n icon: <Focus className=\"w-[18px] h-[18px]\" />,\n label: 'Fit Map to Layer',\n onClick: () => onFitToLayerFeatures(layer.id),\n },\n ] : []),\n ...(!isDefault ? [\n { type: 'divider' as const },\n {\n key: 'delete',\n icon: <Trash2 className=\"w-[18px] h-[18px]\" />,\n label: 'Delete Layer',\n danger: true,\n onClick: () => handleDeleteLayer(layer),\n },\n ] : []),\n ],\n }}\n >\n <Button\n type=\"text\"\n icon={<MoreHorizontal className=\"w-4 h-4\" />}\n className=\"!w-7 !h-7 !min-w-0 !p-0 shrink-0 opacity-0 group-hover:opacity-100\"\n data-testid={`button-layer-menu-${layer.id}`}\n />\n </Dropdown>\n </div>\n </div>\n {isExpanded && (\n <div className=\"pl-2 border-l border-border space-y-1.5 py-1.5 ml-[8px] mr-[8px]\">\n {selectedFeatureIds.length > 0 && !layer.readOnly && (\n <Button\n type=\"default\"\n size=\"small\"\n onClick={() => handleMoveSelectedToLayer(layer.id)}\n className=\"w-full text-xs\"\n data-testid={`button-move-to-layer-${layer.id}`}\n >\n Move {selectedFeatureIds.length} selected here\n </Button>\n )}\n \n {hasPointFeatures?.(layer.id) && (\n <div className=\"space-y-1 p-1.5 bg-muted/30 rounded-md\">\n <div className=\"flex items-center gap-1.5 text-xs font-medium\">\n <span>Point Features</span>\n </div>\n \n {/* Trace Config */}\n <div className=\"flex items-center gap-1.5\">\n <Switch\n size=\"small\"\n checked={layer.traceConfig?.enabled ?? false}\n onChange={(checked) => onUpdateTraceConfig(layer.id, { \n enabled: checked, \n groupByField: layer.traceConfig?.groupByField ?? null \n })}\n data-testid={`switch-trace-${layer.id}`}\n />\n <span className=\"text-xs\">Trace Lines</span>\n </div>\n {layer.traceConfig?.enabled && (\n <Select\n size=\"small\"\n value={layer.traceConfig.groupByField ?? 'all'}\n onChange={(val) => onUpdateTraceConfig(layer.id, { \n enabled: true, \n groupByField: val === 'all' ? null : val \n })}\n className=\"w-full text-xs\"\n options={[\n { value: 'all', label: 'Connect all points' },\n ...getAvailableTraceFields(layer.id).map(f => ({ value: f, label: `Group by ${f}` })),\n ]}\n data-testid={`select-trace-field-${layer.id}`}\n />\n )}\n \n {/* Heatmap Config */}\n {onUpdateHeatmapConfig && (\n <>\n <Divider className=\"!my-1\" />\n <div className=\"flex items-center gap-1.5\">\n <Switch\n size=\"small\"\n checked={layer.heatmapConfig?.enabled ?? false}\n onChange={(checked) => onUpdateHeatmapConfig(layer.id, { \n enabled: checked, \n intensity: layer.heatmapConfig?.intensity ?? 1.0,\n radius: layer.heatmapConfig?.radius ?? 20,\n hideFeatures: layer.heatmapConfig?.hideFeatures ?? false,\n })}\n data-testid={`switch-heatmap-${layer.id}`}\n />\n <span className=\"text-xs\">Heatmap</span>\n </div>\n {layer.heatmapConfig?.enabled && (\n <div className=\"space-y-1 pl-4\">\n <div className=\"flex items-center gap-1\">\n <span className=\"text-[10px] w-12\">Intensity</span>\n <Slider\n value={layer.heatmapConfig.intensity}\n min={0.1}\n max={2.0}\n step={0.1}\n className=\"flex-1\"\n onChange={(val) => onUpdateHeatmapConfig(layer.id, { \n ...layer.heatmapConfig!, \n intensity: val \n })}\n />\n </div>\n <div className=\"flex items-center gap-1\">\n <span className=\"text-[10px] w-12\">Radius</span>\n <Slider\n value={layer.heatmapConfig.radius}\n min={5}\n max={50}\n step={1}\n className=\"flex-1\"\n onChange={(val) => onUpdateHeatmapConfig(layer.id, { \n ...layer.heatmapConfig!, \n radius: val \n })}\n />\n </div>\n <div className=\"flex items-center gap-1.5\">\n <Switch\n size=\"small\"\n checked={layer.heatmapConfig.hideFeatures ?? false}\n onChange={(checked) => onUpdateHeatmapConfig(layer.id, { \n ...layer.heatmapConfig!, \n hideFeatures: checked \n })}\n />\n <span className=\"text-[10px]\">Hide points</span>\n </div>\n </div>\n )}\n </>\n )}\n \n {/* Cluster Config */}\n {onUpdateClusterConfig && (\n <>\n <Divider className=\"!my-1\" />\n <div className=\"flex items-center gap-1.5\">\n <Switch\n size=\"small\"\n checked={layer.clusterConfig?.enabled ?? false}\n onChange={(checked) => onUpdateClusterConfig(layer.id, { \n enabled: checked, \n groupByField: layer.clusterConfig?.groupByField ?? null,\n showPointDots: layer.clusterConfig?.showPointDots ?? false,\n })}\n data-testid={`switch-cluster-${layer.id}`}\n />\n <span className=\"text-xs\">Clustering</span>\n </div>\n {layer.clusterConfig?.enabled && getLayerFields && (\n <div className=\"space-y-1 pl-4\">\n <Select\n size=\"small\"\n value={layer.clusterConfig.groupByField ?? 'count'}\n onChange={(val) => onUpdateClusterConfig(layer.id, { \n ...layer.clusterConfig!, \n groupByField: val === 'count' ? null : val \n })}\n className=\"w-full text-xs\"\n options={[\n { value: 'count', label: 'Simple count' },\n ...getLayerFields(layer.id).filter(f => !f.isNumeric).map(f => ({ value: f.name, label: `Pie by ${f.name}` })),\n ]}\n data-testid={`select-cluster-field-${layer.id}`}\n />\n <div className=\"flex items-center gap-1.5\">\n <Switch\n size=\"small\"\n checked={layer.clusterConfig.showPointDots ?? false}\n onChange={(checked) => onUpdateClusterConfig(layer.id, { \n ...layer.clusterConfig!, \n showPointDots: checked \n })}\n />\n <span className=\"text-[10px]\">Show point dots</span>\n </div>\n </div>\n )}\n </>\n )}\n </div>\n )}\n \n {/* 3D Altitude Mode */}\n {layer.hasAltitudeData && onUpdateAltitudeDisplayMode && (\n <div className=\"space-y-1 p-1.5 bg-muted/30 rounded-md\">\n <div className=\"flex items-center gap-1.5 text-xs font-medium\">\n <Box className=\"w-3.5 h-3.5\" />\n <span>Altitude Display</span>\n </div>\n <Select\n size=\"small\"\n value={layer.altitudeDisplayMode ?? '3d'}\n onChange={(val) => onUpdateAltitudeDisplayMode(layer.id, val as AltitudeDisplayMode)}\n className=\"w-full text-xs\"\n options={[\n { value: '3d', label: '3D (show altitude)' },\n { value: 'flat', label: 'Flat (ignore altitude)' },\n { value: 'both', label: 'Both (3D + flat shadow)' },\n ]}\n data-testid={`select-altitude-mode-${layer.id}`}\n />\n </div>\n )}\n \n {/* Visual Config */}\n {onUpdateVisualConfig && getLayerFields && (\n <div className=\"space-y-1.5 p-1.5 bg-muted/30 rounded-md\">\n <div className=\"text-sm font-medium\">Visual Settings</div>\n \n {/* Label Mode */}\n <div className=\"flex items-center gap-1 text-sm text-muted-foreground\">\n <Type className=\"w-3.5 h-3.5\" />\n <span>Labels</span>\n </div>\n <Select\n size=\"small\"\n value={layer.visualConfig?.label?.mode ?? 'standard'}\n onChange={(val) => onUpdateVisualConfig(layer.id, {\n ...layer.visualConfig,\n label: { mode: val as LabelMode },\n })}\n className=\"w-full text-sm\"\n options={[\n { value: 'standard', label: 'Use name property' },\n { value: 'field', label: 'Use field...' },\n { value: 'fixed', label: 'Fixed text...' },\n ]}\n data-testid={`select-label-mode-${layer.id}`}\n />\n {layer.visualConfig?.label?.mode === 'field' && (\n <Select\n size=\"small\"\n value={layer.visualConfig?.label?.fieldName ?? ''}\n onChange={(val) => onUpdateVisualConfig(layer.id, {\n ...layer.visualConfig,\n label: { mode: 'field', fieldName: val },\n })}\n className=\"w-full text-sm\"\n placeholder=\"Select field...\"\n options={getLayerFields(layer.id).map(f => ({ value: f.name, label: f.name }))}\n data-testid={`select-label-field-${layer.id}`}\n />\n )}\n {layer.visualConfig?.label?.mode === 'fixed' && (\n <Input\n size=\"small\"\n value={layer.visualConfig?.label?.fixedText ?? ''}\n onChange={(e) => onUpdateVisualConfig(layer.id, {\n ...layer.visualConfig,\n label: { mode: 'fixed', fixedText: e.target.value },\n })}\n placeholder=\"Enter label text...\"\n className=\"text-sm\"\n data-testid={`input-label-text-${layer.id}`}\n />\n )}\n\n {/* Size Mode */}\n <div className=\"flex items-center gap-1 text-sm text-muted-foreground pt-0.5\">\n <span className=\"w-3.5 h-3.5 text-center\">S</span>\n <span>Size</span>\n </div>\n <Select\n size=\"small\"\n value={layer.visualConfig?.size?.mode ?? 'standard'}\n onChange={(val) => onUpdateVisualConfig(layer.id, {\n ...layer.visualConfig,\n size: { mode: val as SizeMode },\n })}\n className=\"w-full text-sm\"\n options={[\n { value: 'standard', label: 'Default size' },\n { value: 'field', label: 'Size by field...' },\n { value: 'override', label: 'Override size...' },\n ]}\n data-testid={`select-size-mode-${layer.id}`}\n />\n {layer.visualConfig?.size?.mode === 'field' && (\n <Select\n size=\"small\"\n value={layer.visualConfig?.size?.fieldName ?? ''}\n onChange={(val) => onUpdateVisualConfig(layer.id, {\n ...layer.visualConfig,\n size: { mode: 'field', fieldName: val },\n })}\n className=\"w-full text-sm\"\n placeholder=\"Select numeric field...\"\n options={getLayerFields(layer.id).filter(f => f.isNumeric).map(f => ({ value: f.name, label: f.name }))}\n data-testid={`select-size-field-${layer.id}`}\n />\n )}\n {layer.visualConfig?.size?.mode === 'override' && (\n <div className=\"flex items-center gap-1\">\n <Slider\n value={layer.visualConfig?.size?.overrideValue ?? 5}\n min={1}\n max={10}\n step={1}\n className=\"flex-1\"\n onChange={(val) => onUpdateVisualConfig(layer.id, {\n ...layer.visualConfig,\n size: { mode: 'override', overrideValue: val },\n })}\n />\n <span className=\"text-sm w-4 text-right\">{layer.visualConfig?.size?.overrideValue ?? 5}</span>\n </div>\n )}\n\n {/* Color Mode */}\n <div className=\"flex items-center gap-1 text-sm text-muted-foreground pt-0.5\">\n <span className=\"w-3.5 h-3.5 rounded-full bg-current\" />\n <span>Color</span>\n </div>\n <Select\n size=\"small\"\n value={layer.visualConfig?.color?.mode ?? 'standard'}\n onChange={(val) => onUpdateVisualConfig(layer.id, {\n ...layer.visualConfig,\n color: { mode: val as ColorMode },\n })}\n className=\"w-full text-sm\"\n options={[\n { value: 'standard', label: 'Use feature color' },\n { value: 'field', label: 'Color by field...' },\n { value: 'fixed', label: 'Fixed color...' },\n ]}\n data-testid={`select-color-mode-${layer.id}`}\n />\n {layer.visualConfig?.color?.mode === 'field' && (\n <Select\n size=\"small\"\n value={layer.visualConfig?.color?.fieldName ?? ''}\n onChange={(val) => onUpdateVisualConfig(layer.id, {\n ...layer.visualConfig,\n color: { mode: 'field', fieldName: val },\n })}\n className=\"w-full text-sm\"\n placeholder=\"Select field...\"\n options={getLayerFields(layer.id).map(f => ({ value: f.name, label: f.name }))}\n data-testid={`select-color-field-${layer.id}`}\n />\n )}\n {layer.visualConfig?.color?.mode === 'fixed' && (\n <ColorPickerPopover\n value={layer.visualConfig?.color?.fixedColor ?? '#3b82f6'}\n onChange={(color) => {\n onUpdateVisualConfig?.(layer.id, {\n ...layer.visualConfig,\n color: {\n mode: 'fixed',\n fixedColor: color,\n },\n });\n }}\n testId={`color-fixed-${layer.id}`}\n />\n )}\n\n {hasPointFeatures?.(layer.id) && (\n <>\n <div className=\"flex items-center gap-1 text-sm text-muted-foreground pt-0.5\">\n <Smile className=\"w-3.5 h-3.5\" />\n <span>Point Icon</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <Switch\n size=\"small\"\n checked={layer.visualConfig?.icon?.enabled ?? false}\n onChange={(checked) => {\n onUpdateVisualConfig?.(layer.id, {\n ...layer.visualConfig,\n icon: {\n enabled: checked,\n icon: layer.visualConfig?.icon?.icon ?? '📍',\n size: layer.visualConfig?.icon?.size ?? 24,\n },\n });\n }}\n data-testid={`switch-icon-${layer.id}`}\n />\n {layer.visualConfig?.icon?.enabled && (\n <div className=\"flex items-center gap-1 flex-1\">\n <IconPicker\n value={layer.visualConfig?.icon?.icon ?? '📍'}\n onChange={(icon) => {\n onUpdateVisualConfig?.(layer.id, {\n ...layer.visualConfig,\n icon: {\n enabled: true,\n icon,\n size: layer.visualConfig?.icon?.size ?? 24,\n },\n });\n }}\n />\n <Slider\n value={layer.visualConfig?.icon?.size ?? 24}\n min={12}\n max={48}\n step={2}\n className=\"flex-1\"\n onChange={(val) => {\n onUpdateVisualConfig?.(layer.id, {\n ...layer.visualConfig,\n icon: {\n enabled: true,\n icon: layer.visualConfig?.icon?.icon ?? '📍',\n size: val,\n },\n });\n }}\n />\n <span className=\"text-sm w-6 text-right\">{layer.visualConfig?.icon?.size ?? 24}</span>\n </div>\n )}\n </div>\n </>\n )}\n </div>\n )}\n </div>\n )}\n </div>\n );\n })}\n </div>\n </div>\n <div className=\"p-1.5 border-t border-border shrink-0\">\n <div className=\"flex items-center gap-1\">\n <Input\n value={newLayerName}\n onChange={(e) => setNewLayerName(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n handleAddLayer();\n }\n }}\n placeholder=\"New layer name\"\n className=\"!h-8 text-sm flex-1\"\n data-testid=\"input-new-layer\"\n />\n <Tooltip title=\"Create new layer\">\n <Button\n type=\"default\"\n icon={<Plus className=\"w-4 h-4\" />}\n onClick={handleAddLayer}\n disabled={!newLayerName.trim()}\n className=\"!w-8 !h-8 !min-w-0 !p-0 shrink-0\"\n data-testid=\"button-add-layer\"\n />\n </Tooltip>\n <Tooltip title=\"Load GeoJSON from desktop as new layer\">\n <Button\n type=\"default\"\n icon={<FolderOpen className=\"w-4 h-4\" />}\n onClick={onLoadNewLayerGeoJSON}\n className=\"!w-8 !h-8 !min-w-0 !p-0 shrink-0\"\n data-testid=\"button-open-layer\"\n />\n </Tooltip>\n {onSearchAndAddToNewLayer && (\n <Tooltip title=\"Search and add...\">\n <Button\n type=\"default\"\n icon={\n <div className=\"relative w-5 h-4\">\n <Database className=\"w-4 h-4\" />\n <Search className=\"w-3 h-3 absolute -bottom-0.5 right-[-4px] stroke-[2.5]\" />\n </div>\n }\n onClick={onSearchAndAddToNewLayer}\n className=\"!w-8 !h-8 !min-w-0 !p-0 shrink-0\"\n data-testid=\"button-search-new-layer\"\n />\n </Tooltip>\n )}\n </div>\n </div>\n </div>\n );\n}\n","import { useState, useEffect, useCallback, useRef } from 'react';\nimport { X, Plus, Trash2, MapPin, Minus, Pentagon, Palette, Calendar as CalendarIcon, Type, MoveRight, Circle, Smile, Info, MoreHorizontal, User, Car, Building, TreePine, Package, Save, Blend } from 'lucide-react';\nimport { Button, Input, Divider, Slider, Popover, Tooltip, Tag, Tabs, Badge as AntBadge, ColorPicker, Select, Collapse } from 'antd';\nimport { ChevronDown } from 'lucide-react';\nimport type { InputRef } from 'antd';\nimport { format } from 'date-fns';\nimport { IconPicker } from '@/components/icon-picker';\nimport { useToast } from '@/hooks/use-toast';\nimport * as turf from '@turf/turf';\nimport type { EntityCardProvider, TypePickerProvider, EntityType, FeatureSaveProvider, FeatureSaveContext } from '@/lib/map-editor-api';\n\nconst { TextArea } = Input;\n\nfunction formatDateForState(value: unknown): string {\n if (!value) return '';\n if (value instanceof Date) {\n return value.toISOString();\n }\n if (typeof value === 'string') {\n const date = new Date(value);\n if (!isNaN(date.getTime())) {\n return date.toISOString();\n }\n }\n return '';\n}\n\ninterface FeatureProperties {\n name?: string;\n description?: string;\n [key: string]: unknown;\n}\n\ninterface SelectedFeature {\n id: string;\n type: string;\n properties: FeatureProperties;\n geometry: GeoJSON.Geometry;\n}\n\ninterface PropertiesPanelProps {\n selectedFeatures: SelectedFeature[];\n onUpdateProperties: (featureId: string, properties: FeatureProperties) => void;\n onUpdateGeometry?: (featureId: string, geometry: GeoJSON.Geometry) => void;\n onClose: () => void;\n isEditMode?: boolean;\n layerName?: string;\n layerId?: string;\n autoFocusLabel?: boolean;\n entityCardProvider?: EntityCardProvider;\n typePickerProvider?: TypePickerProvider;\n featureSaveProvider?: FeatureSaveProvider;\n onFeatureSaved?: (featureId: string, newId: string, metadata: { workspace: string; sourceName: string }) => void;\n}\n\nfunction getFeatureTypeIcon(geometryType: string, kind?: string) {\n if (kind === 'text') {\n return <Type className=\"w-4 h-4\" />;\n }\n if (kind === 'arrow') {\n return <MoveRight className=\"w-4 h-4\" />;\n }\n if (kind === 'circle') {\n return <Circle className=\"w-4 h-4\" />;\n }\n switch (geometryType) {\n case 'Point':\n return <MapPin className=\"w-4 h-4\" />;\n case 'LineString':\n return <Minus className=\"w-4 h-4\" />;\n case 'Polygon':\n return <Pentagon className=\"w-4 h-4\" />;\n default:\n return null;\n }\n}\n\nfunction getFeatureTypeLabel(geometryType: string, kind?: string) {\n if (kind === 'text') {\n return 'Text';\n }\n if (kind === 'arrow') {\n return 'Arrow';\n }\n if (kind === 'circle') {\n return 'Circle';\n }\n switch (geometryType) {\n case 'Point':\n return 'Point';\n case 'LineString':\n return 'Line';\n case 'Polygon':\n return 'Polygon';\n default:\n return geometryType;\n }\n}\n\ninterface CustomProperty {\n key: string;\n value: string;\n}\n\nconst PRESET_COLORS = [\n '#3b82f6', \n '#ef4444', \n '#22c55e', \n '#f59e0b', \n '#8b5cf6', \n '#06b6d4', \n '#ec4899', \n '#6366f1', \n '#14b8a6', \n '#f97316', \n];\n\n// Module-level variable to persist tab preference across feature selections\nlet persistedTabPreference: string = 'properties';\n\nexport function PropertiesPanel({ selectedFeatures, onUpdateProperties, onUpdateGeometry, onClose, isEditMode = true, layerName, layerId, autoFocusLabel = false, entityCardProvider, typePickerProvider, featureSaveProvider, onFeatureSaved }: PropertiesPanelProps) {\n const feature = selectedFeatures[0];\n const { toast } = useToast();\n const hasMultipleSelection = selectedFeatures.length > 1;\n const [isSaving, setIsSaving] = useState(false);\n \n // Initialize activeTab from persisted preference (force cards during multi-selection)\n const getInitialTab = () => {\n if (hasMultipleSelection && entityCardProvider) return 'cards';\n // Use persisted preference for single selection\n return entityCardProvider ? persistedTabPreference : 'properties';\n };\n const [activeTab, setActiveTab] = useState<string>(getInitialTab);\n \n // Handle tab click to block forbidden transitions at the event level\n const handleTabClick = useCallback((key: string, e: React.MouseEvent | React.KeyboardEvent) => {\n if (key === 'properties' && hasMultipleSelection) {\n e.preventDefault();\n e.stopPropagation();\n }\n }, [hasMultipleSelection]);\n \n // Handle tab change - guards and persists preference\n const handleTabChange = useCallback((key: string) => {\n // Don't allow switching to properties during multi-selection\n if (key === 'properties' && hasMultipleSelection) return;\n setActiveTab(key);\n // Persist the user's choice (only for valid selections)\n if (!hasMultipleSelection) {\n persistedTabPreference = key;\n }\n }, [hasMultipleSelection]);\n \n // Auto-switch to cards tab when entering multi-selection\n // Restore persisted preference when exiting multi-selection\n const prevMultiSelection = useRef(hasMultipleSelection);\n useEffect(() => {\n if (entityCardProvider) {\n if (hasMultipleSelection && !prevMultiSelection.current) {\n // Entering multi-selection: force cards tab\n setActiveTab('cards');\n } else if (!hasMultipleSelection && prevMultiSelection.current) {\n // Exiting multi-selection: restore persisted preference\n setActiveTab(persistedTabPreference);\n }\n }\n prevMultiSelection.current = hasMultipleSelection;\n }, [hasMultipleSelection, entityCardProvider]);\n const [name, setName] = useState('');\n const [description, setDescription] = useState('');\n const [startDate, setStartDate] = useState('');\n const [endDate, setEndDate] = useState('');\n const [customProperties, setCustomProperties] = useState<CustomProperty[]>([]);\n const [newPropertyKey, setNewPropertyKey] = useState('');\n \n const [strokeColor, setStrokeColor] = useState('#3b82f6');\n const [strokeWidth, setStrokeWidth] = useState(2);\n const [strokeOpacity, setStrokeOpacity] = useState(1);\n const [fillColor, setFillColor] = useState('#3b82f6');\n const [fillOpacity, setFillOpacity] = useState(0.2);\n \n const [labelText, setLabelText] = useState('New Label');\n const [fontSize, setFontSize] = useState(14);\n const [fontColor, setFontColor] = useState('#000000');\n const [fontWeight, setFontWeight] = useState<'normal' | 'bold'>('normal');\n \n const [arrowSize, setArrowSize] = useState(72);\n \n const [pointIcon, setPointIcon] = useState('');\n const [pointIconSize, setPointIconSize] = useState(24);\n \n const [latitude, setLatitude] = useState('');\n const [longitude, setLongitude] = useState('');\n \n // Entity type state\n const [entityType, setEntityType] = useState<string | undefined>(undefined);\n \n const latInputFocused = useRef(false);\n const lngInputFocused = useRef(false);\n\n useEffect(() => {\n if (feature) {\n if (feature.properties.kind === 'text') {\n const textLabel = (feature.properties.label as string) || (feature.properties.text as string) || 'New Label';\n setName(textLabel);\n setLabelText(textLabel);\n } else {\n setName((feature.properties.name as string) || '');\n setLabelText('');\n }\n setDescription((feature.properties.description as string) || '');\n setStartDate(formatDateForState(feature.properties.startDate));\n setEndDate(formatDateForState(feature.properties.endDate));\n \n setStrokeColor((feature.properties.stroke as string) || '#3b82f6');\n setStrokeWidth((feature.properties['stroke-width'] as number) || 2);\n setStrokeOpacity((feature.properties['stroke-opacity'] as number) ?? 1);\n setFillColor((feature.properties.fill as string) || '#3b82f6');\n setFillOpacity((feature.properties['fill-opacity'] as number) ?? 0.2);\n \n setFontSize((feature.properties.fontSize as number) || 14);\n setFontColor((feature.properties.fontColor as string) || '#000000');\n setFontWeight((feature.properties.fontWeight as 'normal' | 'bold') || 'normal');\n \n setArrowSize((feature.properties.arrowSize as number) || 72);\n \n setPointIcon((feature.properties.pointIcon as string) || (feature.properties.icon as string) || '');\n setPointIconSize((feature.properties.pointIconSize as number) || (feature.properties.iconSize as number) || 24);\n \n // Entity type\n setEntityType((feature.properties.entityType as string) || undefined);\n \n if (feature.geometry.type === 'Point') {\n const coords = feature.geometry.coordinates as [number, number];\n setLongitude(coords[0].toFixed(6));\n setLatitude(coords[1].toFixed(6));\n } else {\n try {\n const centroid = turf.centroid(feature.geometry as turf.AllGeoJSON);\n const coords = centroid.geometry.coordinates as [number, number];\n setLongitude(coords[0].toFixed(6));\n setLatitude(coords[1].toFixed(6));\n } catch {\n setLongitude('');\n setLatitude('');\n }\n }\n \n const reserved = ['name', 'description', 'startDate', 'endDate', 'stroke', 'stroke-width', 'stroke-opacity', 'fill', 'fill-opacity', 'kind', 'label', 'fontSize', 'fontColor', 'fontWeight', 'arrowSize', 'circleCenter', 'circleRadius', 'icon', 'iconSize', 'pointIcon', 'pointIconSize', 'entityType'];\n const custom: CustomProperty[] = [];\n Object.entries(feature.properties).forEach(([key, value]) => {\n // Skip reserved properties, internal properties (prefixed with _), and display control properties (isHidden*)\n if (!reserved.includes(key) && value !== undefined && value !== null && !key.startsWith('_') && !key.startsWith('isHidden')) {\n custom.push({ key, value: String(value) });\n }\n });\n setCustomProperties(custom);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [feature?.id]);\n \n useEffect(() => {\n if (!feature) return;\n \n if (latInputFocused.current || lngInputFocused.current) return;\n \n if (feature.geometry.type === 'Point') {\n const coords = feature.geometry.coordinates as [number, number];\n setLongitude(coords[0].toFixed(6));\n setLatitude(coords[1].toFixed(6));\n } else {\n try {\n const centroid = turf.centroid(feature.geometry as turf.AllGeoJSON);\n const coords = centroid.geometry.coordinates as [number, number];\n setLongitude(coords[0].toFixed(6));\n setLatitude(coords[1].toFixed(6));\n } catch {\n // Keep existing values if centroid calculation fails\n }\n }\n }, [feature?.geometry]);\n \n const nameInputRef = useRef<InputRef>(null);\n useEffect(() => {\n if (autoFocusLabel && feature?.properties?.kind === 'text' && nameInputRef.current) {\n setTimeout(() => {\n nameInputRef.current?.focus();\n nameInputRef.current?.select();\n }, 50);\n }\n }, [autoFocusLabel, feature?.id, feature?.properties?.kind]);\n\n const handleSave = useCallback((overrides?: Partial<{\n strokeColor: string;\n fillColor: string;\n strokeWidth: number;\n strokeOpacity: number;\n fillOpacity: number;\n labelText: string;\n fontSize: number;\n fontColor: string;\n fontWeight: 'normal' | 'bold';\n arrowSize: number;\n pointIcon: string;\n pointIconSize: number;\n entityType: string;\n }>) => {\n if (!feature || !isEditMode) return;\n \n const properties: FeatureProperties = {\n ...feature.properties,\n name: name || undefined,\n description: description || undefined,\n startDate: startDate || undefined,\n endDate: endDate || undefined,\n 'stroke': overrides?.strokeColor ?? strokeColor,\n 'stroke-width': overrides?.strokeWidth ?? strokeWidth,\n 'stroke-opacity': overrides?.strokeOpacity ?? strokeOpacity,\n 'fill': overrides?.fillColor ?? fillColor,\n 'fill-opacity': overrides?.fillOpacity ?? fillOpacity,\n };\n \n // Entity type\n if (overrides?.entityType !== undefined) {\n properties.entityType = overrides.entityType;\n } else if (entityType !== undefined) {\n properties.entityType = entityType;\n }\n \n if (feature.properties.kind === 'text') {\n properties.label = overrides?.labelText ?? name;\n properties.fontSize = overrides?.fontSize ?? fontSize;\n properties.fontColor = overrides?.fontColor ?? fontColor;\n properties.fontWeight = overrides?.fontWeight ?? fontWeight;\n delete properties.text;\n }\n \n if (feature.properties.kind === 'arrow') {\n properties.arrowSize = overrides?.arrowSize ?? arrowSize;\n }\n \n if (feature.geometry.type === 'Point' && feature.properties.kind !== 'text') {\n const iconValue = overrides?.pointIcon ?? pointIcon;\n const iconSizeValue = overrides?.pointIconSize ?? pointIconSize;\n if (iconValue) {\n properties.icon = iconValue;\n properties.iconSize = iconSizeValue;\n } else {\n delete properties.icon;\n delete properties.iconSize;\n }\n }\n \n customProperties.forEach(({ key, value }) => {\n if (key.trim()) {\n properties[key.trim()] = value;\n }\n });\n \n onUpdateProperties(feature.id, properties);\n }, [feature, name, description, startDate, endDate, strokeColor, strokeWidth, strokeOpacity, fillColor, fillOpacity, fontSize, fontColor, fontWeight, arrowSize, pointIcon, pointIconSize, entityType, customProperties, onUpdateProperties, isEditMode]);\n\n const handleAddProperty = useCallback(() => {\n if (!newPropertyKey.trim() || !isEditMode) return;\n setCustomProperties(prev => [...prev, { key: newPropertyKey.trim(), value: '' }]);\n setNewPropertyKey('');\n }, [newPropertyKey, isEditMode]);\n\n const handleRemoveProperty = useCallback((index: number) => {\n if (!isEditMode) return;\n setCustomProperties(prev => prev.filter((_, i) => i !== index));\n }, [isEditMode]);\n\n const handlePropertyKeyChange = useCallback((index: number, key: string) => {\n if (!isEditMode) return;\n setCustomProperties(prev => prev.map((prop, i) => i === index ? { ...prop, key } : prop));\n }, [isEditMode]);\n\n const handlePropertyValueChange = useCallback((index: number, value: string) => {\n if (!isEditMode) return;\n setCustomProperties(prev => prev.map((prop, i) => i === index ? { ...prop, value } : prop));\n }, [isEditMode]);\n \n // Handle feature save to workspace\n const handleFeatureSave = useCallback(async () => {\n if (!featureSaveProvider || !feature || !layerId || !layerName) return;\n \n setIsSaving(true);\n try {\n const geoFeature: GeoJSON.Feature = {\n type: 'Feature',\n id: feature.id,\n geometry: feature.geometry,\n properties: feature.properties,\n };\n \n const context: FeatureSaveContext = {\n feature: geoFeature,\n layer: { id: layerId, name: layerName },\n currentWorkspace: feature.properties._workspace as string | undefined,\n currentSourceName: feature.properties._sourceName as string | undefined,\n };\n \n const result = await featureSaveProvider(context);\n \n if (result) {\n // Notify parent to update the feature with new ID and metadata\n onFeatureSaved?.(feature.id, result.id, {\n workspace: result.workspace,\n sourceName: result.sourceName,\n });\n toast({\n title: 'Feature saved',\n description: `Saved to ${result.workspace}`,\n });\n }\n } catch (error) {\n toast({\n title: 'Save failed',\n description: error instanceof Error ? error.message : 'Failed to save feature',\n variant: 'destructive',\n });\n } finally {\n setIsSaving(false);\n }\n }, [featureSaveProvider, feature, layerId, layerName, onFeatureSaved, toast]);\n\n if (selectedFeatures.length === 0) {\n return null;\n }\n \n // Check if feature is unsaved\n const isUnsaved = feature?.properties?._unsaved === true;\n\n // Entity Cards content - renders cards for each selected feature\n const entityCardsContent = (\n <div className=\"p-2 space-y-2\">\n {entityCardProvider ? (\n selectedFeatures.map((f) => {\n const geoFeature: GeoJSON.Feature = {\n type: 'Feature',\n id: f.id,\n geometry: f.geometry,\n properties: f.properties,\n };\n const card = entityCardProvider(geoFeature);\n return card ? (\n <div key={f.id} className=\"border border-border rounded-md p-2 bg-card\">\n {card}\n </div>\n ) : null;\n })\n ) : (\n <div className=\"text-center py-4 text-muted-foreground text-sm\">\n No entity card provider registered\n </div>\n )}\n </div>\n );\n\n // Properties content disabled overlay for multi-selection\n const propertiesDisabledOverlay = (\n <div className=\"absolute inset-0 bg-background/80 flex items-center justify-center z-10 rounded-md\">\n <p className=\"text-sm text-muted-foreground text-center px-4\">\n Select a single feature to see/set properties\n </p>\n </div>\n );\n\n // Multi-selection without entity card provider - show simple message\n if (hasMultipleSelection && !entityCardProvider) {\n return (\n <div \n className=\"absolute top-4 right-4 z-10 w-72 bg-background/95 floating-panel rounded-lg shadow-lg border border-border\"\n data-testid=\"panel-properties\"\n >\n <div className=\"flex items-center justify-between gap-2 px-2.5 py-2 border-b border-border\">\n <div className=\"flex items-center gap-2\">\n <Package className=\"w-4 h-4 text-primary\" />\n <span className=\"text-sm font-semibold\">\n {selectedFeatures.length} selected {selectedFeatures.length === 1 ? 'feature' : 'features'}\n </span>\n </div>\n <Button type=\"text\" icon={<X className=\"w-3.5 h-3.5\" />} onClick={onClose} className=\"!w-6 !h-6 !min-w-0 !p-0\" data-testid=\"button-close-properties\" />\n </div>\n <div className=\"p-2.5\">\n <p className=\"text-xs text-muted-foreground\">\n Select a single feature to edit properties.\n </p>\n </div>\n </div>\n );\n }\n\n // Properties panel (with optional tabs if entityCardProvider exists)\n const propertiesContent = (\n <div className=\"p-2 space-y-2\">\n <div className=\"space-y-0.5\">\n <div className=\"flex items-center justify-between gap-2\">\n <label htmlFor=\"feature-name\" className=\"text-xs text-muted-foreground\">\n {feature.properties.kind === 'text' ? 'Label' : 'Name'}\n </label>\n {isUnsaved && (\n <div className=\"flex items-center gap-1\">\n <Tag color=\"orange\" className=\"!text-[10px] !px-1 !py-0 !leading-4 !border-0\">\n unsaved\n </Tag>\n {featureSaveProvider && isEditMode && (\n <Button\n type=\"primary\"\n size=\"small\"\n icon={<Save className=\"w-3 h-3\" />}\n loading={isSaving}\n onClick={handleFeatureSave}\n className=\"!h-5 !px-1.5 !text-[11px] !p-[1px]\"\n style={{ padding: '1px 6px' }}\n data-testid=\"button-save-feature\"\n >\n Save\n </Button>\n )}\n </div>\n )}\n </div>\n <Input\n ref={nameInputRef}\n id=\"feature-name\"\n value={name}\n onChange={(e) => {\n setName(e.target.value);\n if (feature.properties.kind === 'text') {\n handleSave({ labelText: e.target.value });\n }\n }}\n onBlur={() => handleSave()}\n placeholder={isEditMode ? (feature.properties.kind === 'text' ? \"Enter label...\" : \"Feature name\") : \"No name\"}\n readOnly={!isEditMode}\n className=\"!h-6 text-[13px]\"\n data-testid=\"input-feature-name\"\n />\n </div>\n \n {/* Icon and Type field - Icon first, then Type */}\n {(typePickerProvider || (feature.geometry.type === 'Point' && feature.properties.kind !== 'text')) && (\n <div className=\"flex items-center gap-2\">\n {/* Point Icon - inline with Type */}\n {feature.geometry.type === 'Point' && feature.properties.kind !== 'text' && (\n <div className=\"flex items-center gap-1\">\n <label className=\"text-xs text-muted-foreground\">Icon</label>\n <IconPicker\n value={pointIcon}\n onChange={(icon) => {\n setPointIcon(icon);\n handleSave({ pointIcon: icon });\n }}\n disabled={!isEditMode}\n />\n {pointIcon && (\n <Button\n type=\"text\"\n icon={<X className=\"w-3 h-3\" />}\n onClick={() => {\n setPointIcon('');\n handleSave({ pointIcon: '' });\n }}\n disabled={!isEditMode}\n className=\"!w-5 !h-5 !min-w-0 !p-0\"\n data-testid=\"button-clear-point-icon\"\n />\n )}\n </div>\n )}\n \n {/* Entity Type field */}\n {typePickerProvider && (\n <div className=\"flex items-center gap-1 flex-1\">\n <label className=\"text-xs text-muted-foreground\">Type</label>\n <Input\n value={entityType || ''}\n readOnly\n placeholder=\"No type\"\n className=\"!h-6 text-[13px] flex-1\"\n data-testid=\"input-entity-type\"\n />\n {isEditMode && (\n <Button\n type=\"text\"\n size=\"small\"\n icon={<MoreHorizontal className=\"w-3.5 h-3.5\" />}\n onClick={() => {\n typePickerProvider(\n entityType,\n (selectedType) => {\n setEntityType(selectedType.id);\n handleSave({ entityType: selectedType.id });\n }\n );\n }}\n className=\"!w-6 !h-6 !min-w-0 !p-0 shrink-0\"\n data-testid=\"button-open-type-picker\"\n />\n )}\n </div>\n )}\n </div>\n )}\n \n {/* Lat/Lng display */}\n <div className=\"space-y-0.5\">\n <div className=\"flex items-center gap-1\">\n <label className=\"text-xs text-muted-foreground\">\n Lat / Lng\n </label>\n {feature.geometry.type !== 'Point' && (\n <Tooltip title=\"Lat and Lng refer to the centroid of this feature\">\n <span className=\"text-[13px] text-muted-foreground cursor-help\">*</span>\n </Tooltip>\n )}\n </div>\n <div className=\"flex gap-1\">\n <Input\n value={latitude}\n onChange={(e) => setLatitude(e.target.value)}\n onFocus={() => { latInputFocused.current = true; }}\n onBlur={() => {\n latInputFocused.current = false;\n if (feature.geometry.type === 'Point' && isEditMode && onUpdateGeometry) {\n const lat = parseFloat(latitude);\n const lng = parseFloat(longitude);\n const coords = (feature.geometry as GeoJSON.Point).coordinates as [number, number];\n \n if (isNaN(lat)) {\n toast({ title: 'Invalid latitude', description: 'Please enter a valid number', variant: 'destructive' });\n setLatitude(coords[1].toFixed(6));\n } else if (lat < -90 || lat > 90) {\n toast({ title: 'Invalid latitude', description: 'Latitude must be between -90 and 90', variant: 'destructive' });\n setLatitude(coords[1].toFixed(6));\n } else if (isNaN(lng) || lng < -180 || lng > 180) {\n // Longitude invalid, don't update yet\n } else {\n onUpdateGeometry(feature.id, {\n type: 'Point',\n coordinates: [lng, lat],\n });\n }\n }\n }}\n placeholder=\"Latitude\"\n readOnly={feature.geometry.type !== 'Point' || !isEditMode}\n className=\"!h-6 text-[13px] flex-1\"\n data-testid=\"input-feature-latitude\"\n />\n <Input\n value={longitude}\n onChange={(e) => setLongitude(e.target.value)}\n onFocus={() => { lngInputFocused.current = true; }}\n onBlur={() => {\n lngInputFocused.current = false;\n if (feature.geometry.type === 'Point' && isEditMode && onUpdateGeometry) {\n const lat = parseFloat(latitude);\n const lng = parseFloat(longitude);\n const coords = (feature.geometry as GeoJSON.Point).coordinates as [number, number];\n \n if (isNaN(lng)) {\n toast({ title: 'Invalid longitude', description: 'Please enter a valid number', variant: 'destructive' });\n setLongitude(coords[0].toFixed(6));\n } else if (lng < -180 || lng > 180) {\n toast({ title: 'Invalid longitude', description: 'Longitude must be between -180 and 180', variant: 'destructive' });\n setLongitude(coords[0].toFixed(6));\n } else if (isNaN(lat) || lat < -90 || lat > 90) {\n // Latitude invalid, don't update yet\n } else {\n onUpdateGeometry(feature.id, {\n type: 'Point',\n coordinates: [lng, lat],\n });\n }\n }\n }}\n placeholder=\"Longitude\"\n readOnly={feature.geometry.type !== 'Point' || !isEditMode}\n className=\"!h-6 text-[13px] flex-1\"\n data-testid=\"input-feature-longitude\"\n />\n </div>\n </div>\n \n <div className=\"space-y-0.5\">\n <label htmlFor=\"feature-description\" className=\"text-xs text-muted-foreground\">Description</label>\n <TextArea\n id=\"feature-description\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n onBlur={() => handleSave()}\n placeholder={isEditMode ? \"Add description...\" : \"No description\"}\n className=\"!min-h-[50px] resize-none text-[13px]\"\n readOnly={!isEditMode}\n data-testid=\"input-feature-description\"\n />\n </div>\n \n <Divider className=\"!my-1.5\" />\n \n <Collapse\n size=\"small\"\n defaultActiveKey={startDate || endDate ? ['temporal'] : []}\n ghost\n className=\"[&_.ant-collapse-header]:!px-0 [&_.ant-collapse-header]:!py-1 [&_.ant-collapse-content-box]:!px-0 [&_.ant-collapse-content-box]:!py-1\"\n items={[{\n key: 'temporal',\n label: (\n <div className=\"flex items-center gap-1\">\n <CalendarIcon className=\"w-3 h-3 text-foreground\" />\n <span className=\"text-xs font-medium\">Temporal</span>\n {(startDate || endDate) && (\n <span className=\"text-[10px] text-muted-foreground ml-1\">\n ({startDate && endDate ? '2 dates' : '1 date'})\n </span>\n )}\n </div>\n ),\n children: (\n <div className=\"space-y-1.5\">\n <div className=\"flex items-center gap-2\">\n <label className=\"text-[13px] text-muted-foreground w-8 shrink-0\">Start</label>\n <input\n type=\"datetime-local\"\n value={startDate ? format(new Date(startDate), \"yyyy-MM-dd'T'HH:mm\") : ''}\n onChange={(e) => {\n const val = e.target.value;\n if (val) {\n const newDate = new Date(val).toISOString();\n setStartDate(newDate);\n setTimeout(() => handleSave(), 0);\n } else {\n setStartDate('');\n setTimeout(() => handleSave(), 0);\n }\n }}\n className=\"flex-1 h-6 text-[13px] px-2 rounded-md border border-input bg-background\"\n disabled={!isEditMode}\n data-testid=\"input-feature-start-date\"\n />\n {startDate && isEditMode && (\n <Button\n type=\"text\"\n icon={<X className=\"w-3 h-3\" />}\n onClick={() => {\n setStartDate('');\n setTimeout(() => handleSave(), 0);\n }}\n className=\"!w-6 !h-6 !min-w-0 !p-0 shrink-0\"\n data-testid=\"button-clear-start-date\"\n />\n )}\n </div>\n <div className=\"flex items-center gap-2\">\n <label className=\"text-[13px] text-muted-foreground w-8 shrink-0\">End</label>\n <input\n type=\"datetime-local\"\n value={endDate ? format(new Date(endDate), \"yyyy-MM-dd'T'HH:mm\") : ''}\n onChange={(e) => {\n const val = e.target.value;\n if (val) {\n const newDate = new Date(val).toISOString();\n setEndDate(newDate);\n setTimeout(() => handleSave(), 0);\n } else {\n setEndDate('');\n setTimeout(() => handleSave(), 0);\n }\n }}\n className=\"flex-1 h-6 text-[13px] px-2 rounded-md border border-input bg-background\"\n disabled={!isEditMode}\n data-testid=\"input-feature-end-date\"\n />\n {endDate && isEditMode && (\n <Button\n type=\"text\"\n icon={<X className=\"w-3 h-3\" />}\n onClick={() => {\n setEndDate('');\n setTimeout(() => handleSave(), 0);\n }}\n className=\"!w-6 !h-6 !min-w-0 !p-0 shrink-0\"\n data-testid=\"button-clear-end-date\"\n />\n )}\n </div>\n </div>\n ),\n }]}\n />\n \n <Divider className=\"!my-1.5\" />\n \n <div className=\"space-y-1\">\n <div className=\"flex items-center gap-1\">\n <Palette className=\"w-3 h-3 text-foreground\" />\n <span className=\"text-xs font-medium\">Style</span>\n </div>\n \n {/* Text Feature Styling */}\n {feature.properties.kind === 'text' && (\n <div className=\"space-y-1.5\">\n <div>\n <label className=\"text-[13px] text-muted-foreground\">Font Size</label>\n <div className=\"flex items-center gap-1\">\n <Slider\n value={fontSize}\n min={8}\n max={48}\n step={1}\n className=\"flex-1\"\n onChange={(val) => {\n setFontSize(val);\n handleSave({ fontSize: val });\n }}\n disabled={!isEditMode}\n />\n <span className=\"text-xs w-6 text-right\">{fontSize}</span>\n </div>\n </div>\n <div>\n <label className=\"text-[13px] text-muted-foreground\">Font Color</label>\n <div className=\"flex gap-1 flex-wrap\">\n {PRESET_COLORS.map((color) => (\n <button\n key={color}\n onClick={() => {\n if (!isEditMode) return;\n setFontColor(color);\n handleSave({ fontColor: color });\n }}\n className={`w-5 h-5 rounded-md border-2 ${fontColor === color ? 'border-primary' : 'border-transparent'}`}\n style={{ backgroundColor: color }}\n disabled={!isEditMode}\n data-testid={`button-font-color-${color}`}\n />\n ))}\n </div>\n </div>\n <div>\n <label className=\"text-[13px] text-muted-foreground\">Font Weight</label>\n <div className=\"flex gap-1\">\n <Button\n type={fontWeight === 'normal' ? 'primary' : 'default'}\n size=\"small\"\n onClick={() => {\n if (!isEditMode) return;\n setFontWeight('normal');\n handleSave({ fontWeight: 'normal' });\n }}\n disabled={!isEditMode}\n className=\"flex-1\"\n >\n Normal\n </Button>\n <Button\n type={fontWeight === 'bold' ? 'primary' : 'default'}\n size=\"small\"\n onClick={() => {\n if (!isEditMode) return;\n setFontWeight('bold');\n handleSave({ fontWeight: 'bold' });\n }}\n disabled={!isEditMode}\n className=\"flex-1\"\n >\n Bold\n </Button>\n </div>\n </div>\n </div>\n )}\n \n {/* Arrow Feature Styling */}\n {feature.properties.kind === 'arrow' && (\n <div className=\"space-y-1.5\">\n <div>\n <label className=\"text-[13px] text-muted-foreground\">Arrow Size</label>\n <div className=\"flex items-center gap-1\">\n <Slider\n value={arrowSize}\n min={24}\n max={200}\n step={4}\n className=\"flex-1\"\n onChange={(val) => {\n setArrowSize(val);\n handleSave({ arrowSize: val });\n }}\n disabled={!isEditMode}\n />\n <span className=\"text-xs w-8 text-right\">{arrowSize}px</span>\n </div>\n </div>\n </div>\n )}\n \n {/* Standard Geometry Styling */}\n {feature.properties.kind !== 'text' && (\n <>\n <div className=\"flex items-center gap-2\">\n <label className=\"text-[13px] text-muted-foreground shrink-0\">Stroke</label>\n <Tooltip title=\"Stroke Color\">\n <span>\n <ColorPicker\n value={strokeColor}\n onChange={(color) => {\n const hex = color.toHexString();\n setStrokeColor(hex);\n handleSave({ strokeColor: hex });\n }}\n disabled={!isEditMode}\n size=\"small\"\n showText={false}\n data-testid=\"color-picker-stroke\"\n />\n </span>\n </Tooltip>\n <Tooltip title=\"Stroke Width\">\n <span>\n <Select\n value={strokeWidth}\n onChange={(val) => {\n setStrokeWidth(val);\n handleSave({ strokeWidth: val });\n }}\n disabled={!isEditMode}\n size=\"small\"\n className=\"w-14\"\n options={[\n { value: 1, label: '1px' },\n { value: 2, label: '2px' },\n { value: 3, label: '3px' },\n { value: 4, label: '4px' },\n { value: 5, label: '5px' },\n { value: 6, label: '6px' },\n { value: 7, label: '7px' },\n { value: 8, label: '8px' },\n { value: 9, label: '9px' },\n { value: 10, label: '10px' },\n ]}\n data-testid=\"select-stroke-width\"\n />\n </span>\n </Tooltip>\n <Tooltip title=\"Stroke Opacity\">\n <span className=\"flex items-center gap-1\">\n <Blend className=\"w-3 h-3 text-muted-foreground\" />\n <Select\n value={strokeOpacity}\n onChange={(val) => {\n setStrokeOpacity(val);\n handleSave({ strokeOpacity: val });\n }}\n disabled={!isEditMode}\n size=\"small\"\n className=\"w-[72px]\"\n options={[\n { value: 0, label: '0%' },\n { value: 0.1, label: '10%' },\n { value: 0.2, label: '20%' },\n { value: 0.3, label: '30%' },\n { value: 0.4, label: '40%' },\n { value: 0.5, label: '50%' },\n { value: 0.6, label: '60%' },\n { value: 0.7, label: '70%' },\n { value: 0.8, label: '80%' },\n { value: 0.9, label: '90%' },\n { value: 1, label: '100%' },\n ]}\n data-testid=\"select-stroke-opacity\"\n />\n </span>\n </Tooltip>\n </div>\n \n {(feature.geometry.type === 'Polygon' || feature.properties.kind === 'circle') && (\n <div className=\"flex items-center gap-2\">\n <label className=\"text-[13px] text-muted-foreground shrink-0\">Fill</label>\n <Tooltip title=\"Fill Color\">\n <span>\n <ColorPicker\n value={fillColor}\n onChange={(color) => {\n const hex = color.toHexString();\n setFillColor(hex);\n handleSave({ fillColor: hex });\n }}\n disabled={!isEditMode}\n size=\"small\"\n showText={false}\n data-testid=\"color-picker-fill\"\n />\n </span>\n </Tooltip>\n <Tooltip title=\"Fill Opacity\">\n <span className=\"flex items-center gap-1\">\n <Blend className=\"w-3 h-3 text-muted-foreground\" />\n <Select\n value={fillOpacity}\n onChange={(val) => {\n setFillOpacity(val);\n handleSave({ fillOpacity: val });\n }}\n disabled={!isEditMode}\n size=\"small\"\n className=\"w-[72px]\"\n options={[\n { value: 0, label: '0%' },\n { value: 0.1, label: '10%' },\n { value: 0.2, label: '20%' },\n { value: 0.3, label: '30%' },\n { value: 0.4, label: '40%' },\n { value: 0.5, label: '50%' },\n { value: 0.6, label: '60%' },\n { value: 0.7, label: '70%' },\n { value: 0.8, label: '80%' },\n { value: 0.9, label: '90%' },\n { value: 1, label: '100%' },\n ]}\n data-testid=\"select-fill-opacity\"\n />\n </span>\n </Tooltip>\n </div>\n )}\n \n {/* Point Icon Size - only show when icon is selected (icon picker is now in Icon+Type row) */}\n {feature.geometry.type === 'Point' && feature.properties.kind !== 'text' && pointIcon && (\n <div className=\"flex items-center gap-2\">\n <label className=\"text-[13px] text-muted-foreground shrink-0\">Size</label>\n <Slider\n value={pointIconSize}\n min={12}\n max={48}\n step={2}\n className=\"flex-1\"\n onChange={(val) => {\n setPointIconSize(val);\n handleSave({ pointIconSize: val });\n }}\n disabled={!isEditMode}\n />\n <span className=\"text-xs w-6 text-right\">{pointIconSize}</span>\n </div>\n )}\n </>\n )}\n </div>\n \n <Divider className=\"!my-1.5\" />\n \n <div className=\"space-y-1\">\n <span className=\"text-xs font-medium\">Custom Properties</span>\n \n {customProperties.length === 0 && !isEditMode && (\n <p className=\"text-[13px] text-muted-foreground\">None</p>\n )}\n \n {customProperties.length > 0 && (\n <div className=\"space-y-0.5\">\n {customProperties.map((prop, index) => (\n <div key={index} className=\"flex items-center gap-0.5\">\n <Input\n value={prop.key}\n onChange={(e) => handlePropertyKeyChange(index, e.target.value)}\n onBlur={() => handleSave()}\n placeholder=\"Key\"\n className=\"flex-1 text-[13px] font-mono !h-5 !px-1\"\n readOnly={!isEditMode}\n data-testid={`input-property-key-${index}`}\n />\n <Input\n value={prop.value}\n onChange={(e) => handlePropertyValueChange(index, e.target.value)}\n onBlur={() => handleSave()}\n placeholder=\"Val\"\n className=\"flex-1 text-[13px] !h-5 !px-1\"\n readOnly={!isEditMode}\n data-testid={`input-property-value-${index}`}\n />\n {isEditMode && (\n <button\n type=\"button\"\n onClick={() => {\n handleRemoveProperty(index);\n setTimeout(() => handleSave(), 0);\n }}\n className=\"text-destructive shrink-0 h-5 w-5 flex items-center justify-center\"\n data-testid={`button-remove-property-${index}`}\n >\n <Trash2 className=\"w-2.5 h-2.5\" />\n </button>\n )}\n </div>\n ))}\n </div>\n )}\n \n {isEditMode && (\n <div className=\"flex items-center gap-0.5\">\n <Input\n value={newPropertyKey}\n onChange={(e) => setNewPropertyKey(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n handleAddProperty();\n }\n }}\n placeholder=\"New property...\"\n className=\"flex-1 text-[13px] !h-5 !px-1\"\n data-testid=\"input-new-property-key\"\n />\n <button\n type=\"button\"\n onClick={handleAddProperty}\n disabled={!newPropertyKey.trim()}\n className=\"h-5 w-5 flex items-center justify-center border border-border rounded disabled:opacity-50\"\n data-testid=\"button-add-property\"\n >\n <Plus className=\"w-2.5 h-2.5\" />\n </button>\n </div>\n )}\n </div>\n \n <Divider className=\"!my-1.5\" />\n \n <div className=\"flex items-center gap-3 flex-wrap\">\n {layerName && (\n <div>\n <span className=\"text-[13px] text-muted-foreground\">Layer: </span>\n <span className=\"text-[13px] text-foreground\" data-testid=\"text-feature-layer\">{layerName}</span>\n </div>\n )}\n <div>\n <span className=\"text-[13px] text-muted-foreground\">ID: </span>\n <code className=\"text-[13px] font-mono text-muted-foreground\">{feature.id.slice(0, 12)}...</code>\n </div>\n </div>\n </div>\n );\n\n // With entityCardProvider - show tabs (works for both single and multi-selection)\n if (entityCardProvider) {\n return (\n <div \n className=\"absolute top-4 right-4 z-10 w-72 bg-background/95 floating-panel rounded-lg shadow-lg border border-border flex flex-col overflow-hidden\"\n style={{ maxHeight: 'calc(100vh - 6rem)' }}\n data-testid=\"panel-properties\"\n >\n <div className=\"flex items-center justify-between gap-2 px-3 py-2 border-b border-border shrink-0 bg-background/95\">\n <div className=\"flex items-center gap-2 min-w-0\">\n <span className=\"text-primary shrink-0\">\n {hasMultipleSelection ? (\n <Package className=\"w-4 h-4\" />\n ) : (\n getFeatureTypeIcon(feature.geometry.type, feature.properties.kind as string | undefined)\n )}\n </span>\n <span className=\"text-sm font-semibold\">\n {selectedFeatures.length} selected {selectedFeatures.length === 1 ? 'feature' : 'features'}\n </span>\n </div>\n <Button type=\"text\" icon={<X className=\"w-4 h-4\" />} onClick={onClose} className=\"!w-6 !h-6 !min-w-0 !p-0 shrink-0\" data-testid=\"button-close-properties\" />\n </div>\n \n <Tabs\n activeKey={activeTab}\n onChange={handleTabChange}\n onTabClick={handleTabClick}\n size=\"small\"\n className=\"flex-1 min-h-0 flex flex-col [&_.ant-tabs-nav]:px-2 [&_.ant-tabs-nav]:mb-0 [&_.ant-tabs-nav]:shrink-0 [&_.ant-tabs-content-holder]:flex-1 [&_.ant-tabs-content-holder]:min-h-0 [&_.ant-tabs-content-holder]:flex [&_.ant-tabs-content-holder]:flex-col [&_.ant-tabs-content]:flex-1 [&_.ant-tabs-content]:min-h-0 [&_.ant-tabs-content]:flex [&_.ant-tabs-content]:flex-col [&_.ant-tabs-tabpane-active]:flex-1 [&_.ant-tabs-tabpane-active]:min-h-0 [&_.ant-tabs-tabpane-active]:flex [&_.ant-tabs-tabpane-active]:flex-col\"\n items={[\n {\n key: 'cards',\n label: selectedFeatures.length >= 2 ? `Entity Cards (${selectedFeatures.length})` : 'Entity Cards',\n children: (\n <div className=\"flex-1 min-h-0 overflow-y-auto overflow-x-hidden scrollbar-visible\">\n {entityCardsContent}\n </div>\n ),\n },\n {\n key: 'properties',\n label: 'Properties',\n disabled: hasMultipleSelection,\n children: (\n <div className=\"flex-1 min-h-0 overflow-y-auto overflow-x-hidden scrollbar-visible relative\">\n {hasMultipleSelection ? (\n <>\n {propertiesDisabledOverlay}\n <div \n className=\"opacity-30 pointer-events-none\" \n aria-hidden=\"true\"\n {...{ inert: '' } as any}\n >\n {propertiesContent}\n </div>\n </>\n ) : propertiesContent}\n </div>\n ),\n },\n ]}\n />\n </div>\n );\n }\n\n // Single selection without entityCardProvider - original view\n return (\n <div \n className=\"absolute top-4 right-4 z-10 w-64 bg-background/95 floating-panel rounded-lg shadow-lg border border-border flex flex-col overflow-hidden\"\n style={{ maxHeight: 'calc(100vh - 6rem)' }}\n data-testid=\"panel-properties\"\n >\n <div className=\"flex items-center justify-between gap-2 px-3 py-2 border-b border-border shrink-0 bg-background/95\">\n <div className=\"flex items-center gap-2 min-w-0\">\n <span className=\"text-primary shrink-0\">\n {getFeatureTypeIcon(feature.geometry.type, feature.properties.kind as string | undefined)}\n </span>\n <span className=\"text-sm font-semibold\">1 selected feature</span>\n {!isEditMode && (\n <Tag className=\"text-xs px-1.5 py-0\">View</Tag>\n )}\n </div>\n <Button type=\"text\" icon={<X className=\"w-4 h-4\" />} onClick={onClose} className=\"!w-6 !h-6 !min-w-0 !p-0 shrink-0\" data-testid=\"button-close-properties\" />\n </div>\n \n <div className=\"flex-1 overflow-y-auto overflow-x-hidden scrollbar-visible\">\n {propertiesContent}\n </div>\n </div>\n );\n}\n","import { Tag } from 'antd';\nimport type { DrawingMode, SelectionMode } from '@/components/drawing-toolbar';\n\ninterface StatusIndicatorProps {\n activeMode: DrawingMode;\n featureCount: number;\n selectedCount?: number;\n selectionMode?: SelectionMode;\n}\n\nexport function StatusIndicator({ featureCount, selectedCount = 0 }: StatusIndicatorProps) {\n const hasSelection = selectedCount > 0;\n \n if (!hasSelection) {\n return null;\n }\n \n return (\n <div \n className=\"absolute bottom-4 left-4 z-10 flex items-center gap-2 px-3 py-1.5 bg-background/80 floating-panel rounded-lg shadow-lg border border-border\"\n role=\"status\"\n aria-live=\"polite\"\n data-testid=\"status-indicator\"\n >\n <Tag className=\"font-mono text-xs !m-0\" data-testid=\"badge-feature-count\">\n {featureCount} feature{featureCount !== 1 ? 's' : ''}\n </Tag>\n \n <div className=\"w-px h-4 bg-border\" />\n \n <Tag className=\"font-mono text-xs !m-0\" data-testid=\"badge-selected-count\">\n {selectedCount} selected\n </Tag>\n </div>\n );\n}\n","import { create } from 'zustand';\n\nexport interface TemporalFeature {\n id: string;\n startDate: Date | null;\n endDate: Date | null;\n layerId: string;\n}\n\nexport interface TimelineState {\n isEnabled: boolean;\n hasTemporalData: boolean;\n temporalFeatures: TemporalFeature[];\n untimedFeatureIds: string[];\n \n globalMinDate: Date | null;\n globalMaxDate: Date | null;\n \n rangeStart: Date | null;\n rangeEnd: Date | null;\n \n isPlaying: boolean;\n playbackSpeed: number;\n \n histogramBins: { start: Date; end: Date; count: number }[];\n \n setEnabled: (enabled: boolean) => void;\n setTemporalFeatures: (features: TemporalFeature[], untimedIds: string[]) => void;\n setRange: (start: Date | null, end: Date | null) => void;\n setPlaying: (playing: boolean) => void;\n setPlaybackSpeed: (speed: number) => void;\n advancePlayhead: () => boolean;\n reset: () => void;\n}\n\nfunction parseDate(value: unknown): Date | null {\n if (!value) return null;\n if (value instanceof Date) return value;\n if (typeof value === 'string' || typeof value === 'number') {\n const date = new Date(value);\n return isNaN(date.getTime()) ? null : date;\n }\n return null;\n}\n\nexport function normalizeTemporalProperties(properties: Record<string, unknown>): {\n startDate: Date | null;\n endDate: Date | null;\n} {\n // Check various common date property names for start date\n let startDate = parseDate(properties.startDate) || \n parseDate(properties.startdate) || \n parseDate(properties.start_date) ||\n parseDate(properties.date) ||\n parseDate(properties.timestamp) ||\n parseDate(properties.flightDate) ||\n parseDate(properties.time) ||\n parseDate(properties.datetime);\n \n // Check various common date property names for end date\n let endDate = parseDate(properties.endDate) || \n parseDate(properties.enddate) || \n parseDate(properties.end_date);\n \n if (startDate && endDate && endDate < startDate) {\n [startDate, endDate] = [endDate, startDate];\n }\n \n return { startDate, endDate };\n}\n\nexport function isFeatureInRange(\n feature: TemporalFeature,\n rangeStart: Date | null,\n rangeEnd: Date | null\n): boolean {\n if (!feature.startDate && !feature.endDate) return true;\n if (!rangeStart || !rangeEnd) return true;\n \n const featureStart = feature.startDate || feature.endDate!;\n const featureEnd = feature.endDate || feature.startDate!;\n \n return featureStart <= rangeEnd && featureEnd >= rangeStart;\n}\n\nfunction computeHistogramBins(\n features: TemporalFeature[],\n minDate: Date,\n maxDate: Date,\n binCount: number = 50\n): { start: Date; end: Date; count: number }[] {\n let range = maxDate.getTime() - minDate.getTime();\n \n // Handle single point case: create arbitrary padding (±1 day or ±1 hour if small)\n let effectiveMin = minDate;\n let effectiveMax = maxDate;\n if (range === 0) {\n // Single point - add padding of 1 day on each side\n const padding = 24 * 60 * 60 * 1000; // 1 day in ms\n effectiveMin = new Date(minDate.getTime() - padding);\n effectiveMax = new Date(maxDate.getTime() + padding);\n range = effectiveMax.getTime() - effectiveMin.getTime();\n }\n \n const binSize = range / binCount;\n \n const bins: { start: Date; end: Date; count: number }[] = [];\n \n for (let i = 0; i < binCount; i++) {\n bins.push({\n start: new Date(effectiveMin.getTime() + i * binSize),\n end: new Date(effectiveMin.getTime() + (i + 1) * binSize),\n count: 0,\n });\n }\n \n features.forEach(feature => {\n if (!feature.startDate) return;\n const featureTime = feature.startDate.getTime();\n const binIndex = Math.min(\n Math.floor((featureTime - effectiveMin.getTime()) / binSize),\n binCount - 1\n );\n if (binIndex >= 0 && binIndex < binCount) {\n bins[binIndex].count++;\n }\n });\n \n return bins;\n}\n\nexport const useTimelineStore = create<TimelineState>((set, get) => ({\n isEnabled: false,\n hasTemporalData: false,\n temporalFeatures: [],\n untimedFeatureIds: [],\n \n globalMinDate: null,\n globalMaxDate: null,\n \n rangeStart: null,\n rangeEnd: null,\n \n isPlaying: false,\n playbackSpeed: 1,\n \n histogramBins: [],\n \n setEnabled: (enabled) => {\n if (enabled) {\n // When opening timebar, reset range to full extent\n const state = get();\n set({ \n isEnabled: true,\n rangeStart: state.globalMinDate,\n rangeEnd: state.globalMaxDate,\n });\n } else {\n // When closing, just disable - no filtering should apply\n set({ isEnabled: false, isPlaying: false });\n }\n },\n \n setTemporalFeatures: (features, untimedIds) => {\n const timedFeatures = features.filter(f => f.startDate || f.endDate);\n \n if (timedFeatures.length === 0) {\n set({\n hasTemporalData: false,\n temporalFeatures: [],\n untimedFeatureIds: untimedIds,\n globalMinDate: null,\n globalMaxDate: null,\n rangeStart: null,\n rangeEnd: null,\n histogramBins: [],\n });\n return;\n }\n \n let minDate: Date | null = null;\n let maxDate: Date | null = null;\n \n timedFeatures.forEach(f => {\n const start = f.startDate;\n const end = f.endDate || f.startDate;\n \n if (start && (!minDate || start < minDate)) minDate = start;\n if (end && (!maxDate || end > maxDate)) maxDate = end;\n });\n \n const state = get();\n const histogramBins = minDate && maxDate \n ? computeHistogramBins(timedFeatures, minDate, maxDate)\n : [];\n \n set({\n hasTemporalData: true,\n temporalFeatures: timedFeatures,\n untimedFeatureIds: untimedIds,\n globalMinDate: minDate,\n globalMaxDate: maxDate,\n rangeStart: state.rangeStart || minDate,\n rangeEnd: state.rangeEnd || maxDate,\n histogramBins,\n });\n },\n \n setRange: (start, end) => set({ rangeStart: start, rangeEnd: end }),\n \n setPlaying: (playing) => set({ isPlaying: playing }),\n \n setPlaybackSpeed: (speed) => set({ playbackSpeed: speed }),\n \n advancePlayhead: () => {\n const state = get();\n if (!state.globalMinDate || !state.globalMaxDate || !state.rangeStart) {\n return false;\n }\n \n const totalRange = state.globalMaxDate.getTime() - state.globalMinDate.getTime();\n const stepSize = totalRange / 10;\n \n const newStart = new Date(state.rangeStart.getTime() + stepSize);\n const newEnd = state.rangeEnd ? new Date(state.rangeEnd.getTime() + stepSize) : null;\n \n if (newStart >= state.globalMaxDate) {\n set({ \n isPlaying: false,\n rangeStart: state.globalMinDate,\n rangeEnd: state.globalMaxDate,\n });\n return false;\n }\n \n set({\n rangeStart: newStart,\n rangeEnd: newEnd && newEnd <= state.globalMaxDate ? newEnd : state.globalMaxDate,\n });\n return true;\n },\n \n reset: () => set({\n isEnabled: false,\n hasTemporalData: false,\n temporalFeatures: [],\n untimedFeatureIds: [],\n globalMinDate: null,\n globalMaxDate: null,\n rangeStart: null,\n rangeEnd: null,\n isPlaying: false,\n histogramBins: [],\n }),\n}));\n","import { useEffect, useRef, useCallback, useState } from 'react';\nimport { Clock, Play, Pause, SkipBack } from 'lucide-react';\nimport { Button, Slider } from 'antd';\nimport { useTimelineStore, isFeatureInRange } from '@/lib/timeline-store';\nimport { cn } from '@/lib/utils';\n\n// Export timebar height for positioning other elements\nexport const TIMEBAR_HEIGHT = 152; // timescale(20) + histogram(64) + slider(24) + controls(28) + padding(16)\nexport const TIMEBAR_BOTTOM_OFFSET = 12;\n\ninterface TimebarProps {\n onFilterChange: (visibleIds: string[], hiddenIds: string[], untimedIds: string[]) => void;\n selectedFeatureIds?: string[];\n selectedFeatureColors?: Map<string, string>; // Map of feature ID to color\n className?: string;\n}\n\nfunction formatDate(date: Date | null): string {\n if (!date) return '';\n return date.toLocaleDateString('en-US', { \n month: 'short', \n day: 'numeric',\n year: 'numeric'\n });\n}\n\nfunction formatTickDate(date: Date, showYear: boolean): string {\n if (showYear) {\n return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: '2-digit' });\n }\n return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });\n}\n\nfunction Timescale({ minDate, maxDate, binCount }: { minDate: Date; maxDate: Date; binCount: number }) {\n // Calculate optimal number of ticks (5-7 labels max)\n const tickCount = Math.min(7, Math.max(3, Math.floor(binCount / 3)));\n const range = maxDate.getTime() - minDate.getTime();\n const showYear = range > 180 * 24 * 60 * 60 * 1000; // Show year if range > 6 months\n \n const ticks = Array.from({ length: tickCount }, (_, i) => {\n const percent = i / (tickCount - 1);\n const date = new Date(minDate.getTime() + percent * range);\n return { percent: percent * 100, date };\n });\n \n return (\n <div className=\"relative h-4 text-[9px] text-muted-foreground mb-1\">\n {ticks.map((tick, i) => (\n <div\n key={i}\n className=\"absolute transform -translate-x-1/2 whitespace-nowrap\"\n style={{ left: `${tick.percent}%` }}\n >\n <div className=\"flex flex-col items-center\">\n <span className=\"font-mono\">{formatTickDate(tick.date, showYear)}</span>\n <div className=\"w-px h-1 bg-muted-foreground/40\" />\n </div>\n </div>\n ))}\n </div>\n );\n}\n\nfunction formatDateTime(date: Date): string {\n return date.toLocaleDateString('en-US', { \n month: 'short', \n day: 'numeric',\n year: 'numeric',\n hour: 'numeric',\n minute: '2-digit'\n });\n}\n\ninterface HistogramProps {\n bins: { start: Date; end: Date; count: number }[];\n maxCount: number;\n selectedBins?: number[];\n colorGroupedBins?: { color: string; bins: number[] }[]; // Multiple colored selection lines\n}\n\nfunction Histogram({ bins, maxCount, selectedBins, colorGroupedBins }: HistogramProps) {\n const [hoveredBin, setHoveredBin] = useState<number | null>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n \n if (bins.length === 0 || maxCount === 0) return null;\n \n // Show color-grouped lines if available, otherwise fall back to single line\n const hasColorGroups = colorGroupedBins && colorGroupedBins.length > 0 && \n colorGroupedBins.some(group => group.bins.some(count => count > 0));\n const hasSelection = !hasColorGroups && selectedBins && selectedBins.length > 0 && \n selectedBins.some(count => count > 0);\n \n return (\n <div className=\"relative h-16\" ref={containerRef}>\n {/* Background bars (all features) */}\n <div className=\"absolute inset-0 flex items-end gap-px\">\n {bins.map((bin, i) => {\n const height = (bin.count / maxCount) * 100;\n const isHovered = hoveredBin === i;\n return (\n <div\n key={i}\n className={cn(\n \"flex-1 rounded-t-sm min-w-[2px] transition-colors cursor-pointer\",\n isHovered ? \"bg-primary/80\" : \"bg-primary/50\"\n )}\n style={{ height: `${Math.max(height, bin.count > 0 ? 4 : 0)}%` }}\n onMouseEnter={() => setHoveredBin(i)}\n onMouseLeave={() => setHoveredBin(null)}\n data-testid={`bar-histogram-${i}`}\n />\n );\n })}\n </div>\n \n {/* Color-grouped line chart overlays for selected features */}\n {hasColorGroups && (\n <svg className=\"absolute inset-0 pointer-events-none w-full h-full\" viewBox=\"0 0 100 100\" preserveAspectRatio=\"none\">\n {colorGroupedBins!.map((group, groupIndex) => {\n // Only render if this group has data\n if (!group.bins.some(count => count > 0)) return null;\n return (\n <polyline\n key={groupIndex}\n fill=\"none\"\n stroke={group.color}\n strokeWidth=\"2\"\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n vectorEffect=\"non-scaling-stroke\"\n points={group.bins.map((count, i) => {\n const x = (i + 0.5) * (100 / bins.length);\n const y = 100 - (count / maxCount) * 100;\n return `${x},${y}`;\n }).join(' ')}\n />\n );\n })}\n </svg>\n )}\n \n {/* Fallback: Single line chart overlay for selected features (no color info) */}\n {hasSelection && (\n <svg className=\"absolute inset-0 pointer-events-none w-full h-full\" viewBox=\"0 0 100 100\" preserveAspectRatio=\"none\">\n <polyline\n fill=\"none\"\n stroke=\"hsl(var(--foreground))\"\n strokeWidth=\"1.5\"\n strokeLinejoin=\"round\"\n strokeLinecap=\"round\"\n vectorEffect=\"non-scaling-stroke\"\n points={selectedBins!.map((count, i) => {\n const x = (i + 0.5) * (100 / bins.length);\n const y = 100 - (count / maxCount) * 100;\n return `${x},${y}`;\n }).join(' ')}\n />\n </svg>\n )}\n \n {/* Hover tooltip */}\n {hoveredBin !== null && bins[hoveredBin] && (\n <div \n className=\"absolute z-30 bg-popover border border-border rounded-md shadow-lg px-2 py-1.5 text-xs pointer-events-none whitespace-nowrap\"\n style={{\n left: `${(hoveredBin + 0.5) * (100 / bins.length)}%`,\n bottom: '100%',\n transform: 'translateX(-50%)',\n marginBottom: '4px'\n }}\n >\n <div className=\"font-medium\">{formatDateTime(bins[hoveredBin].start)}</div>\n <div className=\"text-muted-foreground\">\n {bins[hoveredBin].count} event{bins[hoveredBin].count !== 1 ? 's' : ''}\n {selectedBins && selectedBins[hoveredBin] > 0 && (\n <span className=\"ml-1 text-foreground font-medium\">\n ({selectedBins[hoveredBin]} selected)\n </span>\n )}\n </div>\n </div>\n )}\n </div>\n );\n}\n\nexport function TimebarToggle({ onClick, hasData }: { onClick: () => void; hasData: boolean }) {\n if (!hasData) return null;\n \n return (\n <Button\n type=\"text\"\n icon={<Clock className=\"w-5 h-5\" />}\n onClick={onClick}\n className=\"relative !w-9 !h-9 !min-w-0 !p-0\"\n aria-label=\"Toggle timeline\"\n data-testid=\"button-timeline-toggle\"\n />\n );\n}\n\nexport function Timebar({ onFilterChange, selectedFeatureIds = [], selectedFeatureColors, className }: TimebarProps) {\n const {\n isEnabled,\n hasTemporalData,\n temporalFeatures,\n untimedFeatureIds,\n globalMinDate,\n globalMaxDate,\n rangeStart,\n rangeEnd,\n isPlaying,\n histogramBins,\n setRange,\n setPlaying,\n } = useTimelineStore();\n \n // Compute color-grouped bins for selected features\n const colorGroupedBins = histogramBins.length > 0 && selectedFeatureIds.length > 0 && \n selectedFeatureColors && selectedFeatureColors.size > 0 && globalMinDate && globalMaxDate\n ? (() => {\n const selectedSet = new Set(selectedFeatureIds);\n const selectedTemporalFeatures = temporalFeatures.filter(f => selectedSet.has(f.id));\n \n if (selectedTemporalFeatures.length === 0) return [];\n \n // Group features by color\n const colorGroups = new Map<string, typeof selectedTemporalFeatures>();\n selectedTemporalFeatures.forEach(f => {\n const color = selectedFeatureColors.get(f.id) || '#3b82f6';\n if (!colorGroups.has(color)) colorGroups.set(color, []);\n colorGroups.get(color)!.push(f);\n });\n \n // Compute bins for each color group\n const result: { color: string; bins: number[] }[] = [];\n colorGroups.forEach((features, color) => {\n const bins = histogramBins.map((bin, binIndex) => {\n let count = 0;\n const isLastBin = binIndex === histogramBins.length - 1;\n features.forEach(f => {\n if (!f.startDate) return;\n const featureTime = f.startDate.getTime();\n // Use <= for last bin's end to include points exactly on maxDate\n const inBin = featureTime >= bin.start.getTime() && \n (isLastBin ? featureTime <= bin.end.getTime() : featureTime < bin.end.getTime());\n if (inBin) {\n count++;\n }\n });\n return count;\n });\n result.push({ color, bins });\n });\n \n return result;\n })()\n : [];\n \n // Compute bins for selected features only (fallback when no color info)\n const selectedBins = histogramBins.length > 0 && selectedFeatureIds.length > 0 && \n (!selectedFeatureColors || selectedFeatureColors.size === 0) && globalMinDate && globalMaxDate\n ? (() => {\n const selectedSet = new Set(selectedFeatureIds);\n const selectedTemporalFeatures = temporalFeatures.filter(f => selectedSet.has(f.id));\n \n if (selectedTemporalFeatures.length === 0) return [];\n \n const bins = histogramBins.map((bin, binIndex) => {\n let count = 0;\n const isLastBin = binIndex === histogramBins.length - 1;\n selectedTemporalFeatures.forEach(f => {\n if (!f.startDate) return;\n const featureTime = f.startDate.getTime();\n // Use <= for last bin's end to include points exactly on maxDate\n const inBin = featureTime >= bin.start.getTime() && \n (isLastBin ? featureTime <= bin.end.getTime() : featureTime < bin.end.getTime());\n if (inBin) {\n count++;\n }\n });\n return count;\n });\n return bins;\n })()\n : [];\n \n const animationFrameRef = useRef<number | null>(null);\n const lastFrameTimeRef = useRef<number>(0);\n const playbackDuration = 10000; // Complete playback in 10 seconds\n const targetFps = 30;\n const frameInterval = 1000 / targetFps; // ~33ms between frames\n \n const applyFilter = useCallback(() => {\n const visibleIds: string[] = [];\n const hiddenIds: string[] = [];\n \n temporalFeatures.forEach(feature => {\n if (isFeatureInRange(feature, rangeStart, rangeEnd)) {\n visibleIds.push(feature.id);\n } else {\n hiddenIds.push(feature.id);\n }\n });\n \n onFilterChange(visibleIds, hiddenIds, untimedFeatureIds);\n }, [temporalFeatures, untimedFeatureIds, rangeStart, rangeEnd, onFilterChange]);\n \n useEffect(() => {\n if (isEnabled && hasTemporalData) {\n applyFilter();\n }\n }, [isEnabled, hasTemporalData, rangeStart, rangeEnd, applyFilter]);\n \n useEffect(() => {\n if (!isPlaying || !globalMinDate || !globalMaxDate) {\n if (animationFrameRef.current) {\n cancelAnimationFrame(animationFrameRef.current);\n animationFrameRef.current = null;\n }\n return;\n }\n \n const totalRange = globalMaxDate.getTime() - globalMinDate.getTime();\n const stepPerFrame = totalRange / (playbackDuration / frameInterval);\n \n const animate = (timestamp: number) => {\n if (!lastFrameTimeRef.current) {\n lastFrameTimeRef.current = timestamp;\n }\n \n const elapsed = timestamp - lastFrameTimeRef.current;\n \n if (elapsed >= frameInterval) {\n lastFrameTimeRef.current = timestamp;\n \n const state = useTimelineStore.getState();\n if (!state.rangeStart || !state.globalMaxDate || !state.globalMinDate) {\n setPlaying(false);\n return;\n }\n \n const newStart = new Date(state.rangeStart.getTime() + stepPerFrame);\n const newEnd = state.rangeEnd \n ? new Date(state.rangeEnd.getTime() + stepPerFrame) \n : null;\n \n if (newStart >= state.globalMaxDate) {\n setRange(state.globalMinDate, state.globalMaxDate);\n setPlaying(false);\n return;\n }\n \n setRange(\n newStart,\n newEnd && newEnd <= state.globalMaxDate ? newEnd : state.globalMaxDate\n );\n }\n \n animationFrameRef.current = requestAnimationFrame(animate);\n };\n \n lastFrameTimeRef.current = 0;\n animationFrameRef.current = requestAnimationFrame(animate);\n \n return () => {\n if (animationFrameRef.current) {\n cancelAnimationFrame(animationFrameRef.current);\n animationFrameRef.current = null;\n }\n };\n }, [isPlaying, globalMinDate, globalMaxDate, setRange, setPlaying]);\n \n if (!isEnabled || !hasTemporalData || !globalMinDate || !globalMaxDate) {\n return null;\n }\n \n const totalRange = globalMaxDate.getTime() - globalMinDate.getTime();\n const startPercent = rangeStart \n ? ((rangeStart.getTime() - globalMinDate.getTime()) / totalRange) * 100 \n : 0;\n const endPercent = rangeEnd \n ? ((rangeEnd.getTime() - globalMinDate.getTime()) / totalRange) * 100 \n : 100;\n \n const maxBinCount = Math.max(...histogramBins.map(b => b.count), 1);\n \n const handleSliderChange = (values: number[]) => {\n const newStart = new Date(globalMinDate.getTime() + (values[0] / 100) * totalRange);\n const newEnd = new Date(globalMinDate.getTime() + (values[1] / 100) * totalRange);\n setRange(newStart, newEnd);\n setPlaying(false);\n };\n \n const handleReset = () => {\n setRange(globalMinDate, globalMaxDate);\n setPlaying(false);\n };\n \n const handlePlayPause = () => {\n if (!isPlaying && rangeStart && rangeStart >= globalMaxDate) {\n setRange(globalMinDate, globalMaxDate);\n }\n setPlaying(!isPlaying);\n };\n \n return (\n <div \n className={cn(\n \"absolute bottom-3 left-4 right-4 z-20 bg-background/95 floating-panel rounded-lg shadow-lg border border-border px-4 pt-3 pb-1\",\n className\n )}\n data-testid=\"timebar-panel\"\n >\n <Timescale minDate={globalMinDate} maxDate={globalMaxDate} binCount={histogramBins.length} />\n <Histogram \n bins={histogramBins} \n maxCount={maxBinCount} \n selectedBins={selectedBins}\n colorGroupedBins={colorGroupedBins}\n />\n \n <div className=\"mt-1\">\n <Slider\n range\n value={[startPercent, endPercent]}\n onChange={(values) => handleSliderChange(values as number[])}\n min={0}\n max={100}\n step={0.5}\n className=\"w-full\"\n data-testid=\"slider-timeline-range\"\n />\n </div>\n \n <div className=\"flex items-center justify-between mt-1\">\n <div className=\"flex items-center gap-1\">\n <Button\n type=\"text\"\n size=\"small\"\n icon={<SkipBack className=\"w-3.5 h-3.5\" />}\n onClick={handleReset}\n aria-label=\"Reset timeline\"\n data-testid=\"button-timeline-reset\"\n className=\"!h-7 !w-7 !p-0 !min-w-0\"\n />\n <Button\n type=\"text\"\n size=\"small\"\n icon={isPlaying ? <Pause className=\"w-3.5 h-3.5\" /> : <Play className=\"w-3.5 h-3.5\" />}\n onClick={handlePlayPause}\n aria-label={isPlaying ? 'Pause' : 'Play'}\n data-testid=\"button-timeline-play\"\n className=\"!h-7 !w-7 !p-0 !min-w-0\"\n />\n <span className=\"text-xs text-muted-foreground ml-1\">\n {temporalFeatures.length} feature{temporalFeatures.length !== 1 ? 's' : ''}\n </span>\n </div>\n \n <div className=\"flex items-center gap-2 text-xs text-muted-foreground font-mono\">\n <span data-testid=\"text-timeline-start\">{formatDate(rangeStart)}</span>\n <span>-</span>\n <span data-testid=\"text-timeline-end\">{formatDate(rangeEnd)}</span>\n </div>\n </div>\n </div>\n );\n}\n","import { useState, useCallback } from 'react';\nimport { Upload } from 'lucide-react';\nimport { cn } from '@/lib/utils';\n\ninterface MapDropZoneProps {\n onDrop: (name: string, data: GeoJSON.FeatureCollection) => void;\n children: React.ReactNode;\n}\n\nexport function MapDropZone({ onDrop, children }: MapDropZoneProps) {\n const [isDragOver, setIsDragOver] = useState(false);\n \n const handleDragOver = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n \n if (e.dataTransfer.types.includes('application/json')) {\n setIsDragOver(true);\n e.dataTransfer.dropEffect = 'copy';\n }\n }, []);\n \n const handleDragLeave = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n setIsDragOver(false);\n }, []);\n \n const handleDrop = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n setIsDragOver(false);\n \n try {\n const jsonData = e.dataTransfer.getData('application/json');\n if (jsonData) {\n const parsed = JSON.parse(jsonData);\n if (parsed.data && parsed.name) {\n onDrop(parsed.name, parsed.data);\n }\n }\n } catch (error) {\n console.error('Failed to parse dropped GeoJSON:', error);\n }\n }, [onDrop]);\n \n return (\n <div\n className=\"relative flex-1 h-full\"\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n >\n {children}\n \n {isDragOver && (\n <div \n className={cn(\n \"absolute inset-0 z-50 flex items-center justify-center\",\n \"bg-primary/10 border-4 border-dashed border-primary rounded-lg\",\n \"pointer-events-none transition-all\"\n )}\n data-testid=\"map-drop-overlay\"\n >\n <div className=\"bg-background/95 rounded-lg p-6 shadow-lg flex flex-col items-center gap-3\">\n <Upload className=\"w-10 h-10 text-primary\" />\n <span className=\"text-lg font-medium\">Drop GeoJSON here</span>\n <span className=\"text-sm text-muted-foreground\">Add as new layer</span>\n </div>\n </div>\n )}\n </div>\n );\n}\n","import { useEffect, useRef, useCallback, useState } from 'react';\nimport maplibregl from 'maplibre-gl';\n\ninterface CategoryData {\n name: string;\n count: number;\n color: string;\n}\n\ninterface ClusterPieProps {\n map: maplibregl.Map;\n sourceId: string;\n layerId: string;\n categoryValues: string[];\n categoryColorMap: Record<string, string>;\n visible: boolean;\n}\n\nfunction createPieSVG(\n categories: CategoryData[],\n total: number,\n size: number = 44,\n onSliceHover?: (cat: CategoryData | null, event: MouseEvent) => void\n): HTMLDivElement {\n const container = document.createElement('div');\n container.style.width = `${size}px`;\n container.style.height = `${size}px`;\n container.style.cursor = 'pointer';\n \n const radius = size / 2;\n const innerRadius = radius * 0.5; // Donut style\n \n // Create SVG\n const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');\n svg.setAttribute('width', String(size));\n svg.setAttribute('height', String(size));\n svg.setAttribute('viewBox', `0 0 ${size} ${size}`);\n svg.style.display = 'block';\n \n // Add white background circle for better visibility\n const bgCircle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');\n bgCircle.setAttribute('cx', String(radius));\n bgCircle.setAttribute('cy', String(radius));\n bgCircle.setAttribute('r', String(radius));\n bgCircle.setAttribute('fill', 'white');\n svg.appendChild(bgCircle);\n \n // Draw pie slices\n let currentAngle = -90; // Start from top\n \n categories.forEach((cat) => {\n if (cat.count === 0) return;\n \n const sliceAngle = (cat.count / total) * 360;\n const startAngle = currentAngle;\n const endAngle = currentAngle + sliceAngle;\n \n // Convert to radians\n const startRad = (startAngle * Math.PI) / 180;\n const endRad = (endAngle * Math.PI) / 180;\n \n // Outer arc points\n const x1 = radius + radius * Math.cos(startRad);\n const y1 = radius + radius * Math.sin(startRad);\n const x2 = radius + radius * Math.cos(endRad);\n const y2 = radius + radius * Math.sin(endRad);\n \n // Inner arc points\n const x3 = radius + innerRadius * Math.cos(endRad);\n const y3 = radius + innerRadius * Math.sin(endRad);\n const x4 = radius + innerRadius * Math.cos(startRad);\n const y4 = radius + innerRadius * Math.sin(startRad);\n \n const largeArc = sliceAngle > 180 ? 1 : 0;\n \n // Create path for donut slice\n const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n const d = [\n `M ${x1} ${y1}`,\n `A ${radius} ${radius} 0 ${largeArc} 1 ${x2} ${y2}`,\n `L ${x3} ${y3}`,\n `A ${innerRadius} ${innerRadius} 0 ${largeArc} 0 ${x4} ${y4}`,\n 'Z'\n ].join(' ');\n \n path.setAttribute('d', d);\n path.setAttribute('fill', cat.color);\n path.setAttribute('stroke', 'white');\n path.setAttribute('stroke-width', '1');\n path.style.transition = 'opacity 0.15s';\n \n // Add hover effect\n path.addEventListener('mouseenter', (e) => {\n path.style.opacity = '0.8';\n if (onSliceHover) onSliceHover(cat, e as MouseEvent);\n });\n path.addEventListener('mouseleave', (e) => {\n path.style.opacity = '1';\n if (onSliceHover) onSliceHover(null, e as MouseEvent);\n });\n \n svg.appendChild(path);\n currentAngle = endAngle;\n });\n \n // Add center circle with count\n const centerCircle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');\n centerCircle.setAttribute('cx', String(radius));\n centerCircle.setAttribute('cy', String(radius));\n centerCircle.setAttribute('r', String(innerRadius - 2));\n centerCircle.setAttribute('fill', '#1f2937');\n svg.appendChild(centerCircle);\n \n // Add count text\n const text = document.createElementNS('http://www.w3.org/2000/svg', 'text');\n text.setAttribute('x', String(radius));\n text.setAttribute('y', String(radius));\n text.setAttribute('text-anchor', 'middle');\n text.setAttribute('dominant-baseline', 'central');\n text.setAttribute('fill', 'white');\n text.setAttribute('font-size', total >= 1000 ? '9' : total >= 100 ? '10' : '11');\n text.setAttribute('font-weight', 'bold');\n text.setAttribute('font-family', 'system-ui, sans-serif');\n text.textContent = total >= 1000 ? `${(total / 1000).toFixed(1)}k` : String(total);\n svg.appendChild(text);\n \n container.appendChild(svg);\n return container;\n}\n\n// Tooltip element (singleton)\nlet tooltipEl: HTMLDivElement | null = null;\n\nfunction showTooltip(cat: CategoryData, x: number, y: number) {\n if (!tooltipEl) {\n tooltipEl = document.createElement('div');\n tooltipEl.style.cssText = `\n position: fixed;\n background: rgba(0,0,0,0.85);\n color: white;\n padding: 6px 10px;\n border-radius: 4px;\n font-size: 12px;\n font-family: system-ui, sans-serif;\n pointer-events: none;\n z-index: 10000;\n white-space: nowrap;\n box-shadow: 0 2px 8px rgba(0,0,0,0.3);\n `;\n document.body.appendChild(tooltipEl);\n }\n \n tooltipEl.innerHTML = `\n <div style=\"display: flex; align-items: center; gap: 6px;\">\n <span style=\"width: 10px; height: 10px; border-radius: 2px; background: ${cat.color};\"></span>\n <span><strong>${cat.name}</strong>: ${cat.count}</span>\n </div>\n `;\n tooltipEl.style.left = `${x + 12}px`;\n tooltipEl.style.top = `${y - 10}px`;\n tooltipEl.style.display = 'block';\n}\n\nfunction hideTooltip() {\n if (tooltipEl) {\n tooltipEl.style.display = 'none';\n }\n}\n\nexport function ClusterPieManager(props: ClusterPieProps) {\n const { map, sourceId, layerId, categoryValues, categoryColorMap, visible } = props;\n const markersRef = useRef<Map<string, maplibregl.Marker>>(new Map());\n const updateScheduled = useRef(false);\n\n const updateMarkers = useCallback(() => {\n if (!map || !visible) {\n // Clear all markers when not visible\n markersRef.current.forEach(marker => marker.remove());\n markersRef.current.clear();\n return;\n }\n \n const source = map.getSource(sourceId) as maplibregl.GeoJSONSource | undefined;\n if (!source) return;\n \n // Query visible cluster features\n const clusters = map.querySourceFeatures(sourceId, {\n filter: ['has', 'point_count']\n });\n \n const visibleClusterIds = new Set<string>();\n \n clusters.forEach(feature => {\n const clusterId = feature.properties?.cluster_id;\n if (clusterId === undefined) return;\n \n const clusterKey = `${clusterId}`;\n visibleClusterIds.add(clusterKey);\n \n const coords = (feature.geometry as GeoJSON.Point).coordinates as [number, number];\n const pointCount = feature.properties?.point_count || 0;\n \n // Build category data from aggregated properties\n const categories: CategoryData[] = categoryValues.map((cat, i) => ({\n name: cat,\n count: feature.properties?.[`cat_${i}`] || 0,\n color: categoryColorMap[cat] || '#3b82f6'\n })).filter(c => c.count > 0);\n \n // Calculate size based on point count\n const size = pointCount < 100 ? 40 : pointCount < 750 ? 50 : 60;\n \n // Check if marker exists and update or create\n const existingMarker = markersRef.current.get(clusterKey);\n \n if (existingMarker) {\n // Update position\n existingMarker.setLngLat(coords);\n } else {\n // Create new marker with pie chart\n const el = createPieSVG(categories, pointCount, size, (cat, event) => {\n if (cat) {\n showTooltip(cat, event.clientX, event.clientY);\n } else {\n hideTooltip();\n }\n });\n \n // Add click handler for zoom\n el.addEventListener('click', () => {\n (source as any).getClusterExpansionZoom(clusterId, (err: any, zoom: number) => {\n if (!err) {\n map.easeTo({ center: coords, zoom: zoom + 0.5 });\n }\n });\n });\n \n const marker = new maplibregl.Marker({ element: el })\n .setLngLat(coords)\n .addTo(map);\n \n markersRef.current.set(clusterKey, marker);\n }\n });\n \n // Remove markers that are no longer visible\n markersRef.current.forEach((marker, key) => {\n if (!visibleClusterIds.has(key)) {\n marker.remove();\n markersRef.current.delete(key);\n }\n });\n }, [map, sourceId, categoryValues, categoryColorMap, visible]);\n\n useEffect(() => {\n if (!map) return;\n \n const scheduleUpdate = () => {\n if (updateScheduled.current) return;\n updateScheduled.current = true;\n requestAnimationFrame(() => {\n updateScheduled.current = false;\n updateMarkers();\n });\n };\n \n // Initial update\n scheduleUpdate();\n \n // Listen for map events\n map.on('moveend', scheduleUpdate);\n map.on('data', (e: maplibregl.MapDataEvent) => {\n if ((e as any).sourceId === sourceId) {\n scheduleUpdate();\n }\n });\n \n return () => {\n map.off('moveend', scheduleUpdate);\n // Clean up markers\n markersRef.current.forEach(marker => marker.remove());\n markersRef.current.clear();\n hideTooltip();\n };\n }, [map, sourceId, updateMarkers]);\n\n // Update when visibility changes\n useEffect(() => {\n if (!visible) {\n markersRef.current.forEach(marker => marker.remove());\n markersRef.current.clear();\n hideTooltip();\n } else {\n updateMarkers();\n }\n }, [visible, updateMarkers]);\n\n return null; // This is a side-effect only component\n}\n\n// Non-React version for use in effects\nexport function createClusterPieManager(\n map: maplibregl.Map,\n sourceId: string,\n categoryValues: string[],\n categoryColorMap: Record<string, string>\n): { update: () => void; destroy: () => void } {\n const markers = new Map<string, maplibregl.Marker>();\n let updateScheduled = false;\n\n function update() {\n const source = map.getSource(sourceId) as maplibregl.GeoJSONSource | undefined;\n if (!source) return;\n \n const clusters = map.querySourceFeatures(sourceId, {\n filter: ['has', 'point_count']\n });\n \n const visibleClusterIds = new Set<string>();\n \n clusters.forEach(feature => {\n const clusterId = feature.properties?.cluster_id;\n if (clusterId === undefined) return;\n \n const clusterKey = `${clusterId}`;\n visibleClusterIds.add(clusterKey);\n \n const coords = (feature.geometry as GeoJSON.Point).coordinates as [number, number];\n const pointCount = feature.properties?.point_count || 0;\n \n const categories: CategoryData[] = categoryValues.map((cat, i) => ({\n name: cat,\n count: feature.properties?.[`cat_${i}`] || 0,\n color: categoryColorMap[cat] || '#3b82f6'\n })).filter(c => c.count > 0);\n \n const size = pointCount < 100 ? 40 : pointCount < 750 ? 50 : 60;\n \n const existingMarker = markers.get(clusterKey);\n \n if (existingMarker) {\n existingMarker.setLngLat(coords);\n } else {\n const el = createPieSVG(categories, pointCount, size, (cat, event) => {\n if (cat) {\n showTooltip(cat, event.clientX, event.clientY);\n } else {\n hideTooltip();\n }\n });\n \n el.addEventListener('click', () => {\n (source as any).getClusterExpansionZoom(clusterId, (err: any, zoom: number) => {\n if (!err) {\n map.easeTo({ center: coords, zoom: zoom + 0.5 });\n }\n });\n });\n \n const marker = new maplibregl.Marker({ element: el })\n .setLngLat(coords)\n .addTo(map);\n \n markers.set(clusterKey, marker);\n }\n });\n \n markers.forEach((marker, key) => {\n if (!visibleClusterIds.has(key)) {\n marker.remove();\n markers.delete(key);\n }\n });\n }\n\n function scheduleUpdate() {\n if (updateScheduled) return;\n updateScheduled = true;\n requestAnimationFrame(() => {\n updateScheduled = false;\n update();\n });\n }\n\n function onData(e: maplibregl.MapDataEvent) {\n if ((e as any).sourceId === sourceId) {\n scheduleUpdate();\n }\n }\n\n map.on('moveend', scheduleUpdate);\n map.on('data', onData);\n scheduleUpdate();\n\n return {\n update: scheduleUpdate,\n destroy: () => {\n map.off('moveend', scheduleUpdate);\n map.off('data', onData);\n markers.forEach(marker => marker.remove());\n markers.clear();\n hideTooltip();\n }\n };\n}\n","import { useRef, useState, useEffect, useCallback, forwardRef, useImperativeHandle, useMemo } from 'react';\nimport maplibregl from 'maplibre-gl';\nimport MapboxDraw from '@mapbox/mapbox-gl-draw';\nimport * as turf from '@turf/turf';\nimport proj4 from 'proj4';\nimport * as THREE from 'three';\n\n// Define common CRS projections\nproj4.defs('EPSG:27700', '+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 +ellps=airy +towgs84=446.448,-125.157,542.06,0.15,0.247,0.842,-20.489 +units=m +no_defs');\nproj4.defs('EPSG:3857', '+proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs');\nproj4.defs('EPSG:32630', '+proj=utm +zone=30 +datum=WGS84 +units=m +no_defs'); // UTM Zone 30N\nproj4.defs('EPSG:32631', '+proj=utm +zone=31 +datum=WGS84 +units=m +no_defs'); // UTM Zone 31N\n\n// Detect CRS from GeoJSON and reproject to WGS84 if needed\nfunction detectAndReprojectGeoJSON(geojson: GeoJSON.FeatureCollection): { \n features: GeoJSON.FeatureCollection; \n reprojected: boolean; \n sourceCRS: string | null;\n} {\n // Check for CRS property in GeoJSON\n const crsProperty = (geojson as any).crs;\n let sourceCRS: string | null = null;\n \n if (crsProperty?.properties?.name) {\n // Parse CRS URN format like \"urn:ogc:def:crs:EPSG::27700\"\n const crsName = crsProperty.properties.name;\n const epsgMatch = crsName.match(/EPSG::?(\\d+)/i);\n if (epsgMatch) {\n sourceCRS = `EPSG:${epsgMatch[1]}`;\n }\n }\n \n // If no CRS found, check if coordinates look like WGS84\n if (!sourceCRS && geojson.features.length > 0) {\n const firstCoord = getFirstCoordinate(geojson.features[0].geometry);\n if (firstCoord) {\n const [x, y] = firstCoord;\n // WGS84 coords are -180 to 180 for lon, -90 to 90 for lat\n const looksLikeWGS84 = Math.abs(x) <= 180 && Math.abs(y) <= 90;\n if (looksLikeWGS84) {\n return { features: geojson, reprojected: false, sourceCRS: 'EPSG:4326' };\n }\n }\n }\n \n // If CRS is WGS84, no reprojection needed\n if (sourceCRS === 'EPSG:4326') {\n return { features: geojson, reprojected: false, sourceCRS };\n }\n \n // Try to reproject if we have a known CRS\n if (sourceCRS && proj4.defs(sourceCRS)) {\n try {\n const reprojectedFeatures = geojson.features.map(feature => ({\n ...feature,\n geometry: reprojectGeometry(feature.geometry, sourceCRS!)\n }));\n return {\n features: { ...geojson, type: 'FeatureCollection', features: reprojectedFeatures },\n reprojected: true,\n sourceCRS\n };\n } catch (e) {\n console.error('Reprojection failed:', e);\n }\n }\n \n return { features: geojson, reprojected: false, sourceCRS };\n}\n\nfunction getFirstCoordinate(geometry: GeoJSON.Geometry): [number, number] | null {\n if (!geometry) return null;\n switch (geometry.type) {\n case 'Point':\n return geometry.coordinates as [number, number];\n case 'MultiPoint':\n case 'LineString':\n return geometry.coordinates[0] as [number, number];\n case 'MultiLineString':\n case 'Polygon':\n return geometry.coordinates[0]?.[0] as [number, number];\n case 'MultiPolygon':\n return geometry.coordinates[0]?.[0]?.[0] as [number, number];\n default:\n return null;\n }\n}\n\nfunction reprojectGeometry(geometry: GeoJSON.Geometry, fromCRS: string): GeoJSON.Geometry {\n const transform = (coord: number[]): number[] => {\n const [x, y] = proj4(fromCRS, 'EPSG:4326', [coord[0], coord[1]]);\n return coord.length > 2 ? [x, y, ...coord.slice(2)] : [x, y];\n };\n \n const reprojectCoords = (coords: any): any => {\n if (typeof coords[0] === 'number') {\n return transform(coords);\n }\n return coords.map(reprojectCoords);\n };\n \n // Handle GeometryCollection separately\n if (geometry.type === 'GeometryCollection') {\n return {\n type: 'GeometryCollection',\n geometries: geometry.geometries.map(g => reprojectGeometry(g, fromCRS))\n };\n }\n \n // All other geometry types have coordinates\n const geomWithCoords = geometry as GeoJSON.Point | GeoJSON.MultiPoint | GeoJSON.LineString | GeoJSON.MultiLineString | GeoJSON.Polygon | GeoJSON.MultiPolygon;\n return {\n ...geomWithCoords,\n coordinates: reprojectCoords(geomWithCoords.coordinates)\n } as GeoJSON.Geometry;\n}\n\n// Custom read-only select mode that allows selection but prevents dragging\nconst ViewSelectMode = {\n ...MapboxDraw.modes.simple_select,\n \n // Override all drag handlers to prevent feature movement\n dragMove() {\n // No-op: prevent dragging\n },\n onDrag() {\n // No-op: prevent dragging\n },\n onDragStart() {\n // No-op: prevent drag start\n },\n onDragEnd() {\n // No-op: prevent drag end\n },\n dragFeature() {\n // No-op: prevent feature dragging\n },\n};\nimport { saveAs } from 'file-saver';\nimport 'maplibre-gl/dist/maplibre-gl.css';\nimport '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css';\n\n// Interface for 3D flight path data\ninterface FlightPath3D {\n id: string;\n coordinates: [number, number, number][]; // [lng, lat, altitude in meters]\n color: string;\n lineWidth: number;\n}\n\n// Create a Three.js custom layer for rendering 3D flight paths at altitude\n// Uses TubeGeometry for thick, visible lines since WebGL1 ignores linewidth\nfunction createFlightPath3DLayer(\n layerId: string,\n mapInstance: maplibregl.Map,\n flightPaths: FlightPath3D[]\n): maplibregl.CustomLayerInterface {\n let camera: THREE.Camera;\n let scene: THREE.Scene;\n let renderer: THREE.WebGLRenderer;\n let meshes: THREE.Mesh[] = [];\n\n return {\n id: layerId,\n type: 'custom' as const,\n renderingMode: '3d' as const,\n\n onAdd(map: maplibregl.Map, gl: WebGLRenderingContext) {\n camera = new THREE.Camera();\n scene = new THREE.Scene();\n\n // Create tube meshes for each flight path (thick, visible lines)\n flightPaths.forEach(path => {\n if (path.coordinates.length < 2) return;\n\n // Convert coordinates to Vector3 array for CatmullRomCurve3\n const points: THREE.Vector3[] = [];\n const altitudes: number[] = [];\n \n path.coordinates.forEach(coord => {\n const [lng, lat, alt = 0] = coord;\n const mercator = maplibregl.MercatorCoordinate.fromLngLat([lng, lat], alt);\n points.push(new THREE.Vector3(mercator.x, mercator.y, mercator.z));\n altitudes.push(alt);\n });\n\n // Calculate min/max altitude for color gradient\n const minAlt = Math.min(...altitudes);\n const maxAlt = Math.max(...altitudes);\n const altRange = maxAlt - minAlt || 1;\n\n // Create a smooth curve through the points\n const curve = new THREE.CatmullRomCurve3(points, false, 'catmullrom', 0.5);\n \n // Tube radius in Mercator units - thin line for drone flight visualization\n // Small radius for realistic drone path representation\n const tubeRadius = 0.000000075;\n const tubularSegments = Math.max(points.length * 4, 64);\n const radialSegments = 8;\n \n const geometry = new THREE.TubeGeometry(curve, tubularSegments, tubeRadius, radialSegments, false);\n \n // Create vertex colors based on altitude along the tube\n const positionAttr = geometry.attributes.position;\n const colors: number[] = [];\n \n for (let i = 0; i < positionAttr.count; i++) {\n // Approximate the altitude based on position along curve\n const segmentIndex = Math.floor(i / (radialSegments + 1));\n const t = segmentIndex / tubularSegments;\n const altIndex = Math.min(Math.floor(t * altitudes.length), altitudes.length - 1);\n const alt = altitudes[altIndex];\n const normalizedAlt = (alt - minAlt) / altRange;\n \n // Bright magenta (low) to bright cyan (high) gradient\n const color = new THREE.Color();\n color.setRGB(1 - normalizedAlt, normalizedAlt, 1);\n colors.push(color.r, color.g, color.b);\n }\n \n geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3));\n\n const material = new THREE.MeshBasicMaterial({\n vertexColors: true,\n side: THREE.DoubleSide,\n });\n\n const mesh = new THREE.Mesh(geometry, material);\n scene.add(mesh);\n meshes.push(mesh);\n });\n\n renderer = new THREE.WebGLRenderer({\n canvas: map.getCanvas(),\n context: gl,\n antialias: true,\n });\n\n renderer.autoClear = false;\n },\n\n render(_gl: WebGLRenderingContext, options: maplibregl.CustomRenderMethodInput) {\n const matrix = options.defaultProjectionData.mainMatrix;\n const m = new THREE.Matrix4().fromArray(Array.from(matrix as ArrayLike<number>));\n camera.projectionMatrix = m;\n renderer.resetState();\n renderer.render(scene, camera);\n mapInstance.triggerRepaint();\n },\n\n onRemove() {\n meshes.forEach(mesh => {\n scene.remove(mesh);\n mesh.geometry.dispose();\n (mesh.material as THREE.Material).dispose();\n });\n meshes = [];\n },\n };\n}\n\n// Helper to check if a LineString has altitude data (Z coordinates)\nfunction hasAltitudeData(feature: GeoJSON.Feature): boolean {\n if (feature.geometry.type === 'LineString') {\n const coords = feature.geometry.coordinates;\n return coords.some(c => c.length >= 3 && c[2] !== 0);\n }\n if (feature.geometry.type === 'MultiLineString') {\n const coords = feature.geometry.coordinates;\n return coords.some(line => line.some(c => c.length >= 3 && c[2] !== 0));\n }\n return false;\n}\n\n// Extract 3D flight paths from GeoJSON features\n// Handles both LineStrings with Z coordinates AND Point sequences with altitude\nfunction extract3DFlightPaths(features: GeoJSON.Feature[]): FlightPath3D[] {\n const paths: FlightPath3D[] = [];\n \n // First, handle explicit LineString/MultiLineString features\n features.forEach(feature => {\n if (feature.geometry.type === 'LineString' && hasAltitudeData(feature)) {\n paths.push({\n id: feature.id as string || `path-${paths.length}`,\n coordinates: feature.geometry.coordinates as [number, number, number][],\n color: (feature.properties?.stroke as string) || '#3b82f6',\n lineWidth: (feature.properties?.['stroke-width'] as number) || 3,\n });\n } else if (feature.geometry.type === 'MultiLineString') {\n feature.geometry.coordinates.forEach((line, idx) => {\n const has3D = line.some(c => c.length >= 3 && c[2] !== 0);\n if (has3D) {\n paths.push({\n id: `${feature.id || 'path'}-${idx}`,\n coordinates: line as [number, number, number][],\n color: (feature.properties?.stroke as string) || '#3b82f6',\n lineWidth: (feature.properties?.['stroke-width'] as number) || 3,\n });\n }\n });\n }\n });\n \n // Second, build flight paths from Point features with altitude data\n // Group points by TargetID (or use 'default' if not specified)\n const pointsByTarget = new Map<string, { \n coords: [number, number, number]; \n timestamp: number;\n properties: Record<string, unknown>;\n }[]>();\n \n features.forEach(feature => {\n if (feature.geometry.type === 'Point') {\n const coords = feature.geometry.coordinates;\n // Check if point has Z coordinate (altitude)\n if (coords.length >= 3 && coords[2] !== 0) {\n const targetId = (feature.properties?.TargetID as string) || 'default-points';\n const startDateStr = feature.properties?.startDate as string;\n const timestamp = startDateStr ? new Date(startDateStr).getTime() : 0;\n \n if (!pointsByTarget.has(targetId)) {\n pointsByTarget.set(targetId, []);\n }\n pointsByTarget.get(targetId)!.push({\n coords: coords as [number, number, number],\n timestamp,\n properties: feature.properties || {},\n });\n }\n }\n });\n \n // For each target, sort points by timestamp and create a flight path\n pointsByTarget.forEach((points, targetId) => {\n if (points.length < 2) return; // Need at least 2 points for a path\n \n // Sort by timestamp\n points.sort((a, b) => a.timestamp - b.timestamp);\n \n // Extract coordinates in order\n const coordinates = points.map(p => p.coords);\n \n paths.push({\n id: `points-path-${targetId}`,\n coordinates,\n color: '#3b82f6',\n lineWidth: 3,\n });\n });\n \n return paths;\n}\n\nimport { DrawingToolbar, DrawingMode, MeasureMode, SelectionMode } from './drawing-toolbar';\nimport { LayersPanel, Layer, TraceConfig, MapStyle, HeatmapConfig, ClusterConfig, VisualConfig, AutoLabelConfig, AltitudeDisplayMode } from './layers-panel';\nimport { PropertiesPanel } from './properties-panel';\nimport { StatusIndicator } from './status-indicator';\nimport { Timebar, TIMEBAR_HEIGHT, TIMEBAR_BOTTOM_OFFSET } from './timebar';\nimport { MapDropZone } from './map-drop-zone';\nimport { Button, Tooltip, Card } from 'antd';\nimport { useTimelineStore, normalizeTemporalProperties } from '@/lib/timeline-store';\nimport { useToast } from '@/hooks/use-toast';\nimport { ToastContext } from '@/hooks/toast-context';\nimport type { MapEditorHandle, MapEditorProps } from '@/lib/map-editor-api';\nimport { Clock, Layers, AlertTriangle } from 'lucide-react';\nimport { createClusterPieManager } from './cluster-pie-chart';\n\n// Simple base style with satellite raster layer (hidden by default)\n// Streets/terrain/dark layers are added dynamically after loading external styles\n// Default local glyphs URL - uses Noto Sans fonts packaged with the application\nconst DEFAULT_LOCAL_GLYPHS_URL = '/fonts/{fontstack}/{range}.pbf';\n\n// Create base style dynamically based on configuration\nfunction createBaseStyle(options: {\n glyphsUrl?: string;\n enableSatellite?: boolean;\n enableTerrain?: boolean;\n}): maplibregl.StyleSpecification {\n const sources: Record<string, maplibregl.SourceSpecification> = {};\n const layers: maplibregl.LayerSpecification[] = [\n {\n id: 'background',\n type: 'background',\n paint: {\n 'background-color': '#f0f0f0'\n }\n }\n ];\n\n if (options.enableSatellite !== false) {\n sources['satellite-tiles'] = {\n type: 'raster',\n tiles: ['https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}'],\n tileSize: 256,\n attribution: 'Esri, Maxar, Earthstar Geographics',\n };\n layers.push({\n id: 'satellite-layer',\n type: 'raster',\n source: 'satellite-tiles',\n minzoom: 0,\n maxzoom: 22,\n layout: { visibility: 'none' },\n });\n }\n\n if (options.enableTerrain !== false) {\n sources['terrain-dem'] = {\n type: 'raster-dem',\n tiles: ['https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png'],\n tileSize: 256,\n maxzoom: 15,\n encoding: 'terrarium',\n };\n }\n\n return {\n version: 8,\n sources,\n layers,\n glyphs: options.glyphsUrl || DEFAULT_LOCAL_GLYPHS_URL,\n };\n}\n\n// Layer prefixes for each basemap style (used to toggle visibility)\nconst BASEMAP_LAYER_PREFIXES: Record<MapStyle, string> = {\n streets: 'streets-',\n satellite: 'satellite-',\n dark: 'dark-',\n};\n\n// External style URLs to fetch and merge\nconst EXTERNAL_STYLE_URLS: Record<string, string> = {\n streets: 'https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json',\n dark: 'https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json',\n};\n\ninterface UndoState {\n features: GeoJSON.Feature[];\n layers: Layer[];\n selectedIds: string[];\n}\n\nexport const MapEditorCanvas = forwardRef<MapEditorHandle, MapEditorProps>(function MapEditorCanvas(\n {\n className,\n enableDrawing = true,\n enableLayers = true,\n enableTimeline = true,\n enableMeasurement = true,\n enableSelection = true,\n hiddenDrawingTools = [],\n hiddenSelectionTools = [],\n expandSelectionTools = false,\n showFilterTool = false,\n defaultSelectionMode = 'click',\n initialSelectionActive = true,\n showStatusPanel = true,\n onSelectionComplete,\n persistSelection = false,\n showDebugSidebar = false,\n initialCenter = [-74.006, 40.7128],\n initialZoom = 12,\n baseMapStyle = 'streets',\n customBasemaps,\n basemapOrder,\n initialDrawingMode,\n onFeatureSelect,\n onFeatureCreate,\n onFeatureUpdate,\n onFeatureDelete,\n onLayerChange,\n onActiveEditingLayerChange,\n onTimelineChange,\n onMapReady,\n onViewportChange,\n showClearFilter = false,\n onClearFilter,\n showGoToButton = false,\n onDropPoint,\n geocodingUrl,\n geocoderProvider,\n onSearchEngineRequest,\n onWorkspaceLoad,\n onWorkspaceSave,\n entityCardProvider,\n typePickerProvider,\n contextMenuProvider,\n featureSaveProvider,\n tooltipProvider,\n glyphsUrl,\n filterGeometry,\n enableSatellite = true,\n enableTerrain = true,\n enable3D = true,\n hideBasemapSwitcher = false,\n externalPersistence = false,\n enableKeyboardShortcuts = true,\n enableProperties = true,\n toastProvider,\n },\n ref\n) {\n const mapContainer = useRef<HTMLDivElement>(null);\n const map = useRef<maplibregl.Map | null>(null);\n const draw = useRef<MapboxDraw | null>(null);\n const fileInputRef = useRef<HTMLInputElement>(null);\n const hiddenFeatures = useRef<Map<string, GeoJSON.Feature[]>>(new Map());\n const tracePopupRef = useRef<maplibregl.Popup | null>(null);\n const tooltipElRef = useRef<HTMLDivElement | null>(null);\n const layersRef = useRef<Layer[]>([\n { id: 'default', name: 'Default Layer', visible: true, featureIds: [] }\n ]);\n const activeEditingLayerIdRef = useRef<string>('default');\n // Flag to distinguish API/import additions from user-drawn features\n const isApiAddingRef = useRef<boolean>(false);\n const isEditModeRef = useRef<boolean>(false);\n const originalGeometriesRef = useRef<Map<string, GeoJSON.Geometry>>(new Map());\n // Store features for read-only layers (bypasses MapboxDraw for performance)\n const readOnlyFeatures = useRef<Map<string, GeoJSON.Feature[]>>(new Map());\n // Track which basemap styles have been loaded and their layer IDs (for visibility toggling)\n // Note: satellite is only included if enableSatellite is true\n const loadedBasemaps = useRef<Set<string>>(new Set(enableSatellite ? ['satellite'] : []));\n const basemapLayerIds = useRef<Map<string, string[]>>(new Map(enableSatellite ? [['satellite', ['satellite-layer']]] : []));\n const loadingBasemaps = useRef<Set<string>>(new Set());\n // Custom basemap registry (id -> definition)\n const customBasemapRegistry = useRef<Map<string, import('@/lib/map-editor-api').BasemapDefinition>>(new Map());\n // Pie chart cluster managers (for category mode clustering with SVG pie charts)\n const clusterPieManagers = useRef<Map<string, { update: () => void; destroy: () => void }>>(new Map());\n // Ref to store handleMapStyleChange for use in imperative handle\n const handleMapStyleChangeRef = useRef<((style: MapStyle) => Promise<void>) | null>(null);\n // Track 3D flight path layer for altitude visualization\n const flightPath3DLayerId = useRef<string | null>(null);\n // Ref to store update3DFlightPaths for use in syncFeaturesToCustomLayers\n const update3DFlightPathsRef = useRef<(() => void) | null>(null);\n // Keep tooltipProvider in a ref so the mouseenter closure always sees the latest value\n const tooltipProviderRef = useRef(tooltipProvider);\n tooltipProviderRef.current = tooltipProvider;\n \n \n const [isMapLoaded, setIsMapLoaded] = useState(false);\n // Ref to track map loaded state synchronously (for use in imperative handle)\n const isMapLoadedRef = useRef(false);\n const [mapError, setMapError] = useState<string | null>(null);\n const [activeMode, setActiveMode] = useState<DrawingMode>('view_select');\n const [selectedFeatureIds, setSelectedFeatureIds] = useState<string[]>([]);\n const [featureCount, setFeatureCount] = useState(0);\n const [featureUpdateCounter, setFeatureUpdateCounter] = useState(0); // Trigger re-render when features update\n const [showProperties, setShowProperties] = useState(false);\n const [autoFocusLabel, setAutoFocusLabel] = useState(false);\n const [showLayers, setShowLayers] = useState(false);\n const [layers, setLayers] = useState<Layer[]>([\n { id: 'default', name: 'Default Layer', visible: true, featureIds: [] }\n ]);\n const [activeEditingLayerId, setActiveEditingLayerId] = useState<string>('default');\n const [undoStack, setUndoStack] = useState<UndoState[]>([]);\n const [redoStack, setRedoStack] = useState<UndoState[]>([]);\n const [isEditMode, setIsEditMode] = useState(false);\n const [currentMapStyle, setCurrentMapStyle] = useState<MapStyle>(baseMapStyle);\n const [measureMode, setMeasureMode] = useState<MeasureMode>('none');\n const [measurePoints, setMeasurePoints] = useState<[number, number][]>([]);\n const [measureResult, setMeasureResult] = useState<string | null>(null);\n const [is3DTerrainEnabled, setIs3DTerrainEnabled] = useState(false);\n const [selectionMode, setSelectionMode] = useState<SelectionMode>(defaultSelectionMode);\n const [isSelectionToolActive, setIsSelectionToolActive] = useState(initialSelectionActive);\n const filterActiveRef = useRef(false);\n const [selectionPoints, setSelectionPoints] = useState<[number, number][]>([]);\n const [selectionHoverPoint, setSelectionHoverPoint] = useState<[number, number] | null>(null);\n const [persistedSelectionPolygon, setPersistedSelectionPolygon] = useState<[number, number][] | null>(null);\n const isDrawingSelection = useRef(false);\n const isSelectingReadOnlyRef = useRef(false); // Track when selecting read-only to prevent selectionchange override\n const contextMenuFiredRef = useRef(false);\n const filterPolygonRef = useRef<SVGPolygonElement>(null);\n // Track pending feature kind for special tools (text, arrow, circle, rectangle)\n const pendingFeatureKindRef = useRef<'text' | 'arrow' | 'circle' | 'rectangle' | null>(null);\n // Track arrow feature IDs externally since MapboxDraw may not persist kind property reliably\n const arrowFeatureIdsRef = useRef<Set<string>>(new Set());\n // Circle drawing state (click center, drag radius)\n const [circleDrawCenter, setCircleDrawCenter] = useState<[number, number] | null>(null);\n const [circleDrawPreview, setCircleDrawPreview] = useState<[number, number][] | null>(null);\n const isDrawingCircle = useRef(false);\n // Rectangle drawing state (click corner, drag to opposite corner)\n const [rectangleDrawCorner, setRectangleDrawCorner] = useState<[number, number] | null>(null);\n const [rectangleDrawPreview, setRectangleDrawPreview] = useState<[number, number][] | null>(null);\n const isDrawingRectangle = useRef(false);\n const [autoLabelConfig, setAutoLabelConfig] = useState<AutoLabelConfig>({ enabled: true, threshold: 220 });\n // Start with high count so labels stay hidden until first viewport query completes\n const [visibleFeatureCount, setVisibleFeatureCount] = useState<number>(Infinity);\n const lastLabelVisibility = useRef<boolean>(false);\n // Suppress labels during bulk operations and map movements (STATE for re-render)\n const [labelsSuppressed, setLabelsSuppressed] = useState<boolean>(true);\n // Context menu state\n const [contextMenu, setContextMenu] = useState<{\n x: number;\n y: number;\n items: import('@/lib/map-editor-api').ContextMenuItem[];\n } | null>(null);\n \n const timelineStore = useTimelineStore();\n const { toast: internalToast } = useToast();\n const toast = toastProvider ?? internalToast;\n\n // Suppress non-critical MapLibre tile parsing errors that trigger the Vite error overlay\n useEffect(() => {\n const handleError = (event: ErrorEvent) => {\n const msg = event.message || '';\n // Suppress known non-critical errors from MapLibre\n if (msg.includes('unknown feature value') ||\n msg.includes('getSource') ||\n msg.includes('WebGL') ||\n msg.includes('style is not loaded') ||\n msg.includes('Map container') ||\n msg.includes('tile') ||\n msg.includes('already running') ||\n msg.includes('out of range') ||\n msg.includes('DEM data')) {\n event.preventDefault();\n event.stopPropagation();\n return true;\n }\n };\n \n const handleUnhandledRejection = (event: PromiseRejectionEvent) => {\n let message = '';\n try {\n message = event.reason?.message || String(event.reason);\n } catch {\n message = 'unknown';\n }\n // Suppress known non-critical errors\n if (message.includes('unknown feature value') ||\n message.includes('getSource') ||\n message.includes('WebGL') ||\n message.includes('style') ||\n message.includes('tile') ||\n message.includes('Map container') ||\n message.includes('already running') ||\n message.includes('out of range') ||\n message.includes('DEM data')) {\n event.preventDefault();\n return;\n }\n };\n \n // Catch all uncaught errors including non-Error throws\n const handleGlobalError = (event: Event) => {\n // Suppress all errors during map operations to prevent Vite overlay\n if (event instanceof ErrorEvent) {\n const msg = event.message || '';\n if (msg.includes('MapLibre') || msg.includes('maplibre') || msg.includes('map') ||\n msg.includes('tile') || msg.includes('WebGL') || msg.includes('getSource') ||\n msg.includes('style') || !event.message) {\n event.preventDefault();\n event.stopPropagation();\n return false;\n }\n }\n };\n \n window.addEventListener('error', handleError, true);\n window.addEventListener('error', handleGlobalError, true);\n window.addEventListener('unhandledrejection', handleUnhandledRejection, true);\n \n return () => {\n window.removeEventListener('error', handleError, true);\n window.removeEventListener('error', handleGlobalError, true);\n window.removeEventListener('unhandledrejection', handleUnhandledRejection, true);\n if (tooltipElRef.current) {\n try { tooltipElRef.current.parentElement?.removeChild(tooltipElRef.current); } catch {}\n tooltipElRef.current = null;\n }\n };\n }, []);\n\n const hasVisibleLayers = layers.some(l => l.visible);\n \n // Check if there's an editable layer selected (visible, not read-only, and explicitly selected)\n const hasEditableLayer = activeEditingLayerId !== '' && \n layers.some(l => l.id === activeEditingLayerId && l.visible && !l.readOnly);\n\n // Auto-exit edit mode when no editable layer is available\n useEffect(() => {\n if (isEditMode && !hasEditableLayer) {\n setIsEditMode(false);\n if (draw.current) {\n draw.current.changeMode('view_select');\n setActiveMode('view_select');\n }\n }\n }, [hasEditableLayer, isEditMode]);\n\n layersRef.current = layers;\n activeEditingLayerIdRef.current = activeEditingLayerId;\n isEditModeRef.current = isEditMode;\n\n // Helper to get all features (from MapboxDraw and read-only layers)\n const getAllFeatures = useCallback((): GeoJSON.Feature[] => {\n const drawFeatures = draw.current ? draw.current.getAll().features as GeoJSON.Feature[] : [];\n const readOnly: GeoJSON.Feature[] = [];\n readOnlyFeatures.current.forEach((features) => {\n readOnly.push(...features);\n });\n return [...drawFeatures, ...readOnly];\n }, []);\n \n const getSelectedFeatures = useCallback(() => {\n // Get selected features from both MapboxDraw and read-only storage\n const drawSelected = draw.current ? draw.current.getSelected().features as GeoJSON.Feature[] : [];\n \n // Also check if any selected IDs are from read-only features\n const readOnlySelected: GeoJSON.Feature[] = [];\n if (selectedFeatureIds.length > 0) {\n const selectedIdSet = new Set(selectedFeatureIds);\n readOnlyFeatures.current.forEach((features) => {\n features.forEach(f => {\n if (f.id && selectedIdSet.has(String(f.id))) {\n readOnlySelected.push(f);\n }\n });\n });\n }\n \n // Combine and deduplicate\n const allSelected = [...drawSelected, ...readOnlySelected];\n const seenIds = new Set<string>();\n return allSelected.filter(f => {\n const id = String(f.id);\n if (seenIds.has(id)) return false;\n seenIds.add(id);\n return true;\n });\n }, [selectedFeatureIds]);\n\n const selectedFeatures = getSelectedFeatures();\n\n // Helper to get a feature by ID from MapboxDraw or read-only storage\n const getFeatureById = useCallback((id: string): GeoJSON.Feature | null => {\n // Check MapboxDraw first\n if (draw.current) {\n const feature = draw.current.get(id);\n if (feature) return feature;\n }\n // Check read-only storage\n const entries = Array.from(readOnlyFeatures.current.entries());\n for (const [, features] of entries) {\n const found = features.find((f: GeoJSON.Feature) => String(f.id) === id);\n if (found) return found;\n }\n return null;\n }, []);\n\n // Centralized selection state helper that handles editable vs read-only features\n // and prevents MapboxDraw selectionchange from overwriting read-only selections\n const applySelectionState = useCallback((nextIds: string[], options?: { focusProperties?: boolean }) => {\n if (!isMapLoaded || !draw.current) {\n setSelectedFeatureIds(nextIds);\n if (options?.focusProperties) setShowProperties(nextIds.length > 0);\n // Always call onFeatureSelect to notify clearing\n onFeatureSelect?.(nextIds.length > 0 ? nextIds.map(id => getFeatureById(id)).filter(Boolean) as GeoJSON.Feature[] : []);\n return;\n }\n \n // Build set of editable IDs from layers (not draw.getAll() which excludes hidden features)\n const editableIdSet = new Set<string>();\n layersRef.current.forEach(layer => {\n if (!layer.readOnly) {\n layer.featureIds.forEach(id => editableIdSet.add(id));\n }\n });\n \n // Partition IDs into editable vs read-only\n const editableIds: string[] = [];\n const readOnlyIds: string[] = [];\n nextIds.forEach(id => (editableIdSet.has(id) ? editableIds : readOnlyIds).push(id));\n \n // Set guard if any read-only features are being selected\n if (readOnlyIds.length > 0) {\n isSelectingReadOnlyRef.current = true;\n }\n \n // Update MapboxDraw selection (only editable IDs that are currently visible in draw)\n const mode: DrawingMode = isEditModeRef.current ? 'simple_select' : 'view_select';\n // Filter to only IDs that exist in MapboxDraw right now\n const visibleEditableIds = editableIds.filter(id => {\n try { return !!draw.current!.get(id); } catch { return false; }\n });\n draw.current.changeMode(mode as string, { featureIds: visibleEditableIds });\n \n // Update React state with all IDs\n setSelectedFeatureIds(nextIds);\n selectedFeatureIdsRef.current = nextIds;\n if (options?.focusProperties) setShowProperties(nextIds.length > 0);\n \n // Get full feature objects for callback - always call to notify clearing\n const selectedFeaturesForCallback = nextIds.map(id => getFeatureById(id)).filter(Boolean) as GeoJSON.Feature[];\n onFeatureSelect?.(selectedFeaturesForCallback);\n \n // Trigger visual sync\n syncRef.current();\n \n // Clear guard after event loop to prevent race conditions\n if (readOnlyIds.length > 0) {\n queueMicrotask(() => { isSelectingReadOnlyRef.current = false; });\n }\n }, [isMapLoaded, getFeatureById, onFeatureSelect]);\n\n const saveStateForUndo = useCallback(() => {\n if (!draw.current) return;\n const currentState: UndoState = {\n features: draw.current.getAll().features as GeoJSON.Feature[],\n layers: JSON.parse(JSON.stringify(layers)),\n selectedIds: [...selectedFeatureIds],\n };\n setUndoStack(prev => [...prev.slice(-49), currentState]);\n setRedoStack([]);\n }, [layers, selectedFeatureIds]);\n\n const updateFeatureCount = useCallback(() => {\n // Count features from MapboxDraw (visible layers)\n const drawFeatureCount = draw.current ? draw.current.getAll().features.length : 0;\n // Count features from hidden layers\n let hiddenCount = 0;\n hiddenFeatures.current.forEach((features) => {\n hiddenCount += features.length;\n });\n // Count features from visible read-only layers\n let readOnlyCount = 0;\n readOnlyFeatures.current.forEach((features, layerId) => {\n const layer = layersRef.current.find(l => l.id === layerId);\n if (layer?.visible) {\n readOnlyCount += features.length;\n }\n });\n setFeatureCount(drawFeatureCount + hiddenCount + readOnlyCount);\n }, []);\n\n // Ref to track timeline visibility (declared early for use in sync function)\n const timelineVisibleIdsRef = useRef<Set<string> | null>(null);\n \n // Ref to always have the latest sync function available\n const syncRef = useRef<() => void>(() => {});\n\n // Generate consistent color from string value using Tableau 20 palette\n // This is a professionally designed palette for categorical data visualization\n const hashStringToColor = useCallback((str: string): string => {\n // Tableau 20 - balanced, perceptually distinct, colorblind-friendly\n const palette = [\n '#4e79a7', // steel blue\n '#f28e2b', // orange\n '#e15759', // red\n '#76b7b2', // teal\n '#59a14f', // green\n '#edc948', // yellow\n '#b07aa1', // purple\n '#ff9da7', // pink\n '#9c755f', // brown\n '#bab0ac', // gray\n '#5fa2ce', // light blue\n '#ffbe7d', // light orange\n '#ff9888', // salmon\n '#8cd17d', // light green\n '#b6992d', // olive\n '#f1ce63', // gold\n '#d4a6c8', // lavender\n '#86bcb6', // aqua\n '#d37295', // rose\n '#499894', // dark teal\n ];\n \n // Simple hash for consistent color assignment\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n hash = ((hash << 5) - hash) + str.charCodeAt(i);\n hash = hash & hash;\n }\n return palette[Math.abs(hash) % palette.length];\n }, []);\n\n // Compute color map for selected features (for timeline display)\n // This matches the color computation in syncFeaturesToCustomLayers for consistency\n const selectedFeatureColors = useMemo(() => {\n if (selectedFeatureIds.length === 0) return new Map<string, string>();\n \n const colorMap = new Map<string, string>();\n \n // Build feature lookup and layer lookup\n const featureToLayerMap = new Map<string, typeof layers[0]>();\n layers.forEach(layer => {\n layer.featureIds.forEach(fid => {\n featureToLayerMap.set(fid, layer);\n });\n });\n \n // Get all features for lookup\n const allFeats = getAllFeatures();\n const featById = new Map<string, GeoJSON.Feature>();\n allFeats.forEach(f => {\n if (f.id) featById.set(String(f.id), f);\n });\n \n // Compute trace point colors (same logic as syncFeaturesToCustomLayers)\n const tracePointColors = new Map<string, string>();\n layers.forEach(layer => {\n if (!layer.traceConfig?.enabled || !layer.visible) return;\n \n // Get visible point features with startDate from this layer\n const layerFeatures: GeoJSON.Feature[] = [];\n layer.featureIds.forEach(id => {\n const f = featById.get(id);\n if (!f || f.geometry.type !== 'Point' || !f.properties?.startDate) return;\n layerFeatures.push(f);\n });\n \n if (layerFeatures.length < 1) return;\n \n // Group by field if configured\n const groupByField = layer.traceConfig.groupByField;\n const groups = new Map<string, GeoJSON.Feature[]>();\n \n layerFeatures.forEach(f => {\n const key = groupByField && f.properties?.[groupByField] \n ? String(f.properties[groupByField]) \n : '__all__';\n if (!groups.has(key)) groups.set(key, []);\n groups.get(key)!.push(f);\n });\n \n // Generate colors for groups (same logic as trace line colors)\n const groupKeys = Array.from(groups.keys());\n groupKeys.forEach((key, index) => {\n const color = key === '__all__' \n ? '#3b82f6'\n : `hsl(${(index * 360 / groupKeys.length) % 360}, 70%, 50%)`;\n \n groups.get(key)!.forEach(f => {\n if (f.id) tracePointColors.set(String(f.id), color);\n });\n });\n });\n \n // Compute color for each selected feature\n selectedFeatureIds.forEach(fid => {\n const feature = featById.get(fid);\n const layer = featureToLayerMap.get(fid);\n const visualConfig = layer?.visualConfig;\n \n // Check if this is a trace point with assigned color\n if (tracePointColors.has(fid)) {\n colorMap.set(fid, tracePointColors.get(fid)!);\n return;\n }\n \n // Default color\n let color = (feature?.properties?.stroke as string) || '#3b82f6';\n \n // Apply layer color config\n const colorConfig = visualConfig?.color;\n if (colorConfig && feature) {\n if (colorConfig.mode === 'fixed' && colorConfig.fixedColor) {\n color = colorConfig.fixedColor;\n } else if (colorConfig.mode === 'field' && colorConfig.fieldName && feature.properties) {\n const fieldValue = feature.properties[colorConfig.fieldName];\n if (fieldValue !== undefined && fieldValue !== null) {\n color = hashStringToColor(String(fieldValue));\n }\n }\n }\n \n colorMap.set(fid, color);\n });\n \n return colorMap;\n }, [selectedFeatureIds, layers, getAllFeatures, hashStringToColor]);\n\n\n // Sync features to custom rendering layers (separate from MapboxDraw's internal layers)\n const syncFeaturesToCustomLayers = useCallback(() => {\n if (!map.current) return;\n \n const source = map.current.getSource('custom-features') as maplibregl.GeoJSONSource | undefined;\n if (!source) return;\n \n // Get editable features from MapboxDraw (if available)\n const drawFeatures = draw.current ? draw.current.getAll() : { type: 'FeatureCollection' as const, features: [] };\n const drawSelectedIds = draw.current ? draw.current.getSelectedIds() : [];\n const componentSelectedIds = selectedFeatureIdsRef.current;\n const selectedIds = Array.from(new Set([...drawSelectedIds, ...componentSelectedIds]));\n const visibleSet = timelineVisibleIdsRef.current;\n \n // Build combined feature collection from both MapboxDraw and read-only layers\n // Use layersRef.current for immediate access (avoids stale state after setLayers)\n const currentLayers = layersRef.current;\n const allFeatures: GeoJSON.Feature[] = [...drawFeatures.features];\n \n // Add read-only features\n readOnlyFeatures.current.forEach((features, layerId) => {\n const layer = currentLayers.find(l => l.id === layerId);\n if (layer?.visible) {\n allFeatures.push(...features);\n }\n });\n \n // Build O(1) lookup map: feature ID -> feature\n // Normalize all IDs to strings for consistent lookups\n const featureById = new Map<string, GeoJSON.Feature>();\n allFeatures.forEach(f => {\n if (f.id !== undefined && f.id !== null) {\n featureById.set(String(f.id), f);\n }\n });\n \n // Build lookup of feature ID -> layer for visual config\n const featureToLayer = new Map<string, Layer>();\n currentLayers.forEach(layer => {\n layer.featureIds.forEach(fid => featureToLayer.set(fid, layer));\n });\n \n // Pre-calculate min/max for size fields per visible layer only (using O(1) lookup)\n const sizeFieldRanges = new Map<string, { min: number; max: number }>();\n currentLayers.forEach(layer => {\n // Skip hidden layers - they shouldn't influence sizing of visible layers\n if (!layer.visible) return;\n \n const sizeConfig = layer.visualConfig?.size;\n if (sizeConfig?.mode === 'field' && sizeConfig.fieldName) {\n let min = Infinity, max = -Infinity;\n layer.featureIds.forEach(fid => {\n const feature = featureById.get(fid);\n if (feature?.properties) {\n const rawVal = feature.properties[sizeConfig.fieldName!];\n // Handle both numbers and numeric strings\n const val = typeof rawVal === 'number' ? rawVal : \n (typeof rawVal === 'string' && rawVal.trim() !== '' ? Number(rawVal) : NaN);\n if (isFinite(val)) {\n min = Math.min(min, val);\n max = Math.max(max, val);\n }\n }\n });\n if (isFinite(min) && isFinite(max)) {\n sizeFieldRanges.set(layer.id, { min, max });\n }\n }\n });\n \n // Compute trace point info for layers with traces enabled\n // - lastTracePointIds: last point in each group (will be shown with larger size)\n // - tracePointColors: color for ALL trace points (matches trace line color)\n // - tracePointIds: all points in trace layers (will show with small size, trace color)\n const lastTracePointIds = new Set<string>();\n const tracePointColors = new Map<string, string>();\n const lastTracePointLabels = new Map<string, string>();\n const tracePointIds = new Set<string>();\n \n currentLayers.forEach(layer => {\n if (!layer.traceConfig?.enabled || !layer.visible) return;\n \n // Get visible point features with startDate from this layer (O(1) lookup)\n const layerFeatures: GeoJSON.Feature[] = [];\n layer.featureIds.forEach(id => {\n const f = featureById.get(id);\n if (!f || f.geometry.type !== 'Point' || !f.properties?.startDate) return;\n if (visibleSet && f.id && !visibleSet.has(String(f.id))) return;\n layerFeatures.push(f);\n });\n \n if (layerFeatures.length < 1) return;\n \n // Group by field if configured\n const groupByField = layer.traceConfig.groupByField;\n const groups = new Map<string, GeoJSON.Feature[]>();\n \n layerFeatures.forEach(f => {\n const key = groupByField && f.properties?.[groupByField] \n ? String(f.properties[groupByField]) \n : '__all__';\n if (!groups.has(key)) groups.set(key, []);\n groups.get(key)!.push(f);\n });\n \n // Generate colors for groups (same logic as trace line colors)\n const groupKeys = Array.from(groups.keys());\n const groupColors = new Map<string, string>();\n groupKeys.forEach((key, index) => {\n if (key === '__all__') {\n groupColors.set(key, '#3b82f6');\n } else {\n const hue = (index * 360 / groupKeys.length) % 360;\n groupColors.set(key, `hsl(${hue}, 70%, 50%)`);\n }\n });\n \n // Find last point (chronologically) in each group, hide all others\n groups.forEach((groupFeatures, groupKey) => {\n const sorted = [...groupFeatures].sort((a, b) => {\n const dateA = new Date(a.properties?.startDate || 0).getTime();\n const dateB = new Date(b.properties?.startDate || 0).getTime();\n return dateA - dateB;\n });\n \n if (sorted.length > 0) {\n const groupColor = groupColors.get(groupKey) || '#3b82f6';\n \n // All points in trace mode get the trace line color\n sorted.forEach(point => {\n if (point.id) {\n tracePointIds.add(String(point.id));\n tracePointColors.set(String(point.id), groupColor);\n }\n });\n \n // Last point gets shown larger with label\n const lastPoint = sorted[sorted.length - 1];\n if (lastPoint.id) {\n lastTracePointIds.add(String(lastPoint.id));\n // Store the grouping field value as label (if grouping is enabled)\n if (groupByField && groupKey !== '__all__') {\n lastTracePointLabels.set(String(lastPoint.id), groupKey);\n }\n }\n }\n });\n });\n\n // Build feature collection with styling properties\n const sourceData: GeoJSON.FeatureCollection = {\n type: 'FeatureCollection',\n features: allFeatures.map(f => {\n // Normalize ID to string for consistent lookups across all maps/sets\n const featureId = String(f.id);\n const layer = featureToLayer.get(featureId);\n const visualConfig = layer?.visualConfig;\n \n // Check timeline visibility - if no filter active, show all; otherwise check set\n const isTimelineVisible = visibleSet === null || visibleSet.has(featureId);\n const baseOpacity = (f.properties?.['stroke-opacity'] as number) ?? 1;\n \n // Determine color based on visualConfig\n let strokeColor = (f.properties?.stroke as string) || '#3b82f6';\n const colorConfig = visualConfig?.color;\n if (colorConfig) {\n if (colorConfig.mode === 'fixed' && colorConfig.fixedColor) {\n strokeColor = colorConfig.fixedColor;\n } else if (colorConfig.mode === 'field' && colorConfig.fieldName && f.properties) {\n const fieldValue = f.properties[colorConfig.fieldName];\n if (fieldValue !== undefined && fieldValue !== null) {\n strokeColor = hashStringToColor(String(fieldValue));\n }\n }\n // mode === 'standard' uses default from feature properties\n }\n \n // Determine size based on visualConfig\n let strokeWidth = (f.properties?.['stroke-width'] as number) || 2;\n let pointRadius = Math.round(3 + strokeWidth); // Smaller default radius (must be integer)\n const sizeConfig = visualConfig?.size;\n if (sizeConfig) {\n if (sizeConfig.mode === 'override' && sizeConfig.overrideValue !== undefined) {\n // Override size: use directly\n strokeWidth = Math.max(1, Math.min(10, sizeConfig.overrideValue));\n pointRadius = Math.round(3 + strokeWidth);\n } else if (sizeConfig.mode === 'field' && sizeConfig.fieldName && layer) {\n const range = sizeFieldRanges.get(layer.id);\n if (range && f.properties) {\n const rawVal = f.properties[sizeConfig.fieldName];\n // Handle both numbers and numeric strings\n const val = typeof rawVal === 'number' ? rawVal : \n (typeof rawVal === 'string' && rawVal.trim() !== '' ? Number(rawVal) : NaN);\n if (isFinite(val)) {\n // Normalize to range with small minimum for better contrast\n // Min size: 2px stroke, 2px radius; Max size: 10px stroke, 18px radius\n const normalized = range.max > range.min \n ? (val - range.min) / (range.max - range.min)\n : 0.5;\n strokeWidth = 2 + normalized * 8; // 2-10\n pointRadius = Math.round(2 + normalized * 16); // 2-18\n }\n }\n }\n // mode === 'standard' uses default from feature properties\n }\n \n // Handle trace mode styling for points\n const isTracePoint = tracePointIds.has(featureId);\n const isLastTracePoint = lastTracePointIds.has(featureId);\n \n // Determine if this is a last trace point that should show a label\n const traceLabel = lastTracePointLabels.get(featureId);\n \n if (isTracePoint && f.geometry.type === 'Point') {\n // All trace points use the trace line color\n strokeColor = tracePointColors.get(featureId) || strokeColor;\n \n if (isLastTracePoint) {\n // Last trace point: larger size for visibility\n pointRadius = Math.max(pointRadius, 8);\n } else {\n // Non-last trace points: minimum 2px radius\n pointRadius = 2;\n }\n }\n \n // Determine label text based on visualConfig\n let labelText = (f.properties?.name as string) || '';\n const labelConfig = visualConfig?.label;\n if (labelConfig) {\n if (labelConfig.mode === 'fixed' && labelConfig.fixedText) {\n labelText = labelConfig.fixedText;\n } else if (labelConfig.mode === 'field' && labelConfig.fieldName && f.properties) {\n const fieldValue = f.properties[labelConfig.fieldName];\n labelText = fieldValue !== undefined && fieldValue !== null ? String(fieldValue) : '';\n }\n // mode === 'standard' uses default name from properties\n }\n \n // Override label for last trace points when grouping by field\n if (traceLabel) {\n labelText = traceLabel;\n }\n \n // Icon is stored as metadata (shown in properties panel) but not rendered as image overlay\n // The icon property can be any string identifier (e.g., 'map-pin', 'hospital')\n const featureIcon = (f.properties?.pointIcon || f.properties?.icon) as string | undefined;\n \n // Check if this point should be hidden because heatmap hideFeatures is enabled\n // Note: Trace points are now visible with small size, not hidden\n const isPoint = f.geometry.type === 'Point';\n const hideByHeatmap = isPoint && layer?.heatmapConfig?.enabled && layer?.heatmapConfig?.hideFeatures;\n const hideByCluster = isPoint && layer?.clusterConfig?.enabled === true && !layer?.clusterConfig?.showPointDots;\n const isSelected = selectedIds.includes(featureId);\n const hideByTrace = false; // Trace points now visible with small size\n \n // Check if flat (ground-level) line should be hidden when layer is set to '3d' only mode\n const isLine = f.geometry.type === 'LineString' || f.geometry.type === 'MultiLineString';\n const hideFlatFor3DOnly = isLine && layer?.hasAltitudeData && layer?.altitudeDisplayMode === '3d';\n \n // Sanitize properties for MapLibre (only primitives allowed)\n const sanitizedProps: Record<string, string | number | boolean | null> = {};\n if (f.properties) {\n Object.entries(f.properties).forEach(([key, value]) => {\n if (value === null || value === undefined) {\n sanitizedProps[key] = null;\n } else if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {\n sanitizedProps[key] = value;\n } else if (value instanceof Date) {\n sanitizedProps[key] = value.toISOString();\n } else {\n // Convert other types to string\n sanitizedProps[key] = String(value);\n }\n });\n }\n \n const isFeatureSelected = selectedIds.includes(featureId) ? 1 : 0;\n \n return {\n type: 'Feature' as const,\n id: featureId,\n geometry: f.geometry,\n properties: {\n // Preserve original properties for tooltip display (sanitized)\n ...sanitizedProps,\n // Override with computed visual properties\n id: featureId,\n name: labelText,\n isSelected: isFeatureSelected,\n isHiddenByHeatmap: hideByHeatmap ? true : false,\n isHiddenByCluster: hideByCluster ? 1 : 0,\n isHiddenByTrace: hideByTrace ? true : false,\n isTracePoint: isTracePoint ? true : false,\n isTraceLabel: traceLabel ? true : false,\n icon: featureIcon || '',\n stroke: strokeColor,\n 'stroke-width': strokeWidth,\n 'stroke-opacity': hideFlatFor3DOnly ? 0 : (isTimelineVisible ? baseOpacity : 0),\n fill: strokeColor,\n 'fill-opacity': hideFlatFor3DOnly ? 0 : (isTimelineVisible ? ((f.properties?.['fill-opacity'] as number) ?? 0.2) : 0),\n pointRadius: pointRadius,\n isHiddenFor3DOnly: hideFlatFor3DOnly ? 1 : 0,\n isTimelineHidden: isTimelineVisible ? 0 : 1,\n }\n };\n })\n };\n source.setData(sourceData);\n \n // Note: Label visibility is controlled by the fast-path useEffect that uses\n // viewport-aware feature counting. This allows labels to show when zoomed in\n // even if there are many features globally.\n \n // Compute and update trace lines for layers with traceConfig enabled\n const traceSource = map.current.getSource('trace-features') as maplibregl.GeoJSONSource | undefined;\n if (traceSource) {\n const traceSegments: GeoJSON.Feature[] = [];\n \n currentLayers.forEach(layer => {\n // Only process layers with traces enabled AND visible\n if (!layer.traceConfig?.enabled || !layer.visible) return;\n \n // Get point features from this layer that are timeline-visible and have startDate (O(1) lookup)\n const layerFeatures: GeoJSON.Feature[] = [];\n layer.featureIds.forEach(id => {\n const f = featureById.get(id);\n if (!f || f.geometry.type !== 'Point' || !f.properties?.startDate) return;\n if (visibleSet && f.id && !visibleSet.has(String(f.id))) return;\n layerFeatures.push(f);\n });\n \n if (layerFeatures.length < 2) return;\n \n // Group by field if configured\n const groupByField = layer.traceConfig.groupByField;\n const groups = new Map<string, GeoJSON.Feature[]>();\n \n layerFeatures.forEach(f => {\n const key = groupByField && f.properties?.[groupByField] \n ? String(f.properties[groupByField]) \n : '__all__';\n if (!groups.has(key)) groups.set(key, []);\n groups.get(key)!.push(f);\n });\n \n // Generate colors for groups\n const groupKeys = Array.from(groups.keys());\n const groupColors = new Map<string, string>();\n groupKeys.forEach((key, index) => {\n if (key === '__all__') {\n groupColors.set(key, '#3b82f6');\n } else {\n const hue = (index * 360 / groupKeys.length) % 360;\n groupColors.set(key, `hsl(${hue}, 70%, 50%)`);\n }\n });\n \n // Create trace segments for each group\n groups.forEach((groupFeatures, groupKey) => {\n const sorted = [...groupFeatures].sort((a, b) => {\n const dateA = new Date(a.properties?.startDate || 0).getTime();\n const dateB = new Date(b.properties?.startDate || 0).getTime();\n return dateA - dateB;\n });\n \n if (sorted.length < 2) return;\n \n for (let i = 0; i < sorted.length - 1; i++) {\n const from = sorted[i];\n const to = sorted[i + 1];\n const fromCoords = (from.geometry as GeoJSON.Point).coordinates;\n const toCoords = (to.geometry as GeoJSON.Point).coordinates;\n \n // Calculate distance\n const fromPoint = turf.point(fromCoords);\n const toPoint = turf.point(toCoords);\n const distanceKm = turf.distance(fromPoint, toPoint, { units: 'kilometers' });\n \n // Calculate duration and speed\n const fromTime = new Date(from.properties?.startDate || 0).getTime();\n const toTime = new Date(to.properties?.startDate || 0).getTime();\n const durationMs = toTime - fromTime;\n const durationHours = durationMs / (1000 * 60 * 60);\n const avgSpeedKmh = durationHours > 0 ? distanceKm / durationHours : 0;\n \n // Format duration\n let durationStr = '';\n if (durationMs < 60000) {\n durationStr = `${Math.round(durationMs / 1000)}s`;\n } else if (durationMs < 3600000) {\n durationStr = `${Math.round(durationMs / 60000)}m`;\n } else if (durationMs < 86400000) {\n durationStr = `${Math.floor(durationMs / 3600000)}h ${Math.round((durationMs % 3600000) / 60000)}m`;\n } else {\n durationStr = `${Math.floor(durationMs / 86400000)}d ${Math.round((durationMs % 86400000) / 3600000)}h`;\n }\n \n // Format distance\n const distanceStr = distanceKm < 1 ? `${Math.round(distanceKm * 1000)}m` : `${distanceKm.toFixed(2)}km`;\n \n // Format speed\n const speedStr = avgSpeedKmh < 1 ? `${(avgSpeedKmh * 1000).toFixed(0)}m/h` : `${avgSpeedKmh.toFixed(1)}km/h`;\n \n traceSegments.push({\n type: 'Feature',\n properties: {\n group: groupKey,\n color: groupColors.get(groupKey) || '#3b82f6',\n duration: durationStr,\n distance: distanceStr,\n avgSpeed: speedStr,\n fromName: from.properties?.name || '',\n toName: to.properties?.name || '',\n },\n geometry: {\n type: 'LineString',\n coordinates: [fromCoords, toCoords]\n },\n });\n }\n });\n });\n \n traceSource.setData({ type: 'FeatureCollection', features: traceSegments });\n }\n \n // Compute arrow head triangles for arrow features using screen-space projection\n const arrowHeadSource = map.current.getSource('arrow-heads') as maplibregl.GeoJSONSource | undefined;\n if (arrowHeadSource && map.current) {\n const arrowHeadTriangles: GeoJSON.Feature[] = [];\n const mapInstance = map.current;\n \n // Arrow head dimensions in pixels\n const headLength = 16; // Length from tip to base\n const headWidth = 10; // Half-width of the base\n \n sourceData.features.forEach(f => {\n // Check both the kind property and the external arrow ID set\n const isArrow = f.properties?.kind === 'arrow' || arrowFeatureIdsRef.current.has(String(f.id));\n if (f.geometry.type !== 'LineString' || !isArrow) return;\n \n const coords = f.geometry.coordinates as [number, number][];\n if (coords.length < 2) return;\n \n // Get last two points\n const end = coords[coords.length - 1];\n const prev = coords[coords.length - 2];\n \n // Project to screen coordinates\n const endScreen = mapInstance.project(end as [number, number]);\n const prevScreen = mapInstance.project(prev as [number, number]);\n \n // Compute direction vector in screen space (from prev to end)\n const dx = endScreen.x - prevScreen.x;\n const dy = endScreen.y - prevScreen.y;\n const len = Math.sqrt(dx * dx + dy * dy);\n \n if (len < 0.001) return; // Skip degenerate segments\n \n // Normalize direction vector\n const dirX = dx / len;\n const dirY = dy / len;\n \n // Perpendicular vector (90 degrees clockwise in screen space)\n const perpX = -dirY;\n const perpY = dirX;\n \n // Compute triangle vertices in screen space:\n // Tip is at the endpoint\n const tipScreen = { x: endScreen.x, y: endScreen.y };\n \n // Base vertices are behind the tip, offset perpendicular\n const baseLeftScreen = {\n x: endScreen.x - dirX * headLength - perpX * headWidth,\n y: endScreen.y - dirY * headLength - perpY * headWidth\n };\n const baseRightScreen = {\n x: endScreen.x - dirX * headLength + perpX * headWidth,\n y: endScreen.y - dirY * headLength + perpY * headWidth\n };\n \n // Unproject back to geographic coordinates\n const tipGeo = mapInstance.unproject([tipScreen.x, tipScreen.y]);\n const baseLeftGeo = mapInstance.unproject([baseLeftScreen.x, baseLeftScreen.y]);\n const baseRightGeo = mapInstance.unproject([baseRightScreen.x, baseRightScreen.y]);\n \n arrowHeadTriangles.push({\n type: 'Feature',\n geometry: {\n type: 'Polygon',\n coordinates: [[\n [tipGeo.lng, tipGeo.lat],\n [baseLeftGeo.lng, baseLeftGeo.lat],\n [baseRightGeo.lng, baseRightGeo.lat],\n [tipGeo.lng, tipGeo.lat] // Close the polygon\n ]]\n },\n properties: {\n ...f.properties,\n }\n });\n });\n \n arrowHeadSource.setData({ type: 'FeatureCollection', features: arrowHeadTriangles });\n }\n \n // Compute arrow label points (at midpoint of arrow lines)\n const arrowLabelSource = map.current.getSource('arrow-labels') as maplibregl.GeoJSONSource | undefined;\n if (arrowLabelSource) {\n const arrowLabelPoints: GeoJSON.Feature[] = [];\n \n sourceData.features.forEach(f => {\n // Check both the kind property and the external arrow ID set\n const isArrow = f.properties?.kind === 'arrow' || arrowFeatureIdsRef.current.has(String(f.id));\n if (f.geometry.type !== 'LineString' || !isArrow) return;\n \n // Only render label if name exists\n const name = f.properties?.name;\n if (!name) return;\n \n const coords = f.geometry.coordinates as [number, number][];\n if (coords.length < 2) return;\n \n // Calculate true midpoint of the line (average of all points weighted by segments)\n const start = coords[0];\n const end = coords[coords.length - 1];\n const midPoint: [number, number] = [\n (start[0] + end[0]) / 2,\n (start[1] + end[1]) / 2\n ];\n \n // Calculate bearing based on overall line direction (start to end)\n const dLng = end[0] - start[0];\n const dLat = end[1] - start[1];\n \n // atan2 gives angle from positive X axis (east) in radians\n // Convert to degrees: 0 = east, 90 = north, -90 = south, 180/-180 = west\n const angleFromEast = Math.atan2(dLat, dLng) * (180 / Math.PI);\n \n // MapLibre text-rotate is clockwise from horizontal (east-pointing text)\n // To align text with line: rotate by negative of angle from east\n // But we want text readable, so if line points left (west), flip 180\n let labelBearing = -angleFromEast;\n \n // Normalize to [-180, 180]\n labelBearing = ((labelBearing % 360) + 540) % 360 - 180;\n \n // If text would be upside down (pointing generally left), flip it\n if (labelBearing > 90) {\n labelBearing -= 180;\n } else if (labelBearing < -90) {\n labelBearing += 180;\n }\n \n arrowLabelPoints.push({\n type: 'Feature',\n geometry: {\n type: 'Point',\n coordinates: midPoint\n },\n properties: {\n ...f.properties,\n labelBearing: labelBearing,\n }\n });\n });\n \n arrowLabelSource.setData({ type: 'FeatureCollection', features: arrowLabelPoints });\n }\n \n // Update 3D flight paths to respect timeline filtering\n if (update3DFlightPathsRef?.current) {\n update3DFlightPathsRef.current();\n }\n \n // After sync, wait for map idle then count visible features\n // This handles new features being added - must wait for render to complete\n const m = map.current;\n if (m) {\n m.once('idle', () => {\n const countLayers = ['custom-point', 'custom-line', 'custom-polygon-fill'];\n const existing = countLayers.filter(id => m.getLayer(id));\n if (existing.length === 0) {\n setVisibleFeatureCount(0);\n setLabelsSuppressed(false);\n return;\n }\n const threshold = autoLabelConfig.enabled ? autoLabelConfig.threshold : 220;\n const rendered = m.queryRenderedFeatures(undefined, { layers: existing });\n const uniqueIds = new Set<string>();\n let count = 0;\n for (const f of rendered) {\n const fid = f.properties?.id || f.id;\n if (fid && !uniqueIds.has(String(fid))) {\n uniqueIds.add(String(fid));\n count++;\n if (count > threshold) break;\n }\n }\n setVisibleFeatureCount(count);\n setLabelsSuppressed(false);\n });\n }\n }, [layers, hashStringToColor, autoLabelConfig]);\n \n // Update 3D flight path layer for lines with altitude data\n const update3DFlightPaths = useCallback(() => {\n if (!map.current || !is3DTerrainEnabled) {\n // Remove 3D layer if terrain is disabled\n if (map.current && flightPath3DLayerId.current) {\n try {\n map.current.removeLayer(flightPath3DLayerId.current);\n } catch {}\n flightPath3DLayerId.current = null;\n }\n return;\n }\n \n const mapInstance = map.current;\n \n // Use the same timeline visible IDs set that ground features use\n const visibleSet = timelineVisibleIdsRef.current;\n \n // Helper to check if a feature is visible based on timeline\n const isFeatureVisibleInTimeline = (feature: GeoJSON.Feature): boolean => {\n // If no timeline filter is active, show all features\n if (visibleSet === null) return true;\n // Check if feature ID is in the visible set\n const featureId = String(feature.id);\n return visibleSet.has(featureId);\n };\n \n // Collect all features with altitude data from layers that have TRACE enabled\n // 3D tubes only appear when BOTH 3D terrain is on AND TRACE is enabled\n const allFeatures: GeoJSON.Feature[] = [];\n const currentLayers = layersRef.current;\n \n // Get editable features from MapboxDraw - only from layers with TRACE enabled\n if (draw.current) {\n const drawFeatures = draw.current.getAll().features.filter(feature => {\n if (!isFeatureVisibleInTimeline(feature)) return false;\n // Find which layer this feature belongs to\n const featureId = feature.id as string;\n const layer = currentLayers.find(l => l.featureIds.includes(featureId));\n // Only include if TRACE is enabled for this layer\n return layer?.traceConfig?.enabled === true;\n });\n allFeatures.push(...drawFeatures);\n }\n \n // Add read-only features (only from layers with TRACE enabled AND 3D altitude mode)\n readOnlyFeatures.current.forEach((features, layerId) => {\n const layer = currentLayers.find(l => l.id === layerId);\n // Only include features from layers with:\n // 1. TRACE enabled (required for connecting points into tubes)\n // 2. 3D altitude display enabled\n const altitudeMode = layer?.altitudeDisplayMode ?? 'both';\n const traceEnabled = layer?.traceConfig?.enabled === true;\n if (layer?.visible && traceEnabled && (altitudeMode === '3d' || altitudeMode === 'both')) {\n // Also filter by timeline visibility\n const visibleFeatures = features.filter(isFeatureVisibleInTimeline);\n allFeatures.push(...visibleFeatures);\n }\n });\n \n // Extract 3D flight paths (lines with Z coordinates, or points grouped by TargetID)\n const flightPaths = extract3DFlightPaths(allFeatures);\n \n if (flightPaths.length === 0) {\n // No 3D paths, remove layer if exists\n if (flightPath3DLayerId.current) {\n try {\n mapInstance.removeLayer(flightPath3DLayerId.current);\n } catch {}\n flightPath3DLayerId.current = null;\n }\n return;\n }\n \n // Remove existing layer\n if (flightPath3DLayerId.current) {\n try {\n mapInstance.removeLayer(flightPath3DLayerId.current);\n } catch {}\n }\n \n // Create new 3D layer\n const layerId = `flight-path-3d-${Date.now()}`;\n const layer = createFlightPath3DLayer(layerId, mapInstance, flightPaths);\n mapInstance.addLayer(layer);\n flightPath3DLayerId.current = layerId;\n \n }, [is3DTerrainEnabled]);\n \n // Keep syncRef and 3D update ref updated\n useEffect(() => {\n syncRef.current = syncFeaturesToCustomLayers;\n }, [syncFeaturesToCustomLayers]);\n \n // Keep update3DFlightPaths ref in sync so syncFeaturesToCustomLayers can call it\n useEffect(() => {\n update3DFlightPathsRef.current = update3DFlightPaths;\n }, [update3DFlightPaths]);\n \n // Update 3D flight paths when terrain is toggled, layers change, or timeline changes\n useEffect(() => {\n update3DFlightPaths();\n }, [update3DFlightPaths, layers, is3DTerrainEnabled, timelineStore.isEnabled, timelineStore.rangeStart, timelineStore.rangeEnd]);\n \n // Also call 3D update after features sync to pick up new flight path data\n useEffect(() => {\n if (map.current && is3DTerrainEnabled) {\n // Debounce to avoid multiple rapid updates\n const timer = setTimeout(() => {\n update3DFlightPathsRef.current?.();\n }, 100);\n return () => clearTimeout(timer);\n }\n }, [layers, is3DTerrainEnabled]);\n\n const updateTimelineStore = useCallback(() => {\n // Get features from MapboxDraw\n const drawFeatures = draw.current ? draw.current.getAll().features as GeoJSON.Feature[] : [];\n \n // Use layersRef.current for immediate access (avoids stale state after setLayers)\n const currentLayers = layersRef.current;\n \n // Combine with visible read-only features\n const allFeatures: GeoJSON.Feature[] = [...drawFeatures];\n readOnlyFeatures.current.forEach((features, layerId) => {\n const layer = currentLayers.find(l => l.id === layerId);\n if (layer?.visible) {\n allFeatures.push(...features);\n }\n });\n \n const temporalFeatures: { id: string; startDate: Date | null; endDate: Date | null; layerId: string }[] = [];\n const untimedIds: string[] = [];\n \n allFeatures.forEach(feature => {\n const { startDate, endDate } = normalizeTemporalProperties(feature.properties || {});\n const featureLayer = currentLayers.find(l => l.featureIds.includes(feature.id as string));\n \n if (startDate || endDate) {\n temporalFeatures.push({\n id: feature.id as string,\n startDate,\n endDate,\n layerId: featureLayer?.id || 'default',\n });\n } else {\n untimedIds.push(feature.id as string);\n }\n });\n \n timelineStore.setTemporalFeatures(temporalFeatures, untimedIds);\n }, [timelineStore]);\n\n useEffect(() => {\n if (!mapContainer.current || map.current) return;\n\n try {\n const baseStyle = createBaseStyle({\n glyphsUrl,\n enableSatellite,\n enableTerrain,\n });\n \n const mapInstance = new maplibregl.Map({\n container: mapContainer.current,\n style: baseStyle,\n center: initialCenter,\n zoom: initialZoom,\n attributionControl: false,\n boxZoom: false, // Disable default box zoom - we use shift+drag for selection instead\n maxPitch: 80, // Allow steep camera angles for 3D terrain viewing\n });\n\n mapInstance.addControl(new maplibregl.AttributionControl({\n compact: true,\n customAttribution: '© <a href=\"https://www.openstreetmap.org/copyright\" target=\"_blank\">OpenStreetMap</a> contributors',\n }), 'bottom-right');\n mapInstance.addControl(new maplibregl.NavigationControl(), 'bottom-right');\n mapInstance.addControl(new maplibregl.ScaleControl({ unit: 'metric' }), 'bottom-left');\n\n const drawInstance = new MapboxDraw({\n displayControlsDefault: false,\n controls: {},\n modes: {\n ...MapboxDraw.modes,\n view_select: ViewSelectMode,\n },\n // Make MapboxDraw's default styles transparent - we use custom layers for rendering\n // Only keep vertex handles visible for editing\n styles: [\n // Hide default polygon/line/point rendering - custom layers will show these\n { id: 'gl-draw-polygon-fill-inactive', type: 'fill', filter: ['all', ['==', 'active', 'false'], ['==', '$type', 'Polygon']], paint: { 'fill-opacity': 0 } },\n { id: 'gl-draw-polygon-fill-active', type: 'fill', filter: ['all', ['==', 'active', 'true'], ['==', '$type', 'Polygon']], paint: { 'fill-color': '#fbbf24', 'fill-opacity': 0.15 } },\n { id: 'gl-draw-polygon-stroke-inactive', type: 'line', filter: ['all', ['==', 'active', 'false'], ['==', '$type', 'Polygon']], paint: { 'line-opacity': 0 } },\n { id: 'gl-draw-polygon-stroke-active', type: 'line', filter: ['all', ['==', 'active', 'true'], ['==', '$type', 'Polygon']], paint: { 'line-color': '#f59e0b', 'line-width': 2, 'line-dasharray': [2, 2] } },\n { id: 'gl-draw-line-inactive', type: 'line', filter: ['all', ['==', 'active', 'false'], ['==', '$type', 'LineString']], paint: { 'line-opacity': 0 } },\n { id: 'gl-draw-line-active', type: 'line', filter: ['all', ['==', 'active', 'true'], ['==', '$type', 'LineString']], paint: { 'line-color': '#f59e0b', 'line-width': 2, 'line-dasharray': [2, 2] } },\n { id: 'gl-draw-point-inactive', type: 'circle', filter: ['all', ['==', 'active', 'false'], ['==', '$type', 'Point'], ['==', 'meta', 'feature']], paint: { 'circle-opacity': 0 } },\n { id: 'gl-draw-point-active', type: 'circle', filter: ['all', ['==', 'active', 'true'], ['==', '$type', 'Point'], ['==', 'meta', 'feature']], paint: { 'circle-opacity': 0 } },\n // Keep vertex handles visible for editing\n { id: 'gl-draw-polygon-and-line-vertex-inactive', type: 'circle', filter: ['all', ['==', 'meta', 'vertex'], ['==', '$type', 'Point'], ['!=', 'mode', 'static']], paint: { 'circle-radius': 5, 'circle-color': '#fff', 'circle-stroke-color': '#3b82f6', 'circle-stroke-width': 2 } },\n { id: 'gl-draw-polygon-and-line-vertex-active', type: 'circle', filter: ['all', ['==', 'meta', 'vertex'], ['==', '$type', 'Point'], ['==', 'active', 'true']], paint: { 'circle-radius': 6, 'circle-color': '#fff', 'circle-stroke-color': '#f59e0b', 'circle-stroke-width': 2 } },\n { id: 'gl-draw-polygon-midpoint', type: 'circle', filter: ['all', ['==', 'meta', 'midpoint'], ['==', '$type', 'Point']], paint: { 'circle-radius': 4, 'circle-color': '#3b82f6' } },\n ],\n });\n\n mapInstance.addControl(drawInstance as unknown as maplibregl.IControl);\n\n mapInstance.on('load', () => {\n map.current = mapInstance;\n draw.current = drawInstance;\n \n // Add custom source and layers for feature rendering with data-driven styling\n mapInstance.addSource('custom-features', {\n type: 'geojson',\n data: { type: 'FeatureCollection', features: [] }\n });\n \n // Custom polygon fill layer - preserves original styling\n mapInstance.addLayer({\n id: 'custom-polygon-fill',\n type: 'fill',\n source: 'custom-features',\n filter: ['==', '$type', 'Polygon'],\n paint: {\n 'fill-color': ['get', 'fill'],\n 'fill-opacity': ['get', 'fill-opacity']\n }\n });\n \n mapInstance.addLayer({\n id: 'custom-polygon-stroke',\n type: 'line',\n source: 'custom-features',\n filter: ['==', '$type', 'Polygon'],\n paint: {\n 'line-color': ['get', 'stroke'],\n 'line-width': ['get', 'stroke-width'],\n 'line-opacity': ['get', 'stroke-opacity']\n }\n });\n \n // Custom line layer - preserves original styling\n mapInstance.addLayer({\n id: 'custom-line',\n type: 'line',\n source: 'custom-features',\n filter: ['==', '$type', 'LineString'],\n paint: {\n 'line-color': ['get', 'stroke'],\n 'line-width': ['get', 'stroke-width'],\n 'line-opacity': ['get', 'stroke-opacity']\n }\n });\n \n // Shadow layer rendered beneath points for depth\n mapInstance.addLayer({\n id: 'custom-point-shadow',\n type: 'circle',\n source: 'custom-features',\n filter: ['==', '$type', 'Point'],\n paint: {\n 'circle-color': 'rgba(0, 0, 0, 0.2)',\n 'circle-radius': ['+', ['case',\n ['==', ['get', 'isHiddenByCluster'], 1], 0,\n ['coalesce', ['get', 'pointRadius'], 5]\n ], 1.5],\n 'circle-blur': 0.5,\n 'circle-opacity': ['case',\n ['==', ['get', 'isHiddenByCluster'], 1], 0,\n ['coalesce', ['get', 'stroke-opacity'], 1]\n ],\n 'circle-translate': [1, 1]\n }\n });\n\n // Custom point layer with data-driven selection styling\n mapInstance.addLayer({\n id: 'custom-point',\n type: 'circle',\n source: 'custom-features',\n filter: ['==', '$type', 'Point'],\n paint: {\n 'circle-color': ['coalesce', ['get', 'stroke'], '#3b82f6'],\n 'circle-radius': ['case', \n ['==', ['get', 'isHiddenByCluster'], 1], \n 0, \n ['coalesce', ['get', 'pointRadius'], 5]\n ],\n 'circle-opacity': ['case',\n ['==', ['get', 'isHiddenByCluster'], 1],\n 0,\n ['coalesce', ['get', 'stroke-opacity'], 1]\n ],\n 'circle-stroke-color': ['case', ['==', ['get', 'isSelected'], 1], '#06b6d4', '#555555'],\n 'circle-stroke-width': ['case', \n ['==', ['get', 'isHiddenByCluster'], 1], 0,\n ['==', ['get', 'isSelected'], 1], 3, \n 1.5\n ],\n 'circle-stroke-opacity': ['case', ['==', ['get', 'isHiddenByCluster'], 1], 0, 1]\n }\n });\n \n // Selection highlight for lines - bright cyan dashed overlay\n mapInstance.addLayer({\n id: 'custom-line-selection',\n type: 'line',\n source: 'custom-features',\n filter: ['all', ['==', '$type', 'LineString'], ['==', 'isSelected', 1]],\n paint: {\n 'line-color': '#06b6d4',\n 'line-width': ['+', ['get', 'stroke-width'], 4],\n 'line-dasharray': [4, 2]\n }\n });\n \n // Selection highlight for polygons - bright cyan dashed outline\n mapInstance.addLayer({\n id: 'custom-polygon-selection',\n type: 'line',\n source: 'custom-features',\n filter: ['all', ['==', '$type', 'Polygon'], ['==', 'isSelected', 1]],\n paint: {\n 'line-color': '#06b6d4',\n 'line-width': 4,\n 'line-dasharray': [4, 2]\n }\n });\n \n // Label layer for all features - shows 'name' property, or 'text' for text features\n // Trace labels are slightly bigger and bolder, hidden points have no labels\n // Arrow labels are handled separately by the custom-arrow-labels layer\n mapInstance.addLayer({\n id: 'custom-labels',\n type: 'symbol',\n source: 'custom-features',\n layout: {\n 'visibility': 'none',\n // Hide labels for trace points (except last point which has isTraceLabel), arrows handled separately\n 'text-field': ['case', \n ['==', ['get', 'isHiddenByTrace'], true], '',\n ['==', ['get', 'kind'], 'arrow'], '', // Arrows use custom-arrow-labels layer\n // Trace points: only show label if isTraceLabel is true (last point in group)\n ['all', ['==', ['get', 'isTracePoint'], true], ['!=', ['get', 'isTraceLabel'], true]], '',\n ['==', ['get', 'kind'], 'text'], ['coalesce', ['get', 'label'], ['get', 'text'], 'New Label'],\n ['coalesce', ['get', 'name'], '']\n ],\n // Text features use their fontSize property; trace labels 14px; others 12px\n 'text-size': ['case', \n ['==', ['get', 'kind'], 'text'], ['coalesce', ['get', 'fontSize'], 14],\n ['==', ['get', 'isTraceLabel'], true], 14, \n 12\n ],\n // Text features: center anchor; others: top anchor\n 'text-anchor': ['case', ['==', ['get', 'kind'], 'text'], 'center', 'top'],\n 'text-offset': ['case', ['==', ['get', 'kind'], 'text'], ['literal', [0, 0]], ['literal', [0, 0.8]]],\n 'text-allow-overlap': true,\n 'text-ignore-placement': false,\n 'text-optional': true,\n // Bold font for text features with fontWeight=bold, trace labels, others regular\n 'text-font': ['case', \n ['all', ['==', ['get', 'kind'], 'text'], ['==', ['get', 'fontWeight'], 'bold']], \n ['literal', ['Montserrat SemiBold', 'Noto Sans Regular']],\n ['==', ['get', 'isTraceLabel'], true], \n ['literal', ['Montserrat Medium', 'Noto Sans Regular']],\n ['literal', ['Montserrat Regular', 'Noto Sans Regular']]\n ],\n },\n paint: {\n // Text features use fontColor; others use default\n 'text-color': ['case', \n ['==', ['get', 'kind'], 'text'], ['coalesce', ['get', 'fontColor'], '#000000'],\n '#1f2937'\n ],\n 'text-halo-color': '#ffffff',\n // Thicker halo for trace labels and text features\n 'text-halo-width': ['case', \n ['==', ['get', 'kind'], 'text'], 2,\n ['==', ['get', 'isTraceLabel'], true], 2, \n 1.5\n ],\n 'text-opacity': ['*', 0.9, ['get', 'stroke-opacity']],\n }\n });\n \n // Arrow heads source - point features at arrow line endpoints\n mapInstance.addSource('arrow-heads', {\n type: 'geojson',\n data: { type: 'FeatureCollection', features: [] }\n });\n \n // Arrow head layer - triangle polygons computed in screen space for precise positioning\n mapInstance.addLayer({\n id: 'custom-arrow-heads',\n type: 'fill',\n source: 'arrow-heads',\n paint: {\n 'fill-color': ['coalesce', ['get', 'stroke'], '#3b82f6'],\n 'fill-opacity': ['coalesce', ['get', 'stroke-opacity'], 1],\n }\n });\n \n // Arrow labels source - positioned at midpoint of arrow lines\n mapInstance.addSource('arrow-labels', {\n type: 'geojson',\n data: { type: 'FeatureCollection', features: [] }\n });\n \n // Arrow labels layer - shows name alongside the arrow direction\n mapInstance.addLayer({\n id: 'custom-arrow-labels',\n type: 'symbol',\n source: 'arrow-labels',\n layout: {\n 'text-field': ['get', 'name'],\n 'text-size': 12,\n 'text-allow-overlap': false,\n 'text-ignore-placement': false,\n 'text-rotate': ['get', 'labelBearing'],\n 'text-rotation-alignment': 'map',\n 'text-keep-upright': true, // Always readable (not upside down)\n 'text-anchor': 'center',\n 'text-offset': [0, -1], // Offset above the line\n 'text-font': ['Montserrat Medium', 'Noto Sans Regular'],\n },\n paint: {\n 'text-color': ['coalesce', ['get', 'stroke'], '#3b82f6'],\n 'text-halo-color': '#ffffff',\n 'text-halo-width': 1.5,\n 'text-opacity': ['coalesce', ['get', 'stroke-opacity'], 1],\n }\n });\n \n // Add trace source and layer - traces are computed in syncFeaturesToCustomLayers\n mapInstance.addSource('trace-features', {\n type: 'geojson',\n data: { type: 'FeatureCollection', features: [] }\n });\n \n mapInstance.addLayer({\n id: 'trace-lines',\n type: 'line',\n source: 'trace-features',\n paint: {\n 'line-color': ['get', 'color'],\n 'line-width': 2,\n 'line-opacity': 0.7,\n },\n });\n \n // Tooltip rendered inside map container with position:absolute, clamped to container bounds\n if (tooltipElRef.current) {\n tooltipElRef.current.parentElement?.removeChild(tooltipElRef.current);\n }\n const tooltipEl = document.createElement('div');\n tooltipEl.className = 'feature-tooltip-fixed';\n tooltipEl.style.cssText = 'position:absolute;z-index:50;pointer-events:auto;display:none;max-width:320px;';\n mapInstance.getContainer().appendChild(tooltipEl);\n tooltipElRef.current = tooltipEl;\n \n let tooltipLngLat: maplibregl.LngLat | null = null;\n let tooltipHideTimeout: ReturnType<typeof setTimeout> | null = null;\n let tooltipShowTimeout: ReturnType<typeof setTimeout> | null = null;\n let isMouseOverPopup = false;\n let tooltipFeatures: GeoJSON.Feature[] = [];\n let tooltipPageIndex = 0;\n let tooltipLngLatForPagination: maplibregl.LngLat | null = null;\n \n const positionTooltip = () => {\n if (!tooltipLngLat || tooltipEl.style.display === 'none') return;\n const point = mapInstance.project(tooltipLngLat);\n const container = mapInstance.getContainer();\n const cw = container.clientWidth;\n const ch = container.clientHeight;\n \n tooltipEl.style.maxWidth = Math.min(320, cw - 24) + 'px';\n const tw = tooltipEl.offsetWidth || 200;\n const th = tooltipEl.offsetHeight || 80;\n const gap = 12;\n \n let left = point.x < cw / 2 ? point.x + gap : point.x - tw - gap;\n let top = point.y - th - gap;\n if (top < 4) top = point.y + gap;\n \n if (left + tw > cw - 4) left = cw - tw - 4;\n if (top + th > ch - 4) top = ch - th - 4;\n left = Math.max(4, left);\n top = Math.max(4, top);\n \n tooltipEl.style.left = left + 'px';\n tooltipEl.style.top = top + 'px';\n };\n \n const showTooltip = (lngLat: maplibregl.LngLat, html: string) => {\n tooltipEl.innerHTML = html;\n tooltipEl.style.display = 'block';\n tooltipLngLat = lngLat;\n requestAnimationFrame(() => positionTooltip());\n };\n \n const hideTooltip = () => {\n if (tooltipShowTimeout) { clearTimeout(tooltipShowTimeout); tooltipShowTimeout = null; }\n tooltipEl.style.display = 'none';\n tooltipLngLat = null;\n tooltipFeatures = [];\n tooltipPageIndex = 0;\n tooltipLngLatForPagination = null;\n };\n \n mapInstance.on('move', positionTooltip);\n \n const scheduleTooltipHide = () => {\n if (tooltipHideTimeout) clearTimeout(tooltipHideTimeout);\n tooltipHideTimeout = setTimeout(() => {\n if (!isMouseOverPopup) {\n hideTooltip();\n }\n }, 300);\n };\n \n const cancelTooltipHide = () => {\n if (tooltipHideTimeout) {\n clearTimeout(tooltipHideTimeout);\n tooltipHideTimeout = null;\n }\n };\n \n tooltipEl.addEventListener('mouseenter', () => {\n isMouseOverPopup = true;\n cancelTooltipHide();\n });\n tooltipEl.addEventListener('mouseleave', () => {\n isMouseOverPopup = false;\n scheduleTooltipHide();\n });\n tooltipEl.addEventListener('click', (ev) => {\n const target = (ev.target as HTMLElement).closest('[data-tooltip-nav]');\n if (!target) return;\n ev.stopPropagation();\n const dir = target.getAttribute('data-tooltip-nav');\n if (dir === 'prev' && tooltipPageIndex > 0) {\n tooltipPageIndex--;\n renderTooltipPage();\n } else if (dir === 'next' && tooltipPageIndex < tooltipFeatures.length - 1) {\n tooltipPageIndex++;\n renderTooltipPage();\n }\n });\n \n\n // Show tooltip on hover for custom layers\n const customLayers = ['custom-point', 'custom-line', 'custom-polygon-fill'];\n \n const buildBuiltinTooltipHtml = (feature: GeoJSON.Feature): string => {\n const props = feature.properties || {};\n const featureId = String(props.id || feature.id);\n const currentLayers = layersRef.current;\n const featureLayer = currentLayers.find(l => l.featureIds.includes(featureId));\n const visualConfig = featureLayer?.visualConfig;\n const highlightFields = new Set<string>();\n if (visualConfig?.size?.mode === 'field' && visualConfig.size.fieldName) highlightFields.add(visualConfig.size.fieldName);\n if (visualConfig?.color?.mode === 'field' && visualConfig.color.fieldName) highlightFields.add(visualConfig.color.fieldName);\n const excludeKeys = ['stroke','stroke-width','stroke-opacity','fill','fill-opacity','pointRadius','isSelected','kind','meta:type','circleCenter','circleRadius','icon','iconSize','pointIcon','pointIconSize','fontSize','fontColor','fontWeight','arrowSize','label','entityType'];\n const displayProps = Object.entries(props)\n .filter(([key, value]) => !excludeKeys.includes(key) && !key.startsWith('_') && !key.startsWith('isHidden') && !key.startsWith('isTrace') && !key.startsWith('isTimeline') && !key.startsWith('trace') && value != null && value !== '')\n .slice(0, 5);\n const name = props.name;\n let html = '<div class=\"text-sm space-y-0.5\">';\n if (name) html += `<div class=\"font-medium\">${name}</div>`;\n if (featureId) html += `<div class=\"text-xs text-muted-foreground\"><span class=\"opacity-70\">ID:</span> ${String(featureId).slice(0, 30)}</div>`;\n const otherProps = displayProps.filter(([k]) => k !== 'name' && k !== 'id');\n if (otherProps.length > 0) {\n html += '<div class=\"text-xs text-muted-foreground space-y-0.5\">';\n otherProps.forEach(([key, value]) => { html += `<div><span class=\"opacity-70\">${key}:</span> ${String(value).slice(0, 30)}</div>`; });\n html += '</div>';\n }\n if (highlightFields.size > 0) {\n html += '<div class=\"text-xs border-t border-border/50 mt-1 pt-1 space-y-0.5\">';\n highlightFields.forEach(fieldName => {\n const value = props[fieldName];\n if (value != null && value !== '') html += `<div class=\"flex justify-between gap-2\"><span class=\"opacity-70\">${fieldName}:</span> <span class=\"font-medium\">${String(value).slice(0, 20)}</span></div>`;\n });\n html += '</div>';\n }\n html += '</div>';\n return html;\n };\n \n const renderTooltipPage = () => {\n if (tooltipFeatures.length === 0 || !tooltipLngLatForPagination) return;\n const feature = tooltipFeatures[tooltipPageIndex];\n let html: string | null = null;\n \n if (tooltipProviderRef.current) {\n html = tooltipProviderRef.current(feature);\n } else {\n html = buildBuiltinTooltipHtml(feature);\n }\n \n if (!html) return;\n \n if (tooltipFeatures.length > 1) {\n const prevDisabled = tooltipPageIndex === 0;\n const nextDisabled = tooltipPageIndex === tooltipFeatures.length - 1;\n const btnBase = 'background:none;border-radius:4px;padding:1px 8px;font-size:12px;line-height:1.4;';\n const navHtml = `<div style=\"display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid #eee;padding:4px 0 6px;margin-bottom:4px;font-size:12px;color:#666;user-select:none\">`\n + `<button data-tooltip-nav=\"prev\" style=\"${btnBase}border:1px solid ${prevDisabled ? '#eee' : '#ddd'};cursor:${prevDisabled ? 'default' : 'pointer'};color:${prevDisabled ? '#ccc' : '#444'}\"${prevDisabled ? ' disabled' : ''}>‹</button>`\n + `<span>${tooltipPageIndex + 1} / ${tooltipFeatures.length}</span>`\n + `<button data-tooltip-nav=\"next\" style=\"${btnBase}border:1px solid ${nextDisabled ? '#eee' : '#ddd'};cursor:${nextDisabled ? 'default' : 'pointer'};color:${nextDisabled ? '#ccc' : '#444'}\"${nextDisabled ? ' disabled' : ''}>›</button>`\n + `</div>`;\n html = navHtml + html;\n }\n \n showTooltip(tooltipLngLatForPagination, html);\n };\n \n customLayers.forEach(layerId => {\n mapInstance.on('mouseenter', layerId, (e) => {\n mapInstance.getCanvas().style.cursor = 'pointer';\n if (tooltipShowTimeout) { clearTimeout(tooltipShowTimeout); tooltipShowTimeout = null; }\n if (tooltipHideTimeout) { clearTimeout(tooltipHideTimeout); tooltipHideTimeout = null; }\n\n if (!isMouseOverPopup) {\n tooltipEl.style.display = 'none';\n tooltipLngLat = null;\n }\n \n if (e.features && e.features.length > 0) {\n const coordinates = e.lngLat;\n\n tooltipShowTimeout = setTimeout(() => {\n tooltipShowTimeout = null;\n if (isDrawingSelection.current) return;\n const drawMode = draw.current?.getMode?.();\n const tooltipAllowedModes = ['simple_select', 'direct_select', 'view_select'];\n if (drawMode && !tooltipAllowedModes.includes(drawMode)) return;\n\n const hoveredFeature = e.features![0];\n const hoveredGeom = hoveredFeature.geometry;\n let hoveredCoords: [number, number] | null = null;\n if (hoveredGeom.type === 'Point') {\n hoveredCoords = hoveredGeom.coordinates as [number, number];\n }\n\n const seen = new Set<string>();\n const uniqueFeatures: GeoJSON.Feature[] = [];\n\n const addUnique = (f: GeoJSON.Feature | maplibregl.MapGeoJSONFeature) => {\n const fid = String((f.properties || {}).id || f.id || '');\n if (fid && seen.has(fid)) return;\n if (fid) seen.add(fid);\n uniqueFeatures.push({\n type: 'Feature',\n geometry: f.geometry as GeoJSON.Geometry,\n properties: { ...(f.properties || {}) },\n id: f.id,\n });\n };\n\n addUnique(hoveredFeature);\n\n if (hoveredCoords) {\n const allFeatures: GeoJSON.Feature[] = [];\n if (draw.current) {\n allFeatures.push(...draw.current.getAll().features);\n }\n readOnlyFeatures.current.forEach((features, lid) => {\n const layer = layersRef.current.find(l => l.id === lid);\n if (layer?.visible) allFeatures.push(...features);\n });\n const EPS = 1e-7;\n for (const cf of allFeatures) {\n if (cf.geometry?.type !== 'Point') continue;\n const cc = (cf.geometry as GeoJSON.Point).coordinates;\n if (Math.abs(cc[0] - hoveredCoords[0]) < EPS && Math.abs(cc[1] - hoveredCoords[1]) < EPS) {\n addUnique(cf);\n }\n }\n }\n\n if (uniqueFeatures.length === 0) {\n addUnique(hoveredFeature);\n }\n \n tooltipFeatures = uniqueFeatures;\n tooltipPageIndex = 0;\n tooltipLngLatForPagination = coordinates;\n \n renderTooltipPage();\n }, 250);\n }\n });\n \n mapInstance.on('mouseleave', layerId, () => {\n mapInstance.getCanvas().style.cursor = '';\n if (tooltipShowTimeout) { clearTimeout(tooltipShowTimeout); tooltipShowTimeout = null; }\n scheduleTooltipHide();\n });\n });\n \n // Trace line hover handlers\n mapInstance.on('mouseenter', 'trace-lines', (e) => {\n mapInstance.getCanvas().style.cursor = 'pointer';\n \n if (e.features && e.features.length > 0) {\n const props = e.features[0].properties || {};\n const duration = props.duration || '';\n const distance = props.distance || '';\n const avgSpeed = props.avgSpeed || '';\n const group = props.group !== '__all__' ? props.group : null;\n const fromName = props.fromName || '';\n const toName = props.toName || '';\n \n let html = '<div class=\"text-sm space-y-1\">';\n \n if (fromName || toName) {\n html += `<div class=\"font-medium text-xs text-muted-foreground\">${fromName || '?'} → ${toName || '?'}</div>`;\n }\n \n html += '<div class=\"space-y-0.5\">';\n html += `<div><span class=\"text-muted-foreground\">Duration:</span> <span class=\"font-medium\">${duration}</span></div>`;\n html += `<div><span class=\"text-muted-foreground\">Distance:</span> <span class=\"font-medium\">${distance}</span></div>`;\n html += `<div><span class=\"text-muted-foreground\">Avg Speed:</span> <span class=\"font-medium\">${avgSpeed}</span></div>`;\n html += '</div>';\n \n if (group) {\n html += `<div class=\"text-xs text-muted-foreground border-t border-border/50 mt-1 pt-1\">Group: ${group}</div>`;\n }\n \n html += '</div>';\n \n if (!tracePopupRef.current) {\n tracePopupRef.current = new maplibregl.Popup({\n closeButton: false,\n closeOnClick: false,\n className: 'feature-tooltip',\n anchor: 'bottom',\n offset: [0, -10]\n });\n }\n \n tracePopupRef.current\n .setLngLat(e.lngLat)\n .setHTML(html)\n .addTo(mapInstance);\n }\n });\n \n mapInstance.on('mouseleave', 'trace-lines', () => {\n mapInstance.getCanvas().style.cursor = '';\n if (tracePopupRef.current) {\n tracePopupRef.current.remove();\n }\n });\n \n setIsMapLoaded(true);\n isMapLoadedRef.current = true; // Set ref synchronously for imperative handle\n updateFeatureCount();\n \n // Apply initial drawing mode if specified\n if (initialDrawingMode && draw.current) {\n draw.current.changeMode(initialDrawingMode as string);\n setActiveMode(initialDrawingMode as DrawingMode);\n }\n \n // Notify parent that map is ready for programmatic control\n onMapReady?.();\n \n // Load the initial basemap style (streets by default)\n // This is async but we don't need to wait for it\n if (baseMapStyle !== 'satellite') {\n // For non-satellite styles, fetch and add layers\n // Check customBasemaps for a vector override first\n const customDef = customBasemaps?.[baseMapStyle];\n const styleUrl = (customDef?.type === 'vector' && typeof customDef.style === 'string') ? customDef.style : EXTERNAL_STYLE_URLS[baseMapStyle];\n if (styleUrl) {\n const prefix = BASEMAP_LAYER_PREFIXES[baseMapStyle] || `${baseMapStyle}-`;\n fetch(styleUrl)\n .then(res => res.json())\n .then((externalStyle: maplibregl.StyleSpecification) => {\n const addedLayerIds: string[] = [];\n\n // Resolve glyphs/sprite URLs from the external style so\n // the map can load fonts and icons served by the tileserver\n // instead of relying on bundled assets (which aren't\n // available when this component is consumed as a library).\n const resolveUrl = (url: string) => {\n if (/^https?:\\/\\//.test(url)) return url;\n try { return new URL(url, styleUrl).href; } catch { return url; }\n };\n if (externalStyle.glyphs) {\n mapInstance.setGlyphs(resolveUrl(externalStyle.glyphs as string));\n }\n if (externalStyle.sprite) {\n const spriteUrl = typeof externalStyle.sprite === 'string'\n ? resolveUrl(externalStyle.sprite)\n : externalStyle.sprite;\n mapInstance.setSprite(spriteUrl as any);\n }\n\n // Add sources\n if (externalStyle.sources) {\n for (const [sourceId, sourceSpec] of Object.entries(externalStyle.sources)) {\n const prefixedSourceId = `${prefix}${sourceId}`;\n if (!mapInstance.getSource(prefixedSourceId)) {\n mapInstance.addSource(prefixedSourceId, sourceSpec as maplibregl.SourceSpecification);\n }\n }\n }\n \n // Add layers (visible by default for initial style)\n if (externalStyle.layers) {\n for (const layer of externalStyle.layers) {\n const prefixedLayerId = `${prefix}${layer.id}`;\n if (!mapInstance.getLayer(prefixedLayerId)) {\n const newLayer = {\n ...layer,\n id: prefixedLayerId,\n layout: {\n ...(layer.layout || {}),\n visibility: 'visible' as const,\n },\n } as maplibregl.LayerSpecification;\n \n if ('source' in newLayer && typeof newLayer.source === 'string') {\n (newLayer as any).source = `${prefix}${newLayer.source}`;\n }\n \n try {\n const beforeLayer = mapInstance.getLayer('satellite-layer') ? 'satellite-layer'\n : (mapInstance.getLayer('custom-polygon-fill') ? 'custom-polygon-fill' : undefined);\n mapInstance.addLayer(newLayer, beforeLayer);\n addedLayerIds.push(prefixedLayerId);\n } catch (e) {\n // Continue on layer failures\n }\n }\n }\n }\n \n // Track loaded basemap\n basemapLayerIds.current.set(baseMapStyle, addedLayerIds);\n loadedBasemaps.current.add(baseMapStyle);\n })\n .catch(err => {\n console.error('Failed to load initial basemap:', err);\n });\n }\n } else {\n // Satellite is already in base style, just make it visible\n mapInstance.setLayoutProperty('satellite-layer', 'visibility', 'visible');\n }\n \n // Register custom basemaps from props\n if (customBasemaps) {\n for (const [id, definition] of Object.entries(customBasemaps)) {\n customBasemapRegistry.current.set(id, definition);\n \n if (definition.type === 'raster') {\n const sourceId = `custom-basemap-${id}`;\n const layerId = `custom-basemap-layer-${id}`;\n \n if (!mapInstance.getSource(sourceId)) {\n mapInstance.addSource(sourceId, {\n type: 'raster',\n tiles: definition.tiles,\n tileSize: definition.tileSize || 256,\n minzoom: definition.minzoom || 0,\n maxzoom: definition.maxzoom || 22,\n attribution: definition.attribution || '',\n });\n \n // Check if this custom basemap is the initial style\n const isInitialStyle = baseMapStyle === id;\n \n mapInstance.addLayer({\n id: layerId,\n type: 'raster',\n source: sourceId,\n layout: { visibility: isInitialStyle ? 'visible' : 'none' },\n }, 'satellite-layer');\n \n loadedBasemaps.current.add(id);\n basemapLayerIds.current.set(id, [layerId]);\n }\n } else if (definition.type === 'vector' && definition.style) {\n // Vector basemaps are loaded via the initial basemap loading code above\n // (which checks customBasemaps for style URL overrides).\n // Just mark it as a known basemap for the switcher.\n loadedBasemaps.current.add(id);\n }\n }\n }\n });\n\n // Track processed feature IDs to prevent duplicate handling\n const processedFeatureIds = new Set<string>();\n \n mapInstance.on('draw.create', (e: { features: GeoJSON.Feature[] }) => {\n const newFeatures = e.features.filter(f => {\n const id = f.id as string;\n if (processedFeatureIds.has(id)) return false;\n processedFeatureIds.add(id);\n // Clean up old IDs after a delay to prevent memory leak\n setTimeout(() => processedFeatureIds.delete(id), 1000);\n return true;\n });\n \n if (newFeatures.length === 0) return;\n \n // Check if this was a special tool (text or arrow) and add properties\n const pendingKind = pendingFeatureKindRef.current;\n if (pendingKind) {\n newFeatures.forEach(feature => {\n const fid = feature.id as string;\n const existingFeature = drawInstance.get(fid);\n if (existingFeature) {\n let newProps: Record<string, unknown> = { \n ...existingFeature.properties,\n kind: pendingKind \n };\n \n if (pendingKind === 'text') {\n // Default text properties\n newProps = {\n ...newProps,\n label: 'New Label',\n fontSize: 14,\n fontColor: '#000000',\n fontWeight: 'normal',\n };\n // Auto-focus the label input when text feature is created\n setTimeout(() => {\n setAutoFocusLabel(true);\n // Reset after a short delay so subsequent features don't auto-focus\n setTimeout(() => setAutoFocusLabel(false), 200);\n }, 0);\n } else if (pendingKind === 'arrow') {\n // Default arrow properties\n newProps = {\n ...newProps,\n arrowSize: 72,\n stroke: '#3b82f6',\n 'stroke-width': 2,\n };\n // Track this arrow ID externally for reliable detection\n arrowFeatureIdsRef.current.add(fid);\n }\n \n // Update the feature with new properties using setFeatureProperty\n Object.entries(newProps).forEach(([key, value]) => {\n drawInstance.setFeatureProperty(fid, key, value);\n });\n }\n });\n // Clear the pending kind\n pendingFeatureKindRef.current = null;\n }\n \n // Set default entityType for Point features (except text/arrow which have their own kind)\n newFeatures.forEach(feature => {\n const fid = feature.id as string;\n const existingFeature = drawInstance.get(fid);\n if (existingFeature && existingFeature.geometry.type === 'Point') {\n // Only set default entityType if not already set and not a special kind (text/arrow)\n const kind = existingFeature.properties?.kind;\n if (!existingFeature.properties?.entityType && kind !== 'text' && kind !== 'arrow') {\n drawInstance.setFeatureProperty(fid, 'entityType', 'os_geo_thing');\n }\n }\n });\n \n // Mark newly created features as unsaved only if they were user-drawn (not API/import)\n if (!isApiAddingRef.current) {\n newFeatures.forEach(feature => {\n const fid = feature.id as string;\n // Skip marking as unsaved when external persistence handles data\n if (!externalPersistence) {\n drawInstance.setFeatureProperty(fid, '_unsaved', true);\n }\n });\n }\n \n // Use ref to get current activeEditingLayerId (not stale closure value)\n const currentActiveEditingLayerId = activeEditingLayerIdRef.current;\n \n setLayers(prev => {\n // Find a valid target layer: must be visible and not read-only\n let targetLayer = prev.find(l => l.id === currentActiveEditingLayerId && l.visible && !l.readOnly);\n \n // If no valid active editing layer, find the first visible writable layer\n if (!targetLayer) {\n targetLayer = prev.find(l => l.visible && !l.readOnly);\n }\n \n // If still no valid layer, fall back to default even if it's not ideal\n if (!targetLayer) {\n targetLayer = prev.find(l => l.id === 'default');\n }\n \n if (!targetLayer) return prev; // Safety: no layers available\n \n return prev.map(layer => {\n if (layer.id === targetLayer!.id) {\n return {\n ...layer,\n featureIds: [...layer.featureIds, ...newFeatures.map(f => f.id as string)]\n };\n }\n return layer;\n });\n });\n updateFeatureCount();\n updateTimelineStore();\n saveStateForUndo();\n syncRef.current();\n \n // Reset to simple_select mode after creating any feature (so draw tools turn off)\n // Use setTimeout to avoid triggering another draw.create event\n setTimeout(() => {\n setActiveMode('simple_select');\n if (drawInstance.getMode() !== 'simple_select') {\n drawInstance.changeMode('simple_select');\n }\n }, 0);\n \n newFeatures.forEach(feature => {\n onFeatureCreate?.(feature);\n });\n });\n\n // Sync custom layers during drag for real-time visual feedback\n mapInstance.on('draw.render', () => {\n syncRef.current();\n });\n\n mapInstance.on('draw.update', (e: { features: GeoJSON.Feature[]; action?: string }) => {\n const activeLayerId = activeEditingLayerIdRef.current;\n const currentLayers = layersRef.current;\n const editMode = isEditModeRef.current;\n \n // Build feature-to-layer lookup\n const featureToLayerId = new Map<string, string>();\n currentLayers.forEach(layer => {\n layer.featureIds.forEach(fid => featureToLayerId.set(fid, layer.id));\n });\n \n // Check each updated feature - revert if not editable\n let hasRevertedFeatures = false;\n e.features.forEach(feature => {\n const fid = feature.id as string;\n const owningLayerId = featureToLayerId.get(fid);\n const owningLayer = currentLayers.find(l => l.id === owningLayerId);\n \n // Feature is NOT editable if:\n // 1. Edit mode is off, OR\n // 2. It belongs to a different layer than activeEditingLayerId, OR\n // 3. Its layer is read-only\n const isEditable = editMode && owningLayerId === activeLayerId && !owningLayer?.readOnly;\n \n if (!isEditable) {\n // Revert to original geometry\n const originalGeometry = originalGeometriesRef.current.get(fid);\n if (originalGeometry && drawInstance) {\n // Restore original geometry by updating the feature in draw\n const currentFeature = drawInstance.get(fid);\n if (currentFeature) {\n drawInstance.add({\n ...currentFeature,\n geometry: originalGeometry\n });\n hasRevertedFeatures = true;\n }\n }\n } else {\n // Feature was validly edited - update stored geometry\n originalGeometriesRef.current.set(fid, JSON.parse(JSON.stringify(feature.geometry)));\n // Mark feature as unsaved since geometry was modified via UI (skip when external persistence)\n if (!externalPersistence) {\n drawInstance.setFeatureProperty(fid, '_unsaved', true);\n }\n onFeatureUpdate?.(feature);\n // Trigger re-render to update properties panel with new coordinates\n setFeatureUpdateCounter(c => c + 1);\n }\n });\n \n // Sync custom layers on every update for visual feedback\n syncRef.current();\n \n // Only save undo state and update timeline when action is complete (not during vertex moves)\n // And only if we didn't revert all changes\n if (e.action === 'change_coordinates' && !hasRevertedFeatures) {\n updateTimelineStore();\n saveStateForUndo();\n }\n });\n\n mapInstance.on('draw.delete', (e: { features: GeoJSON.Feature[] }) => {\n const deletedIds = e.features.map(f => f.id as string);\n // Clean up arrow tracking\n deletedIds.forEach(id => arrowFeatureIdsRef.current.delete(id));\n \n setLayers(prev => prev.map(layer => ({\n ...layer,\n featureIds: layer.featureIds.filter(id => !deletedIds.includes(id))\n })));\n updateFeatureCount();\n updateTimelineStore();\n saveStateForUndo();\n syncRef.current();\n \n onFeatureDelete?.(deletedIds);\n });\n\n mapInstance.on('draw.selectionchange', (e: { features: GeoJSON.Feature[] }) => {\n // Skip if we're in the middle of selecting a read-only feature\n // (the clear operation triggers this event but we've already set our selection)\n if (isSelectingReadOnlyRef.current) {\n return;\n }\n \n const ids = e.features.map(f => f.id as string);\n \n // Capture original geometries for selected features (for edit protection)\n e.features.forEach(feature => {\n const fid = feature.id as string;\n if (!originalGeometriesRef.current.has(fid)) {\n originalGeometriesRef.current.set(fid, JSON.parse(JSON.stringify(feature.geometry)));\n }\n });\n \n // Clean up geometries for deselected features\n const currentIds = new Set(ids);\n originalGeometriesRef.current.forEach((_, key) => {\n if (!currentIds.has(key)) {\n originalGeometriesRef.current.delete(key);\n }\n });\n \n setSelectedFeatureIds(ids);\n setShowProperties(ids.length > 0);\n syncRef.current();\n \n onFeatureSelect?.(e.features);\n });\n \n // Also sync on mode change to ensure consistency\n mapInstance.on('draw.modechange', () => {\n syncRef.current();\n });\n \n // Click handler for selecting read-only features (not in MapboxDraw)\n // Supports toggle (click selected → deselect) and Ctrl/Cmd multi-select\n mapInstance.on('click', (e) => {\n if (e.originalEvent.button !== 0) return;\n if (contextMenuFiredRef.current) return;\n \n const isModifierKey = e.originalEvent.ctrlKey || e.originalEvent.metaKey;\n \n const features = mapInstance.queryRenderedFeatures(e.point, {\n layers: ['custom-polygon-fill', 'custom-line', 'custom-point']\n });\n \n if (features.length === 0) return;\n \n const hitFeature = features[0];\n const featureId = hitFeature.properties?.id;\n if (!featureId) return;\n \n let isReadOnly = false;\n readOnlyFeatures.current.forEach((layerFeatures) => {\n if (layerFeatures.some(f => String(f.id) === String(featureId))) {\n isReadOnly = true;\n }\n });\n \n if (!isReadOnly) {\n const currentMode = drawInstance.getMode();\n if (currentMode !== 'simple_select') return;\n return;\n }\n \n const fid = String(featureId);\n const currentSelection = selectedFeatureIdsRef.current;\n const isAlreadySelected = currentSelection.includes(fid);\n \n let nextIds: string[];\n if (isModifierKey) {\n nextIds = isAlreadySelected\n ? currentSelection.filter(id => id !== fid)\n : [...currentSelection, fid];\n } else {\n nextIds = isAlreadySelected\n ? currentSelection.filter(id => id !== fid)\n : [fid];\n }\n \n isSelectingReadOnlyRef.current = true;\n \n if (drawInstance.getSelected().features.length > 0) {\n drawInstance.changeMode('simple_select', { featureIds: [] });\n }\n \n setSelectedFeatureIds(nextIds);\n selectedFeatureIdsRef.current = nextIds;\n if (enableProperties) setShowProperties(nextIds.length > 0);\n syncRef.current();\n \n const selectedFeatures: GeoJSON.Feature[] = [];\n for (const id of nextIds) {\n readOnlyFeatures.current.forEach((layerFeatures) => {\n const found = layerFeatures.find(f => String(f.id) === id);\n if (found) selectedFeatures.push(found);\n });\n }\n onFeatureSelect?.(selectedFeatures);\n \n setTimeout(() => {\n isSelectingReadOnlyRef.current = false;\n }, 0);\n });\n\n mapInstance.on('error', (e) => {\n console.error('Map error:', e);\n });\n\n } catch (error) {\n console.error('Failed to initialize map:', error);\n setMapError(error instanceof Error ? error.message : 'Failed to initialize map');\n }\n\n return () => {\n if (map.current) {\n map.current.remove();\n map.current = null;\n draw.current = null;\n }\n };\n }, []);\n\n // Handle container resize - tell MapLibre to resize when container size changes\n useEffect(() => {\n if (!mapContainer.current || !map.current || !isMapLoaded) return;\n \n const container = mapContainer.current;\n const mapInstance = map.current;\n \n const resizeObserver = new ResizeObserver(() => {\n // Use requestAnimationFrame to batch resize calls and avoid WebGL errors\n requestAnimationFrame(() => {\n try {\n if (mapInstance && !mapInstance._removed) {\n mapInstance.resize();\n }\n } catch {\n // Ignore resize errors - map may be in transition\n }\n });\n });\n \n resizeObserver.observe(container);\n \n return () => {\n resizeObserver.disconnect();\n };\n }, [isMapLoaded]);\n\n // Project filter geometry coordinates onto the SVG overlay.\n // Uses state for initial render so React creates the element, then\n // imperative setAttribute on 'move' to avoid re-rendering 7k+ lines per frame.\n const [filterSvgPoints, setFilterSvgPoints] = useState<string>('');\n useEffect(() => {\n const mapInstance = map.current;\n if (!mapInstance || !isMapLoaded) return;\n if (!filterGeometry) {\n setFilterSvgPoints('');\n return;\n }\n\n const computePoints = (): string => {\n if (!map.current) return '';\n let coords: [number, number][] = [];\n if (filterGeometry.type === 'Polygon') {\n coords = filterGeometry.coordinates[0] as [number, number][];\n }\n if (coords.length === 0) return '';\n return coords.map(([lng, lat]) => {\n const pt = map.current!.project([lng, lat]);\n return `${pt.x},${pt.y}`;\n }).join(' ');\n };\n\n setFilterSvgPoints(computePoints());\n\n const onMove = () => {\n const pts = computePoints();\n if (pts) filterPolygonRef.current?.setAttribute('points', pts);\n };\n mapInstance.on('move', onMove);\n return () => { mapInstance.off('move', onMove); };\n }, [isMapLoaded, filterGeometry]);\n\n useEffect(() => {\n onLayerChange?.(layers);\n }, [layers, onLayerChange]);\n\n // Notify when active editing layer changes\n useEffect(() => {\n // Check if the current active layer can receive new features\n const layer = layers.find(l => l.id === activeEditingLayerId);\n const canAdd = !!layer && !layer.readOnly && layer.visible;\n onActiveEditingLayerChange?.(activeEditingLayerId || null, canAdd);\n }, [activeEditingLayerId, layers, onActiveEditingLayerChange]);\n\n useImperativeHandle(ref, () => ({\n flyTo: (coords: [number, number], zoom?: number) => {\n // Use ref for synchronous check (state may not have updated yet when called from onMapReady)\n if (!map.current || !isMapLoadedRef.current) return;\n map.current.flyTo({ center: coords, zoom: zoom ?? map.current.getZoom(), duration: 2000 });\n },\n \n fitToData: (layerIds?: string[]) => {\n if (!map.current || !isMapLoadedRef.current) return;\n \n const drawFeatures = draw.current ? draw.current.getAll().features : [];\n const readOnlyFeaturesList: GeoJSON.Feature[] = [];\n readOnlyFeatures.current.forEach((features) => {\n readOnlyFeaturesList.push(...features);\n });\n const allFeatures = [...drawFeatures, ...readOnlyFeaturesList];\n \n const currentLayers = layersRef.current;\n const targetLayerIds = layerIds ?? currentLayers.map(l => l.id);\n const targetFeatureIds = currentLayers\n .filter(l => targetLayerIds.includes(l.id))\n .flatMap(l => l.featureIds);\n \n const targetFeatures = allFeatures.filter(f => targetFeatureIds.includes(f.id as string));\n \n if (targetFeatures.length === 0) return;\n \n const fc = turf.featureCollection(targetFeatures);\n const bbox = turf.bbox(fc);\n map.current.fitBounds([[bbox[0], bbox[1]], [bbox[2], bbox[3]]], { padding: 50 });\n },\n \n centerOnFeature: (featureId: string) => {\n if (!map.current || !isMapLoaded) return;\n \n // First try MapboxDraw\n let feature = draw.current?.get(featureId);\n \n // If not found, check read-only features\n if (!feature) {\n readOnlyFeatures.current.forEach((features) => {\n const found = features.find(f => String(f.id) === featureId);\n if (found) feature = found as any;\n });\n }\n \n if (!feature) return;\n \n const center = turf.center(feature as turf.AllGeoJSON);\n map.current.flyTo({ center: center.geometry.coordinates as [number, number] });\n },\n \n listLayers: () => [...layersRef.current],\n \n addLayer: (name: string, geojson?: GeoJSON.FeatureCollection, options?: { readOnly?: boolean; skipFit?: boolean; fitPadding?: number }) => {\n if (!isMapLoadedRef.current) return '';\n \n // Evict any existing layers with the same name to prevent duplicates\n const dupes = layersRef.current.filter(l => l.name === name);\n for (const dupe of dupes) {\n if (draw.current && !dupe.readOnly) {\n dupe.featureIds.forEach(id => { try { draw.current!.delete(id); } catch {} });\n }\n readOnlyFeatures.current.delete(dupe.id);\n hiddenFeatures.current.delete(dupe.id);\n }\n if (dupes.length > 0) {\n const dupeIds = new Set(dupes.map(d => d.id));\n layersRef.current = layersRef.current.filter(l => !dupeIds.has(l.id));\n }\n \n const layerId = `layer-${Date.now()}`;\n const newLayer: Layer = {\n id: layerId,\n name,\n visible: true,\n featureIds: [],\n readOnly: options?.readOnly,\n };\n \n if (geojson) {\n if (options?.readOnly) {\n const featuresWithIds = geojson.features.map(f => {\n const id = f.id ? String(f.id) : crypto.randomUUID();\n return { ...f, id };\n });\n readOnlyFeatures.current.set(layerId, featuresWithIds);\n newLayer.featureIds = featuresWithIds.map(f => String(f.id));\n } else if (draw.current) {\n isApiAddingRef.current = true;\n try {\n const addedIds = geojson.features.map(f => {\n const ids = draw.current!.add(f);\n return ids[0];\n });\n newLayer.featureIds = addedIds;\n } finally {\n isApiAddingRef.current = false;\n }\n }\n }\n \n const updatedLayers = [...layersRef.current, newLayer];\n layersRef.current = updatedLayers;\n setLayers(updatedLayers);\n updateFeatureCount();\n updateTimelineStore();\n syncFeaturesToCustomLayers();\n \n // Fly to features if any (unless caller opted out)\n if (!options?.skipFit && geojson && geojson.features.length > 0 && map.current) {\n try {\n const bbox = turf.bbox(geojson);\n if (bbox.every(v => isFinite(v))) {\n map.current.fitBounds(\n [[bbox[0], bbox[1]], [bbox[2], bbox[3]]],\n { padding: options?.fitPadding ?? 50, maxZoom: 16, duration: 1000 }\n );\n }\n } catch {}\n }\n \n return newLayer.id;\n },\n \n removeLayer: (layerId: string) => {\n const layer = layersRef.current.find(l => l.id === layerId);\n if (!layer || !isMapLoadedRef.current) return false;\n \n if (draw.current && !layer.readOnly) {\n layer.featureIds.forEach(id => {\n try { draw.current!.delete(id); } catch {}\n });\n }\n \n readOnlyFeatures.current.delete(layerId);\n hiddenFeatures.current.delete(layerId);\n \n const updatedLayers = layersRef.current.filter(l => l.id !== layerId);\n layersRef.current = updatedLayers;\n setLayers(updatedLayers);\n updateFeatureCount();\n updateTimelineStore();\n requestAnimationFrame(() => {\n syncRef.current();\n });\n \n return true;\n },\n \n setLayerVisibility: (layerId: string, visible: boolean) => {\n const layer = layersRef.current.find(l => l.id === layerId);\n if (!layer || !isMapLoadedRef.current) return;\n \n if (layer.readOnly) {\n const nextLayers = layersRef.current.map(l => \n l.id === layerId ? { ...l, visible } : l\n );\n layersRef.current = nextLayers;\n setLayers(nextLayers);\n updateFeatureCount();\n updateTimelineStore();\n requestAnimationFrame(() => {\n syncRef.current();\n });\n return;\n }\n \n if (!draw.current) return;\n \n let nextLayers: Layer[];\n if (visible) {\n const hidden = hiddenFeatures.current.get(layerId) || [];\n const newIds: string[] = [];\n isApiAddingRef.current = true;\n try {\n hidden.forEach(f => {\n const ids = draw.current!.add(f);\n newIds.push(ids[0]);\n });\n } finally {\n isApiAddingRef.current = false;\n }\n hiddenFeatures.current.delete(layerId);\n \n nextLayers = layersRef.current.map(l => \n l.id === layerId ? { ...l, visible: true, featureIds: newIds } : l\n );\n } else {\n const features = layer.featureIds.map(id => draw.current!.get(id)).filter(Boolean) as GeoJSON.Feature[];\n hiddenFeatures.current.set(layerId, features);\n layer.featureIds.forEach(id => {\n try { draw.current!.delete(id); } catch {}\n });\n \n nextLayers = layersRef.current.map(l => \n l.id === layerId ? { ...l, visible: false, featureIds: [] } : l\n );\n }\n \n layersRef.current = nextLayers;\n setLayers(nextLayers);\n updateFeatureCount();\n updateTimelineStore();\n // Use syncRef to get latest sync function with updated layers\n requestAnimationFrame(() => {\n syncRef.current();\n });\n },\n \n addFeatures: (layerId: string, features: GeoJSON.Feature[]) => {\n // Use layersRef for synchronous access (state may not have updated yet when called from onMapReady)\n const layer = layersRef.current.find(l => l.id === layerId);\n if (!layer || !draw.current || !isMapLoadedRef.current) return [];\n \n const addedIds: string[] = [];\n \n // Mark as API adding so draw.create doesn't set _unsaved flag\n isApiAddingRef.current = true;\n try {\n features.forEach(f => {\n const { startDate, endDate } = normalizeTemporalProperties(f.properties || {});\n const normalizedFeature = {\n ...f,\n properties: {\n ...f.properties,\n startDate: startDate?.toISOString() || null,\n endDate: endDate?.toISOString() || null,\n }\n };\n const ids = draw.current!.add(normalizedFeature);\n addedIds.push(ids[0]);\n });\n } finally {\n isApiAddingRef.current = false;\n }\n \n setLayers(prev => prev.map(l => \n l.id === layerId ? { ...l, featureIds: [...l.featureIds, ...addedIds] } : l\n ));\n \n updateFeatureCount();\n updateTimelineStore();\n syncFeaturesToCustomLayers();\n \n return addedIds;\n },\n \n removeFeatures: (featureIds: string[]) => {\n if (!draw.current || !isMapLoaded) return;\n \n featureIds.forEach(id => {\n try { draw.current!.delete(id); } catch {}\n });\n \n setLayers(prev => prev.map(l => ({\n ...l,\n featureIds: l.featureIds.filter(id => !featureIds.includes(id))\n })));\n \n updateFeatureCount();\n updateTimelineStore();\n onFeatureDelete?.(featureIds);\n },\n \n selectFeatures: (featureIds: string[]) => {\n applySelectionState(featureIds, { focusProperties: true });\n },\n \n getSelectedFeatures,\n \n setEditMode: (enabled: boolean) => {\n // Always update the ref immediately so draw.update handler respects edit mode\n setIsEditMode(enabled);\n isEditModeRef.current = enabled;\n \n // Only change draw mode when DISABLING edit mode (to prevent accidental edits)\n // When enabling, keep the current mode (could be draw_point, draw_polygon, etc.)\n if (!enabled && draw.current) {\n draw.current.changeMode('view_select' as string);\n setActiveMode('view_select');\n }\n },\n \n isEditModeEnabled: () => isEditMode,\n \n setTimelineEnabled: (enabled: boolean) => {\n timelineStore.setEnabled(enabled);\n },\n \n setTimelineRange: (start: Date, end: Date) => {\n timelineStore.setRange(start, end);\n onTimelineChange?.(start, end);\n },\n \n exportGeoJSON: (layerIds?: string[]) => {\n const targetLayerIds = layerIds ?? layers.map(l => l.id);\n const allFeatures: GeoJSON.Feature[] = [];\n \n layers.filter(l => targetLayerIds.includes(l.id)).forEach(layer => {\n // Check if this is a read-only layer\n const readOnly = readOnlyFeatures.current.get(layer.id);\n if (readOnly) {\n allFeatures.push(...readOnly);\n } else if (layer.visible) {\n layer.featureIds.forEach(id => {\n const f = draw.current?.get(id);\n if (f) allFeatures.push(f as GeoJSON.Feature);\n });\n } else {\n const hidden = hiddenFeatures.current.get(layer.id) || [];\n allFeatures.push(...hidden);\n }\n });\n \n // Strip internal properties (prefixed with _) from exported features\n const cleanedFeatures = allFeatures.map(f => ({\n ...f,\n properties: Object.fromEntries(\n Object.entries(f.properties || {}).filter(([key]) => !key.startsWith('_'))\n ),\n }));\n \n return { type: 'FeatureCollection' as const, features: cleanedFeatures };\n },\n \n importGeoJSON: (layerId: string, geojson: GeoJSON.FeatureCollection) => {\n const layer = layers.find(l => l.id === layerId);\n if (!layer || !draw.current || !isMapLoaded) return [];\n \n const addedIds: string[] = [];\n \n // Mark as API adding so draw.create doesn't set _unsaved flag\n isApiAddingRef.current = true;\n try {\n geojson.features.forEach(f => {\n const { startDate, endDate } = normalizeTemporalProperties(f.properties || {});\n const normalizedFeature = {\n ...f,\n properties: {\n ...f.properties,\n startDate: startDate?.toISOString() || null,\n endDate: endDate?.toISOString() || null,\n }\n };\n const ids = draw.current!.add(normalizedFeature);\n addedIds.push(ids[0]);\n });\n } finally {\n isApiAddingRef.current = false;\n }\n \n setLayers(prev => prev.map(l => \n l.id === layerId ? { ...l, featureIds: [...l.featureIds, ...addedIds] } : l\n ));\n \n updateFeatureCount();\n updateTimelineStore();\n syncFeaturesToCustomLayers();\n \n return addedIds;\n },\n \n getActiveEditableLayerId: () => {\n // Return the active editing layer ID if it's not read-only, otherwise null\n if (!activeEditingLayerId) return null;\n const layer = layers.find(l => l.id === activeEditingLayerId);\n if (!layer || layer.readOnly) return null;\n return activeEditingLayerId;\n },\n \n canAddFeatures: () => {\n // Can add features if there's an active editable layer that is not read-only\n if (!activeEditingLayerId) return false;\n const layer = layers.find(l => l.id === activeEditingLayerId);\n return !!layer && !layer.readOnly && layer.visible;\n },\n \n // Basemap management methods\n \n registerBasemap: (id: string, definition: import('@/lib/map-editor-api').BasemapDefinition) => {\n if (!map.current) return;\n \n // Store in registry\n customBasemapRegistry.current.set(id, definition);\n \n // If raster, add the source and layer immediately (hidden)\n if (definition.type === 'raster') {\n const sourceId = `custom-basemap-${id}`;\n const layerId = `custom-basemap-layer-${id}`;\n \n if (!map.current.getSource(sourceId)) {\n map.current.addSource(sourceId, {\n type: 'raster',\n tiles: definition.tiles,\n tileSize: definition.tileSize || 256,\n minzoom: definition.minzoom || 0,\n maxzoom: definition.maxzoom || 22,\n attribution: definition.attribution || '',\n });\n \n // Add layer at the bottom (after background)\n map.current.addLayer({\n id: layerId,\n type: 'raster',\n source: sourceId,\n layout: { visibility: 'none' },\n }, 'satellite-layer'); // Insert before satellite layer\n \n loadedBasemaps.current.add(id);\n basemapLayerIds.current.set(id, [layerId]);\n }\n }\n // Vector basemaps will be loaded on-demand when selected\n },\n \n unregisterBasemap: (id: string) => {\n if (!map.current) return false;\n \n // Can't unregister built-in basemaps\n const builtIn = ['streets', 'satellite', 'dark'];\n if (builtIn.includes(id)) return false;\n \n // Remove from registry\n customBasemapRegistry.current.delete(id);\n \n // Remove layers and source\n const layerIds = basemapLayerIds.current.get(id) || [];\n for (const layerId of layerIds) {\n if (map.current.getLayer(layerId)) {\n map.current.removeLayer(layerId);\n }\n }\n \n const sourceId = `custom-basemap-${id}`;\n if (map.current.getSource(sourceId)) {\n map.current.removeSource(sourceId);\n }\n \n loadedBasemaps.current.delete(id);\n basemapLayerIds.current.delete(id);\n \n return true;\n },\n \n setBasemap: (id: string) => {\n handleMapStyleChangeRef.current?.(id as MapStyle);\n },\n \n getBasemap: () => {\n return currentMapStyle;\n },\n \n listBasemaps: () => {\n const builtIn = ['streets', 'satellite', 'dark'];\n const custom = Array.from(customBasemapRegistry.current.keys());\n return [...builtIn, ...custom];\n },\n \n setDrawingMode: (mode: 'simple_select' | 'draw_point' | 'draw_line_string' | 'draw_polygon') => {\n // Use ref for synchronous check (state may not have updated yet when called from onMapReady)\n if (!draw.current || !isMapLoadedRef.current) return;\n setActiveMode(mode as DrawingMode);\n draw.current.changeMode(mode as string);\n },\n \n getDrawingMode: () => {\n return activeMode;\n },\n \n updateReadOnlyLayer: (layerId: string, features: GeoJSON.Feature[]) => {\n const layer = layersRef.current.find(l => l.id === layerId);\n if (!layer || !layer.readOnly || !isMapLoadedRef.current) return false;\n \n const featuresWithIds = features.map(f => {\n const id = f.id ? String(f.id) : crypto.randomUUID();\n return { ...f, id };\n });\n readOnlyFeatures.current.set(layerId, featuresWithIds);\n \n const newFeatureIds = featuresWithIds.map(f => String(f.id));\n const updatedLayers = layersRef.current.map(l => \n l.id === layerId ? { ...l, featureIds: newFeatureIds } : l\n );\n layersRef.current = updatedLayers;\n setLayers(updatedLayers);\n updateFeatureCount();\n \n requestAnimationFrame(() => {\n syncRef.current();\n });\n \n return true;\n },\n \n setLayerData: (name: string, geojson: GeoJSON.FeatureCollection, options?: { fitPadding?: number }) => {\n if (!isMapLoadedRef.current) return '';\n\n const featuresWithIds = geojson.features.map(f => {\n const id = f.id ? String(f.id) : crypto.randomUUID();\n return { ...f, id };\n });\n const newFeatureIds = featuresWithIds.map(f => String(f.id));\n\n const layerId = `managed-${name}`;\n readOnlyFeatures.current.set(layerId, featuresWithIds);\n\n const newLayerObj: Layer = {\n id: layerId,\n name,\n visible: true,\n featureIds: newFeatureIds,\n readOnly: true,\n };\n\n // Eagerly update layersRef so sync functions see correct data\n const eagerCleaned = layersRef.current.filter(l => !(l.name === name && l.id !== layerId));\n const eagerIdx = eagerCleaned.findIndex(l => l.id === layerId);\n layersRef.current = eagerIdx >= 0\n ? eagerCleaned.map(l => l.id === layerId ? newLayerObj : l)\n : [...eagerCleaned, newLayerObj];\n\n // Functional update guarantees we operate on latest React state\n setLayers(prev => {\n const cleaned = prev.filter(l => {\n if (l.name === name && l.id !== layerId) {\n readOnlyFeatures.current.delete(l.id);\n hiddenFeatures.current.delete(l.id);\n if (draw.current && !l.readOnly) {\n l.featureIds.forEach(fid => { try { draw.current!.delete(fid); } catch {} });\n }\n return false;\n }\n return true;\n });\n const idx = cleaned.findIndex(l => l.id === layerId);\n const result = idx >= 0\n ? cleaned.map(l => l.id === layerId ? newLayerObj : l)\n : [...cleaned, newLayerObj];\n layersRef.current = result;\n return result;\n });\n\n updateFeatureCount();\n requestAnimationFrame(() => { syncRef.current(); });\n\n if (options?.fitPadding != null && geojson.features.length > 0 && map.current) {\n try {\n const bbox = turf.bbox(geojson);\n if (bbox.every(v => isFinite(v))) {\n map.current.fitBounds(\n [[bbox[0], bbox[1]], [bbox[2], bbox[3]]],\n { padding: options.fitPadding, maxZoom: 16, duration: 1000 }\n );\n }\n } catch {}\n }\n\n return layerId;\n },\n\n clearSelection: () => {\n setPersistedSelectionPolygon(null);\n setSelectionPoints([]);\n // Clear selected features\n setSelectedFeatureIds([]);\n applySelectionState([], { focusProperties: true });\n },\n \n // Viewport and state getters\n \n getViewport: (): import('@/lib/map-editor-api').ViewportInfo | null => {\n if (!map.current || !isMapLoaded) {\n return null;\n }\n \n const mapInstance = map.current;\n const center = mapInstance.getCenter();\n const zoom = mapInstance.getZoom();\n const bounds = mapInstance.getBounds();\n const rawBounds: [number, number, number, number] = [\n bounds.getWest(),\n bounds.getSouth(),\n bounds.getEast(),\n bounds.getNorth()\n ];\n \n return {\n center: [center.lng, center.lat],\n zoom,\n bounds: rawBounds,\n queryBounds: {\n minLng: Math.max(-180, Math.min(180, rawBounds[0])),\n maxLng: Math.max(-180, Math.min(180, rawBounds[2])),\n minLat: Math.max(-90, Math.min(90, rawBounds[1])),\n maxLat: Math.max(-90, Math.min(90, rawBounds[3])),\n },\n };\n },\n \n getLayerData: (layerId: string): GeoJSON.Feature[] => {\n const layer = layersRef.current.find(l => l.id === layerId);\n if (!layer) return [];\n \n const features: GeoJSON.Feature[] = [];\n \n // Check if this is a read-only layer\n const readOnly = readOnlyFeatures.current.get(layerId);\n if (readOnly) {\n // Clone read-only features to prevent mutation\n return readOnly.map(f => JSON.parse(JSON.stringify(f)));\n }\n \n // Editable layer - get from MapboxDraw or hidden storage\n if (layer.visible) {\n layer.featureIds.forEach(id => {\n const f = draw.current?.get(id);\n if (f) {\n // Clone and ensure consistent structure (same as exportGeoJSON)\n features.push(JSON.parse(JSON.stringify(f)));\n }\n });\n } else {\n const hidden = hiddenFeatures.current.get(layerId) || [];\n return hidden.map(f => JSON.parse(JSON.stringify(f)));\n }\n \n return features;\n },\n \n getTimelineRange: () => {\n return {\n start: timelineStore.rangeStart,\n end: timelineStore.rangeEnd,\n };\n },\n \n getMapUnsavedCount: () => {\n if (!draw.current) return 0;\n const allFeatures = draw.current.getAll().features;\n return allFeatures.filter(f => f.properties?._unsaved === true).length;\n },\n }), [layers, isEditMode, isMapLoaded, getSelectedFeatures, updateFeatureCount, updateTimelineStore, syncFeaturesToCustomLayers, timelineStore, onFeatureDelete, onTimelineChange, activeEditingLayerId, currentMapStyle, activeMode]);\n\n const handleModeChange = useCallback((mode: DrawingMode) => {\n if (!draw.current || !isMapLoaded) return;\n \n if (!hasVisibleLayers && mode !== 'simple_select' && mode !== 'view_select') {\n toast({\n title: \"No visible layers\",\n description: \"Show at least one layer to draw features\",\n variant: \"destructive\",\n });\n return;\n }\n \n // Handle special modes that map to underlying MapboxDraw modes\n if (mode === 'draw_text') {\n pendingFeatureKindRef.current = 'text';\n setActiveMode(mode);\n draw.current.changeMode('draw_point');\n return;\n } else if (mode === 'draw_arrow') {\n pendingFeatureKindRef.current = 'arrow';\n setActiveMode(mode);\n draw.current.changeMode('draw_line_string');\n return;\n } else if (mode === 'draw_circle') {\n // Circle uses custom handling (click center, drag radius)\n pendingFeatureKindRef.current = 'circle';\n setActiveMode(mode);\n // Put MapboxDraw in simple_select so it doesn't interfere\n draw.current.changeMode('simple_select');\n return;\n } else if (mode === 'draw_rectangle') {\n // Rectangle uses custom handling (click corner, drag to opposite corner)\n pendingFeatureKindRef.current = 'rectangle';\n setActiveMode(mode);\n // Put MapboxDraw in simple_select so it doesn't interfere\n draw.current.changeMode('simple_select');\n return;\n }\n \n // Clear pending kind for normal modes\n pendingFeatureKindRef.current = null;\n setActiveMode(mode);\n draw.current.changeMode(mode as string);\n }, [isMapLoaded, hasVisibleLayers, toast]);\n\n const handleUndo = useCallback(() => {\n if (undoStack.length === 0 || !draw.current) return;\n \n const currentState: UndoState = {\n features: draw.current.getAll().features as GeoJSON.Feature[],\n layers: JSON.parse(JSON.stringify(layers)),\n selectedIds: [...selectedFeatureIds],\n };\n \n const prevState = undoStack[undoStack.length - 1];\n \n // Set guard to prevent selectionchange from overwriting restored selection\n isSelectingReadOnlyRef.current = true;\n \n draw.current.deleteAll();\n // Mark as API adding so draw.create doesn't set _unsaved flag\n isApiAddingRef.current = true;\n try {\n prevState.features.forEach(f => draw.current!.add(f));\n } finally {\n isApiAddingRef.current = false;\n }\n setLayers(prevState.layers);\n \n // Use applySelectionState to properly handle restored selection\n applySelectionState(prevState.selectedIds, { focusProperties: false });\n \n setUndoStack(prev => prev.slice(0, -1));\n setRedoStack(prev => [...prev, currentState]);\n updateFeatureCount();\n updateTimelineStore();\n syncFeaturesToCustomLayers();\n }, [undoStack, layers, selectedFeatureIds, updateFeatureCount, updateTimelineStore, syncFeaturesToCustomLayers, applySelectionState]);\n\n const handleRedo = useCallback(() => {\n if (redoStack.length === 0 || !draw.current) return;\n \n const currentState: UndoState = {\n features: draw.current.getAll().features as GeoJSON.Feature[],\n layers: JSON.parse(JSON.stringify(layers)),\n selectedIds: [...selectedFeatureIds],\n };\n \n const nextState = redoStack[redoStack.length - 1];\n \n // Set guard to prevent selectionchange from overwriting restored selection\n isSelectingReadOnlyRef.current = true;\n \n draw.current.deleteAll();\n // Mark as API adding so draw.create doesn't set _unsaved flag\n isApiAddingRef.current = true;\n try {\n nextState.features.forEach(f => draw.current!.add(f));\n } finally {\n isApiAddingRef.current = false;\n }\n setLayers(nextState.layers);\n \n // Use applySelectionState to properly handle restored selection\n applySelectionState(nextState.selectedIds, { focusProperties: false });\n \n setRedoStack(prev => prev.slice(0, -1));\n setUndoStack(prev => [...prev, currentState]);\n updateFeatureCount();\n updateTimelineStore();\n syncFeaturesToCustomLayers();\n }, [redoStack, layers, selectedFeatureIds, updateFeatureCount, updateTimelineStore, syncFeaturesToCustomLayers, applySelectionState]);\n\n const handleClear = useCallback(() => {\n if (!draw.current) return;\n \n // Get active layer - only clear editable layers\n const activeLayer = layersRef.current.find(l => l.id === activeEditingLayerId);\n if (!activeLayer) {\n toast({\n title: \"No layer selected\",\n description: \"Select an editable layer to clear features\",\n variant: \"destructive\",\n });\n return;\n }\n \n if (activeLayer.readOnly) {\n toast({\n title: \"Cannot clear read-only layer\",\n description: \"This layer is locked and cannot be modified\",\n variant: \"destructive\",\n });\n return;\n }\n \n if (activeLayer.featureIds.length === 0) {\n toast({\n title: \"Layer is empty\",\n description: \"No features to clear\",\n });\n return;\n }\n \n saveStateForUndo();\n \n // Only delete features from the active layer\n activeLayer.featureIds.forEach(id => {\n arrowFeatureIdsRef.current.delete(id);\n try { draw.current!.delete(id); } catch {}\n });\n \n // Only clear featureIds for the active layer\n setLayers(prev => prev.map(l => \n l.id === activeEditingLayerId ? { ...l, featureIds: [] } : l\n ));\n \n setSelectedFeatureIds([]);\n setShowProperties(false);\n updateFeatureCount();\n updateTimelineStore();\n syncFeaturesToCustomLayers();\n \n toast({\n title: \"Layer cleared\",\n description: `Removed all features from \"${activeLayer.name}\"`,\n });\n }, [activeEditingLayerId, saveStateForUndo, updateFeatureCount, updateTimelineStore, syncFeaturesToCustomLayers, toast]);\n\n const handleDeleteSelected = useCallback(() => {\n if (!draw.current || selectedFeatureIds.length === 0) return;\n saveStateForUndo();\n \n selectedFeatureIds.forEach(id => {\n // Clean up arrow tracking\n arrowFeatureIdsRef.current.delete(id);\n try { draw.current!.delete(id); } catch {}\n });\n \n setLayers(prev => prev.map(l => ({\n ...l,\n featureIds: l.featureIds.filter(id => !selectedFeatureIds.includes(id))\n })));\n \n onFeatureDelete?.(selectedFeatureIds);\n setSelectedFeatureIds([]);\n setShowProperties(false);\n updateFeatureCount();\n updateTimelineStore();\n syncFeaturesToCustomLayers();\n }, [selectedFeatureIds, saveStateForUndo, updateFeatureCount, updateTimelineStore, syncFeaturesToCustomLayers, onFeatureDelete]);\n\n const handleToggleEditMode = useCallback(() => {\n setIsEditMode(prev => {\n const newMode = !prev;\n if (draw.current) {\n if (newMode) {\n draw.current.changeMode('simple_select');\n setActiveMode('simple_select');\n } else {\n draw.current.changeMode('view_select');\n setActiveMode('view_select');\n }\n }\n return newMode;\n });\n }, []);\n\n const handleToggleLayers = useCallback(() => {\n setShowLayers(prev => !prev);\n }, []);\n\n // Keyboard shortcuts scoped to the map container (requires focus)\n useEffect(() => {\n if (!isMapLoaded || !enableKeyboardShortcuts || !mapContainer.current) return;\n \n const container = mapContainer.current;\n \n const handleKeyDown = (e: KeyboardEvent) => {\n const target = e.target as HTMLElement;\n if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable) {\n return;\n }\n \n const key = e.key.toLowerCase();\n const isCtrlOrCmd = e.ctrlKey || e.metaKey;\n \n if (isCtrlOrCmd && key === 'z' && !e.shiftKey) {\n e.preventDefault();\n handleUndo();\n return;\n }\n if (isCtrlOrCmd && (key === 'y' || (key === 'z' && e.shiftKey))) {\n e.preventDefault();\n handleRedo();\n return;\n }\n \n if (key === 'e' && !isCtrlOrCmd && !e.altKey) {\n e.preventDefault();\n handleToggleEditMode();\n return;\n }\n \n if (!isEditMode) return;\n if (isCtrlOrCmd) return;\n \n switch (key) {\n case 'delete':\n case 'backspace':\n if (selectedFeatureIds.length > 0) {\n e.preventDefault();\n handleDeleteSelected();\n }\n break;\n case 'p':\n e.preventDefault();\n handleModeChange(activeMode === 'draw_point' ? 'simple_select' : 'draw_point');\n break;\n case 'l':\n e.preventDefault();\n handleModeChange(activeMode === 'draw_line_string' ? 'simple_select' : 'draw_line_string');\n break;\n case 'g':\n e.preventDefault();\n handleModeChange(activeMode === 'draw_polygon' ? 'simple_select' : 'draw_polygon');\n break;\n case 'b':\n e.preventDefault();\n handleModeChange(activeMode === 'draw_rectangle' ? 'simple_select' : 'draw_rectangle');\n break;\n case 't':\n e.preventDefault();\n handleModeChange(activeMode === 'draw_text' ? 'simple_select' : 'draw_text');\n break;\n case 'w':\n e.preventDefault();\n handleModeChange(activeMode === 'draw_arrow' ? 'simple_select' : 'draw_arrow');\n break;\n case 'c':\n e.preventDefault();\n handleModeChange(activeMode === 'draw_circle' ? 'simple_select' : 'draw_circle');\n break;\n case 'escape':\n handleModeChange('simple_select');\n break;\n }\n };\n \n container.addEventListener('keydown', handleKeyDown);\n return () => container.removeEventListener('keydown', handleKeyDown);\n }, [isMapLoaded, enableKeyboardShortcuts, isEditMode, activeMode, handleToggleEditMode, handleUndo, handleRedo, handleModeChange, selectedFeatureIds, handleDeleteSelected]);\n\n // Handle right-click context menu on features\n const handleFeatureContextMenu = useCallback((e: MouseEvent) => {\n contextMenuFiredRef.current = true;\n setTimeout(() => { contextMenuFiredRef.current = false; }, 0);\n \n if (!contextMenuProvider || !map.current) return;\n \n const mapInstance = map.current;\n \n // Query features at click point (including read-only layers)\n const point: [number, number] = [e.offsetX, e.offsetY];\n const clickedFeatures = mapInstance.queryRenderedFeatures(point, {\n layers: ['custom-point', 'custom-line', 'custom-polygon-fill']\n });\n \n // Use clicked feature for context menu without changing selection state\n let features: GeoJSON.Feature[] = [];\n \n if (clickedFeatures.length > 0) {\n const clickedId = String(clickedFeatures[0].properties?.id || clickedFeatures[0].id);\n let clickedFeature: GeoJSON.Feature | null = null;\n \n readOnlyFeatures.current.forEach((layerFeatures) => {\n const found = layerFeatures.find(f => String(f.id) === clickedId);\n if (found) clickedFeature = found;\n });\n \n if (!clickedFeature && draw.current) {\n const drawFeature = draw.current.get(clickedId);\n if (drawFeature) clickedFeature = drawFeature;\n }\n \n if (clickedFeature) {\n features = [clickedFeature];\n }\n }\n \n if (features.length === 0) return;\n \n e.preventDefault();\n \n // Get click coordinates in lng/lat\n const lngLat = mapInstance.unproject([e.offsetX, e.offsetY]);\n const clickCoords: [number, number] = [lngLat.lng, lngLat.lat];\n \n // Build feature-layer mapping\n const featureLayers: Record<string, { layerId: string; layerName: string }> = {};\n features.forEach(f => {\n const fid = String(f.id);\n // Find which layer this feature belongs to\n for (const layer of layersRef.current) {\n if (layer.featureIds.includes(fid)) {\n featureLayers[fid] = { layerId: layer.id, layerName: layer.name };\n break;\n }\n }\n });\n \n // Get viewport info\n const bounds = mapInstance.getBounds();\n const rawBounds: [number, number, number, number] = [\n bounds.getWest(),\n bounds.getSouth(),\n bounds.getEast(),\n bounds.getNorth()\n ];\n const queryBounds = {\n minLng: Math.max(-180, Math.min(180, rawBounds[0])),\n maxLng: Math.max(-180, Math.min(180, rawBounds[2])),\n minLat: Math.max(-90, Math.min(90, rawBounds[1])),\n maxLat: Math.max(-90, Math.min(90, rawBounds[3])),\n };\n const viewport: import('@/lib/map-editor-api').ViewportInfo = {\n center: [mapInstance.getCenter().lng, mapInstance.getCenter().lat],\n zoom: mapInstance.getZoom(),\n bounds: rawBounds,\n queryBounds,\n };\n \n // Build context and call provider\n const context: import('@/lib/map-editor-api').ContextMenuContext = {\n selectedFeatures: features,\n featureLayers,\n clickCoords,\n viewport,\n isEditMode,\n activeLayerId: activeEditingLayerIdRef.current,\n event: e,\n };\n \n const items = contextMenuProvider(context);\n if (!items || items.length === 0) return;\n \n // Show the context menu at the click position\n setContextMenu({\n x: e.clientX,\n y: e.clientY,\n items,\n });\n }, [contextMenuProvider, getSelectedFeatures, isEditMode, applySelectionState]);\n\n // Block right-click mousedown from reaching MapLibre/MapboxDraw to prevent selection\n useEffect(() => {\n if (!isMapLoaded || !map.current) return;\n \n const canvas = map.current.getCanvas();\n \n const blockRightMouseDown = (e: MouseEvent) => {\n if (e.button === 2) {\n e.stopPropagation();\n }\n };\n \n canvas.addEventListener('mousedown', blockRightMouseDown, true);\n \n return () => {\n canvas.removeEventListener('mousedown', blockRightMouseDown, true);\n };\n }, [isMapLoaded]);\n\n // Add right-click listener to map canvas\n useEffect(() => {\n if (!isMapLoaded || !map.current || !contextMenuProvider) return;\n \n const canvas = map.current.getCanvas();\n \n const handleContextMenu = (e: MouseEvent) => {\n handleFeatureContextMenu(e);\n };\n \n canvas.addEventListener('contextmenu', handleContextMenu);\n \n return () => {\n canvas.removeEventListener('contextmenu', handleContextMenu);\n };\n }, [isMapLoaded, contextMenuProvider, handleFeatureContextMenu]);\n\n // Close context menu when clicking elsewhere\n useEffect(() => {\n if (!contextMenu) return;\n \n const handleClick = () => {\n setContextMenu(null);\n };\n \n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n setContextMenu(null);\n }\n };\n \n // Delay adding listener so current click doesn't immediately close it\n const timeoutId = setTimeout(() => {\n window.addEventListener('click', handleClick);\n window.addEventListener('keydown', handleKeyDown);\n }, 0);\n \n return () => {\n clearTimeout(timeoutId);\n window.removeEventListener('click', handleClick);\n window.removeEventListener('keydown', handleKeyDown);\n };\n }, [contextMenu]);\n\n const handleCloseProperties = useCallback(() => {\n setShowProperties(false);\n if (draw.current) {\n const mode: DrawingMode = isEditMode ? 'simple_select' : 'view_select';\n draw.current.changeMode(mode as string, { featureIds: [] });\n }\n setSelectedFeatureIds([]);\n }, [isEditMode]);\n\n const handleUpdateProperties = useCallback((featureId: string, properties: Record<string, unknown>) => {\n if (!draw.current || !map.current) return;\n \n const feature = draw.current.get(featureId);\n if (!feature) return;\n \n saveStateForUndo();\n \n const { startDate, endDate } = normalizeTemporalProperties(properties);\n const normalizedProperties = {\n ...properties,\n startDate: startDate?.toISOString() || null,\n endDate: endDate?.toISOString() || null,\n };\n \n // Update properties using setFeatureProperty\n Object.entries(normalizedProperties).forEach(([key, value]) => {\n draw.current!.setFeatureProperty(featureId, key, value);\n });\n \n // Mark feature as unsaved since properties were modified via UI (skip when external persistence)\n if (!externalPersistence) {\n draw.current.setFeatureProperty(featureId, '_unsaved', true);\n }\n \n // Clear legacy 'text' property for text features to ensure 'label' is used\n if (properties.kind === 'text' || feature.properties?.kind === 'text') {\n draw.current!.setFeatureProperty(featureId, 'text', undefined);\n }\n \n // Sync to custom rendering layers\n syncFeaturesToCustomLayers();\n updateTimelineStore();\n \n const updated = draw.current.get(featureId);\n if (updated) {\n onFeatureUpdate?.(updated as GeoJSON.Feature);\n }\n }, [saveStateForUndo, updateTimelineStore, onFeatureUpdate, syncFeaturesToCustomLayers]);\n\n // Handler for updating point geometry (coordinates) from properties panel\n const handleUpdateGeometry = useCallback((featureId: string, geometry: GeoJSON.Geometry) => {\n if (!draw.current || !map.current) return;\n \n const feature = draw.current.get(featureId);\n if (!feature) return;\n \n // Only allow updating Point geometry\n if (feature.geometry.type !== 'Point' || geometry.type !== 'Point') return;\n \n saveStateForUndo();\n \n // Get all features, update the target one, and set them all back\n // This preserves layer bookkeeping and IDs\n const allFeatures = draw.current.getAll();\n const updatedFeatures = allFeatures.features.map(f => {\n if (f.id === featureId) {\n return { ...f, geometry };\n }\n return f;\n });\n \n // Set all features back - this updates in place\n draw.current.set({\n type: 'FeatureCollection',\n features: updatedFeatures,\n });\n \n // Mark feature as unsaved since geometry was modified via UI (skip when external persistence)\n if (!externalPersistence) {\n draw.current.setFeatureProperty(featureId, '_unsaved', true);\n }\n \n // Re-select the feature to maintain selection state\n draw.current.changeMode('simple_select', { featureIds: [featureId] });\n \n // Sync to custom rendering layers\n syncFeaturesToCustomLayers();\n \n const updated = draw.current.get(featureId);\n if (updated) {\n onFeatureUpdate?.(updated as GeoJSON.Feature);\n }\n }, [saveStateForUndo, onFeatureUpdate, syncFeaturesToCustomLayers]);\n\n // Handle feature saved - update feature with new ID and workspace metadata\n const handleFeatureSaved = useCallback((oldId: string, newId: string, metadata: { workspace: string; sourceName: string }) => {\n if (!draw.current) return;\n \n const feature = draw.current.get(oldId);\n if (!feature) return;\n \n // Update the feature in place with new metadata (clear _unsaved, add workspace info)\n draw.current.setFeatureProperty(oldId, '_unsaved', undefined);\n draw.current.setFeatureProperty(oldId, '_workspaceRecord', true);\n // Store workspace metadata both as internal (underscore) and visible properties\n draw.current.setFeatureProperty(oldId, '_workspace', metadata.workspace);\n draw.current.setFeatureProperty(oldId, '_sourceName', metadata.sourceName);\n // Also store as visible custom properties so they show in properties panel\n draw.current.setFeatureProperty(oldId, 'workspace', metadata.workspace);\n draw.current.setFeatureProperty(oldId, 'source_name', metadata.sourceName);\n \n // If the new ID is different from old ID, we need to replace the feature\n if (newId !== oldId) {\n const updatedFeature = draw.current.get(oldId);\n if (updatedFeature) {\n // Delete old feature\n draw.current.delete(oldId);\n \n // Add feature with new ID\n const newFeature = {\n ...updatedFeature,\n id: newId,\n };\n // Mark as API adding so draw.create doesn't set _unsaved flag\n isApiAddingRef.current = true;\n try {\n draw.current.add(newFeature);\n } finally {\n isApiAddingRef.current = false;\n }\n \n // Update layer bookkeeping\n setLayers(prev => prev.map(layer => ({\n ...layer,\n featureIds: layer.featureIds.map(fid => fid === oldId ? newId : fid),\n })));\n \n // Update selection to new ID in React state\n setSelectedFeatureIds(prev => prev.map(fid => fid === oldId ? newId : fid));\n \n // Also update MapboxDraw's internal selection to the new ID\n draw.current.changeMode('simple_select', { featureIds: [newId] });\n }\n }\n \n // Sync rendering\n syncFeaturesToCustomLayers();\n \n // Force a state update to trigger re-render with new properties\n setLayers(prev => [...prev]);\n }, [syncFeaturesToCustomLayers]);\n\n const handleAddLayer = useCallback((name: string) => {\n const newLayer: Layer = {\n id: `layer-${Date.now()}`,\n name,\n visible: true,\n featureIds: [],\n };\n setLayers(prev => [...prev, newLayer]);\n setActiveEditingLayerId(newLayer.id);\n }, []);\n\n const handleRemoveLayer = useCallback((layerId: string) => {\n if (layers.length <= 1) return;\n \n const layer = layers.find(l => l.id === layerId);\n if (!layer || !draw.current) return;\n \n saveStateForUndo();\n \n layer.featureIds.forEach(id => {\n try { draw.current!.delete(id); } catch {}\n });\n \n hiddenFeatures.current.delete(layerId);\n \n setLayers(prev => {\n const filtered = prev.filter(l => l.id !== layerId);\n if (activeEditingLayerId === layerId && filtered.length > 0) {\n setActiveEditingLayerId(filtered[0].id);\n }\n return filtered;\n });\n \n updateFeatureCount();\n updateTimelineStore();\n }, [layers, activeEditingLayerId, saveStateForUndo, updateFeatureCount, updateTimelineStore]);\n\n const handleRenameLayer = useCallback((layerId: string, newName: string) => {\n setLayers(prev => prev.map(l => \n l.id === layerId ? { ...l, name: newName } : l\n ));\n }, []);\n\n const handleToggleLayerVisibility = useCallback((layerId: string) => {\n const layer = layers.find(l => l.id === layerId);\n if (!layer) return;\n \n saveStateForUndo();\n \n let nextLayers: Layer[];\n \n // Handle read-only layers differently - no draw.current needed\n if (layer.readOnly) {\n nextLayers = layers.map(l => \n l.id === layerId ? { ...l, visible: !l.visible } : l\n );\n } else {\n if (!draw.current) return;\n \n if (layer.visible) {\n const features = layer.featureIds.map(id => draw.current!.get(id)).filter(Boolean) as GeoJSON.Feature[];\n hiddenFeatures.current.set(layerId, features);\n layer.featureIds.forEach(id => {\n try { draw.current!.delete(id); } catch {}\n });\n \n nextLayers = layers.map(l => \n l.id === layerId ? { ...l, visible: false, featureIds: [] } : l\n );\n } else {\n const features = hiddenFeatures.current.get(layerId) || [];\n const newIds: string[] = [];\n // Mark as API adding so draw.create doesn't set _unsaved flag\n isApiAddingRef.current = true;\n try {\n features.forEach(f => {\n const ids = draw.current!.add(f);\n newIds.push(ids[0]);\n });\n } finally {\n isApiAddingRef.current = false;\n }\n hiddenFeatures.current.delete(layerId);\n \n nextLayers = layers.map(l => \n l.id === layerId ? { ...l, visible: true, featureIds: newIds } : l\n );\n }\n }\n \n // Update ref BEFORE setLayers so sync functions see new data immediately\n layersRef.current = nextLayers;\n setLayers(nextLayers);\n updateFeatureCount();\n updateTimelineStore();\n \n // For read-only layers, trigger sync to update custom layers\n if (layer.readOnly) {\n requestAnimationFrame(() => {\n syncRef.current();\n });\n }\n }, [layers, saveStateForUndo, updateFeatureCount, updateTimelineStore]);\n\n const handleMoveFeatureToLayer = useCallback((featureId: string, targetLayerId: string) => {\n saveStateForUndo();\n setLayers(prev => prev.map(l => {\n if (l.featureIds.includes(featureId)) {\n return { ...l, featureIds: l.featureIds.filter(id => id !== featureId) };\n }\n if (l.id === targetLayerId) {\n return { ...l, featureIds: [...l.featureIds, featureId] };\n }\n return l;\n }));\n }, [saveStateForUndo]);\n\n const getFeatureCountForLayer = useCallback((layerId: string) => {\n const layer = layers.find(l => l.id === layerId);\n if (!layer) return 0;\n \n if (layer.visible) {\n return layer.featureIds.length;\n } else {\n return hiddenFeatures.current.get(layerId)?.length || 0;\n }\n }, [layers]);\n\n // Get count of unsaved features in a layer\n const getLayerUnsavedCount = useCallback((layerId: string) => {\n const layer = layers.find(l => l.id === layerId);\n if (!layer || !draw.current) return 0;\n \n let count = 0;\n if (layer.visible) {\n layer.featureIds.forEach(id => {\n const feature = draw.current!.get(id);\n if (feature?.properties?._unsaved) {\n count++;\n }\n });\n } else {\n const hidden = hiddenFeatures.current.get(layerId) || [];\n hidden.forEach(f => {\n if (f.properties?._unsaved) {\n count++;\n }\n });\n }\n return count;\n }, [layers]);\n\n // Get total count of unsaved features across all layers (for map-level indicator)\n const getMapUnsavedCount = useCallback(() => {\n let total = 0;\n layers.forEach(layer => {\n total += getLayerUnsavedCount(layer.id);\n });\n return total;\n }, [layers, getLayerUnsavedCount]);\n\n // Load a basemap style and add its layers to the map (prefixed to avoid conflicts)\n const loadBasemapStyle = useCallback(async (styleName: string): Promise<string[]> => {\n if (!map.current) return [];\n \n const mapInstance = map.current;\n const prefix = BASEMAP_LAYER_PREFIXES[styleName as MapStyle] || `${styleName}-`;\n const styleUrl = EXTERNAL_STYLE_URLS[styleName];\n \n if (!styleUrl) {\n console.warn(`No external style URL for: ${styleName}`);\n return [];\n }\n \n try {\n const response = await fetch(styleUrl);\n const externalStyle = await response.json() as maplibregl.StyleSpecification;\n \n const addedLayerIds: string[] = [];\n\n const resolveUrl = (url: string) => {\n if (/^https?:\\/\\//.test(url)) return url;\n try { return new URL(url, styleUrl).href; } catch { return url; }\n };\n if (externalStyle.glyphs) {\n mapInstance.setGlyphs(resolveUrl(externalStyle.glyphs as string));\n }\n if (externalStyle.sprite) {\n const spriteUrl = typeof externalStyle.sprite === 'string'\n ? resolveUrl(externalStyle.sprite)\n : externalStyle.sprite;\n mapInstance.setSprite(spriteUrl as any);\n }\n\n // Add all sources from the external style (prefixed)\n if (externalStyle.sources) {\n for (const [sourceId, sourceSpec] of Object.entries(externalStyle.sources)) {\n const prefixedSourceId = `${prefix}${sourceId}`;\n if (!mapInstance.getSource(prefixedSourceId)) {\n mapInstance.addSource(prefixedSourceId, sourceSpec as maplibregl.SourceSpecification);\n }\n }\n }\n \n // Add all layers from the external style (prefixed, hidden by default)\n // Insert BEFORE satellite-layer so they appear under it when satellite is visible\n if (externalStyle.layers) {\n for (const layer of externalStyle.layers) {\n const prefixedLayerId = `${prefix}${layer.id}`;\n \n if (!mapInstance.getLayer(prefixedLayerId)) {\n const newLayer = {\n ...layer,\n id: prefixedLayerId,\n layout: {\n ...(layer.layout || {}),\n visibility: 'none' as const, // Hidden by default\n },\n } as maplibregl.LayerSpecification;\n \n // Update source reference if it exists\n if ('source' in newLayer && typeof newLayer.source === 'string') {\n (newLayer as any).source = `${prefix}${newLayer.source}`;\n }\n \n try {\n const beforeLayer = mapInstance.getLayer('satellite-layer') ? 'satellite-layer'\n : (mapInstance.getLayer('custom-polygon-fill') ? 'custom-polygon-fill' : undefined);\n mapInstance.addLayer(newLayer, beforeLayer);\n addedLayerIds.push(prefixedLayerId);\n } catch (e) {\n console.warn(`Failed to add layer ${prefixedLayerId}:`, e);\n }\n }\n }\n }\n \n return addedLayerIds;\n } catch (e) {\n console.error(`Failed to load basemap style ${styleName}:`, e);\n return [];\n }\n }, []);\n\n // Toggle visibility of basemap layers\n const setBasemapVisibility = useCallback((styleName: string, visible: boolean) => {\n if (!map.current) return;\n \n const mapInstance = map.current;\n const layerIds = basemapLayerIds.current.get(styleName) || [];\n \n for (const layerId of layerIds) {\n if (mapInstance.getLayer(layerId)) {\n mapInstance.setLayoutProperty(layerId, 'visibility', visible ? 'visible' : 'none');\n }\n }\n }, []);\n\n const handleMapStyleChange = useCallback(async (style: MapStyle) => {\n if (!map.current) return;\n const mapInstance = map.current;\n \n // Hide all basemaps first\n basemapLayerIds.current.forEach((_, basemapName) => {\n setBasemapVisibility(basemapName, false);\n });\n \n // Check if this is a custom basemap from the registry\n const customDef = customBasemapRegistry.current.get(style);\n \n if (customDef) {\n // Handle custom basemap\n if (!loadedBasemaps.current.has(style)) {\n if (customDef.type === 'raster') {\n const sourceId = `custom-basemap-${style}`;\n const layerId = `custom-basemap-layer-${style}`;\n \n if (!mapInstance.getSource(sourceId)) {\n mapInstance.addSource(sourceId, {\n type: 'raster',\n tiles: customDef.tiles,\n tileSize: customDef.tileSize || 256,\n minzoom: customDef.minzoom || 0,\n maxzoom: customDef.maxzoom || 22,\n attribution: customDef.attribution || '',\n });\n \n mapInstance.addLayer({\n id: layerId,\n type: 'raster',\n source: sourceId,\n layout: { visibility: 'none' },\n }, 'satellite-layer');\n }\n \n loadedBasemaps.current.add(style);\n basemapLayerIds.current.set(style, [layerId]);\n }\n // TODO: Handle vector custom basemaps\n }\n } else if (!loadedBasemaps.current.has(style) && !loadingBasemaps.current.has(style)) {\n // Load built-in basemap if not already loaded\n loadingBasemaps.current.add(style);\n \n const layerIds = await loadBasemapStyle(style);\n basemapLayerIds.current.set(style, layerIds);\n loadedBasemaps.current.add(style);\n loadingBasemaps.current.delete(style);\n }\n \n // Show the selected basemap\n setBasemapVisibility(style, true);\n setCurrentMapStyle(style);\n }, [loadBasemapStyle, setBasemapVisibility]);\n \n // Keep ref updated for use in imperative handle\n handleMapStyleChangeRef.current = handleMapStyleChange;\n\n const handleUpdateTraceConfig = useCallback((layerId: string, config: TraceConfig) => {\n setLayers(prev => prev.map(l => \n l.id === layerId ? { ...l, traceConfig: config } : l\n ));\n }, []);\n\n const handleUpdateHeatmapConfig = useCallback((layerId: string, config: HeatmapConfig) => {\n setLayers(prev => prev.map(l => \n l.id === layerId ? { ...l, heatmapConfig: config } : l\n ));\n }, []);\n\n const handleUpdateClusterConfig = useCallback((layerId: string, config: ClusterConfig) => {\n setLayers(prev => prev.map(l => \n l.id === layerId ? { ...l, clusterConfig: config } : l\n ));\n }, []);\n\n const handleUpdateVisualConfig = useCallback((layerId: string, config: VisualConfig) => {\n setLayers(prev => prev.map(l => \n l.id === layerId ? { ...l, visualConfig: config } : l\n ));\n }, []);\n\n const handleUpdateAltitudeDisplayMode = useCallback((layerId: string, mode: AltitudeDisplayMode) => {\n setLayers(prev => prev.map(l => \n l.id === layerId ? { ...l, altitudeDisplayMode: mode } : l\n ));\n }, []);\n\n const handleUpdateAutoLabelConfig = useCallback((config: AutoLabelConfig) => {\n setAutoLabelConfig(config);\n }, []);\n\n // Count visible features using MapLibre's queryRenderedFeatures\n // This uses MapLibre's internal spatial index - efficient and accurate\n const LABEL_THRESHOLD = 500;\n \n const countVisibleFeaturesInViewport = useCallback(() => {\n if (!map.current || !isMapLoaded) return;\n \n const customLayers = ['custom-point', 'custom-line', 'custom-polygon-fill'];\n const existingLayers = customLayers.filter(id => map.current!.getLayer(id));\n \n if (existingLayers.length === 0) {\n setVisibleFeatureCount(0);\n return;\n }\n \n // queryRenderedFeatures returns features currently visible on screen\n const rendered = map.current.queryRenderedFeatures(undefined, { layers: existingLayers });\n \n // Dedupe by feature ID (same feature can appear from multiple tiles)\n const uniqueIds = new Set<string>();\n for (const f of rendered) {\n const fid = f.properties?.id || f.id;\n if (fid) uniqueIds.add(String(fid));\n }\n \n setVisibleFeatureCount(uniqueIds.size);\n }, [isMapLoaded]);\n\n // Listen to map move/zoom to update visible feature count (debounced)\n useEffect(() => {\n if (!map.current || !isMapLoaded) return;\n \n const mapInstance = map.current;\n let debounceTimer: ReturnType<typeof setTimeout> | null = null;\n \n const handleMoveEnd = () => {\n // Debounce to avoid rapid-fire updates during continuous panning\n if (debounceTimer) clearTimeout(debounceTimer);\n debounceTimer = setTimeout(() => {\n countVisibleFeaturesInViewport();\n }, 300); // 300ms debounce for smoother interaction\n };\n \n mapInstance.on('moveend', handleMoveEnd);\n mapInstance.on('zoomend', handleMoveEnd);\n \n // Initial count\n countVisibleFeaturesInViewport();\n \n return () => {\n if (debounceTimer) clearTimeout(debounceTimer);\n try {\n mapInstance.off('moveend', handleMoveEnd);\n mapInstance.off('zoomend', handleMoveEnd);\n } catch {\n // Map may already be destroyed\n }\n };\n }, [isMapLoaded, countVisibleFeaturesInViewport]);\n\n // Also update count when features change\n useEffect(() => {\n countVisibleFeaturesInViewport();\n }, [featureCount, countVisibleFeaturesInViewport]);\n\n // Sync arrow heads on every map move (screen-space computed features need continuous updates)\n useEffect(() => {\n if (!map.current || !isMapLoaded) return;\n \n const mapInstance = map.current;\n \n const handleMove = () => {\n // Use syncRef to get current sync function\n if (syncRef.current) {\n syncRef.current();\n }\n };\n \n mapInstance.on('move', handleMove);\n \n return () => {\n try {\n mapInstance.off('move', handleMove);\n } catch {\n // Map may already be destroyed\n }\n };\n }, [isMapLoaded]);\n\n // Fire onViewportChange callback when map viewport changes\n useEffect(() => {\n if (!map.current || !isMapLoaded || !onViewportChange) return;\n \n const mapInstance = map.current;\n \n const emitViewportChange = () => {\n if (!mapInstance) return;\n \n const center = mapInstance.getCenter();\n const zoom = mapInstance.getZoom();\n const bounds = mapInstance.getBounds();\n \n // Get raw bounds\n const rawBounds: [number, number, number, number] = [\n bounds.getWest(),\n bounds.getSouth(),\n bounds.getEast(),\n bounds.getNorth()\n ];\n \n // Normalize query bounds - clamp latitude to valid range, handle longitude wrapping\n const queryBounds = {\n minLng: Math.max(-180, Math.min(180, rawBounds[0])),\n maxLng: Math.max(-180, Math.min(180, rawBounds[2])),\n minLat: Math.max(-90, Math.min(90, rawBounds[1])),\n maxLat: Math.max(-90, Math.min(90, rawBounds[3]))\n };\n \n onViewportChange({\n center: [center.lng, center.lat],\n zoom,\n bounds: rawBounds,\n queryBounds\n });\n };\n \n mapInstance.on('moveend', emitViewportChange);\n mapInstance.on('zoomend', emitViewportChange);\n \n // Fire initial viewport\n emitViewportChange();\n \n return () => {\n try {\n mapInstance.off('moveend', emitViewportChange);\n mapInstance.off('zoomend', emitViewportChange);\n } catch {\n // Map may already be destroyed\n }\n };\n }, [isMapLoaded, onViewportChange]);\n\n // Viewport feature counting - OPTIMIZED: stop counting once threshold exceeded\n // Only counts on actual viewport changes (zoom level or center changes)\n useEffect(() => {\n if (!map.current || !isMapLoaded) return;\n \n const mapInstance = map.current;\n let lastCenter = mapInstance.getCenter();\n let lastZoom = mapInstance.getZoom();\n \n const updateViewportCount = () => {\n const layers = ['custom-point', 'custom-line', 'custom-polygon-fill'];\n const existing = layers.filter(id => mapInstance.getLayer(id));\n if (existing.length === 0) {\n setVisibleFeatureCount(0);\n setLabelsSuppressed(false);\n return;\n }\n \n // Get threshold for early exit optimization\n const threshold = autoLabelConfig.enabled ? autoLabelConfig.threshold : 220;\n \n // Query features but stop counting once we exceed threshold\n const rendered = mapInstance.queryRenderedFeatures(undefined, { layers: existing });\n const uniqueIds = new Set<string>();\n let count = 0;\n \n for (const f of rendered) {\n const fid = f.properties?.id || f.id;\n if (fid && !uniqueIds.has(String(fid))) {\n uniqueIds.add(String(fid));\n count++;\n if (count > threshold) {\n setVisibleFeatureCount(count);\n setLabelsSuppressed(false);\n return;\n }\n }\n }\n \n setVisibleFeatureCount(count);\n setLabelsSuppressed(false);\n };\n \n const onMapMovement = () => {\n // Only update if viewport actually changed (not just click-hold-release)\n const center = mapInstance.getCenter();\n const zoom = mapInstance.getZoom();\n const centerMoved = Math.abs(center.lng - lastCenter.lng) > 0.0001 || \n Math.abs(center.lat - lastCenter.lat) > 0.0001;\n const zoomChanged = Math.abs(zoom - lastZoom) > 0.01;\n \n if (centerMoved || zoomChanged) {\n lastCenter = center;\n lastZoom = zoom;\n // Small delay to batch rapid movements\n requestAnimationFrame(() => {\n if (mapInstance.loaded()) {\n updateViewportCount();\n }\n });\n }\n };\n \n // Listen for map movements\n mapInstance.on('moveend', onMapMovement);\n \n // Initial count after first idle\n mapInstance.once('idle', updateViewportCount);\n \n return () => {\n try {\n mapInstance.off('moveend', onMapMovement);\n } catch {\n // Map may be destroyed\n }\n };\n }, [isMapLoaded, autoLabelConfig.threshold, autoLabelConfig.enabled]);\n\n // Update label visibility directly without rebuilding all data\n // This is the fast path for pan/zoom - just toggle layer visibility\n const DEFAULT_LABEL_THRESHOLD = 220;\n useEffect(() => {\n if (!map.current || !isMapLoaded) return;\n \n const labelLayer = map.current.getLayer('custom-labels');\n if (!labelLayer) return;\n \n // Use viewport count with threshold (configurable or default 220)\n const threshold = autoLabelConfig.enabled ? autoLabelConfig.threshold : DEFAULT_LABEL_THRESHOLD;\n // Don't show labels while suppressed (during bulk operations)\n const shouldShowLabels = !labelsSuppressed && visibleFeatureCount < threshold;\n \n // Only update if visibility changed\n if (lastLabelVisibility.current !== shouldShowLabels) {\n lastLabelVisibility.current = shouldShowLabels;\n map.current.setLayoutProperty('custom-labels', 'visibility', shouldShowLabels ? 'visible' : 'none');\n }\n }, [autoLabelConfig, visibleFeatureCount, isMapLoaded, labelsSuppressed]);\n\n const getLayerFields = useCallback((layerId: string): { name: string; isNumeric: boolean }[] => {\n const layer = layers.find(l => l.id === layerId);\n if (!layer) return [];\n\n const fieldsMap = new Map<string, boolean>();\n const excludedFields = new Set(['name', 'startDate', 'endDate', 'opacity']);\n const MAX_SAMPLES = 10000; // Limit for performance with large datasets\n\n // Get features from appropriate source\n let features: (GeoJSON.Feature | undefined)[] = [];\n if (layer.readOnly) {\n // Read-only layer: get from readOnlyFeatures storage\n features = readOnlyFeatures.current.get(layerId) || [];\n } else if (layer.visible) {\n // Editable visible layer: get from MapboxDraw\n features = draw.current ? layer.featureIds.map(id => draw.current!.get(id)) : [];\n } else {\n // Editable hidden layer: get from hiddenFeatures\n features = hiddenFeatures.current.get(layerId) || [];\n }\n\n // Sample up to MAX_SAMPLES for field scanning\n const sampleFeatures = features.slice(0, MAX_SAMPLES);\n \n sampleFeatures.forEach(f => {\n if (f && f.properties) {\n Object.entries(f.properties).forEach(([key, value]) => {\n if (!excludedFields.has(key)) {\n // Check if value is a number or a numeric string\n const isNumeric = typeof value === 'number' || \n (typeof value === 'string' && value.trim() !== '' && !isNaN(Number(value)));\n if (!fieldsMap.has(key)) {\n fieldsMap.set(key, isNumeric);\n } else if (isNumeric && !fieldsMap.get(key)) {\n fieldsMap.set(key, true);\n }\n }\n });\n }\n });\n\n return Array.from(fieldsMap.entries())\n .map(([name, isNumeric]) => ({ name, isNumeric }))\n .sort((a, b) => a.name.localeCompare(b.name));\n }, [layers]);\n\n const handleFitToLayerFeatures = useCallback((layerId: string) => {\n const layer = layers.find(l => l.id === layerId);\n if (!layer || !map.current) return;\n \n let features: GeoJSON.Feature[];\n \n if (!layer.visible) {\n // Hidden layers - use hiddenFeatures storage\n features = hiddenFeatures.current.get(layerId) || [];\n } else if (layer.readOnly) {\n // Visible read-only layers - use readOnlyFeatures storage\n features = readOnlyFeatures.current.get(layerId) || [];\n } else {\n // Visible editable layers - use MapboxDraw\n features = layer.featureIds.map(id => draw.current?.get(id)).filter(Boolean) as GeoJSON.Feature[];\n }\n \n if (features.length === 0) return;\n \n const featureCollection: GeoJSON.FeatureCollection = {\n type: 'FeatureCollection',\n features: features,\n };\n \n const bounds = turf.bbox(featureCollection);\n if (bounds.some(v => !isFinite(v))) return;\n \n map.current.fitBounds(\n [[bounds[0], bounds[1]], [bounds[2], bounds[3]]],\n { padding: 50, maxZoom: 18 }\n );\n }, [layers]);\n\n const hasPointFeatures = useCallback((layerId: string): boolean => {\n const layer = layers.find(l => l.id === layerId);\n if (!layer) return false;\n \n if (layer.visible) {\n if (layer.readOnly) {\n // Read-only layers store features in readOnlyFeatures ref\n const roFeatures = readOnlyFeatures.current.get(layerId) || [];\n return roFeatures.some(f => f.geometry?.type === 'Point');\n } else {\n // Editable layers use MapboxDraw\n if (!draw.current) return false;\n for (const id of layer.featureIds) {\n const feature = draw.current.get(id);\n if (feature?.geometry?.type === 'Point') return true;\n }\n return false;\n }\n } else {\n // Hidden layers (any type)\n const hidden = hiddenFeatures.current.get(layerId) || [];\n return hidden.some(f => f.geometry?.type === 'Point');\n }\n }, [layers]);\n\n const getAvailableTraceFields = useCallback((layerId: string): string[] => {\n const layer = layers.find(l => l.id === layerId);\n if (!layer) return [];\n\n const fieldsSet = new Set<string>();\n const excludedFields = new Set(['name', 'startDate', 'endDate', 'opacity']);\n const MAX_SAMPLES = 10000; // Limit for performance with large datasets\n\n // Get features from appropriate source\n let features: (GeoJSON.Feature | undefined)[] = [];\n if (layer.readOnly) {\n // Read-only layer: get from readOnlyFeatures storage\n features = readOnlyFeatures.current.get(layerId) || [];\n } else if (layer.visible) {\n // Editable visible layer: get from MapboxDraw\n features = draw.current ? layer.featureIds.map(id => draw.current!.get(id)) : [];\n } else {\n // Editable hidden layer: get from hiddenFeatures\n features = hiddenFeatures.current.get(layerId) || [];\n }\n\n // Sample up to MAX_SAMPLES for field scanning\n const sampleFeatures = features.slice(0, MAX_SAMPLES);\n\n sampleFeatures.forEach(f => {\n if (f && f.properties) {\n Object.entries(f.properties).forEach(([key, value]) => {\n if (!excludedFields.has(key) && (typeof value === 'string' || typeof value === 'number')) {\n fieldsSet.add(key);\n }\n });\n }\n });\n\n return Array.from(fieldsSet).sort();\n }, [layers]);\n\n const handleMeasureModeChange = useCallback((mode: MeasureMode) => {\n setMeasureMode(mode);\n setMeasurePoints([]);\n setMeasureResult(null);\n \n if (mode !== 'none' && draw.current) {\n const selectMode: DrawingMode = isEditMode ? 'simple_select' : 'view_select';\n draw.current.changeMode(selectMode as string);\n setActiveMode(selectMode);\n }\n }, [isEditMode]);\n\n // Toggle 3D terrain on/off\n const handleToggle3DTerrain = useCallback(() => {\n if (!map.current) return;\n \n // Don't allow 3D if terrain is disabled\n if (!enableTerrain || !enable3D) {\n toast({\n title: '3D Terrain Unavailable',\n description: 'Terrain features are disabled for this configuration.',\n variant: 'destructive',\n });\n return;\n }\n \n const newState = !is3DTerrainEnabled;\n setIs3DTerrainEnabled(newState);\n \n const mapInstance = map.current;\n \n if (newState) {\n // Enable 3D terrain with exaggeration for visible effect\n mapInstance.setTerrain({ source: 'terrain-dem', exaggeration: 1.5 });\n \n // Add hillshade layer for better terrain visualization if not already present\n if (!mapInstance.getLayer('terrain-hillshade')) {\n // Find a good insertion point (before first symbol layer or at end)\n const layers = mapInstance.getStyle().layers || [];\n let beforeId: string | undefined;\n for (const layer of layers) {\n if (layer.type === 'symbol') {\n beforeId = layer.id;\n break;\n }\n }\n \n mapInstance.addLayer({\n id: 'terrain-hillshade',\n type: 'hillshade',\n source: 'terrain-dem',\n paint: {\n 'hillshade-exaggeration': 0.5,\n 'hillshade-shadow-color': '#000000',\n 'hillshade-highlight-color': '#ffffff',\n }\n }, beforeId);\n } else {\n mapInstance.setLayoutProperty('terrain-hillshade', 'visibility', 'visible');\n }\n \n toast({\n title: '3D Terrain Enabled',\n description: 'Tilt the map (right-click + drag or Ctrl + drag) to see the 3D effect.',\n });\n } else {\n // Disable 3D terrain\n mapInstance.setTerrain(null);\n \n // Hide hillshade layer\n if (mapInstance.getLayer('terrain-hillshade')) {\n mapInstance.setLayoutProperty('terrain-hillshade', 'visibility', 'none');\n }\n }\n }, [is3DTerrainEnabled, enableTerrain, enable3D, toast]);\n\n const handleSelectionModeChange = useCallback((mode: SelectionMode) => {\n setSelectionMode(mode);\n setSelectionPoints([]);\n setSelectionHoverPoint(null);\n isDrawingSelection.current = false;\n }, []);\n\n // Ref to track selection points for polygon selection (avoids stale closure in dblclick handler)\n const selectionPointsRef = useRef<[number, number][]>([]);\n useEffect(() => {\n selectionPointsRef.current = selectionPoints;\n }, [selectionPoints]);\n\n // Ref to track selected feature IDs for shift-merge selection (avoids stale closure)\n const selectedFeatureIdsRef = useRef<string[]>([]);\n useEffect(() => {\n selectedFeatureIdsRef.current = selectedFeatureIds;\n }, [selectedFeatureIds]);\n\n // Rectangle and Lasso selection mouse handlers\n useEffect(() => {\n // Only require map.current for cursor/pan control - draw.current is only needed for feature queries\n if (!map.current || !isMapLoaded) {\n return;\n }\n if (selectionMode === 'click' || !isSelectionToolActive) {\n // Ensure navigation is enabled when in click mode or selection tool not active\n if (map.current) {\n map.current.dragPan.enable();\n map.current.getCanvas().style.cursor = '';\n }\n return;\n }\n \n const mapInstance = map.current;\n const canvas = mapInstance.getCanvas();\n \n // Disable map panning when in rectangle/polygon selection mode AND tool is active\n mapInstance.dragPan.disable();\n \n // Change cursor\n console.log('[Selection Effect] Setting crosshair cursor');\n canvas.style.cursor = 'crosshair';\n \n let startPoint: { x: number; y: number } | null = null;\n \n const handleMouseDown = (e: MouseEvent) => {\n if (e.button !== 0) return; // Only left click\n \n if (selectionMode === 'rectangle' || selectionMode === 'circle') {\n startPoint = { x: e.offsetX, y: e.offsetY };\n isDrawingSelection.current = true;\n const lngLat = mapInstance.unproject([e.offsetX, e.offsetY]);\n setSelectionPoints([[lngLat.lng, lngLat.lat]]);\n }\n };\n \n const handleMouseMove = (e: MouseEvent) => {\n if (selectionMode === 'rectangle' && isDrawingSelection.current && startPoint) {\n const startLngLat = mapInstance.unproject([startPoint.x, startPoint.y]);\n const currentLngLat = mapInstance.unproject([e.offsetX, e.offsetY]);\n \n // Normalize coordinates to handle any drag direction\n const minLng = Math.min(startLngLat.lng, currentLngLat.lng);\n const maxLng = Math.max(startLngLat.lng, currentLngLat.lng);\n const minLat = Math.min(startLngLat.lat, currentLngLat.lat);\n const maxLat = Math.max(startLngLat.lat, currentLngLat.lat);\n \n // Create rectangle from normalized corners\n setSelectionPoints([\n [minLng, maxLat], // top-left\n [maxLng, maxLat], // top-right\n [maxLng, minLat], // bottom-right\n [minLng, minLat], // bottom-left\n [minLng, maxLat], // close polygon\n ]);\n } else if (selectionMode === 'circle' && isDrawingSelection.current && startPoint) {\n const centerLngLat = mapInstance.unproject([startPoint.x, startPoint.y]);\n const edgeLngLat = mapInstance.unproject([e.offsetX, e.offsetY]);\n \n // Calculate radius in kilometers using turf\n const center = turf.point([centerLngLat.lng, centerLngLat.lat]);\n const edge = turf.point([edgeLngLat.lng, edgeLngLat.lat]);\n const radiusKm = turf.distance(center, edge, { units: 'kilometers' });\n \n // Create circle polygon using turf (64 points for smooth circle)\n if (radiusKm > 0) {\n const circle = turf.circle([centerLngLat.lng, centerLngLat.lat], radiusKm, { steps: 64, units: 'kilometers' });\n const coords = circle.geometry.coordinates[0] as [number, number][];\n setSelectionPoints(coords);\n }\n } else if (selectionMode === 'polygon') {\n // Track hover position for rubber-band preview\n const lngLat = mapInstance.unproject([e.offsetX, e.offsetY]);\n setSelectionHoverPoint([lngLat.lng, lngLat.lat]);\n }\n };\n \n const handleMouseUp = (e: MouseEvent) => {\n if (selectionMode === 'rectangle' && isDrawingSelection.current && startPoint) {\n isDrawingSelection.current = false;\n \n const MIN_DRAG_PX = 32;\n const dx = Math.abs(e.offsetX - startPoint.x);\n const dy = Math.abs(e.offsetY - startPoint.y);\n if (dx < MIN_DRAG_PX || dy < MIN_DRAG_PX) {\n startPoint = null;\n setSelectionPoints([]);\n return;\n }\n \n const startLngLat = mapInstance.unproject([startPoint.x, startPoint.y]);\n const endLngLat = mapInstance.unproject([e.offsetX, e.offsetY]);\n \n // Normalize coordinates to handle any drag direction\n const minLng = Math.min(startLngLat.lng, endLngLat.lng);\n const maxLng = Math.max(startLngLat.lng, endLngLat.lng);\n const minLat = Math.min(startLngLat.lat, endLngLat.lat);\n const maxLat = Math.max(startLngLat.lat, endLngLat.lat);\n \n // Create selection polygon with proper winding\n const selectionPolygon = turf.polygon([[\n [minLng, maxLat], // top-left\n [maxLng, maxLat], // top-right\n [maxLng, minLat], // bottom-right\n [minLng, minLat], // bottom-left\n [minLng, maxLat], // close polygon\n ]]);\n \n // Find all features within the selection (including read-only)\n const drawFeatures = draw.current ? draw.current.getAll().features : [];\n const readOnlyFeaturesList: GeoJSON.Feature[] = [];\n readOnlyFeatures.current.forEach((features, layerId) => {\n const layer = layersRef.current.find(l => l.id === layerId);\n if (layer?.visible) readOnlyFeaturesList.push(...features);\n });\n const allFeatures = [...drawFeatures, ...readOnlyFeaturesList];\n \n const selectedIds: string[] = [];\n \n allFeatures.forEach(feature => {\n try {\n const geom = feature.geometry;\n let isInside = false;\n \n if (geom.type === 'Point') {\n isInside = turf.booleanPointInPolygon(geom.coordinates as [number, number], selectionPolygon);\n } else if (geom.type === 'LineString' || geom.type === 'Polygon' || geom.type === 'MultiPoint' || geom.type === 'MultiLineString' || geom.type === 'MultiPolygon') {\n isInside = turf.booleanIntersects(feature as GeoJSON.Feature, selectionPolygon);\n }\n \n if (isInside && feature.id) {\n selectedIds.push(String(feature.id));\n }\n } catch (err) {\n // Skip features that cause errors\n }\n });\n \n // Merge with existing selection when shift is held\n const finalIds = e.shiftKey \n ? Array.from(new Set([...selectedFeatureIdsRef.current, ...selectedIds]))\n : selectedIds;\n applySelectionState(finalIds, { focusProperties: true });\n \n const isFilterAction = filterActiveRef.current || !showFilterTool;\n if (onSelectionComplete && isFilterAction) {\n onSelectionComplete(selectionPolygon.geometry);\n }\n \n // Deactivate selection tool after completion (return to pan mode)\n setIsSelectionToolActive(false);\n \n if (persistSelection && isFilterAction) {\n setPersistedSelectionPolygon([\n [minLng, maxLat],\n [maxLng, maxLat],\n [maxLng, minLat],\n [minLng, minLat],\n [minLng, maxLat],\n ]);\n }\n \n startPoint = null;\n setSelectionPoints([]);\n } else if (selectionMode === 'circle' && isDrawingSelection.current && startPoint) {\n isDrawingSelection.current = false;\n \n const centerLngLat = mapInstance.unproject([startPoint.x, startPoint.y]);\n const edgeLngLat = mapInstance.unproject([e.offsetX, e.offsetY]);\n \n // Calculate radius in kilometers using turf\n const center = turf.point([centerLngLat.lng, centerLngLat.lat]);\n const edge = turf.point([edgeLngLat.lng, edgeLngLat.lat]);\n const radiusKm = turf.distance(center, edge, { units: 'kilometers' });\n \n if (radiusKm > 0) {\n // Create selection circle polygon using turf\n const selectionPolygon = turf.circle([centerLngLat.lng, centerLngLat.lat], radiusKm, { steps: 64, units: 'kilometers' });\n \n // Find all features within the selection (including read-only)\n const drawFeatures = draw.current ? draw.current.getAll().features : [];\n const readOnlyFeaturesList: GeoJSON.Feature[] = [];\n readOnlyFeatures.current.forEach((features, layerId) => {\n const layer = layersRef.current.find(l => l.id === layerId);\n if (layer?.visible) readOnlyFeaturesList.push(...features);\n });\n const allFeatures = [...drawFeatures, ...readOnlyFeaturesList];\n \n const selectedIds: string[] = [];\n \n allFeatures.forEach(feature => {\n try {\n const geom = feature.geometry;\n let isInside = false;\n \n if (geom.type === 'Point') {\n isInside = turf.booleanPointInPolygon(geom.coordinates as [number, number], selectionPolygon);\n } else if (geom.type === 'LineString' || geom.type === 'Polygon' || geom.type === 'MultiPoint' || geom.type === 'MultiLineString' || geom.type === 'MultiPolygon') {\n isInside = turf.booleanIntersects(feature as GeoJSON.Feature, selectionPolygon);\n }\n \n if (isInside && feature.id) {\n selectedIds.push(String(feature.id));\n }\n } catch (err) {\n // Skip features that cause errors\n }\n });\n \n // Merge with existing selection when shift is held\n const finalIds = e.shiftKey \n ? Array.from(new Set([...selectedFeatureIdsRef.current, ...selectedIds]))\n : selectedIds;\n applySelectionState(finalIds, { focusProperties: true });\n \n const isFilterAction = filterActiveRef.current || !showFilterTool;\n if (onSelectionComplete && isFilterAction) {\n onSelectionComplete(selectionPolygon.geometry);\n }\n \n // Deactivate selection tool after completion (return to pan mode)\n setIsSelectionToolActive(false);\n \n if (persistSelection && isFilterAction) {\n setPersistedSelectionPolygon(selectionPolygon.geometry.coordinates[0] as [number, number][]);\n }\n }\n \n startPoint = null;\n setSelectionPoints([]);\n }\n };\n \n const handleClick = (e: MouseEvent) => {\n if (selectionMode === 'polygon') {\n const lngLat = mapInstance.unproject([e.offsetX, e.offsetY]);\n setSelectionPoints(prev => [...prev, [lngLat.lng, lngLat.lat]]);\n }\n };\n \n const handleDblClick = (e: MouseEvent) => {\n if (selectionMode === 'polygon') {\n e.preventDefault();\n e.stopPropagation();\n \n // Use ref to get current selection points (avoid stale closure)\n const currentPoints = selectionPointsRef.current;\n \n // Need at least 3 points for a valid polygon\n if (currentPoints.length < 3) {\n setSelectionPoints([]);\n return;\n }\n \n // Close the polygon and find features (including read-only)\n const closedPoints = [...currentPoints, currentPoints[0]];\n const selectionPolygon = turf.polygon([closedPoints]);\n \n const drawFeatures = draw.current ? draw.current.getAll().features : [];\n const readOnlyFeaturesList: GeoJSON.Feature[] = [];\n readOnlyFeatures.current.forEach((features, layerId) => {\n const layer = layersRef.current.find(l => l.id === layerId);\n if (layer?.visible) readOnlyFeaturesList.push(...features);\n });\n const allFeatures = [...drawFeatures, ...readOnlyFeaturesList];\n \n const selectedIds: string[] = [];\n \n allFeatures.forEach(feature => {\n try {\n const geom = feature.geometry;\n let isInside = false;\n \n if (geom.type === 'Point') {\n isInside = turf.booleanPointInPolygon(geom.coordinates as [number, number], selectionPolygon);\n } else if (geom.type === 'LineString' || geom.type === 'Polygon' || geom.type === 'MultiPoint' || geom.type === 'MultiLineString' || geom.type === 'MultiPolygon') {\n isInside = turf.booleanIntersects(feature as GeoJSON.Feature, selectionPolygon);\n }\n \n if (isInside && feature.id) {\n selectedIds.push(String(feature.id));\n }\n } catch (err) {\n // Skip features that cause errors\n }\n });\n \n // Merge with existing selection when shift is held\n const finalIds = e.shiftKey \n ? Array.from(new Set([...selectedFeatureIdsRef.current, ...selectedIds]))\n : selectedIds;\n applySelectionState(finalIds, { focusProperties: true });\n \n const isFilterAction = filterActiveRef.current || !showFilterTool;\n if (onSelectionComplete && isFilterAction) {\n onSelectionComplete(selectionPolygon.geometry);\n }\n \n // Deactivate selection tool after completion (return to pan mode)\n setIsSelectionToolActive(false);\n \n if (persistSelection && isFilterAction) {\n setPersistedSelectionPolygon(closedPoints);\n }\n \n setSelectionPoints([]);\n setSelectionHoverPoint(null);\n }\n };\n \n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n isDrawingSelection.current = false;\n setSelectionPoints([]);\n setSelectionHoverPoint(null);\n startPoint = null;\n }\n };\n \n const handleContextMenu = (e: MouseEvent) => {\n e.preventDefault();\n isDrawingSelection.current = false;\n setSelectionPoints([]);\n setSelectionHoverPoint(null);\n startPoint = null;\n };\n \n const handleMouseLeave = () => {\n setSelectionHoverPoint(null);\n };\n \n // Add listeners\n canvas.addEventListener('mousedown', handleMouseDown);\n canvas.addEventListener('mousemove', handleMouseMove);\n canvas.addEventListener('mouseup', handleMouseUp);\n canvas.addEventListener('click', handleClick);\n canvas.addEventListener('dblclick', handleDblClick);\n canvas.addEventListener('mouseleave', handleMouseLeave);\n window.addEventListener('keydown', handleKeyDown);\n canvas.addEventListener('contextmenu', handleContextMenu);\n \n return () => {\n // Re-enable map navigation\n if (map.current) {\n map.current.dragPan.enable();\n map.current.getCanvas().style.cursor = '';\n }\n setSelectionHoverPoint(null);\n \n canvas.removeEventListener('mousedown', handleMouseDown);\n canvas.removeEventListener('mousemove', handleMouseMove);\n canvas.removeEventListener('mouseup', handleMouseUp);\n canvas.removeEventListener('click', handleClick);\n canvas.removeEventListener('dblclick', handleDblClick);\n canvas.removeEventListener('mouseleave', handleMouseLeave);\n window.removeEventListener('keydown', handleKeyDown);\n canvas.removeEventListener('contextmenu', handleContextMenu);\n };\n }, [selectionMode, isMapLoaded, onFeatureSelect, onSelectionComplete, persistSelection, isSelectionToolActive]);\n\n // Shift+Drag rectangle selection (works in click selection mode)\n const shiftSelectionRef = useRef<{ \n isActive: boolean; \n startPoint: { x: number; y: number } | null \n }>({ isActive: false, startPoint: null });\n \n useEffect(() => {\n if (!map.current || !isMapLoaded || !draw.current) return;\n // Only active in click selection mode - other modes have their own handlers\n if (selectionMode !== 'click') return;\n \n const mapInstance = map.current;\n const canvas = mapInstance.getCanvas();\n \n const handleShiftMouseDown = (e: MouseEvent) => {\n if (e.button !== 0 || !e.shiftKey) return;\n \n // Start shift+drag selection\n shiftSelectionRef.current = {\n isActive: true,\n startPoint: { x: e.offsetX, y: e.offsetY }\n };\n \n // Disable panning during shift selection\n mapInstance.dragPan.disable();\n canvas.style.cursor = 'crosshair';\n \n const lngLat = mapInstance.unproject([e.offsetX, e.offsetY]);\n setSelectionPoints([[lngLat.lng, lngLat.lat]]);\n \n e.preventDefault();\n e.stopPropagation();\n };\n \n const handleShiftMouseMove = (e: MouseEvent) => {\n if (!shiftSelectionRef.current.isActive || !shiftSelectionRef.current.startPoint) return;\n \n const startPoint = shiftSelectionRef.current.startPoint;\n const startLngLat = mapInstance.unproject([startPoint.x, startPoint.y]);\n const currentLngLat = mapInstance.unproject([e.offsetX, e.offsetY]);\n \n // Normalize coordinates\n const minLng = Math.min(startLngLat.lng, currentLngLat.lng);\n const maxLng = Math.max(startLngLat.lng, currentLngLat.lng);\n const minLat = Math.min(startLngLat.lat, currentLngLat.lat);\n const maxLat = Math.max(startLngLat.lat, currentLngLat.lat);\n \n setSelectionPoints([\n [minLng, maxLat],\n [maxLng, maxLat],\n [maxLng, minLat],\n [minLng, minLat],\n [minLng, maxLat],\n ]);\n };\n \n const handleShiftMouseUp = (e: MouseEvent) => {\n if (!shiftSelectionRef.current.isActive || !shiftSelectionRef.current.startPoint) return;\n \n const startPoint = shiftSelectionRef.current.startPoint;\n const startLngLat = mapInstance.unproject([startPoint.x, startPoint.y]);\n const endLngLat = mapInstance.unproject([e.offsetX, e.offsetY]);\n \n // Normalize coordinates\n const minLng = Math.min(startLngLat.lng, endLngLat.lng);\n const maxLng = Math.max(startLngLat.lng, endLngLat.lng);\n const minLat = Math.min(startLngLat.lat, endLngLat.lat);\n const maxLat = Math.max(startLngLat.lat, endLngLat.lat);\n \n // Create selection polygon\n const selectionPolygon = turf.polygon([[\n [minLng, maxLat],\n [maxLng, maxLat],\n [maxLng, minLat],\n [minLng, minLat],\n [minLng, maxLat],\n ]]);\n \n // Find all features within the selection (including read-only)\n const drawFeatures = draw.current ? draw.current.getAll().features : [];\n const readOnlyFeaturesList: GeoJSON.Feature[] = [];\n readOnlyFeatures.current.forEach((features, layerId) => {\n const layer = layersRef.current.find(l => l.id === layerId);\n if (layer?.visible) readOnlyFeaturesList.push(...features);\n });\n const allFeatures = [...drawFeatures, ...readOnlyFeaturesList];\n \n const selectedIds: string[] = [];\n \n allFeatures.forEach(feature => {\n try {\n const geom = feature.geometry;\n let isInside = false;\n \n if (geom.type === 'Point') {\n isInside = turf.booleanPointInPolygon(geom.coordinates as [number, number], selectionPolygon);\n } else if (geom.type === 'LineString' || geom.type === 'Polygon' || geom.type === 'MultiPoint' || geom.type === 'MultiLineString' || geom.type === 'MultiPolygon') {\n isInside = turf.booleanIntersects(feature as GeoJSON.Feature, selectionPolygon);\n }\n \n if (isInside && feature.id) {\n selectedIds.push(String(feature.id));\n }\n } catch {}\n });\n \n // Merge with existing selection when shift is held\n const mergedIds = Array.from(new Set([...selectedFeatureIdsRef.current, ...selectedIds]));\n applySelectionState(mergedIds, { focusProperties: true });\n \n // Reset state\n shiftSelectionRef.current = { isActive: false, startPoint: null };\n setSelectionPoints([]);\n mapInstance.dragPan.enable();\n canvas.style.cursor = '';\n };\n \n const handleKeyUp = (e: KeyboardEvent) => {\n // Cancel if shift is released during selection\n if (e.key === 'Shift' && shiftSelectionRef.current.isActive) {\n shiftSelectionRef.current = { isActive: false, startPoint: null };\n setSelectionPoints([]);\n mapInstance.dragPan.enable();\n canvas.style.cursor = '';\n }\n };\n \n canvas.addEventListener('mousedown', handleShiftMouseDown);\n canvas.addEventListener('mousemove', handleShiftMouseMove);\n canvas.addEventListener('mouseup', handleShiftMouseUp);\n window.addEventListener('keyup', handleKeyUp);\n \n return () => {\n canvas.removeEventListener('mousedown', handleShiftMouseDown);\n canvas.removeEventListener('mousemove', handleShiftMouseMove);\n canvas.removeEventListener('mouseup', handleShiftMouseUp);\n window.removeEventListener('keyup', handleKeyUp);\n \n // Ensure panning is re-enabled\n if (map.current) {\n map.current.dragPan.enable();\n }\n };\n }, [selectionMode, isMapLoaded, onFeatureSelect, onSelectionComplete, persistSelection, isSelectionToolActive]);\n\n // Manage MapLibre layer for persisted selection (so it zooms with the map)\n useEffect(() => {\n if (!map.current || !isMapLoaded) return;\n \n const mapInstance = map.current;\n const sourceId = 'persisted-selection-source';\n const fillLayerId = 'persisted-selection-fill';\n const lineLayerId = 'persisted-selection-line';\n \n // Create empty GeoJSON for when there's no selection\n const emptyGeojson: GeoJSON.FeatureCollection = {\n type: 'FeatureCollection',\n features: []\n };\n \n // Create GeoJSON polygon if we have a valid selection\n const geojson: GeoJSON.FeatureCollection = \n (persistedSelectionPolygon && persistedSelectionPolygon.length >= 4)\n ? {\n type: 'FeatureCollection',\n features: [{\n type: 'Feature',\n properties: {},\n geometry: {\n type: 'Polygon',\n coordinates: [persistedSelectionPolygon]\n }\n }]\n }\n : emptyGeojson;\n \n // Check if source already exists\n const existingSource = mapInstance.getSource(sourceId) as maplibregl.GeoJSONSource | undefined;\n \n if (existingSource) {\n // Update existing source data\n existingSource.setData(geojson);\n } else {\n // Add source and layers for the first time\n mapInstance.addSource(sourceId, {\n type: 'geojson',\n data: geojson\n });\n \n // Add fill layer\n mapInstance.addLayer({\n id: fillLayerId,\n type: 'fill',\n source: sourceId,\n paint: {\n 'fill-color': '#3B82F6',\n 'fill-opacity': 0.2\n }\n });\n \n // Add line layer\n mapInstance.addLayer({\n id: lineLayerId,\n type: 'line',\n source: sourceId,\n paint: {\n 'line-color': '#3B82F6',\n 'line-width': 2\n }\n });\n }\n \n return () => {\n // Cleanup on unmount only - check map still exists\n try {\n if (mapInstance && mapInstance.getLayer && mapInstance.getLayer(lineLayerId)) {\n mapInstance.removeLayer(lineLayerId);\n }\n if (mapInstance && mapInstance.getLayer && mapInstance.getLayer(fillLayerId)) {\n mapInstance.removeLayer(fillLayerId);\n }\n if (mapInstance && mapInstance.getSource && mapInstance.getSource(sourceId)) {\n mapInstance.removeSource(sourceId);\n }\n } catch (e) {\n // Map may have been destroyed, ignore cleanup errors\n }\n };\n }, [persistedSelectionPolygon, isMapLoaded]);\n\n // Circle drawing mode (click center, drag radius)\n useEffect(() => {\n if (!map.current || !isMapLoaded || !draw.current) return;\n if (activeMode !== 'draw_circle') {\n // Reset circle drawing state when leaving circle mode\n setCircleDrawCenter(null);\n setCircleDrawPreview(null);\n isDrawingCircle.current = false;\n return;\n }\n \n const mapInstance = map.current;\n const drawInstance = draw.current;\n const canvas = mapInstance.getCanvas();\n \n // Disable map panning during circle drawing\n mapInstance.dragPan.disable();\n canvas.style.cursor = 'crosshair';\n \n let centerPoint: { x: number; y: number; lngLat: [number, number] } | null = null;\n \n const handleMouseDown = (e: MouseEvent) => {\n if (e.button !== 0) return;\n \n const lngLat = mapInstance.unproject([e.offsetX, e.offsetY]);\n centerPoint = { \n x: e.offsetX, \n y: e.offsetY, \n lngLat: [lngLat.lng, lngLat.lat] \n };\n isDrawingCircle.current = true;\n setCircleDrawCenter([lngLat.lng, lngLat.lat]);\n };\n \n const handleMouseMove = (e: MouseEvent) => {\n if (!isDrawingCircle.current || !centerPoint) return;\n \n const edgeLngLat = mapInstance.unproject([e.offsetX, e.offsetY]);\n \n // Calculate radius using turf\n const center = turf.point(centerPoint.lngLat);\n const edge = turf.point([edgeLngLat.lng, edgeLngLat.lat]);\n const radiusKm = turf.distance(center, edge, { units: 'kilometers' });\n \n if (radiusKm > 0.001) { // Minimum 1 meter\n const circle = turf.circle(centerPoint.lngLat, radiusKm, { steps: 64, units: 'kilometers' });\n const coords = circle.geometry.coordinates[0] as [number, number][];\n setCircleDrawPreview(coords);\n }\n };\n \n const handleMouseUp = (e: MouseEvent) => {\n if (!isDrawingCircle.current || !centerPoint) return;\n \n const edgeLngLat = mapInstance.unproject([e.offsetX, e.offsetY]);\n \n // Calculate final radius\n const center = turf.point(centerPoint.lngLat);\n const edge = turf.point([edgeLngLat.lng, edgeLngLat.lat]);\n const radiusKm = turf.distance(center, edge, { units: 'kilometers' });\n \n if (radiusKm > 0.001) { // Minimum 1 meter\n // Create circle polygon\n const circle = turf.circle(centerPoint.lngLat, radiusKm, { steps: 64, units: 'kilometers' });\n \n // Add to MapboxDraw\n const featureId = crypto.randomUUID();\n const circleFeature: GeoJSON.Feature<GeoJSON.Polygon> = {\n type: 'Feature',\n id: featureId,\n properties: {\n kind: 'circle',\n circleCenter: centerPoint.lngLat,\n circleRadius: radiusKm * 1000 // Store in meters\n },\n geometry: circle.geometry\n };\n \n // Add to draw\n drawInstance.add(circleFeature);\n \n // Add to active layer\n const currentActiveEditingLayerId = activeEditingLayerIdRef.current;\n setLayers(prev => {\n let targetLayer = prev.find(l => l.id === currentActiveEditingLayerId && l.visible && !l.readOnly);\n if (!targetLayer) {\n targetLayer = prev.find(l => l.visible && !l.readOnly);\n }\n if (!targetLayer) return prev;\n \n return prev.map(layer => \n layer.id === targetLayer!.id \n ? { ...layer, featureIds: [...layer.featureIds, featureId] }\n : layer\n );\n });\n \n // Sync to custom layers\n syncFeaturesToCustomLayers();\n \n // Update feature count\n const newCount = drawInstance.getAll().features.length;\n setFeatureCount(newCount);\n \n // Save undo state\n setUndoStack(prev => [...prev, {\n features: drawInstance.getAll().features as GeoJSON.Feature[],\n selectedIds: [featureId],\n layers: layersRef.current\n }]);\n setRedoStack([]);\n \n // Select the new feature and reset to pan mode\n drawInstance.changeMode('simple_select', { featureIds: [featureId] });\n setActiveMode('simple_select');\n setSelectedFeatureIds([featureId]);\n if (enableProperties) setShowProperties(true);\n \n // Callback\n if (onFeatureCreate) {\n onFeatureCreate(circleFeature);\n }\n }\n \n // Reset\n centerPoint = null;\n isDrawingCircle.current = false;\n setCircleDrawCenter(null);\n setCircleDrawPreview(null);\n };\n \n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n centerPoint = null;\n isDrawingCircle.current = false;\n setCircleDrawCenter(null);\n setCircleDrawPreview(null);\n setActiveMode('simple_select');\n }\n };\n \n canvas.addEventListener('mousedown', handleMouseDown);\n canvas.addEventListener('mousemove', handleMouseMove);\n canvas.addEventListener('mouseup', handleMouseUp);\n window.addEventListener('keydown', handleKeyDown);\n \n return () => {\n canvas.removeEventListener('mousedown', handleMouseDown);\n canvas.removeEventListener('mousemove', handleMouseMove);\n canvas.removeEventListener('mouseup', handleMouseUp);\n window.removeEventListener('keydown', handleKeyDown);\n \n // Re-enable panning\n if (map.current) {\n map.current.dragPan.enable();\n map.current.getCanvas().style.cursor = '';\n }\n };\n }, [activeMode, isMapLoaded, onFeatureCreate]);\n\n // Rectangle drawing mode (click corner, drag to opposite corner)\n useEffect(() => {\n if (!map.current || !isMapLoaded || !draw.current) return;\n if (activeMode !== 'draw_rectangle') {\n // Reset rectangle drawing state when leaving rectangle mode\n setRectangleDrawCorner(null);\n setRectangleDrawPreview(null);\n isDrawingRectangle.current = false;\n return;\n }\n \n const mapInstance = map.current;\n const drawInstance = draw.current;\n const canvas = mapInstance.getCanvas();\n \n // Disable map panning during rectangle drawing\n mapInstance.dragPan.disable();\n canvas.style.cursor = 'crosshair';\n \n let cornerPoint: { lngLat: [number, number] } | null = null;\n \n const handleMouseDown = (e: MouseEvent) => {\n if (e.button !== 0) return;\n \n const lngLat = mapInstance.unproject([e.offsetX, e.offsetY]);\n cornerPoint = { lngLat: [lngLat.lng, lngLat.lat] };\n isDrawingRectangle.current = true;\n setRectangleDrawCorner([lngLat.lng, lngLat.lat]);\n };\n \n const handleMouseMove = (e: MouseEvent) => {\n if (!isDrawingRectangle.current || !cornerPoint) return;\n \n const oppositeCorner = mapInstance.unproject([e.offsetX, e.offsetY]);\n const [x1, y1] = cornerPoint.lngLat;\n const [x2, y2] = [oppositeCorner.lng, oppositeCorner.lat];\n \n // Create rectangle coordinates (4 corners + closing point)\n const rectCoords: [number, number][] = [\n [x1, y1], // top-left\n [x2, y1], // top-right\n [x2, y2], // bottom-right\n [x1, y2], // bottom-left\n [x1, y1], // close polygon\n ];\n \n setRectangleDrawPreview(rectCoords);\n };\n \n const handleMouseUp = (e: MouseEvent) => {\n if (!isDrawingRectangle.current || !cornerPoint) return;\n \n const oppositeCorner = mapInstance.unproject([e.offsetX, e.offsetY]);\n const [x1, y1] = cornerPoint.lngLat;\n const [x2, y2] = [oppositeCorner.lng, oppositeCorner.lat];\n \n // Check if rectangle has meaningful size\n const width = Math.abs(x2 - x1);\n const height = Math.abs(y2 - y1);\n \n if (width > 0.00001 && height > 0.00001) {\n // Create rectangle polygon\n const rectCoords: [number, number][] = [\n [x1, y1],\n [x2, y1],\n [x2, y2],\n [x1, y2],\n [x1, y1],\n ];\n \n const featureId = crypto.randomUUID();\n const rectFeature: GeoJSON.Feature<GeoJSON.Polygon> = {\n type: 'Feature',\n id: featureId,\n properties: {\n kind: 'rectangle',\n },\n geometry: {\n type: 'Polygon',\n coordinates: [rectCoords],\n },\n };\n \n // Add to draw\n drawInstance.add(rectFeature);\n \n // Add to active layer\n const currentActiveEditingLayerId = activeEditingLayerIdRef.current;\n setLayers(prev => {\n let targetLayer = prev.find(l => l.id === currentActiveEditingLayerId && l.visible && !l.readOnly);\n if (!targetLayer) {\n targetLayer = prev.find(l => l.visible && !l.readOnly);\n }\n if (!targetLayer) return prev;\n \n return prev.map(layer => \n layer.id === targetLayer!.id \n ? { ...layer, featureIds: [...layer.featureIds, featureId] }\n : layer\n );\n });\n \n // Sync to custom layers\n syncFeaturesToCustomLayers();\n \n // Update feature count\n const newCount = drawInstance.getAll().features.length;\n setFeatureCount(newCount);\n \n // Save undo state\n setUndoStack(prev => [...prev, {\n features: drawInstance.getAll().features as GeoJSON.Feature[],\n selectedIds: [featureId],\n layers: layersRef.current\n }]);\n setRedoStack([]);\n \n // Select the new feature and reset to pan mode\n drawInstance.changeMode('simple_select', { featureIds: [featureId] });\n setActiveMode('simple_select');\n setSelectedFeatureIds([featureId]);\n if (enableProperties) setShowProperties(true);\n \n // Callback\n if (onFeatureCreate) {\n onFeatureCreate(rectFeature);\n }\n }\n \n // Reset\n cornerPoint = null;\n isDrawingRectangle.current = false;\n setRectangleDrawCorner(null);\n setRectangleDrawPreview(null);\n };\n \n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n cornerPoint = null;\n isDrawingRectangle.current = false;\n setRectangleDrawCorner(null);\n setRectangleDrawPreview(null);\n setActiveMode('simple_select');\n }\n };\n \n canvas.addEventListener('mousedown', handleMouseDown);\n canvas.addEventListener('mousemove', handleMouseMove);\n canvas.addEventListener('mouseup', handleMouseUp);\n window.addEventListener('keydown', handleKeyDown);\n \n return () => {\n canvas.removeEventListener('mousedown', handleMouseDown);\n canvas.removeEventListener('mousemove', handleMouseMove);\n canvas.removeEventListener('mouseup', handleMouseUp);\n window.removeEventListener('keydown', handleKeyDown);\n \n // Re-enable panning\n if (map.current) {\n map.current.dragPan.enable();\n map.current.getCanvas().style.cursor = '';\n }\n };\n }, [activeMode, isMapLoaded, onFeatureCreate]);\n\n // Measurement mode mouse handlers\n const measurePointsRef = useRef<[number, number][]>([]);\n useEffect(() => {\n measurePointsRef.current = measurePoints;\n }, [measurePoints]);\n\n useEffect(() => {\n if (!map.current || !isMapLoaded || measureMode === 'none') return;\n \n const mapInstance = map.current;\n const canvas = mapInstance.getCanvas();\n \n // Set cursor to crosshair for measurement\n canvas.style.cursor = 'crosshair';\n \n const handleClick = (e: MouseEvent) => {\n const lngLat = mapInstance.unproject([e.offsetX, e.offsetY]);\n const newPoint: [number, number] = [lngLat.lng, lngLat.lat];\n \n setMeasurePoints(prev => {\n const updated = [...prev, newPoint];\n \n // Calculate result based on mode\n if (measureMode === 'distance' && updated.length >= 2) {\n const line = turf.lineString(updated);\n const distance = turf.length(line, { units: 'kilometers' });\n if (distance < 1) {\n setMeasureResult(`${(distance * 1000).toFixed(1)} m`);\n } else {\n setMeasureResult(`${distance.toFixed(2)} km`);\n }\n } else if (measureMode === 'area' && updated.length >= 3) {\n const closed = [...updated, updated[0]];\n const polygon = turf.polygon([closed]);\n const area = turf.area(polygon);\n if (area < 10000) {\n setMeasureResult(`${area.toFixed(1)} m²`);\n } else if (area < 1000000) {\n setMeasureResult(`${(area / 10000).toFixed(2)} ha`);\n } else {\n setMeasureResult(`${(area / 1000000).toFixed(2)} km²`);\n }\n }\n \n return updated;\n });\n };\n \n const handleDblClick = (e: MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n // Clear measurement on double-click\n setMeasurePoints([]);\n setMeasureResult(null);\n };\n \n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n setMeasurePoints([]);\n setMeasureResult(null);\n }\n };\n \n canvas.addEventListener('click', handleClick);\n canvas.addEventListener('dblclick', handleDblClick);\n window.addEventListener('keydown', handleKeyDown);\n \n return () => {\n canvas.style.cursor = '';\n canvas.removeEventListener('click', handleClick);\n canvas.removeEventListener('dblclick', handleDblClick);\n window.removeEventListener('keydown', handleKeyDown);\n };\n }, [measureMode, isMapLoaded]);\n\n // Render measurement overlay on the map\n useEffect(() => {\n if (!map.current || !isMapLoaded) return;\n \n const mapInstance = map.current;\n const sourceId = 'measure-overlay';\n const lineLayerId = 'measure-line';\n const pointsLayerId = 'measure-points';\n \n // Add source if it doesn't exist\n if (!mapInstance.getSource(sourceId)) {\n mapInstance.addSource(sourceId, {\n type: 'geojson',\n data: { type: 'FeatureCollection', features: [] }\n });\n \n mapInstance.addLayer({\n id: lineLayerId,\n type: 'line',\n source: sourceId,\n filter: ['==', '$type', 'LineString'],\n paint: {\n 'line-color': '#ef4444',\n 'line-width': 2,\n 'line-dasharray': [4, 2]\n }\n });\n \n mapInstance.addLayer({\n id: pointsLayerId,\n type: 'circle',\n source: sourceId,\n filter: ['==', '$type', 'Point'],\n paint: {\n 'circle-radius': 5,\n 'circle-color': '#ef4444',\n 'circle-stroke-color': '#fff',\n 'circle-stroke-width': 2\n }\n });\n }\n \n // Update the source data based on measurePoints\n const features: GeoJSON.Feature[] = [];\n \n if (measurePoints.length > 0) {\n // Add points\n measurePoints.forEach((pt, i) => {\n features.push({\n type: 'Feature',\n properties: { index: i },\n geometry: { type: 'Point', coordinates: pt }\n });\n });\n \n // Add line if we have 2+ points\n if (measurePoints.length >= 2) {\n if (measureMode === 'area' && measurePoints.length >= 3) {\n // Close the polygon for area mode\n features.push({\n type: 'Feature',\n properties: {},\n geometry: { type: 'LineString', coordinates: [...measurePoints, measurePoints[0]] }\n });\n } else {\n features.push({\n type: 'Feature',\n properties: {},\n geometry: { type: 'LineString', coordinates: measurePoints }\n });\n }\n }\n }\n \n const source = mapInstance.getSource(sourceId) as maplibregl.GeoJSONSource | undefined;\n if (source) {\n source.setData({ type: 'FeatureCollection', features });\n }\n }, [measurePoints, measureMode, isMapLoaded]);\n\n const handleSaveLayerGeoJSON = useCallback((layerId: string) => {\n const layer = layers.find(l => l.id === layerId);\n if (!layer || !draw.current) return;\n \n const features: GeoJSON.Feature[] = [];\n \n if (layer.visible) {\n layer.featureIds.forEach(id => {\n const f = draw.current!.get(id);\n if (f) features.push(f as GeoJSON.Feature);\n });\n } else {\n const hidden = hiddenFeatures.current.get(layerId) || [];\n features.push(...hidden);\n }\n \n // Include layer metadata in the export\n const layerMetadata: Record<string, unknown> = {\n name: layer.name,\n };\n if (layer.traceConfig) layerMetadata.traceConfig = layer.traceConfig;\n if (layer.heatmapConfig) layerMetadata.heatmapConfig = layer.heatmapConfig;\n if (layer.visualConfig) layerMetadata.visualConfig = layer.visualConfig;\n \n // Strip internal properties (prefixed with _) from exported features\n const cleanedFeatures = features.map(f => ({\n ...f,\n properties: Object.fromEntries(\n Object.entries(f.properties || {}).filter(([key]) => !key.startsWith('_'))\n ),\n }));\n \n const geojson = {\n type: 'FeatureCollection' as const,\n features: cleanedFeatures,\n properties: {\n layerMetadata,\n },\n };\n \n const blob = new Blob([JSON.stringify(geojson, null, 2)], { type: 'application/json' });\n saveAs(blob, `${layer.name.replace(/[^a-z0-9]/gi, '_')}.geojson`);\n }, [layers]);\n\n const handleLoadLayerGeoJSON = useCallback((layerId: string) => {\n const input = fileInputRef.current;\n if (!input) return;\n \n input.dataset.targetLayer = layerId;\n input.dataset.createNewLayer = '';\n input.click();\n }, []);\n\n const handleLoadNewLayerGeoJSON = useCallback(() => {\n const input = fileInputRef.current;\n if (!input) return;\n \n input.dataset.targetLayer = '';\n input.dataset.createNewLayer = 'true';\n input.click();\n }, []);\n\n const handleSaveAllGeoJSON = useCallback(() => {\n if (!draw.current) return;\n \n const allFeatures: GeoJSON.Feature[] = [];\n const layersMetadata: Record<string, unknown>[] = [];\n \n layers.forEach(layer => {\n // Collect features with layer ID added to properties\n if (layer.visible) {\n layer.featureIds.forEach(id => {\n const f = draw.current!.get(id);\n if (f) {\n const featureWithLayer = {\n ...f,\n properties: {\n ...f.properties,\n _layerId: layer.id,\n },\n };\n allFeatures.push(featureWithLayer as GeoJSON.Feature);\n }\n });\n } else {\n const hidden = hiddenFeatures.current.get(layer.id) || [];\n hidden.forEach(f => {\n const featureWithLayer = {\n ...f,\n properties: {\n ...f.properties,\n _layerId: layer.id,\n },\n };\n allFeatures.push(featureWithLayer as GeoJSON.Feature);\n });\n }\n \n // Collect layer metadata\n const layerMeta: Record<string, unknown> = {\n id: layer.id,\n name: layer.name,\n };\n if (layer.traceConfig) layerMeta.traceConfig = layer.traceConfig;\n if (layer.heatmapConfig) layerMeta.heatmapConfig = layer.heatmapConfig;\n if (layer.visualConfig) layerMeta.visualConfig = layer.visualConfig;\n layersMetadata.push(layerMeta);\n });\n \n // Strip internal properties (prefixed with _) from exported features, except _layerId which is used for restore\n const cleanedFeatures = allFeatures.map(f => ({\n ...f,\n properties: Object.fromEntries(\n Object.entries(f.properties || {}).filter(([key]) => !key.startsWith('_') || key === '_layerId')\n ),\n }));\n \n const geojson = {\n type: 'FeatureCollection' as const,\n features: cleanedFeatures,\n properties: {\n layers: layersMetadata,\n },\n };\n \n const blob = new Blob([JSON.stringify(geojson, null, 2)], { type: 'application/json' });\n saveAs(blob, 'map_export.geojson');\n }, [layers]);\n\n // Handler for \"Search and add...\" button in New Layer row\n // Uses same pattern as addLayer + addFeatures in imperative handle\n const handleSearchAndAddToNewLayer = useCallback(async () => {\n if (!onSearchEngineRequest || !map.current || !draw.current) return;\n \n const mapInstance = map.current;\n const center = mapInstance.getCenter();\n const zoom = mapInstance.getZoom();\n const bounds = mapInstance.getBounds();\n \n const rawBounds: [number, number, number, number] = [\n bounds.getWest(),\n bounds.getSouth(),\n bounds.getEast(),\n bounds.getNorth()\n ];\n \n const queryBounds = {\n minLng: Math.max(-180, Math.min(180, rawBounds[0])),\n maxLng: Math.max(-180, Math.min(180, rawBounds[2])),\n minLat: Math.max(-90, Math.min(90, rawBounds[1])),\n maxLat: Math.max(-90, Math.min(90, rawBounds[3]))\n };\n \n const viewport = {\n center: [center.lng, center.lat] as [number, number],\n zoom,\n bounds: rawBounds,\n queryBounds,\n };\n \n try {\n const result = await onSearchEngineRequest({\n viewport,\n activeLayerId: null, // Creating new layer\n });\n \n if (result && result.features && result.features.length > 0) {\n saveStateForUndo();\n \n // Auto-generate layer name based on feature count\n const layerName = `${result.features.length} workspace features`;\n const newLayerId = `layer-${Date.now()}`;\n \n // Add features using same pattern as addFeatures in imperative handle\n const addedIds: string[] = [];\n // Mark as API adding so draw.create doesn't set _unsaved flag\n isApiAddingRef.current = true;\n try {\n result.features.forEach(f => {\n const { startDate, endDate } = normalizeTemporalProperties(f.properties || {});\n const normalizedFeature = {\n ...f,\n properties: {\n ...f.properties,\n startDate: startDate?.toISOString() || null,\n endDate: endDate?.toISOString() || null,\n }\n };\n const ids = draw.current!.add(normalizedFeature);\n addedIds.push(ids[0]);\n });\n } finally {\n isApiAddingRef.current = false;\n }\n \n // Create new layer with the added feature IDs\n const newLayer: Layer = {\n id: newLayerId,\n name: layerName,\n visible: true,\n featureIds: addedIds,\n };\n \n // Update layers state \n layersRef.current = [...layersRef.current, newLayer];\n setLayers(layersRef.current);\n setActiveEditingLayerId(newLayerId);\n \n updateFeatureCount();\n updateTimelineStore();\n syncFeaturesToCustomLayers();\n \n toast({\n title: 'Layer created',\n description: `Added ${result.features.length} features to \"${layerName}\"`,\n });\n }\n } catch (error) {\n toast({\n title: 'Search failed',\n description: error instanceof Error ? error.message : 'Failed to search data source',\n variant: 'destructive',\n });\n }\n }, [onSearchEngineRequest, saveStateForUndo, updateFeatureCount, updateTimelineStore, syncFeaturesToCustomLayers, toast]);\n\n // Handler for workspace load (external file picker)\n // Uses same pattern as addFeatures in imperative handle\n const handleWorkspaceLoad = useCallback(async (layerId: string) => {\n if (!onWorkspaceLoad || !draw.current) return;\n \n const layer = layersRef.current.find(l => l.id === layerId);\n if (!layer) return;\n \n try {\n const result = await onWorkspaceLoad(layerId);\n if (result && result.features && result.features.length > 0) {\n saveStateForUndo();\n \n // Add features using same pattern as addFeatures in imperative handle\n const addedIds: string[] = [];\n // Mark as API adding so draw.create doesn't set _unsaved flag\n isApiAddingRef.current = true;\n try {\n result.features.forEach(f => {\n const { startDate, endDate } = normalizeTemporalProperties(f.properties || {});\n const normalizedFeature = {\n ...f,\n properties: {\n ...f.properties,\n startDate: startDate?.toISOString() || null,\n endDate: endDate?.toISOString() || null,\n }\n };\n const ids = draw.current!.add(normalizedFeature);\n addedIds.push(ids[0]);\n });\n } finally {\n isApiAddingRef.current = false;\n }\n \n // Update layer with new features\n layersRef.current = layersRef.current.map(l =>\n l.id === layerId ? { ...l, featureIds: [...l.featureIds, ...addedIds] } : l\n );\n setLayers(layersRef.current);\n \n updateFeatureCount();\n updateTimelineStore();\n syncFeaturesToCustomLayers();\n \n toast({\n title: 'Features loaded',\n description: `Added ${result.features.length} features to \"${layer.name}\"`,\n });\n }\n } catch (error) {\n toast({\n title: 'Load failed',\n description: error instanceof Error ? error.message : 'Failed to load from workspace',\n variant: 'destructive',\n });\n }\n }, [onWorkspaceLoad, saveStateForUndo, updateFeatureCount, updateTimelineStore, syncFeaturesToCustomLayers, toast]);\n\n // Handler for workspace save (external file saver)\n const handleWorkspaceSave = useCallback(async (layerId: string) => {\n if (!onWorkspaceSave) return;\n \n const layer = layersRef.current.find(l => l.id === layerId);\n if (!layer) return;\n \n // Collect features from the layer (same pattern as handleSaveLayerGeoJSON)\n const features: GeoJSON.Feature[] = [];\n if (layer.visible && draw.current) {\n layer.featureIds.forEach(id => {\n const f = draw.current!.get(id);\n if (f) features.push(f as GeoJSON.Feature);\n });\n } else {\n const hidden = hiddenFeatures.current.get(layerId) || [];\n features.push(...hidden);\n }\n \n // Also check read-only features\n const roFeatures = readOnlyFeatures.current.get(layerId);\n if (roFeatures) {\n features.push(...roFeatures);\n }\n \n // Strip internal properties (prefixed with _) from exported features\n const cleanedFeatures = features.map(f => ({\n ...f,\n properties: Object.fromEntries(\n Object.entries(f.properties || {}).filter(([key]) => !key.startsWith('_'))\n ),\n }));\n \n const geojson: GeoJSON.FeatureCollection = {\n type: 'FeatureCollection',\n features: cleanedFeatures,\n };\n \n try {\n await onWorkspaceSave(layerId, geojson);\n \n // Clear _unsaved flag on all features in this layer after successful save\n if (layer.visible && draw.current) {\n layer.featureIds.forEach(id => {\n const feature = draw.current!.get(id);\n if (feature?.properties?._unsaved) {\n draw.current!.setFeatureProperty(id, '_unsaved', undefined);\n }\n });\n } else {\n // Update hidden features\n const hidden = hiddenFeatures.current.get(layerId) || [];\n const updatedHidden = hidden.map(f => ({\n ...f,\n properties: {\n ...f.properties,\n _unsaved: undefined,\n },\n }));\n hiddenFeatures.current.set(layerId, updatedHidden);\n }\n \n // Force re-render to update unsaved counts\n setLayers(prev => [...prev]);\n \n toast({\n title: 'Saved',\n description: `Saved ${features.length} features to workspace`,\n });\n } catch (error) {\n // Only show error toast if it's not a user cancellation\n const errorMessage = error instanceof Error ? error.message : 'Failed to save to workspace';\n if (!errorMessage.includes('cancelled')) {\n toast({\n title: 'Save failed',\n description: errorMessage,\n variant: 'destructive',\n });\n }\n }\n }, [onWorkspaceSave, toast]);\n\n const handleFitToFeatures = useCallback(() => {\n if (!map.current || !draw.current) return;\n \n // Collect all features (visible and hidden)\n const allFeatures: GeoJSON.Feature[] = [];\n \n layers.forEach(layer => {\n if (layer.visible) {\n layer.featureIds.forEach(id => {\n const f = draw.current!.get(id);\n if (f) allFeatures.push(f as GeoJSON.Feature);\n });\n } else {\n const hidden = hiddenFeatures.current.get(layer.id) || [];\n allFeatures.push(...hidden);\n }\n });\n \n if (allFeatures.length === 0) {\n toast({\n title: \"No features\",\n description: \"There are no features to fit to\",\n });\n return;\n }\n \n const fc: GeoJSON.FeatureCollection = {\n type: 'FeatureCollection',\n features: allFeatures,\n };\n \n const bbox = turf.bbox(fc);\n map.current.fitBounds([[bbox[0], bbox[1]], [bbox[2], bbox[3]]], { \n padding: 80,\n maxZoom: 16,\n });\n }, [layers, toast]);\n\n const handleFileChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (!file || !draw.current) return;\n \n // Get target layer from dataset or active editing layer\n const requestedTargetLayerId = e.target.dataset.targetLayer || activeEditingLayerId;\n const createNewLayer = e.target.dataset.createNewLayer === 'true';\n \n // Clear the flags\n delete e.target.dataset.createNewLayer;\n \n const reader = new FileReader();\n reader.onload = (event) => {\n try {\n const rawGeojson = JSON.parse(event.target?.result as string) as GeoJSON.FeatureCollection & { \n properties?: { \n layerMetadata?: {\n name?: string;\n traceConfig?: TraceConfig;\n heatmapConfig?: HeatmapConfig;\n visualConfig?: VisualConfig;\n };\n };\n };\n \n if (rawGeojson.type !== 'FeatureCollection' || !Array.isArray(rawGeojson.features)) {\n throw new Error('Invalid GeoJSON format');\n }\n \n if (rawGeojson.features.length === 0) {\n toast({\n title: \"Empty GeoJSON\",\n description: \"The file contains no features\",\n variant: \"destructive\",\n });\n return;\n }\n \n // Detect CRS and reproject to WGS84 if needed\n const { features: geojson, reprojected, sourceCRS } = detectAndReprojectGeoJSON(rawGeojson);\n \n saveStateForUndo();\n \n // Extract layer metadata if present\n const layerMetadata = rawGeojson.properties?.layerMetadata;\n \n // Normalize features\n const normalizedFeatures = geojson.features.map(f => {\n const { startDate, endDate } = normalizeTemporalProperties(f.properties || {});\n return {\n ...f,\n properties: {\n ...f.properties,\n startDate: startDate?.toISOString() || null,\n endDate: endDate?.toISOString() || null,\n }\n };\n });\n \n if (createNewLayer) {\n // Create a new READ-ONLY layer from the file for performance\n const fileName = file.name.replace(/\\.geojson$|\\.json$/i, '');\n const layerId = `layer-${Date.now()}`;\n \n const newLayer: Layer = {\n id: layerId,\n name: layerMetadata?.name || fileName,\n visible: true,\n featureIds: [],\n readOnly: true, // High-performance mode by default\n ...(layerMetadata?.traceConfig && { traceConfig: layerMetadata.traceConfig }),\n ...(layerMetadata?.heatmapConfig && { heatmapConfig: layerMetadata.heatmapConfig }),\n ...(layerMetadata?.visualConfig && { visualConfig: layerMetadata.visualConfig }),\n };\n \n // Assign unique IDs and store in read-only storage\n const addedIds: string[] = [];\n const featuresWithIds: GeoJSON.Feature[] = [];\n normalizedFeatures.forEach(f => {\n const featureId = f.id ? String(f.id) : crypto.randomUUID();\n const normalizedFeature = { ...f, id: featureId };\n featuresWithIds.push(normalizedFeature);\n addedIds.push(featureId);\n });\n \n // Store in read-only features ref (not MapboxDraw)\n readOnlyFeatures.current.set(layerId, featuresWithIds);\n newLayer.featureIds = addedIds;\n \n setLayers(prev => [...prev, newLayer]);\n // Don't set active editing layer for read-only layers\n updateFeatureCount();\n updateTimelineStore();\n syncFeaturesToCustomLayers();\n \n // Fly to the new features\n if (map.current && geojson.features.length > 0) {\n try {\n const bbox = turf.bbox(geojson);\n if (bbox && bbox.every(v => isFinite(v))) {\n map.current.fitBounds(\n [[bbox[0], bbox[1]], [bbox[2], bbox[3]]],\n { padding: 50, maxZoom: 16, duration: 1000 }\n );\n }\n } catch (e) {\n // Silently fail if bbox calculation fails\n }\n }\n \n const reprojectMsg = reprojected ? ` (reprojected from ${sourceCRS})` : '';\n toast({\n title: \"Layer created\",\n description: `Created \"${newLayer.name}\" with ${addedIds.length} features${reprojectMsg} (high-performance mode)`,\n });\n return;\n }\n \n // Find the target layer - must be visible and not read-only for loading\n let targetLayer = layers.find(l => l.id === requestedTargetLayerId && !l.readOnly);\n \n // If no valid target, find first visible writable layer\n if (!targetLayer) {\n targetLayer = layers.find(l => l.visible && !l.readOnly);\n }\n \n // If still no valid layer, fall back to default\n if (!targetLayer) {\n targetLayer = layers.find(l => l.id === 'default');\n }\n \n if (targetLayer?.visible) {\n // Layer is visible - add to MapboxDraw\n const addedIds: string[] = [];\n // Mark as API adding so draw.create doesn't set _unsaved flag\n isApiAddingRef.current = true;\n try {\n normalizedFeatures.forEach(f => {\n const ids = draw.current!.add(f);\n addedIds.push(ids[0]);\n });\n } finally {\n isApiAddingRef.current = false;\n }\n \n const targetId = targetLayer.id;\n setLayers(prev => prev.map(l => {\n if (l.id !== targetId) return l;\n // Apply layer metadata if present\n return {\n ...l,\n featureIds: [...l.featureIds, ...addedIds],\n ...(layerMetadata?.traceConfig && { traceConfig: layerMetadata.traceConfig }),\n ...(layerMetadata?.heatmapConfig && { heatmapConfig: layerMetadata.heatmapConfig }),\n ...(layerMetadata?.visualConfig && { visualConfig: layerMetadata.visualConfig }),\n };\n }));\n } else if (targetLayer) {\n // Layer is hidden - add to hiddenFeatures\n const featuresWithIds = normalizedFeatures.map(f => ({\n ...f,\n id: f.id || `feature-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,\n })) as GeoJSON.Feature[];\n \n const targetId = targetLayer.id;\n const addedIds = featuresWithIds.map(f => f.id as string);\n const existing = hiddenFeatures.current.get(targetId) || [];\n hiddenFeatures.current.set(targetId, [...existing, ...featuresWithIds]);\n \n setLayers(prev => prev.map(l => {\n if (l.id !== targetId) return l;\n // Apply layer metadata if present\n return {\n ...l,\n featureIds: [...l.featureIds, ...addedIds],\n ...(layerMetadata?.traceConfig && { traceConfig: layerMetadata.traceConfig }),\n ...(layerMetadata?.heatmapConfig && { heatmapConfig: layerMetadata.heatmapConfig }),\n ...(layerMetadata?.visualConfig && { visualConfig: layerMetadata.visualConfig }),\n };\n }));\n }\n \n updateFeatureCount();\n updateTimelineStore();\n syncFeaturesToCustomLayers();\n \n const reprojectMsg = reprojected ? ` (reprojected from ${sourceCRS})` : '';\n toast({\n title: \"GeoJSON loaded\",\n description: `Added ${normalizedFeatures.length} features${reprojectMsg}${!targetLayer?.visible ? ' (layer hidden)' : ''}`,\n });\n } catch (error) {\n toast({\n title: \"Failed to load GeoJSON\",\n description: error instanceof Error ? error.message : 'Invalid file',\n variant: \"destructive\",\n });\n }\n };\n reader.readAsText(file);\n \n e.target.value = '';\n }, [layers, activeEditingLayerId, saveStateForUndo, updateFeatureCount, updateTimelineStore, syncFeaturesToCustomLayers, toast]);\n\n const handleDropGeoJSON = useCallback((name: string, data: GeoJSON.FeatureCollection & {\n properties?: {\n layerMetadata?: {\n name?: string;\n traceConfig?: TraceConfig;\n heatmapConfig?: HeatmapConfig;\n visualConfig?: VisualConfig;\n };\n };\n }) => {\n if (!map.current) return;\n \n // Detect CRS and reproject to WGS84 if needed\n const { features: reprojectedData, reprojected, sourceCRS } = detectAndReprojectGeoJSON(data);\n \n saveStateForUndo();\n \n // Extract layer metadata if present\n const layerMetadata = data.properties?.layerMetadata;\n const layerId = `layer-${Date.now()}`;\n \n // Check if any features have altitude data\n const layerHasAltitudeData = reprojectedData.features.some(f => hasAltitudeData(f));\n \n const newLayer: Layer = {\n id: layerId,\n name: layerMetadata?.name || name,\n visible: true,\n featureIds: [],\n readOnly: true, // Dropped layers are read-only for performance\n ...(layerMetadata?.traceConfig && { traceConfig: layerMetadata.traceConfig }),\n ...(layerMetadata?.heatmapConfig && { heatmapConfig: layerMetadata.heatmapConfig }),\n ...(layerMetadata?.visualConfig && { visualConfig: layerMetadata.visualConfig }),\n ...(layerHasAltitudeData && { hasAltitudeData: true, altitudeDisplayMode: 'both' as AltitudeDisplayMode }),\n };\n \n // Store features in readOnlyFeatures ref (bypasses MapboxDraw for performance)\n const normalizedFeatures: GeoJSON.Feature[] = [];\n const addedIds: string[] = [];\n \n reprojectedData.features.forEach((f, index) => {\n const { startDate, endDate } = normalizeTemporalProperties(f.properties || {});\n // Generate unique ID for each feature\n const featureId = f.id !== undefined && f.id !== null \n ? String(f.id) \n : `${layerId}-f${index}`;\n \n const normalizedFeature: GeoJSON.Feature = {\n ...f,\n id: featureId,\n properties: {\n ...f.properties,\n startDate: startDate?.toISOString() || null,\n endDate: endDate?.toISOString() || null,\n }\n };\n normalizedFeatures.push(normalizedFeature);\n addedIds.push(featureId);\n });\n \n // Store in read-only features ref (not MapboxDraw)\n readOnlyFeatures.current.set(layerId, normalizedFeatures);\n newLayer.featureIds = addedIds;\n \n // Build the new layers array and update ref BEFORE calling update functions\n // This ensures updateTimelineStore/syncFeaturesToCustomLayers see the new layer immediately\n const nextLayers = [...layersRef.current, newLayer];\n layersRef.current = nextLayers;\n setLayers(nextLayers);\n \n // Don't set active editing layer for read-only dropped layers\n updateFeatureCount();\n updateTimelineStore();\n syncFeaturesToCustomLayers();\n \n // Fly to the new features\n if (reprojectedData.features.length > 0) {\n try {\n const bbox = turf.bbox(reprojectedData);\n if (bbox && bbox.every(v => isFinite(v))) {\n map.current.fitBounds(\n [[bbox[0], bbox[1]], [bbox[2], bbox[3]]],\n { padding: 50, maxZoom: 16, duration: 1000 }\n );\n }\n } catch (e) {\n // Silently fail if bbox calculation fails\n }\n }\n \n const reprojectMsg = reprojected ? ` (reprojected from ${sourceCRS})` : '';\n toast({\n title: \"Layer added\",\n description: `Created \"${newLayer.name}\" with ${addedIds.length} features${reprojectMsg} (read-only)`,\n });\n }, [saveStateForUndo, updateFeatureCount, updateTimelineStore, syncFeaturesToCustomLayers, toast]);\n\n const handleTimelineFilterChange = useCallback((visibleIds: string[], hiddenIds: string[], untimedIds: string[]) => {\n if (!draw.current || !map.current) return;\n \n // Store visible IDs for custom layer sync\n timelineVisibleIdsRef.current = new Set([...visibleIds, ...untimedIds]);\n \n // Sync custom layers with timeline visibility (also updates traces)\n syncFeaturesToCustomLayers();\n }, [syncFeaturesToCustomLayers]);\n\n // Track previous timeline enabled state to detect open/close transitions\n const prevTimelineEnabledRef = useRef(timelineStore.isEnabled);\n \n // Effect to handle timeline open/close\n useEffect(() => {\n const wasEnabled = prevTimelineEnabledRef.current;\n const isNowEnabled = timelineStore.isEnabled;\n prevTimelineEnabledRef.current = isNowEnabled;\n \n if (!isNowEnabled || !timelineStore.hasTemporalData) {\n // Clear the filter - show all features\n timelineVisibleIdsRef.current = null;\n syncFeaturesToCustomLayers();\n } else if (!wasEnabled && isNowEnabled) {\n // Timeline just opened - refresh timeline data to ensure it's up to date\n updateTimelineStore();\n }\n }, [timelineStore.isEnabled, timelineStore.hasTemporalData, syncFeaturesToCustomLayers, updateTimelineStore]);\n\n // Effect to render heatmap layers for layers with heatmapConfig enabled\n useEffect(() => {\n if (!map.current || !draw.current || !isMapLoaded) return;\n\n const mapInstance = map.current;\n const drawInstance = draw.current;\n\n const rebuildHeatmaps = () => {\n if (!mapInstance.isStyleLoaded()) {\n mapInstance.once('idle', rebuildHeatmaps);\n return;\n }\n\n // Clean up old heatmap sources/layers\n layers.forEach(layer => {\n const sourceId = `heatmap-source-${layer.id}`;\n const heatmapLayerId = `heatmap-layer-${layer.id}`;\n\n try {\n if (mapInstance.getLayer(heatmapLayerId)) {\n mapInstance.removeLayer(heatmapLayerId);\n }\n if (mapInstance.getSource(sourceId)) {\n mapInstance.removeSource(sourceId);\n }\n } catch {}\n });\n\n // Build heatmaps for layers with heatmapConfig enabled\n layers.forEach(layer => {\n if (!layer.heatmapConfig?.enabled) return;\n\n const sourceId = `heatmap-source-${layer.id}`;\n const heatmapLayerId = `heatmap-layer-${layer.id}`;\n\n // Get point features for this layer (from draw, read-only storage, or hidden storage)\n let pointFeatures: GeoJSON.Feature[] = [];\n if (layer.visible) {\n if (layer.readOnly) {\n // Read-only layers store features in readOnlyFeatures ref\n const roFeatures = readOnlyFeatures.current.get(layer.id) || [];\n pointFeatures = roFeatures.filter(f => f.geometry?.type === 'Point');\n } else {\n // Editable layers use MapboxDraw\n layer.featureIds.forEach(id => {\n const f = drawInstance.get(id);\n if (f && f.geometry?.type === 'Point') {\n pointFeatures.push(f);\n }\n });\n }\n } else {\n const hidden = hiddenFeatures.current.get(layer.id) || [];\n pointFeatures = hidden.filter(f => f.geometry?.type === 'Point');\n }\n\n if (pointFeatures.length === 0) return;\n\n const { intensity, radius } = layer.heatmapConfig;\n\n try {\n mapInstance.addSource(sourceId, {\n type: 'geojson',\n data: { type: 'FeatureCollection', features: pointFeatures },\n });\n\n mapInstance.addLayer({\n id: heatmapLayerId,\n type: 'heatmap',\n source: sourceId,\n paint: {\n 'heatmap-weight': 1,\n 'heatmap-intensity': [\n 'interpolate', ['linear'], ['zoom'],\n 0, intensity * 0.5,\n 9, intensity * 3\n ],\n 'heatmap-color': [\n 'interpolate', ['linear'], ['heatmap-density'],\n 0, 'rgba(33,102,172,0)',\n 0.2, 'rgb(103,169,207)',\n 0.4, 'rgb(209,229,240)',\n 0.6, 'rgb(253,219,199)',\n 0.8, 'rgb(239,138,98)',\n 1, 'rgb(178,24,43)'\n ],\n 'heatmap-radius': [\n 'interpolate', ['linear'], ['zoom'],\n 0, radius / 2,\n 9, radius * 1.5\n ],\n 'heatmap-opacity': 0.8,\n },\n });\n } catch {}\n });\n };\n\n rebuildHeatmaps();\n\n const handleStyleLoad = () => {\n mapInstance.once('idle', rebuildHeatmaps);\n };\n mapInstance.on('style.load', handleStyleLoad);\n\n return () => {\n try {\n mapInstance.off('style.load', handleStyleLoad);\n } catch {\n // Map may already be destroyed\n }\n };\n }, [isMapLoaded, layers, currentMapStyle]);\n\n // Effect to render cluster layers for layers with clusterConfig enabled\n useEffect(() => {\n if (!map.current || !draw.current || !isMapLoaded) return;\n\n const mapInstance = map.current;\n const drawInstance = draw.current;\n\n const rebuildClusters = () => {\n if (!mapInstance.isStyleLoaded()) {\n mapInstance.once('idle', rebuildClusters);\n return;\n }\n\n // Clean up old cluster sources/layers and pie managers\n layers.forEach(layer => {\n const sourceId = `cluster-source-${layer.id}`;\n const clustersLayerId = `clusters-${layer.id}`;\n const clusterCountLayerId = `cluster-count-${layer.id}`;\n const unclusteredLayerId = `unclustered-point-${layer.id}`;\n\n // Destroy any existing pie manager for this layer\n const existingPieManager = clusterPieManagers.current.get(layer.id);\n if (existingPieManager) {\n existingPieManager.destroy();\n clusterPieManagers.current.delete(layer.id);\n }\n\n try {\n if (mapInstance.getLayer(clusterCountLayerId)) {\n mapInstance.removeLayer(clusterCountLayerId);\n }\n if (mapInstance.getLayer(clustersLayerId)) {\n mapInstance.removeLayer(clustersLayerId);\n }\n if (mapInstance.getLayer(unclusteredLayerId)) {\n mapInstance.removeLayer(unclusteredLayerId);\n }\n if (mapInstance.getSource(sourceId)) {\n mapInstance.removeSource(sourceId);\n }\n } catch {}\n });\n\n // Build clusters for layers with clusterConfig enabled AND visible\n layers.forEach(layer => {\n if (!layer.clusterConfig?.enabled || !layer.visible) return;\n\n const sourceId = `cluster-source-${layer.id}`;\n const clustersLayerId = `clusters-${layer.id}`;\n const clusterCountLayerId = `cluster-count-${layer.id}`;\n const unclusteredLayerId = `unclustered-point-${layer.id}`;\n\n // Get point features for this layer (from draw, read-only storage, or hidden storage)\n let pointFeatures: GeoJSON.Feature[] = [];\n if (layer.visible) {\n if (layer.readOnly) {\n const roFeatures = readOnlyFeatures.current.get(layer.id) || [];\n pointFeatures = roFeatures.filter(f => f.geometry?.type === 'Point');\n } else {\n layer.featureIds.forEach(id => {\n const f = drawInstance.get(id);\n if (f && f.geometry?.type === 'Point') {\n pointFeatures.push(f);\n }\n });\n }\n } else {\n const hidden = hiddenFeatures.current.get(layer.id) || [];\n pointFeatures = hidden.filter(f => f.geometry?.type === 'Point');\n }\n\n if (pointFeatures.length === 0) return;\n\n const groupByField = layer.clusterConfig?.groupByField;\n \n // Category color palette for pie charts\n const categoryColors = [\n '#3b82f6', '#ef4444', '#22c55e', '#f59e0b', '#8b5cf6', \n '#ec4899', '#06b6d4', '#f97316', '#84cc16', '#6366f1',\n '#14b8a6', '#d946ef', '#0ea5e9', '#a855f7', '#10b981',\n ];\n\n try {\n // Get layer color for styling (use visual config color or default)\n const layerColor = layer.visualConfig?.color?.fixedColor || '#3b82f6';\n \n // Build cluster properties for category aggregation if groupByField is set\n let clusterProperties: Record<string, any> = {};\n let categoryValues: string[] = [];\n let categoryColorMap: Record<string, string> = {};\n \n if (groupByField) {\n // Collect unique category values from features\n const uniqueCategories = new Set<string>();\n pointFeatures.forEach(f => {\n const val = f.properties?.[groupByField];\n if (val !== undefined && val !== null) {\n uniqueCategories.add(String(val));\n }\n });\n categoryValues = Array.from(uniqueCategories).slice(0, 15); // Limit to 15 categories\n \n // Assign colors to categories\n categoryValues.forEach((cat, i) => {\n categoryColorMap[cat] = categoryColors[i % categoryColors.length];\n // Create aggregation expression for this category\n clusterProperties[`cat_${i}`] = [\n '+',\n ['case', ['==', ['get', groupByField], cat], 1, 0]\n ];\n });\n }\n\n // Create cluster source with automatic clustering\n mapInstance.addSource(sourceId, {\n type: 'geojson',\n data: { type: 'FeatureCollection', features: pointFeatures },\n cluster: true,\n clusterMaxZoom: 14,\n clusterRadius: 50,\n ...(Object.keys(clusterProperties).length > 0 ? { clusterProperties } : {}),\n });\n\n if (groupByField && categoryValues.length > 0) {\n // CATEGORY MODE: Use DOM-based SVG pie chart markers\n // Create pie chart manager for this layer\n const pieManager = createClusterPieManager(\n mapInstance,\n sourceId,\n categoryValues,\n categoryColorMap\n );\n clusterPieManagers.current.set(layer.id, pieManager);\n \n // Note: No circle layers needed - pie charts are rendered as DOM markers\n // The pie manager handles cluster visualization with interactive pie slices\n \n } else {\n // SIMPLE COUNT MODE: Colored circles with count\n\n // Cluster circles layer\n mapInstance.addLayer({\n id: clustersLayerId,\n type: 'circle',\n source: sourceId,\n filter: ['has', 'point_count'],\n paint: {\n 'circle-color': [\n 'step',\n ['get', 'point_count'],\n layerColor, // color for count < 100\n 100, '#f59e0b', // yellow for count >= 100\n 750, '#ef4444', // red for count >= 750\n ],\n 'circle-radius': [\n 'step',\n ['get', 'point_count'],\n 20, // 20px for count < 100\n 100, 30, // 30px for count >= 100\n 750, 40, // 40px for count >= 750\n ],\n 'circle-stroke-width': 2,\n 'circle-stroke-color': '#ffffff',\n },\n });\n\n // Cluster count labels\n mapInstance.addLayer({\n id: clusterCountLayerId,\n type: 'symbol',\n source: sourceId,\n filter: ['has', 'point_count'],\n layout: {\n 'text-field': ['get', 'point_count_abbreviated'],\n 'text-font': ['Open Sans Bold', 'Arial Unicode MS Bold'],\n 'text-size': 12,\n },\n paint: {\n 'text-color': '#ffffff',\n },\n });\n }\n\n // Unclustered point layer (for individual points when zoomed in)\n const unclusteredColor = groupByField \n ? ['match', ['get', groupByField], \n ...categoryValues.flatMap(cat => [cat, categoryColorMap[cat] || layerColor]),\n layerColor\n ]\n : layerColor;\n \n mapInstance.addLayer({\n id: unclusteredLayerId,\n type: 'circle',\n source: sourceId,\n filter: ['!', ['has', 'point_count']],\n paint: {\n 'circle-color': unclusteredColor as any,\n 'circle-radius': 6,\n 'circle-stroke-width': 1,\n 'circle-stroke-color': '#ffffff',\n },\n });\n\n // Add click handler for expanding clusters\n mapInstance.on('click', clustersLayerId, async (e) => {\n const features = mapInstance.queryRenderedFeatures(e.point, {\n layers: [clustersLayerId],\n });\n if (!features.length) return;\n\n const clusterId = features[0].properties?.cluster_id;\n const source = mapInstance.getSource(sourceId) as maplibregl.GeoJSONSource;\n \n try {\n const zoom = await source.getClusterExpansionZoom(clusterId);\n const geometry = features[0].geometry;\n if (geometry.type === 'Point') {\n mapInstance.easeTo({\n center: geometry.coordinates as [number, number],\n zoom: zoom ?? 10,\n });\n }\n } catch {\n // Cluster may have been removed\n }\n });\n\n // Change cursor on cluster hover\n mapInstance.on('mouseenter', clustersLayerId, () => {\n mapInstance.getCanvas().style.cursor = 'pointer';\n });\n mapInstance.on('mouseleave', clustersLayerId, () => {\n mapInstance.getCanvas().style.cursor = '';\n });\n } catch (e) {\n console.warn('Error creating cluster layer:', e);\n }\n });\n };\n\n rebuildClusters();\n\n const handleStyleLoad = () => {\n mapInstance.once('idle', rebuildClusters);\n };\n mapInstance.on('style.load', handleStyleLoad);\n\n return () => {\n try {\n mapInstance.off('style.load', handleStyleLoad);\n } catch {\n // Map may already be destroyed\n }\n };\n }, [isMapLoaded, layers, currentMapStyle]);\n\n if (mapError) {\n return (\n <div className={`flex items-center justify-center h-full bg-muted/30 ${className || ''}`} data-testid=\"map-error\">\n <Card className=\"max-w-md\">\n <div className=\"p-4 border-b border-border\">\n <div className=\"flex items-center gap-3\">\n <div className=\"p-2 rounded-full bg-destructive/10\">\n <AlertTriangle className=\"w-6 h-6 text-destructive\" />\n </div>\n <div>\n <h3 className=\"text-lg font-semibold\">Map Initialization Failed</h3>\n <p className=\"text-sm text-muted-foreground\">Unable to load the interactive map</p>\n </div>\n </div>\n </div>\n <div className=\"p-4 space-y-4\">\n <p className=\"text-sm text-muted-foreground\">{mapError}</p>\n <Button type=\"primary\" onClick={() => window.location.reload()} className=\"w-full\" data-testid=\"button-reload\">\n Refresh Page\n </Button>\n </div>\n </Card>\n </div>\n );\n }\n\n const toastContextValue = toastProvider ?? null;\n\n return (\n <ToastContext.Provider value={toastContextValue}>\n <MapDropZone onDrop={handleDropGeoJSON}>\n <div className={`map-container w-full h-full min-w-0 relative ${className || ''}`} data-testid=\"map-editor-canvas\">\n <div \n ref={mapContainer} \n className={`w-full h-full ${activeMode.startsWith('draw_') ? 'cursor-crosshair' : ''}`}\n data-testid=\"map-canvas\"\n tabIndex={enableKeyboardShortcuts ? 0 : undefined}\n style={{ outline: 'none' }}\n />\n {/* Filter geometry overlay – dashed SVG like the selection rectangle */}\n {filterSvgPoints && (\n <svg\n className=\"absolute inset-0 w-full h-full pointer-events-none z-[99]\"\n data-testid=\"filter-overlay\"\n >\n <polygon\n ref={filterPolygonRef}\n points={filterSvgPoints}\n fill=\"rgba(0, 0, 0, 0.03)\"\n stroke=\"#555\"\n strokeWidth=\"1.5\"\n strokeDasharray=\"6,3\"\n strokeOpacity=\"0.6\"\n />\n </svg>\n )}\n\n {/* Selection overlay for rectangle selection preview (rectangle mode or shift+drag in click mode) */}\n {selectionPoints.length >= 4 && (selectionMode === 'rectangle' || selectionMode === 'click') && map.current && (\n <svg \n className=\"absolute inset-0 w-full h-full pointer-events-none z-[100]\"\n data-testid=\"selection-overlay\"\n >\n <polygon\n points={selectionPoints.map(([lng, lat]) => {\n const point = map.current!.project([lng, lat]);\n return `${point.x},${point.y}`;\n }).join(' ')}\n fill=\"rgba(59, 130, 246, 0.15)\"\n stroke=\"rgb(59, 130, 246)\"\n strokeWidth=\"2\"\n strokeDasharray=\"6,3\"\n />\n </svg>\n )}\n\n {/* Polygon selection with rubber-band preview */}\n {selectionMode === 'polygon' && map.current && (selectionPoints.length >= 1 || selectionHoverPoint) && (\n <svg \n className=\"absolute inset-0 w-full h-full pointer-events-none z-[100]\"\n data-testid=\"polygon-points-overlay\"\n >\n {/* Lines between clicked points */}\n {selectionPoints.length >= 2 && selectionPoints.map(([lng, lat], i) => {\n if (i === 0) return null;\n const prevPoint = map.current!.project([selectionPoints[i - 1][0], selectionPoints[i - 1][1]]);\n const currPoint = map.current!.project([lng, lat]);\n return (\n <line\n key={`line-${i}`}\n x1={prevPoint.x}\n y1={prevPoint.y}\n x2={currPoint.x}\n y2={currPoint.y}\n stroke=\"rgb(59, 130, 246)\"\n strokeWidth=\"2\"\n />\n );\n })}\n \n {/* Rubber-band line from last point to hover position */}\n {selectionPoints.length >= 1 && selectionHoverPoint && (\n <line\n x1={map.current!.project([selectionPoints[selectionPoints.length - 1][0], selectionPoints[selectionPoints.length - 1][1]]).x}\n y1={map.current!.project([selectionPoints[selectionPoints.length - 1][0], selectionPoints[selectionPoints.length - 1][1]]).y}\n x2={map.current!.project(selectionHoverPoint).x}\n y2={map.current!.project(selectionHoverPoint).y}\n stroke=\"rgb(59, 130, 246)\"\n strokeWidth=\"2\"\n strokeDasharray=\"6,3\"\n />\n )}\n \n {/* Closing preview line from hover to first point (when 3+ points) */}\n {selectionPoints.length >= 3 && selectionHoverPoint && (\n <line\n x1={map.current!.project(selectionHoverPoint).x}\n y1={map.current!.project(selectionHoverPoint).y}\n x2={map.current!.project([selectionPoints[0][0], selectionPoints[0][1]]).x}\n y2={map.current!.project([selectionPoints[0][0], selectionPoints[0][1]]).y}\n stroke=\"rgb(59, 130, 246)\"\n strokeWidth=\"2\"\n strokeDasharray=\"6,3\"\n opacity=\"0.5\"\n />\n )}\n \n {/* Point markers at each clicked vertex */}\n {selectionPoints.map(([lng, lat], i) => {\n const point = map.current!.project([lng, lat]);\n return (\n <circle\n key={`point-${i}`}\n cx={point.x}\n cy={point.y}\n r=\"5\"\n fill=\"rgb(59, 130, 246)\"\n stroke=\"white\"\n strokeWidth=\"2\"\n />\n );\n })}\n \n {/* Hover point indicator */}\n {selectionHoverPoint && (\n <circle\n cx={map.current!.project(selectionHoverPoint).x}\n cy={map.current!.project(selectionHoverPoint).y}\n r=\"4\"\n fill=\"rgba(59, 130, 246, 0.5)\"\n stroke=\"white\"\n strokeWidth=\"1\"\n />\n )}\n </svg>\n )}\n\n {/* Circle selection overlay */}\n {selectionMode === 'circle' && selectionPoints.length >= 4 && map.current && (\n <svg \n className=\"absolute inset-0 w-full h-full pointer-events-none z-[100]\"\n data-testid=\"circle-selection-overlay\"\n >\n <polygon\n points={selectionPoints.map(([lng, lat]) => {\n const point = map.current!.project([lng, lat]);\n return `${point.x},${point.y}`;\n }).join(' ')}\n fill=\"rgba(59, 130, 246, 0.15)\"\n stroke=\"rgb(59, 130, 246)\"\n strokeWidth=\"2\"\n strokeDasharray=\"6,3\"\n />\n </svg>\n )}\n\n {/* Persisted selection is rendered via MapLibre layer for proper zoom behavior */}\n\n {/* Circle drawing preview */}\n {activeMode === 'draw_circle' && circleDrawPreview && circleDrawPreview.length >= 4 && map.current && (\n <svg \n className=\"absolute inset-0 w-full h-full pointer-events-none z-[100]\"\n data-testid=\"circle-draw-preview\"\n >\n <polygon\n points={circleDrawPreview.map(([lng, lat]) => {\n const point = map.current!.project([lng, lat]);\n return `${point.x},${point.y}`;\n }).join(' ')}\n fill=\"rgba(34, 197, 94, 0.15)\"\n stroke=\"rgb(34, 197, 94)\"\n strokeWidth=\"2\"\n strokeDasharray=\"6,3\"\n />\n {/* Center point indicator */}\n {circleDrawCenter && (\n <circle\n cx={map.current!.project(circleDrawCenter).x}\n cy={map.current!.project(circleDrawCenter).y}\n r=\"6\"\n fill=\"rgb(34, 197, 94)\"\n stroke=\"white\"\n strokeWidth=\"2\"\n />\n )}\n </svg>\n )}\n\n {/* Rectangle drawing preview */}\n {activeMode === 'draw_rectangle' && rectangleDrawPreview && rectangleDrawPreview.length >= 4 && map.current && (\n <svg \n className=\"absolute inset-0 w-full h-full pointer-events-none z-[100]\"\n data-testid=\"rectangle-draw-preview\"\n >\n <polygon\n points={rectangleDrawPreview.map(([lng, lat]) => {\n const point = map.current!.project([lng, lat]);\n return `${point.x},${point.y}`;\n }).join(' ')}\n fill=\"rgba(34, 197, 94, 0.15)\"\n stroke=\"rgb(34, 197, 94)\"\n strokeWidth=\"2\"\n strokeDasharray=\"6,3\"\n />\n {/* Corner point indicator */}\n {rectangleDrawCorner && (\n <circle\n cx={map.current!.project(rectangleDrawCorner).x}\n cy={map.current!.project(rectangleDrawCorner).y}\n r=\"5\"\n fill=\"rgb(34, 197, 94)\"\n stroke=\"white\"\n strokeWidth=\"2\"\n />\n )}\n </svg>\n )}\n\n {(enableDrawing || enableSelection) && (\n <DrawingToolbar\n activeMode={activeMode}\n onModeChange={handleModeChange}\n onClear={handleClear}\n onDeleteSelected={handleDeleteSelected}\n onUndo={handleUndo}\n onRedo={handleRedo}\n featureCount={featureCount}\n selectedCount={selectedFeatureIds.length}\n canUndo={undoStack.length > 0}\n canRedo={redoStack.length > 0}\n disabled={!isMapLoaded}\n isEditMode={isEditMode}\n onToggleEditMode={handleToggleEditMode}\n hasVisibleLayers={hasVisibleLayers}\n hasEditableLayer={hasEditableLayer}\n measureMode={measureMode}\n onMeasureModeChange={handleMeasureModeChange}\n selectionMode={selectionMode}\n onSelectionModeChange={handleSelectionModeChange}\n isSelectionToolActive={isSelectionToolActive}\n onSelectionToolActiveChange={setIsSelectionToolActive}\n enableMeasurement={enableMeasurement}\n enableSelection={enableSelection}\n hiddenDrawingTools={hiddenDrawingTools}\n hiddenSelectionTools={hiddenSelectionTools}\n expandSelectionTools={expandSelectionTools}\n showFilterTool={showFilterTool}\n selectionOnly={!enableDrawing && enableSelection}\n showShortcutHints={enableKeyboardShortcuts}\n onGoTo={(coords, zoom) => {\n if (map.current) {\n const currentZoom = map.current.getZoom();\n map.current.flyTo({ center: coords, zoom: zoom ?? Math.max(currentZoom, 14), duration: 2000 });\n }\n }}\n showClearFilter={showClearFilter}\n onClearFilter={onClearFilter}\n onFilterActiveChange={(active: boolean) => { filterActiveRef.current = active; }}\n showGoToButton={showGoToButton}\n onDropPoint={onDropPoint}\n geocodingUrl={geocodingUrl}\n geocoderProvider={geocoderProvider}\n onSearchEngineRequest={onSearchEngineRequest ? async () => {\n // Get current viewport info and call the external search engine\n if (!map.current) {\n console.error('Map not ready');\n return;\n }\n \n const mapInstance = map.current;\n const center = mapInstance.getCenter();\n const zoom = mapInstance.getZoom();\n const bounds = mapInstance.getBounds();\n \n const rawBounds: [number, number, number, number] = [\n bounds.getWest(),\n bounds.getSouth(),\n bounds.getEast(),\n bounds.getNorth()\n ];\n \n const queryBounds = {\n minLng: Math.max(-180, Math.min(180, rawBounds[0])),\n maxLng: Math.max(-180, Math.min(180, rawBounds[2])),\n minLat: Math.max(-90, Math.min(90, rawBounds[1])),\n maxLat: Math.max(-90, Math.min(90, rawBounds[3]))\n };\n \n const viewport = {\n center: [center.lng, center.lat] as [number, number],\n zoom,\n bounds: rawBounds,\n queryBounds\n };\n \n const activeLayerId = activeEditingLayerIdRef.current;\n \n try {\n const result = await onSearchEngineRequest({\n viewport,\n activeLayerId,\n });\n \n // If we got features back, add them to the active layer using proper helper\n if (result && result.features && result.features.length > 0 && activeLayerId) {\n const layer = layersRef.current.find(l => l.id === activeLayerId);\n if (layer && !layer.readOnly && draw.current && isMapLoaded) {\n const addedIds: string[] = [];\n \n // Mark as API adding so draw.create doesn't set _unsaved flag\n isApiAddingRef.current = true;\n try {\n result.features.forEach(f => {\n // Normalize temporal properties like addFeatures helper does\n const { startDate, endDate } = normalizeTemporalProperties(f.properties || {});\n const normalizedFeature = {\n ...f,\n properties: {\n ...f.properties,\n startDate: startDate?.toISOString() || null,\n endDate: endDate?.toISOString() || null,\n }\n };\n const ids = draw.current!.add(normalizedFeature);\n addedIds.push(ids[0]);\n });\n } finally {\n isApiAddingRef.current = false;\n }\n \n // Update layers properly with ref pattern\n const nextLayers = layersRef.current.map(l => \n l.id === activeLayerId ? { ...l, featureIds: [...l.featureIds, ...addedIds] } : l\n );\n layersRef.current = nextLayers;\n setLayers(nextLayers);\n \n updateFeatureCount();\n updateTimelineStore();\n syncFeaturesToCustomLayers();\n \n // Fire create callback for each added feature\n addedIds.forEach(id => {\n const feature = draw.current?.get(id);\n if (feature) {\n onFeatureCreate?.(feature as GeoJSON.Feature);\n }\n });\n }\n }\n } catch (error) {\n console.error('Search engine error:', error);\n }\n } : undefined}\n />\n )}\n\n {enableMeasurement && measureMode !== 'none' && (\n <div \n className=\"absolute top-4 left-16 z-10 bg-background/90 floating-panel rounded-lg shadow-lg border border-border px-4 py-2\"\n data-testid=\"measure-result-panel\"\n >\n <div className=\"flex items-center gap-3\">\n <span className=\"text-xs text-muted-foreground\">\n {measureMode === 'distance' ? 'Distance:' : 'Area:'}\n </span>\n <span className=\"font-mono text-sm font-medium\" data-testid=\"text-measure-result\">\n {measureResult || (measureMode === 'distance' ? 'Click points to measure' : 'Click 3+ points')}\n </span>\n <span className=\"text-xs text-muted-foreground\">\n (double-click to clear)\n </span>\n </div>\n </div>\n )}\n\n {/* Timeline toggle - moves above timebar when open */}\n {enableTimeline && timelineStore.hasTemporalData && (\n <div \n className=\"absolute left-4 z-[200] transition-all\"\n style={{ bottom: timelineStore.isEnabled ? TIMEBAR_HEIGHT + TIMEBAR_BOTTOM_OFFSET + 8 : 48 }}\n >\n <Tooltip title=\"Timeline\" placement=\"right\">\n <Button\n type=\"default\"\n icon={<Clock className=\"w-5 h-5\" />}\n onClick={() => timelineStore.setEnabled(!timelineStore.isEnabled)}\n disabled={!isMapLoaded}\n className={`!w-10 !h-10 !min-w-0 !p-0 bg-background shadow-lg ${timelineStore.isEnabled ? 'bg-primary/10' : ''}`}\n aria-label=\"Toggle timeline\"\n aria-pressed={timelineStore.isEnabled}\n data-testid=\"button-toggle-timeline\"\n />\n </Tooltip>\n </div>\n )}\n\n {/* Layers toggle - top right */}\n {enableLayers && (\n <div className=\"absolute top-4 right-4 z-[200] flex items-center gap-2\">\n {getMapUnsavedCount() > 0 && (\n <div \n className=\"px-2 py-1 bg-orange-500 text-white text-xs font-medium rounded-md shadow-lg\"\n data-testid=\"badge-unsaved-count\"\n >\n {getMapUnsavedCount()} unsaved\n </div>\n )}\n <Tooltip title=\"Layers\" placement=\"left\">\n <Button\n type=\"default\"\n icon={<Layers className=\"w-6 h-6\" />}\n onClick={handleToggleLayers}\n disabled={!isMapLoaded}\n className={`!w-11 !h-11 !min-w-0 !p-0 bg-background shadow-lg ${showLayers ? 'bg-primary/10' : ''}`}\n aria-label=\"Toggle layers panel\"\n aria-pressed={showLayers}\n data-testid=\"button-toggle-layers\"\n />\n </Tooltip>\n </div>\n )}\n\n \n {enableLayers && showLayers && (\n <LayersPanel\n layers={layers}\n onAddLayer={handleAddLayer}\n onRemoveLayer={handleRemoveLayer}\n onRenameLayer={handleRenameLayer}\n onToggleLayerVisibility={handleToggleLayerVisibility}\n onMoveFeatureToLayer={handleMoveFeatureToLayer}\n selectedFeatureIds={selectedFeatureIds}\n getFeatureCount={getFeatureCountForLayer}\n getLayerUnsavedCount={getLayerUnsavedCount}\n getMapUnsavedCount={getMapUnsavedCount}\n activeEditingLayerId={activeEditingLayerId}\n onSetActiveEditingLayer={setActiveEditingLayerId}\n onSaveLayerGeoJSON={handleSaveLayerGeoJSON}\n onLoadLayerGeoJSON={handleLoadLayerGeoJSON}\n onLoadNewLayerGeoJSON={handleLoadNewLayerGeoJSON}\n onSaveAllGeoJSON={handleSaveAllGeoJSON}\n onSearchAndAddToNewLayer={onSearchEngineRequest ? handleSearchAndAddToNewLayer : undefined}\n onWorkspaceLoad={onWorkspaceLoad ? handleWorkspaceLoad : undefined}\n onWorkspaceSave={onWorkspaceSave ? handleWorkspaceSave : undefined}\n onFitToFeatures={handleFitToFeatures}\n currentMapStyle={currentMapStyle}\n onMapStyleChange={handleMapStyleChange}\n onUpdateTraceConfig={handleUpdateTraceConfig}\n getAvailableTraceFields={getAvailableTraceFields}\n onUpdateHeatmapConfig={handleUpdateHeatmapConfig}\n onUpdateClusterConfig={handleUpdateClusterConfig}\n hasPointFeatures={hasPointFeatures}\n onUpdateVisualConfig={handleUpdateVisualConfig}\n getLayerFields={getLayerFields}\n onFitToLayerFeatures={handleFitToLayerFeatures}\n autoLabelConfig={autoLabelConfig}\n onUpdateAutoLabelConfig={handleUpdateAutoLabelConfig}\n visibleFeatureCount={visibleFeatureCount}\n is3DTerrainEnabled={is3DTerrainEnabled}\n onToggle3DTerrain={handleToggle3DTerrain}\n onUpdateAltitudeDisplayMode={handleUpdateAltitudeDisplayMode}\n hideSatellite={!enableSatellite}\n hideTerrain={!enableTerrain}\n hideBasemapSwitcher={hideBasemapSwitcher}\n externalPersistence={externalPersistence}\n />\n )}\n\n {showProperties && selectedFeatures.length > 0 && (() => {\n // Find the layer name for the first selected feature\n const firstFeatureId = selectedFeatures[0]?.id as string;\n const featureLayer = layers.find(l => l.featureIds.includes(firstFeatureId));\n const layerName = featureLayer?.name;\n const layerId = featureLayer?.id;\n \n return (\n <PropertiesPanel\n selectedFeatures={selectedFeatures.map(f => ({\n id: f.id as string,\n type: f.type,\n properties: f.properties || {},\n geometry: f.geometry,\n }))}\n onUpdateProperties={handleUpdateProperties}\n onUpdateGeometry={handleUpdateGeometry}\n onClose={handleCloseProperties}\n isEditMode={isEditMode}\n layerName={layerName}\n layerId={layerId}\n autoFocusLabel={autoFocusLabel}\n entityCardProvider={entityCardProvider}\n typePickerProvider={typePickerProvider}\n featureSaveProvider={featureSaveProvider}\n onFeatureSaved={handleFeatureSaved}\n />\n );\n })()}\n\n {showStatusPanel && (\n <StatusIndicator\n activeMode={activeMode}\n featureCount={featureCount}\n selectedCount={selectedFeatureIds.length}\n selectionMode={selectionMode}\n />\n )}\n\n {enableTimeline && timelineStore.isEnabled && (\n <Timebar \n onFilterChange={handleTimelineFilterChange} \n selectedFeatureIds={selectedFeatureIds}\n selectedFeatureColors={selectedFeatureColors}\n />\n )}\n\n {/* Custom context menu */}\n {contextMenu && (\n <div\n className=\"fixed z-[9999] min-w-[160px] rounded-md border bg-popover p-1 shadow-md\"\n style={{ left: contextMenu.x, top: contextMenu.y }}\n data-testid=\"context-menu\"\n >\n {contextMenu.items.map((item) => (\n <button\n key={item.id}\n className={`flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-sm hover-elevate active-elevate-2 ${\n item.disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'\n } ${item.destructive ? 'text-destructive' : ''}`}\n disabled={item.disabled}\n onClick={() => {\n if (!item.disabled) {\n item.onSelect();\n setContextMenu(null);\n }\n }}\n data-testid={`context-menu-item-${item.id}`}\n >\n {item.label}\n </button>\n ))}\n </div>\n )}\n\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\".geojson,.json\"\n onChange={handleFileChange}\n className=\"hidden\"\n data-testid=\"input-file-geojson\"\n />\n </div>\n </MapDropZone>\n </ToastContext.Provider>\n );\n});\n","import { Download, Upload } from 'lucide-react';\nimport { Button, Tooltip } from 'antd';\n\ninterface ActionPanelProps {\n onSave: () => void;\n onLoad: () => void;\n disabled?: boolean;\n}\n\nexport function ActionPanel({ onSave, onLoad, disabled }: ActionPanelProps) {\n return (\n <div \n className=\"absolute top-4 right-4 z-10 flex items-center gap-2 p-2 bg-background/80 floating-panel rounded-lg shadow-lg border border-border\"\n role=\"group\"\n aria-label=\"File actions\"\n data-testid=\"panel-actions\"\n >\n <Tooltip \n title={\n <div className=\"flex items-center gap-2\">\n <span>Download features as GeoJSON</span>\n <kbd className=\"px-1.5 py-0.5 text-xs font-mono bg-white/20 rounded\">S</kbd>\n </div>\n }\n >\n <Button\n type=\"default\"\n onClick={onSave}\n disabled={disabled}\n className=\"gap-2 flex items-center\"\n aria-label=\"Save as GeoJSON\"\n data-testid=\"button-save-geojson\"\n >\n <Download className=\"w-4 h-4\" />\n <span className=\"text-sm font-medium\">Save GeoJSON</span>\n </Button>\n </Tooltip>\n \n <Tooltip title=\"Import features from GeoJSON file\">\n <Button\n type=\"default\"\n onClick={onLoad}\n disabled={disabled}\n className=\"gap-2 flex items-center\"\n aria-label=\"Load GeoJSON file\"\n data-testid=\"button-load-geojson\"\n >\n <Upload className=\"w-4 h-4\" />\n <span className=\"text-sm font-medium\">Load GeoJSON</span>\n </Button>\n </Tooltip>\n </div>\n );\n}\n","import { useState, useCallback } from 'react';\nimport { Plus, FileJson, GripVertical, TestTube, Upload, Plane, Users, Phone, Car, AlertCircle, Check, Loader2 } from 'lucide-react';\nimport { Button, Card, Divider, Modal, DatePicker, Table, Tag } from 'antd';\nimport type { ColumnsType } from 'antd/es/table';\nimport dayjs from 'dayjs';\nimport { cn } from '@/lib/utils';\nimport * as toGeoJSON from '@mapbox/togeojson';\n\n// Mock entity data for the import wizard demonstration\ninterface PositionIdentifier {\n type: 'phone' | 'vehicle' | 'device';\n value: string;\n}\n\ninterface MockEntity {\n id: string;\n name: string;\n type: 'person' | 'phone' | 'vehicle';\n identifiers: PositionIdentifier[];\n}\n\nconst MOCK_ENTITIES: MockEntity[] = [\n { id: '1', name: 'John Smith', type: 'person', identifiers: [{ type: 'phone', value: '+1-555-0101' }, { type: 'vehicle', value: 'ABC-1234' }] },\n { id: '2', name: 'Jane Doe', type: 'person', identifiers: [{ type: 'phone', value: '+1-555-0102' }] },\n { id: '3', name: 'Bob Wilson', type: 'person', identifiers: [] },\n { id: '4', name: 'Alice Brown', type: 'person', identifiers: [{ type: 'vehicle', value: 'XYZ-5678' }, { type: 'vehicle', value: 'DEF-9012' }] },\n { id: '5', name: '+1-555-0200', type: 'phone', identifiers: [{ type: 'phone', value: '+1-555-0200' }] },\n { id: '6', name: '+1-555-0201', type: 'phone', identifiers: [{ type: 'phone', value: '+1-555-0201' }] },\n { id: '7', name: 'Vehicle GHI-3456', type: 'vehicle', identifiers: [{ type: 'vehicle', value: 'GHI-3456' }] },\n { id: '8', name: 'Carol White', type: 'person', identifiers: [{ type: 'phone', value: '+1-555-0103' }, { type: 'device', value: 'IMEI-123456' }] },\n { id: '9', name: 'David Lee', type: 'person', identifiers: [] },\n { id: '10', name: 'Emma Garcia', type: 'person', identifiers: [{ type: 'phone', value: '+1-555-0104' }] },\n { id: '11', name: 'Frank Miller', type: 'person', identifiers: [{ type: 'vehicle', value: 'JKL-7890' }] },\n];\n\ninterface ImportWizardProps {\n open: boolean;\n onClose: () => void;\n onImportComplete: (summary: string) => void;\n}\n\nfunction ImportWizard({ open, onClose, onImportComplete }: ImportWizardProps) {\n const [fromDate, setFromDate] = useState<dayjs.Dayjs | null>(dayjs().subtract(10, 'day'));\n const [toDate, setToDate] = useState<dayjs.Dayjs | null>(dayjs());\n const [isValidating, setIsValidating] = useState(false);\n const [validationResult, setValidationResult] = useState<{\n totalPositions: number;\n entitiesWithData: number;\n entitiesWithoutData: number;\n } | null>(null);\n\n const handleSetToNow = () => {\n setToDate(dayjs());\n };\n\n const handleValidate = async () => {\n setIsValidating(true);\n setValidationResult(null);\n \n // Simulate async validation\n await new Promise(resolve => setTimeout(resolve, 1500));\n \n // Generate mock validation result\n const entitiesWithIdentifiers = MOCK_ENTITIES.filter(e => e.identifiers.length > 0);\n const entitiesWithoutIdentifiers = MOCK_ENTITIES.filter(e => e.identifiers.length === 0);\n const totalPositions = entitiesWithIdentifiers.reduce((sum, e) => {\n // Random number of positions per identifier\n return sum + e.identifiers.length * Math.floor(Math.random() * 50 + 10);\n }, 0);\n \n setValidationResult({\n totalPositions,\n entitiesWithData: entitiesWithIdentifiers.length,\n entitiesWithoutData: entitiesWithoutIdentifiers.length,\n });\n setIsValidating(false);\n };\n\n const handleInsert = () => {\n if (!validationResult) return;\n \n const summary = `${validationResult.totalPositions} positions added from ${validationResult.entitiesWithData} entities, ${validationResult.entitiesWithoutData} entities had no positions`;\n onImportComplete(summary);\n \n // Reset state\n setValidationResult(null);\n setFromDate(dayjs().subtract(10, 'day'));\n setToDate(dayjs());\n onClose();\n };\n\n const handleCancel = () => {\n setValidationResult(null);\n setIsValidating(false);\n onClose();\n };\n\n const columns: ColumnsType<MockEntity> = [\n {\n title: 'Entity',\n dataIndex: 'name',\n key: 'name',\n render: (name: string, record: MockEntity) => (\n <div className=\"flex items-center gap-2\">\n {record.type === 'person' && <Users className=\"w-4 h-4 text-muted-foreground\" />}\n {record.type === 'phone' && <Phone className=\"w-4 h-4 text-blue-500\" />}\n {record.type === 'vehicle' && <Car className=\"w-4 h-4 text-green-500\" />}\n <span>{name}</span>\n </div>\n ),\n },\n {\n title: 'Position Identifiers',\n dataIndex: 'identifiers',\n key: 'identifiers',\n render: (identifiers: PositionIdentifier[], record: MockEntity) => {\n // For phones, they ARE the identifier\n if (record.type === 'phone') {\n return (\n <Tag color=\"blue\" className=\"flex items-center gap-1 w-fit\">\n <Phone className=\"w-3 h-3\" />\n Self (Phone)\n </Tag>\n );\n }\n \n if (identifiers.length === 0) {\n return (\n <span className=\"text-amber-600 dark:text-amber-400 flex items-center gap-1 text-sm\">\n <AlertCircle className=\"w-4 h-4\" />\n No position identifiers available\n </span>\n );\n }\n \n return (\n <div className=\"flex flex-wrap gap-1\">\n {identifiers.map((id, idx) => (\n <Tag \n key={idx} \n color={id.type === 'phone' ? 'blue' : id.type === 'vehicle' ? 'green' : 'purple'}\n className=\"flex items-center gap-1\"\n >\n {id.type === 'phone' && <Phone className=\"w-3 h-3\" />}\n {id.type === 'vehicle' && <Car className=\"w-3 h-3\" />}\n {id.value}\n </Tag>\n ))}\n </div>\n );\n },\n },\n ];\n\n return (\n <Modal\n open={open}\n onCancel={handleCancel}\n title={\n <div className=\"flex items-center gap-2\">\n <Users className=\"w-5 h-5 text-primary\" />\n Import non os_geo_thing Wizard\n </div>\n }\n width={700}\n footer={null}\n data-testid=\"dialog-import-wizard\"\n >\n <div className=\"space-y-4\">\n <p className=\"text-sm text-muted-foreground\">\n This wizard demonstrates importing position data for entities that are not of type os_geo_thing. \n Select a time range and validate to see available positions.\n </p>\n \n {/* Entity List */}\n <div>\n <h4 className=\"font-medium text-sm mb-2\">Entities ({MOCK_ENTITIES.length})</h4>\n <Table\n dataSource={MOCK_ENTITIES}\n columns={columns}\n rowKey=\"id\"\n size=\"small\"\n pagination={{ pageSize: 5 }}\n className=\"border rounded-md\"\n data-testid=\"table-entities\"\n />\n </div>\n \n {/* Time Range Picker */}\n <div className=\"bg-muted/30 p-3 rounded-md\">\n <h4 className=\"font-medium text-sm mb-2\">Time Range</h4>\n <div className=\"flex items-center gap-2 flex-wrap\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm text-muted-foreground\">From:</span>\n <DatePicker\n value={fromDate}\n onChange={setFromDate}\n size=\"small\"\n format=\"YYYY-MM-DD\"\n data-testid=\"datepicker-from\"\n />\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm text-muted-foreground\">To:</span>\n <DatePicker\n value={toDate}\n onChange={setToDate}\n size=\"small\"\n format=\"YYYY-MM-DD\"\n data-testid=\"datepicker-to\"\n />\n </div>\n <Button\n type=\"default\"\n size=\"small\"\n onClick={handleSetToNow}\n data-testid=\"button-set-to-now\"\n >\n Set to Now\n </Button>\n </div>\n </div>\n \n {/* Validation Result */}\n {validationResult && (\n <div className=\"bg-green-50 dark:bg-green-950/30 border border-green-200 dark:border-green-800 p-3 rounded-md\">\n <div className=\"flex items-center gap-2 text-green-700 dark:text-green-400\">\n <Check className=\"w-5 h-5\" />\n <span className=\"font-medium\">Validation Complete</span>\n </div>\n <p className=\"text-sm text-green-600 dark:text-green-400 mt-1\">\n <strong>{validationResult.totalPositions}</strong> positions available from{' '}\n <strong>{validationResult.entitiesWithData}</strong> entities\n {validationResult.entitiesWithoutData > 0 && (\n <span className=\"text-amber-600 dark:text-amber-400\">\n {' '}({validationResult.entitiesWithoutData} entities had no positions)\n </span>\n )}\n </p>\n </div>\n )}\n \n {/* Action Buttons */}\n <div className=\"flex justify-end gap-2 pt-2 border-t\">\n <Button onClick={handleCancel} data-testid=\"button-cancel-wizard\">\n Cancel\n </Button>\n {!validationResult ? (\n <Button\n type=\"primary\"\n onClick={handleValidate}\n disabled={isValidating || !fromDate || !toDate}\n data-testid=\"button-validate\"\n >\n {isValidating ? (\n <>\n <Loader2 className=\"w-4 h-4 mr-2 animate-spin\" />\n Validating...\n </>\n ) : (\n 'Validate'\n )}\n </Button>\n ) : (\n <Button\n type=\"primary\"\n onClick={handleInsert}\n data-testid=\"button-insert\"\n >\n <Check className=\"w-4 h-4 mr-2\" />\n Insert {validationResult.totalPositions} Positions\n </Button>\n )}\n </div>\n </div>\n </Modal>\n );\n}\n\nconst CITY_NAMES = [\n 'Paris', 'London', 'Tokyo', 'Milan', 'Cairo', 'Sydney', 'Berlin', 'Madrid',\n 'Rome', 'Vienna', 'Prague', 'Dublin', 'Oslo', 'Helsinki', 'Lisbon', 'Athens',\n 'Budapest', 'Warsaw', 'Moscow', 'Beijing', 'Seoul', 'Mumbai', 'Singapore'\n];\n\nfunction generateRandomName(): string {\n const city = CITY_NAMES[Math.floor(Math.random() * CITY_NAMES.length)];\n const number = Math.floor(Math.random() * 10000);\n return `${city} ${number}`;\n}\n\nfunction generateRandomDate(start: Date, end: Date): Date {\n return new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime()));\n}\n\nfunction generateRandomPoint(): GeoJSON.Feature {\n const lng = (Math.random() * 360) - 180;\n const lat = (Math.random() * 170) - 85;\n const name = generateRandomName();\n \n const hasTemporal = Math.random() < 0.2;\n \n let properties: Record<string, unknown> = { name };\n \n if (hasTemporal) {\n const baseDate = new Date(2020, 0, 1);\n const endDate = new Date(2024, 11, 31);\n const startDate = generateRandomDate(baseDate, endDate);\n const featureEndDate = generateRandomDate(startDate, new Date(endDate.getTime() + 365 * 24 * 60 * 60 * 1000));\n \n properties = {\n ...properties,\n startDate: startDate.toISOString(),\n endDate: featureEndDate.toISOString(),\n };\n }\n \n return {\n type: 'Feature',\n properties,\n geometry: {\n type: 'Point',\n coordinates: [lng, lat],\n },\n };\n}\n\nfunction generateSequentialPoints(): GeoJSON.Feature[] {\n const baseDate = new Date();\n const baseLng = 0;\n const baseLat = 20;\n \n return Array.from({ length: 10 }, (_, i) => {\n const date = new Date(baseDate.getTime() + i * 24 * 60 * 60 * 1000); // +1 day each\n const lng = baseLng + i * 10; // 10 degrees east each (~1000km at equator)\n \n return {\n type: 'Feature' as const,\n properties: {\n name: `Point ${i + 1}`,\n startDate: date.toISOString(),\n },\n geometry: {\n type: 'Point' as const,\n coordinates: [lng, baseLat],\n },\n };\n });\n}\n\nfunction generateNYCPoints(count: number): GeoJSON.FeatureCollection {\n // NYC area bounds: roughly -74.3 to -73.7 lng, 40.5 to 40.9 lat\n const nycCenter = { lng: -74.006, lat: 40.7128 };\n const spread = 0.15; // ~15km radius\n \n // 12 types with weighted distribution for realistic NYC data\n const types = [\n { name: 'bus stop', weight: 0.18 },\n { name: 'retail', weight: 0.15 },\n { name: 'restaurant', weight: 0.14 },\n { name: 'office', weight: 0.12 },\n { name: 'residential', weight: 0.10 },\n { name: 'school', weight: 0.08 },\n { name: 'park', weight: 0.06 },\n { name: 'subway', weight: 0.05 },\n { name: 'hotel', weight: 0.04 },\n { name: 'museum', weight: 0.03 },\n { name: 'hospital', weight: 0.03 },\n { name: 'theater', weight: 0.02 },\n ];\n \n const getRandomType = () => {\n const r = Math.random();\n let cumulative = 0;\n for (const t of types) {\n cumulative += t.weight;\n if (r < cumulative) return t.name;\n }\n return types[0].name;\n };\n \n // Max occupancy ranges by type\n const getMaxOccupancy = (type: string) => {\n switch (type) {\n case 'hospital': return Math.floor(Math.random() * 9000) + 1000; // 1000-10000\n case 'residential': return Math.floor(Math.random() * 500) + 50; // 50-550\n case 'office': return Math.floor(Math.random() * 2000) + 100; // 100-2100\n case 'school': return Math.floor(Math.random() * 1500) + 200; // 200-1700\n case 'hotel': return Math.floor(Math.random() * 800) + 100; // 100-900\n case 'theater': return Math.floor(Math.random() * 2000) + 200; // 200-2200\n case 'museum': return Math.floor(Math.random() * 1000) + 100; // 100-1100\n case 'restaurant': return Math.floor(Math.random() * 200) + 20; // 20-220\n case 'retail': return Math.floor(Math.random() * 400) + 10; // 10-410\n case 'park': return Math.floor(Math.random() * 5000) + 100; // 100-5100\n case 'subway': return Math.floor(Math.random() * 500) + 50; // 50-550\n case 'bus stop': return Math.floor(Math.random() * 45) + 5; // 5-50\n default: return Math.floor(Math.random() * 100) + 5;\n }\n };\n \n const features: GeoJSON.Feature[] = Array.from({ length: count }, (_, i) => {\n // Random position within NYC area with gaussian-ish distribution (more density at center)\n const angle = Math.random() * Math.PI * 2;\n const distance = Math.random() * Math.random() * spread; // Squared for center concentration\n const lng = nycCenter.lng + Math.cos(angle) * distance;\n const lat = nycCenter.lat + Math.sin(angle) * distance * 0.7; // Adjust for lat/lng ratio\n \n const type = getRandomType();\n const maxOccupancy = getMaxOccupancy(type);\n \n return {\n type: 'Feature' as const,\n properties: {\n name: `NYC Point ${i + 1}`,\n type,\n maxOccupancy,\n },\n geometry: {\n type: 'Point' as const,\n coordinates: [lng, lat],\n },\n };\n });\n \n return {\n type: 'FeatureCollection',\n features,\n };\n}\n\nfunction generatePeopleTraces(): GeoJSON.Feature[] {\n // NYC bounds for movement\n const nycCenter = { lng: -74.006, lat: 40.7128 };\n const features: GeoJSON.Feature[] = [];\n \n // 5 people, 6 hours, 1 point per 10 minutes = 36 points per person\n const numPeople = 5;\n const durationHours = 6;\n const intervalMinutes = 10;\n const pointsPerPerson = (durationHours * 60) / intervalMinutes; // 36\n \n const baseDate = new Date();\n baseDate.setHours(8, 0, 0, 0); // Start at 8 AM\n \n for (let person = 0; person < numPeople; person++) {\n const targetId = `Person-${person + 1}`;\n \n // Random starting position within NYC\n let currentLng = nycCenter.lng + (Math.random() - 0.5) * 0.1;\n let currentLat = nycCenter.lat + (Math.random() - 0.5) * 0.08;\n \n for (let i = 0; i < pointsPerPerson; i++) {\n const timestamp = new Date(baseDate.getTime() + i * intervalMinutes * 60 * 1000);\n \n // Add feature\n features.push({\n type: 'Feature',\n properties: {\n name: `${targetId} - ${i + 1}`,\n TargetID: targetId,\n startDate: timestamp.toISOString(),\n },\n geometry: {\n type: 'Point',\n coordinates: [currentLng, currentLat],\n },\n });\n \n // Move for next point (walking speed ~0.001 degrees per 10 min, ~100m)\n const walkSpeed = 0.001 + Math.random() * 0.001;\n const angle = Math.random() * Math.PI * 2;\n currentLng += Math.cos(angle) * walkSpeed;\n currentLat += Math.sin(angle) * walkSpeed * 0.7;\n \n // Keep within NYC bounds\n currentLng = Math.max(nycCenter.lng - 0.1, Math.min(nycCenter.lng + 0.1, currentLng));\n currentLat = Math.max(nycCenter.lat - 0.08, Math.min(nycCenter.lat + 0.08, currentLat));\n }\n }\n \n return features;\n}\n\n/**\n * Generate a sample drone flight path over NYC with altitude data\n * This simulates a drone survey flight as timestamped GPS points.\n * Enable TRACE feature in layer menu to see flight path as connected line.\n * Each point has its own timestamp for timeline filtering.\n */\nfunction generateDroneFlightOverNYC(): GeoJSON.FeatureCollection {\n // Flight waypoints with altitude in meters\n const waypoints = [\n { lng: -73.9654, lat: 40.7829, alt: 50, name: 'Takeoff - Central Park' },\n { lng: -73.9654, lat: 40.7829, alt: 120, name: 'Climb to survey altitude' },\n { lng: -73.9810, lat: 40.7614, alt: 120, name: 'Times Square flyover' },\n { lng: -73.9857, lat: 40.7484, alt: 150, name: 'Empire State Building' },\n { lng: -73.9776, lat: 40.7527, alt: 180, name: 'Grand Central area' },\n { lng: -73.9712, lat: 40.7580, alt: 160, name: 'Rockefeller Center' },\n { lng: -73.9632, lat: 40.7794, alt: 140, name: 'Upper East Side' },\n { lng: -73.9654, lat: 40.7851, alt: 100, name: 'Central Park North' },\n { lng: -73.9654, lat: 40.7829, alt: 60, name: 'Return to start' },\n { lng: -73.9654, lat: 40.7829, alt: 0, name: 'Landing' },\n ];\n \n const baseTime = new Date();\n baseTime.setHours(14, 0, 0, 0); // 2 PM flight\n const flightDurationMs = 25 * 60 * 1000; // 25 minutes total flight\n \n // Generate interpolated points along the flight path\n // Each point is a separate feature with its own timestamp\n const features: GeoJSON.Feature[] = [];\n let pointIndex = 0;\n const totalSegments = waypoints.length - 1;\n const pointsPerSegment = 10;\n const totalPoints = totalSegments * pointsPerSegment + 1;\n const timePerPoint = flightDurationMs / totalPoints;\n \n for (let i = 0; i < waypoints.length - 1; i++) {\n const from = waypoints[i];\n const to = waypoints[i + 1];\n \n for (let j = 0; j < pointsPerSegment; j++) {\n const t = j / pointsPerSegment;\n const lng = from.lng + (to.lng - from.lng) * t;\n const lat = from.lat + (to.lat - from.lat) * t;\n const alt = from.alt + (to.alt - from.alt) * t;\n // Add some noise to altitude for realism\n const noise = (Math.random() - 0.5) * 5;\n const finalAlt = Math.max(0, alt + noise);\n \n const timestamp = new Date(baseTime.getTime() + pointIndex * timePerPoint);\n const isWaypoint = j === 0;\n \n features.push({\n type: 'Feature',\n properties: {\n name: isWaypoint ? from.name : `Flight point ${pointIndex + 1}`,\n altitude: Math.round(finalAlt),\n startDate: timestamp.toISOString(),\n TargetID: 'DJI-001',\n },\n geometry: {\n type: 'Point',\n coordinates: [lng, lat, finalAlt],\n },\n });\n \n pointIndex++;\n }\n }\n \n // Add final landing point\n const last = waypoints[waypoints.length - 1];\n features.push({\n type: 'Feature',\n properties: {\n name: last.name,\n altitude: last.alt,\n startDate: new Date(baseTime.getTime() + flightDurationMs).toISOString(),\n TargetID: 'DJI-001',\n },\n geometry: {\n type: 'Point',\n coordinates: [last.lng, last.lat, last.alt],\n },\n });\n \n return {\n type: 'FeatureCollection',\n features,\n };\n}\n\n/**\n * Parse KML file content to GeoJSON using @mapbox/togeojson\n */\nexport function parseKMLToGeoJSON(kmlContent: string): GeoJSON.FeatureCollection | null {\n try {\n const parser = new DOMParser();\n const kmlDoc = parser.parseFromString(kmlContent, 'application/xml');\n \n // Check for parse errors\n const parseError = kmlDoc.querySelector('parsererror');\n if (parseError) {\n console.error('KML parse error:', parseError.textContent);\n return null;\n }\n \n // Convert KML to GeoJSON\n const geoJSON = toGeoJSON.kml(kmlDoc);\n return geoJSON as GeoJSON.FeatureCollection;\n } catch (error) {\n console.error('Error parsing KML:', error);\n return null;\n }\n}\n\n// Sample drone flight data\nconst SAMPLE_DRONE_FLIGHT = {\n id: 'sample-drone-flight',\n name: 'NYC Drone Flight',\n description: 'Enable TRACE to see flight path',\n getData: generateDroneFlightOverNYC,\n};\n\nconst SAMPLE_GEOJSON_ITEMS = [\n {\n id: 'sample-cities',\n name: 'World Cities',\n description: '5 major cities with dates',\n data: {\n type: 'FeatureCollection',\n features: [\n {\n type: 'Feature',\n properties: { name: 'New York', startDate: '2023-01-15', endDate: '2023-06-30' },\n geometry: { type: 'Point', coordinates: [-74.006, 40.7128] }\n },\n {\n type: 'Feature',\n properties: { name: 'Los Angeles', startDate: '2023-03-01' },\n geometry: { type: 'Point', coordinates: [-118.2437, 34.0522] }\n },\n {\n type: 'Feature',\n properties: { name: 'Chicago' },\n geometry: { type: 'Point', coordinates: [-87.6298, 41.8781] }\n },\n {\n type: 'Feature',\n properties: { name: 'Houston', startDate: '2022-12-01', endDate: '2023-12-01' },\n geometry: { type: 'Point', coordinates: [-95.3698, 29.7604] }\n },\n {\n type: 'Feature',\n properties: { name: 'Phoenix' },\n geometry: { type: 'Point', coordinates: [-112.074, 33.4484] }\n }\n ]\n } as GeoJSON.FeatureCollection\n },\n {\n id: 'sample-route',\n name: 'Sample Route',\n description: 'Points with timestamps and phone',\n data: {\n type: 'FeatureCollection',\n features: [\n {\n type: 'Feature',\n properties: { name: 'Stop 1', startDate: '2023-01-01T08:00:00Z', phone: '+1-555-0100' },\n geometry: { type: 'Point', coordinates: [-122.4194, 37.7749] }\n },\n {\n type: 'Feature',\n properties: { name: 'Stop 2', startDate: '2023-01-01T10:30:00Z', phone: '+1-555-0100' },\n geometry: { type: 'Point', coordinates: [-118.2437, 34.0522] }\n },\n {\n type: 'Feature',\n properties: { name: 'Stop 3', startDate: '2023-01-01T14:00:00Z', phone: '+1-555-0100' },\n geometry: { type: 'Point', coordinates: [-112.074, 33.4484] }\n },\n {\n type: 'Feature',\n properties: { name: 'Stop 4', startDate: '2023-01-02T09:00:00Z', phone: '+1-555-0100' },\n geometry: { type: 'Point', coordinates: [-104.9903, 39.7392] }\n },\n {\n type: 'Feature',\n properties: { name: 'Stop 5', startDate: '2023-01-02T16:00:00Z', phone: '+1-555-0100' },\n geometry: { type: 'Point', coordinates: [-95.3698, 29.7604] }\n }\n ]\n } as GeoJSON.FeatureCollection\n },\n {\n id: 'sample-region',\n name: 'Sample Region',\n description: 'A polygon without dates',\n data: {\n type: 'FeatureCollection',\n features: [\n {\n type: 'Feature',\n properties: { name: 'Western Region' },\n geometry: {\n type: 'Polygon',\n coordinates: [[\n [-125, 48],\n [-125, 32],\n [-110, 32],\n [-110, 48],\n [-125, 48]\n ]]\n }\n }\n ]\n } as GeoJSON.FeatureCollection\n }\n];\n\ninterface DraggableGeoJSONProps {\n item: typeof SAMPLE_GEOJSON_ITEMS[0];\n}\n\nfunction DraggableGeoJSON({ item }: DraggableGeoJSONProps) {\n const handleDragStart = (e: React.DragEvent) => {\n e.dataTransfer.setData('application/json', JSON.stringify({\n name: item.name,\n data: item.data\n }));\n e.dataTransfer.effectAllowed = 'copy';\n };\n \n return (\n <Card\n draggable\n onDragStart={handleDragStart}\n className=\"pl-[10px] pr-[10px] pt-[1px] pb-[1px] cursor-grab active:cursor-grabbing hover-elevate\"\n data-testid={`draggable-geojson-${item.id}`}\n >\n <div className=\"flex items-start gap-2\">\n <GripVertical className=\"w-4 h-4 text-muted-foreground mt-0.5 flex-shrink-0\" />\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <FileJson className=\"w-4 h-4 text-primary\" />\n <span className=\"font-medium text-sm truncate\">{item.name}</span>\n </div>\n <p className=\"text-xs text-muted-foreground mt-1\">{item.description}</p>\n </div>\n </div>\n </Card>\n );\n}\n\ninterface DraggableDroneFlightProps {\n item: typeof SAMPLE_DRONE_FLIGHT;\n}\n\nfunction DraggableDroneFlight({ item }: DraggableDroneFlightProps) {\n const handleDragStart = (e: React.DragEvent) => {\n const data = item.getData();\n e.dataTransfer.setData('application/json', JSON.stringify({\n name: item.name,\n data: data\n }));\n e.dataTransfer.effectAllowed = 'copy';\n };\n \n return (\n <Card\n draggable\n onDragStart={handleDragStart}\n className=\"p-3 cursor-grab active:cursor-grabbing hover-elevate border-primary/30\"\n data-testid={`draggable-drone-flight-${item.id}`}\n >\n <div className=\"flex items-start gap-2\">\n <GripVertical className=\"w-4 h-4 text-muted-foreground mt-0.5 flex-shrink-0\" />\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <Plane className=\"w-4 h-4 text-primary\" />\n <span className=\"font-medium text-sm truncate\">{item.name}</span>\n </div>\n <p className=\"text-xs text-muted-foreground mt-1\">{item.description}</p>\n </div>\n </div>\n </Card>\n );\n}\n\ninterface DebugSidebarProps {\n onAddRandomPoints: (features: GeoJSON.Feature[]) => void;\n onImportKML?: (name: string, geojson: GeoJSON.FeatureCollection) => void;\n canAddFeatures?: boolean;\n className?: string;\n onCloseMap?: () => void;\n}\n\nexport function DebugSidebar({ onAddRandomPoints, onImportKML, canAddFeatures = true, className, onCloseMap }: DebugSidebarProps) {\n const [isGenerating, setIsGenerating] = useState(false);\n const [isDragOver, setIsDragOver] = useState(false);\n const [wizardOpen, setWizardOpen] = useState(false);\n const [importSummary, setImportSummary] = useState<string | null>(null);\n \n // Handle KML file drop\n const handleKMLDrop = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n setIsDragOver(false);\n \n const files = e.dataTransfer.files;\n if (files.length === 0) return;\n \n const file = files[0];\n const isKML = file.name.toLowerCase().endsWith('.kml') || \n file.name.toLowerCase().endsWith('.kmz');\n \n if (!isKML) {\n console.warn('Please drop a KML file');\n return;\n }\n \n const reader = new FileReader();\n reader.onload = (event) => {\n const content = event.target?.result as string;\n const geojson = parseKMLToGeoJSON(content);\n \n if (geojson && onImportKML) {\n // Use filename without extension as layer name\n const layerName = file.name.replace(/\\.(kml|kmz)$/i, '');\n onImportKML(layerName, geojson);\n }\n };\n reader.readAsText(file);\n }, [onImportKML]);\n \n const handleDragOver = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n setIsDragOver(true);\n }, []);\n \n const handleDragLeave = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n setIsDragOver(false);\n }, []);\n \n const handleGeneratePoints = () => {\n setIsGenerating(true);\n const points = Array.from({ length: 10 }, () => generateRandomPoint());\n onAddRandomPoints(points);\n setTimeout(() => setIsGenerating(false), 500);\n };\n \n const handleGenerateSequential = () => {\n setIsGenerating(true);\n const points = generateSequentialPoints();\n onAddRandomPoints(points);\n setTimeout(() => setIsGenerating(false), 500);\n };\n\n const handleGenerateNYC = () => {\n setIsGenerating(true);\n const nycData = generateNYCPoints(1000);\n onAddRandomPoints(nycData.features);\n setTimeout(() => setIsGenerating(false), 500);\n };\n\n const handleGeneratePeopleTraces = () => {\n setIsGenerating(true);\n const traces = generatePeopleTraces();\n onAddRandomPoints(traces);\n setTimeout(() => setIsGenerating(false), 500);\n };\n \n return (\n <div\n className={cn(\n \"h-full w-72 bg-sidebar border-r border-border flex flex-col min-h-0\",\n className\n )}\n data-testid=\"debug-sidebar\"\n >\n <div className=\"flex items-center gap-2 p-4 border-b border-border flex-shrink-0\">\n <TestTube className=\"w-5 h-5 text-primary\" />\n <h2 className=\"font-semibold flex-1\">Debug Panel</h2>\n {onCloseMap && (\n <Button\n type=\"default\"\n size=\"small\"\n danger\n onClick={onCloseMap}\n data-testid=\"button-close-map\"\n >\n Close Map\n </Button>\n )}\n </div>\n \n <div className=\"flex-1 min-h-0 overflow-auto\">\n <div className=\"p-4 space-y-4\">\n <div>\n <h3 className=\"text-sm font-medium mb-2\">Test Data</h3>\n {!canAddFeatures && (\n <p className=\"text-xs text-amber-600 dark:text-amber-400 mb-2\">\n Select an editable layer to add test data\n </p>\n )}\n <div className=\"space-y-2\">\n <Button\n type=\"default\"\n size=\"small\"\n onClick={handleGeneratePoints}\n disabled={isGenerating || !canAddFeatures}\n className=\"w-full flex items-center justify-center\"\n data-testid=\"button-add-random-points\"\n >\n <Plus className=\"w-4 h-4 mr-2\" />\n {isGenerating ? 'Adding...' : 'Add 10 Random Points'}\n </Button>\n <Button\n type=\"default\"\n size=\"small\"\n onClick={handleGenerateSequential}\n disabled={isGenerating || !canAddFeatures}\n className=\"w-full flex items-center justify-center\"\n data-testid=\"button-add-sequential-points\"\n >\n <Plus className=\"w-4 h-4 mr-2\" />\n Add 10 Sequential Points\n </Button>\n <Button\n type=\"default\"\n size=\"small\"\n onClick={handleGenerateNYC}\n disabled={isGenerating || !canAddFeatures}\n className=\"w-full flex items-center justify-center\"\n data-testid=\"button-add-nyc-points\"\n >\n <Plus className=\"w-4 h-4 mr-2\" />\n Add 1000 NYC Points\n </Button>\n <Button\n type=\"default\"\n size=\"small\"\n onClick={handleGeneratePeopleTraces}\n disabled={isGenerating || !canAddFeatures}\n className=\"w-full flex items-center justify-center\"\n data-testid=\"button-add-people-traces\"\n >\n <Plus className=\"w-4 h-4 mr-2\" />\n Add People Traces\n </Button>\n <Button\n type=\"default\"\n size=\"small\"\n onClick={() => {\n setIsGenerating(true);\n const data = generateNYCPoints(100000);\n onAddRandomPoints(data.features);\n setTimeout(() => setIsGenerating(false), 500);\n }}\n disabled={isGenerating || !canAddFeatures}\n className=\"w-full flex items-center justify-center\"\n data-testid=\"button-add-100k-points\"\n >\n <Plus className=\"w-4 h-4 mr-2\" />\n Add 100k NYC Points\n </Button>\n </div>\n <p className=\"text-xs text-muted-foreground mt-2\">\n Sequential: 10 points going east, 1 day apart. NYC: points clustered around Manhattan. People: 5 people moving for 6 hours. 100k: Performance test.\n </p>\n </div>\n \n <Divider className=\"!my-3\" />\n \n <div>\n <h3 className=\"text-sm font-medium mb-2\">Drag to Map</h3>\n <p className=\"text-xs text-muted-foreground mb-3\">\n Drag these samples onto the map to add them as new layers\n </p>\n <div className=\"space-y-2\">\n <DraggableDroneFlight item={SAMPLE_DRONE_FLIGHT} />\n {SAMPLE_GEOJSON_ITEMS.map(item => (\n <DraggableGeoJSON key={item.id} item={item} />\n ))}\n </div>\n </div>\n \n <Divider className=\"!my-3\" />\n \n <div>\n <h3 className=\"text-sm font-medium mb-2\">Import Wizard Demo</h3>\n <p className=\"text-xs text-muted-foreground mb-2\">\n Demonstrates importing positions for non-os_geo_thing entities\n </p>\n <Button\n type=\"default\"\n size=\"small\"\n onClick={() => setWizardOpen(true)}\n className=\"w-full flex items-center justify-center\"\n data-testid=\"button-open-import-wizard\"\n >\n <Users className=\"w-4 h-4 mr-2\" />\n Import non os_geo_thing Wizard\n </Button>\n {importSummary && (\n <div className=\"mt-2 p-2 bg-green-50 dark:bg-green-950/30 border border-green-200 dark:border-green-800 rounded-md\">\n <p className=\"text-xs text-green-700 dark:text-green-400\">\n {importSummary}\n </p>\n </div>\n )}\n </div>\n \n <Divider className=\"!my-3\" />\n \n <div>\n <h3 className=\"text-sm font-medium mb-2\">Import KML</h3>\n <p className=\"text-xs text-muted-foreground mb-2\">\n Drop a KML file to import drone flight logs or GPS tracks\n </p>\n <div\n onDrop={handleKMLDrop}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n className={cn(\n \"border-2 border-dashed rounded-md p-4 text-center transition-colors\",\n isDragOver \n ? \"border-primary bg-primary/10\" \n : \"border-muted-foreground/30\"\n )}\n data-testid=\"kml-drop-zone\"\n >\n <Upload className={cn(\n \"w-8 h-8 mx-auto mb-2\",\n isDragOver ? \"text-primary\" : \"text-muted-foreground\"\n )} />\n <p className=\"text-sm text-muted-foreground\">\n {isDragOver ? \"Drop KML file here\" : \"Drop .kml file\"}\n </p>\n </div>\n </div>\n </div>\n </div>\n \n {/* Import Wizard Modal */}\n <ImportWizard\n open={wizardOpen}\n onClose={() => setWizardOpen(false)}\n onImportComplete={(summary) => {\n setImportSummary(summary);\n // Clear summary after 10 seconds\n setTimeout(() => setImportSummary(null), 10000);\n }}\n />\n </div>\n );\n}\n"],"names":["message","staticMessage","PRESET_COLORS","Map","Tag","_a","_b","_c","_d","CalendarIcon","totalRange","MapEditorCanvas","layer","layerId","tooltipEl","showTooltip","hideTooltip","selectedFeatures","nextLayers","layers","e","reprojectMsg"],"mappings":"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"}
|