maplibre-gl-layer-control 0.16.0 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/dist/index.cjs +38 -175
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +38 -175
- package/dist/index.mjs.map +1 -1
- package/dist/maplibre-gl-layer-control.css +0 -57
- package/dist/types/index.d.ts +10 -26
- package/package.json +1 -1
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../src/lib/core/CustomLayerRegistry.ts","../src/lib/utils/layerUtils.ts","../src/lib/utils/styleCache.ts","../src/lib/utils/colorUtils.ts","../src/lib/utils/formatters.ts","../src/lib/utils/symbolUtils.ts","../src/lib/core/LayerControl.ts"],"sourcesContent":["import type { CustomLayerAdapter, LayerState } from './types';\n\n/**\n * Registry for managing custom layer adapters.\n * Routes layer operations to the appropriate adapter based on layer ID.\n */\nexport class CustomLayerRegistry {\n private adapters: Map<string, CustomLayerAdapter> = new Map();\n private changeListeners: Array<(event: 'add' | 'remove', layerId: string) => void> = [];\n private unsubscribers: Map<string, () => void> = new Map();\n\n /**\n * Register a custom layer adapter.\n * @param adapter The adapter to register\n */\n register(adapter: CustomLayerAdapter): void {\n this.adapters.set(adapter.type, adapter);\n\n // Subscribe to adapter's layer changes if supported\n if (adapter.onLayerChange) {\n const unsubscribe = adapter.onLayerChange((event, layerId) => {\n this.notifyChange(event, layerId);\n });\n this.unsubscribers.set(adapter.type, unsubscribe);\n }\n }\n\n /**\n * Unregister an adapter by type.\n * @param type The adapter type to unregister\n */\n unregister(type: string): void {\n // Clean up the subscription for this adapter\n const unsubscribe = this.unsubscribers.get(type);\n if (unsubscribe) {\n unsubscribe();\n this.unsubscribers.delete(type);\n }\n this.adapters.delete(type);\n }\n\n /**\n * Get all custom layer IDs across all adapters.\n * @returns Array of layer IDs\n */\n getAllLayerIds(): string[] {\n const ids: string[] = [];\n this.adapters.forEach(adapter => {\n ids.push(...adapter.getLayerIds());\n });\n return ids;\n }\n\n /**\n * Check if a layer ID is managed by any adapter.\n * @param layerId The layer ID to check\n * @returns true if the layer is managed by an adapter\n */\n hasLayer(layerId: string): boolean {\n for (const adapter of this.adapters.values()) {\n if (adapter.getLayerIds().includes(layerId)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Get the adapter responsible for a specific layer.\n * @param layerId The layer ID\n * @returns The adapter or null if not found\n */\n getAdapterForLayer(layerId: string): CustomLayerAdapter | null {\n for (const adapter of this.adapters.values()) {\n if (adapter.getLayerIds().includes(layerId)) {\n return adapter;\n }\n }\n return null;\n }\n\n /**\n * Get the state of a custom layer.\n * @param layerId The layer ID\n * @returns The layer state or null if not found\n */\n getLayerState(layerId: string): LayerState | null {\n const adapter = this.getAdapterForLayer(layerId);\n return adapter ? adapter.getLayerState(layerId) : null;\n }\n\n /**\n * Set visibility of a custom layer.\n * @param layerId The layer ID\n * @param visible Whether the layer should be visible\n * @returns true if the operation was handled by an adapter\n */\n setVisibility(layerId: string, visible: boolean): boolean {\n const adapter = this.getAdapterForLayer(layerId);\n if (adapter) {\n adapter.setVisibility(layerId, visible);\n return true;\n }\n return false;\n }\n\n /**\n * Set opacity of a custom layer.\n * @param layerId The layer ID\n * @param opacity The opacity value (0-1)\n * @returns true if the operation was handled by an adapter\n */\n setOpacity(layerId: string, opacity: number): boolean {\n const adapter = this.getAdapterForLayer(layerId);\n if (adapter) {\n adapter.setOpacity(layerId, opacity);\n return true;\n }\n return false;\n }\n\n /**\n * Get the symbol type for a custom layer (for UI display).\n * @param layerId The layer ID\n * @returns The symbol type or null if not available\n */\n getSymbolType(layerId: string): string | null {\n const adapter = this.getAdapterForLayer(layerId);\n if (adapter && adapter.getSymbolType) {\n return adapter.getSymbolType(layerId);\n }\n return null;\n }\n\n /**\n * Get the bounds of a custom layer (for zoom-to-layer).\n * @param layerId The layer ID\n * @returns The bounds [west, south, east, north] or null if not available\n */\n getBounds(layerId: string): [number, number, number, number] | null {\n const adapter = this.getAdapterForLayer(layerId);\n if (adapter && adapter.getBounds) {\n return adapter.getBounds(layerId);\n }\n return null;\n }\n\n /**\n * Get native MapLibre layer IDs for a custom layer.\n * @param layerId The custom layer ID\n * @returns Array of native layer IDs, or null if not available\n */\n getNativeLayerIds(layerId: string): string[] | null {\n const adapter = this.getAdapterForLayer(layerId);\n if (adapter && adapter.getNativeLayerIds) {\n return adapter.getNativeLayerIds(layerId);\n }\n return null;\n }\n\n /**\n * Remove a custom layer through its adapter.\n * @param layerId The layer ID to remove\n * @returns true if the operation was handled by an adapter\n */\n removeLayer(layerId: string): boolean {\n const adapter = this.getAdapterForLayer(layerId);\n if (adapter && adapter.removeLayer) {\n adapter.removeLayer(layerId);\n return true;\n }\n return false;\n }\n\n /**\n * Subscribe to layer changes across all adapters.\n * @param callback Function called when layers are added or removed\n * @returns Unsubscribe function\n */\n onChange(callback: (event: 'add' | 'remove', layerId: string) => void): () => void {\n this.changeListeners.push(callback);\n return () => {\n const idx = this.changeListeners.indexOf(callback);\n if (idx >= 0) {\n this.changeListeners.splice(idx, 1);\n }\n };\n }\n\n private notifyChange(event: 'add' | 'remove', layerId: string): void {\n this.changeListeners.forEach(cb => cb(event, layerId));\n }\n\n /**\n * Clean up all subscriptions and adapters.\n */\n destroy(): void {\n this.unsubscribers.forEach(unsub => unsub());\n this.unsubscribers.clear();\n this.adapters.clear();\n this.changeListeners = [];\n }\n}\n","import type { Map as MapLibreMap } from 'maplibre-gl';\nimport type { StyleableLayerType } from '../core/types';\n\n/**\n * Get the opacity property name for a given layer type\n * Supports all MapLibre layer types: fill, line, symbol, circle, heatmap,\n * fill-extrusion, raster, hillshade, color-relief, background\n * @param layerType MapLibre layer type\n * @returns Opacity property name(s), or null if the layer type doesn't support opacity\n */\nexport function getOpacityProperty(layerType: string): string | string[] | null {\n switch (layerType) {\n case 'fill':\n return 'fill-opacity';\n case 'line':\n return 'line-opacity';\n case 'circle':\n return 'circle-opacity';\n case 'symbol':\n // Symbol layers have both icon and text opacity\n return ['icon-opacity', 'text-opacity'];\n case 'raster':\n return 'raster-opacity';\n case 'background':\n return 'background-opacity';\n case 'heatmap':\n return 'heatmap-opacity';\n case 'fill-extrusion':\n return 'fill-extrusion-opacity';\n case 'hillshade':\n // Hillshade uses exaggeration for intensity, not opacity\n return 'hillshade-exaggeration';\n case 'color-relief':\n // Color-relief doesn't have a standard opacity property\n return null;\n default:\n // For custom layer types, try the standard pattern\n return `${layerType}-opacity`;\n }\n}\n\n/**\n * Get the current opacity value for a layer\n * @param map MapLibre map instance\n * @param layerId Layer ID\n * @param layerType Layer type\n * @returns Current opacity value (0-1), or 1.0 if the layer type doesn't support opacity\n */\nexport function getLayerOpacity(\n map: MapLibreMap,\n layerId: string,\n layerType: string\n): number {\n const opacityProp = getOpacityProperty(layerType);\n\n // Layer type doesn't support opacity\n if (opacityProp === null) {\n return 1.0;\n }\n\n if (Array.isArray(opacityProp)) {\n // For symbol layers, use icon-opacity as the primary value\n const opacity = map.getPaintProperty(layerId, opacityProp[0]);\n return (opacity !== undefined && opacity !== null) ? opacity as number : 1.0;\n }\n\n const opacity = map.getPaintProperty(layerId, opacityProp);\n return (opacity !== undefined && opacity !== null) ? opacity as number : 1.0;\n}\n\n/**\n * Set the opacity for a layer\n * @param map MapLibre map instance\n * @param layerId Layer ID\n * @param layerType Layer type\n * @param opacity Opacity value (0-1)\n */\nexport function setLayerOpacity(\n map: MapLibreMap,\n layerId: string,\n layerType: string,\n opacity: number\n): void {\n const opacityProp = getOpacityProperty(layerType);\n\n // Layer type doesn't support opacity\n if (opacityProp === null) {\n return;\n }\n\n if (Array.isArray(opacityProp)) {\n // For symbol layers, set both icon and text opacity\n opacityProp.forEach((prop) => {\n map.setPaintProperty(layerId, prop, opacity);\n });\n } else {\n map.setPaintProperty(layerId, opacityProp, opacity);\n }\n}\n\n/**\n * Check if a layer type supports style editing\n * @param layerType Layer type\n * @returns True if the layer type supports style editing\n */\nexport function isStyleableLayerType(layerType: string): layerType is StyleableLayerType {\n return [\n 'fill',\n 'line',\n 'circle',\n 'symbol',\n 'raster',\n 'heatmap',\n 'fill-extrusion',\n 'hillshade',\n ].includes(layerType);\n}\n\n/**\n * Get layer type from map\n * @param map MapLibre map instance\n * @param layerId Layer ID\n * @returns Layer type or null if layer not found\n */\nexport function getLayerType(map: MapLibreMap, layerId: string): string | null {\n try {\n const layer = map.getLayer(layerId);\n return layer ? layer.type : null;\n } catch (error) {\n console.warn(`Failed to get layer type for ${layerId}:`, error);\n return null;\n }\n}\n","import type { Map as MapLibreMap } from 'maplibre-gl';\nimport type { OriginalStyle } from '../core/types';\n\n/**\n * Deep clone a paint value (handles complex MapLibre expressions)\n * @param value Paint value to clone\n * @returns Cloned value\n */\nexport function clonePaintValue(value: any): any {\n if (Array.isArray(value)) {\n return value.map((item) => clonePaintValue(item));\n }\n if (value && typeof value === 'object') {\n try {\n return JSON.parse(JSON.stringify(value));\n } catch (error) {\n return value;\n }\n }\n return value;\n}\n\n/**\n * Cache the original paint properties for a layer\n * @param map MapLibre map instance\n * @param layerId Layer ID\n * @param originalStyles Map to store original styles\n */\nexport function cacheOriginalLayerStyle(\n map: MapLibreMap,\n layerId: string,\n originalStyles: Map<string, OriginalStyle>\n): void {\n if (originalStyles.has(layerId)) {\n return; // Already cached\n }\n\n try {\n const layer = map.getLayer(layerId);\n if (!layer) {\n return;\n }\n\n const paint: Record<string, any> = {};\n const style = map.getStyle();\n const layerDef = style.layers?.find(l => l.id === layerId);\n\n // For raster layers, handle all properties with defaults\n if (layer.type === 'raster') {\n // Default values from MapLibre GL spec\n const rasterDefaults: Record<string, number> = {\n 'raster-opacity': 1,\n 'raster-brightness-min': 0,\n 'raster-brightness-max': 1,\n 'raster-saturation': 0,\n 'raster-contrast': 0,\n 'raster-hue-rotate': 0\n };\n\n // Start with defaults\n Object.assign(paint, rasterDefaults);\n\n // Override with values from layer definition\n if (layerDef && 'paint' in layerDef && layerDef.paint) {\n Object.entries(layerDef.paint).forEach(([prop, value]) => {\n if (prop.startsWith('raster-')) {\n paint[prop] = clonePaintValue(value);\n }\n });\n }\n } else {\n // For non-raster layers, just get values from the layer definition\n if (layerDef && 'paint' in layerDef && layerDef.paint) {\n Object.entries(layerDef.paint).forEach(([prop, value]) => {\n paint[prop] = clonePaintValue(value);\n });\n }\n }\n\n originalStyles.set(layerId, { paint });\n } catch (error) {\n console.warn(`Failed to cache original style for ${layerId}:`, error);\n }\n}\n\n/**\n * Get the current value of a paint property\n * @param map MapLibre map instance\n * @param layerId Layer ID\n * @param property Property name\n * @param fallback Fallback value if property is not set\n * @returns Current property value\n */\nexport function getCurrentPaintValue(\n map: MapLibreMap,\n layerId: string,\n property: string,\n fallback?: any\n): any {\n try {\n const value = map.getPaintProperty(layerId, property);\n return value !== undefined ? value : fallback;\n } catch (error) {\n return fallback;\n }\n}\n\n/**\n * Restore original paint properties for a layer\n * @param map MapLibre map instance\n * @param layerId Layer ID\n * @param originalStyles Map of original styles\n * @returns Object with restored properties\n */\nexport function restoreOriginalStyle(\n map: MapLibreMap,\n layerId: string,\n originalStyles: Map<string, OriginalStyle>\n): Record<string, any> {\n const original = originalStyles.get(layerId);\n if (!original) {\n return {};\n }\n\n const applied: Record<string, any> = {};\n\n Object.entries(original.paint).forEach(([property, value]) => {\n try {\n const restoredValue = clonePaintValue(value);\n map.setPaintProperty(layerId, property, restoredValue);\n applied[property] = restoredValue;\n } catch (error) {\n console.warn(`Failed to restore ${property} for ${layerId}:`, error);\n }\n });\n\n return applied;\n}\n","/**\n * Convert RGB values to hex color string\n * @param r Red component (0-255)\n * @param g Green component (0-255)\n * @param b Blue component (0-255)\n * @returns Hex color string (e.g., '#ff0000')\n */\nexport function rgbToHex(r: number, g: number, b: number): string {\n const clamp = (v: number) => Math.max(0, Math.min(255, Math.round(v)));\n const toHex = (v: number) => {\n const hex = clamp(v).toString(16);\n return hex.length === 1 ? `0${hex}` : hex;\n };\n return `#${toHex(r)}${toHex(g)}${toHex(b)}`;\n}\n\n/**\n * Normalize a color value to hex format\n * Handles hex strings, RGB strings, and RGB arrays\n * @param value Color value in various formats\n * @returns Normalized hex color string (always 6 digits)\n */\nexport function normalizeColor(value: any): string {\n if (typeof value === 'string') {\n // Already hex format\n if (value.startsWith('#')) {\n // Expand shorthand hex (#RGB to #RRGGBB)\n if (value.length === 4) {\n const r = value[1];\n const g = value[2];\n const b = value[3];\n return `#${r}${r}${g}${g}${b}${b}`;\n }\n return value;\n }\n\n // RGB string format: 'rgb(51, 136, 255)'\n if (value.startsWith('rgb')) {\n const match = value.match(/\\d+/g);\n if (match && match.length >= 3) {\n const [r, g, b] = match.map((num) => parseInt(num, 10));\n return rgbToHex(r, g, b);\n }\n }\n } else if (Array.isArray(value) && value.length >= 3) {\n // RGB array format: [51, 136, 255]\n return rgbToHex(value[0], value[1], value[2]);\n }\n\n // Fallback color (MapLibre default blue)\n return '#3388ff';\n}\n","/**\n * Format a numeric value based on the step size\n * @param value Numeric value to format\n * @param step Step size (determines decimal places)\n * @returns Formatted string\n */\nexport function formatNumericValue(value: number, step: number): string {\n let decimals = 0;\n\n if (step && Number(step) !== 1) {\n const stepNumber = Number(step);\n if (stepNumber > 0 && stepNumber < 1) {\n decimals = Math.min(4, Math.ceil(Math.abs(Math.log10(stepNumber))));\n }\n }\n\n return value.toFixed(decimals);\n}\n\n/**\n * Clamp a numeric value between min and max\n * @param value Value to clamp\n * @param min Minimum value\n * @param max Maximum value\n * @returns Clamped value\n */\nexport function clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value));\n}\n","import type { Map as MapLibreMap, LayerSpecification } from 'maplibre-gl';\nimport { normalizeColor, rgbToHex } from './colorUtils';\n\n/**\n * Map of layer types to their primary color property\n */\nconst COLOR_PROPERTY_MAP: Record<string, string[]> = {\n fill: ['fill-color', 'fill-outline-color'],\n line: ['line-color'],\n circle: ['circle-color', 'circle-stroke-color'],\n symbol: ['icon-color', 'text-color'],\n background: ['background-color'],\n heatmap: ['heatmap-color'],\n 'fill-extrusion': ['fill-extrusion-color'],\n};\n\n/**\n * Extract the first color value from a MapLibre expression\n * Handles expressions like ['case', ...], ['match', ...], ['interpolate', ...]\n * @param expression The MapLibre expression to extract color from\n * @returns The first color found, or null\n */\nfunction extractColorFromExpression(expression: any[]): string | null {\n if (!Array.isArray(expression) || expression.length === 0) return null;\n\n // Recursively search for color values\n for (const item of expression) {\n if (typeof item === 'string') {\n // Check if it's a color string\n if (\n item.startsWith('#') ||\n item.startsWith('rgb') ||\n item.startsWith('hsl')\n ) {\n return normalizeColor(item);\n }\n } else if (Array.isArray(item)) {\n const result = extractColorFromExpression(item);\n if (result) return result;\n }\n }\n return null;\n}\n\n/**\n * Get the primary color from a layer's paint properties\n * @param map The MapLibre map instance\n * @param layerId The layer ID\n * @param layerType The layer type\n * @returns The normalized hex color, or null if not found\n */\nexport function getLayerColor(\n map: MapLibreMap,\n layerId: string,\n layerType: string\n): string | null {\n const propertyNames = COLOR_PROPERTY_MAP[layerType];\n if (!propertyNames) return null;\n\n // Try each property in order\n for (const propertyName of propertyNames) {\n // First try runtime property (may have been changed)\n try {\n const runtimeColor = map.getPaintProperty(layerId, propertyName);\n if (runtimeColor) {\n if (typeof runtimeColor === 'string') {\n return normalizeColor(runtimeColor);\n }\n if (Array.isArray(runtimeColor)) {\n // Handle expressions\n const extracted = extractColorFromExpression(runtimeColor);\n if (extracted) return extracted;\n }\n }\n } catch {\n // Property doesn't exist, continue\n }\n\n // Try from layer definition\n const style = map.getStyle();\n const layer = style?.layers?.find(\n (l: LayerSpecification) => l.id === layerId\n );\n if (layer && 'paint' in layer && layer.paint) {\n const paintColor = (layer.paint as Record<string, any>)[propertyName];\n if (paintColor) {\n if (typeof paintColor === 'string') {\n return normalizeColor(paintColor);\n }\n if (Array.isArray(paintColor)) {\n const extracted = extractColorFromExpression(paintColor);\n if (extracted) return extracted;\n }\n }\n }\n }\n\n return null;\n}\n\n/**\n * Get the primary color directly from a layer specification\n * @param layer The layer specification\n * @returns The normalized hex color, or null if not found\n */\nexport function getLayerColorFromSpec(layer: LayerSpecification): string | null {\n const propertyNames = COLOR_PROPERTY_MAP[layer.type];\n if (!propertyNames) return null;\n\n for (const propertyName of propertyNames) {\n if ('paint' in layer && layer.paint) {\n const paintColor = (layer.paint as Record<string, any>)[propertyName];\n if (paintColor) {\n if (typeof paintColor === 'string') {\n return normalizeColor(paintColor);\n }\n if (Array.isArray(paintColor)) {\n const extracted = extractColorFromExpression(paintColor);\n if (extracted) return extracted;\n }\n }\n }\n }\n\n return null;\n}\n\n/**\n * Darken a hex color by a given amount\n * @param hexColor The hex color to darken (e.g., '#ff0000')\n * @param amount Amount to darken (0-1, where 1 is fully black)\n * @returns The darkened hex color\n */\nexport function darkenColor(hexColor: string, amount: number): string {\n // Normalize to 6-digit hex\n let hex = hexColor.replace('#', '');\n if (hex.length === 3) {\n hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];\n }\n\n const r = Math.max(\n 0,\n parseInt(hex.slice(0, 2), 16) - Math.round(255 * amount)\n );\n const g = Math.max(\n 0,\n parseInt(hex.slice(2, 4), 16) - Math.round(255 * amount)\n );\n const b = Math.max(\n 0,\n parseInt(hex.slice(4, 6), 16) - Math.round(255 * amount)\n );\n return rgbToHex(r, g, b);\n}\n\n// SVG Symbol Templates\n\n/**\n * Create a fill symbol (filled rectangle)\n */\nfunction createFillSymbol(size: number, color: string): string {\n const padding = 2;\n const borderColor = darkenColor(color, 0.3);\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"${padding}\" y=\"${padding}\" width=\"${size - padding * 2}\" height=\"${size - padding * 2}\"\n fill=\"${color}\" stroke=\"${borderColor}\" stroke-width=\"1\" rx=\"1\"/>\n </svg>`;\n}\n\n/**\n * Create a line symbol (horizontal line)\n */\nfunction createLineSymbol(\n size: number,\n color: string,\n strokeWidth: number = 2\n): string {\n const y = size / 2;\n const padding = 2;\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <line x1=\"${padding}\" y1=\"${y}\" x2=\"${size - padding}\" y2=\"${y}\"\n stroke=\"${color}\" stroke-width=\"${strokeWidth}\" stroke-linecap=\"round\"/>\n </svg>`;\n}\n\n/**\n * Create a circle symbol (filled circle)\n */\nfunction createCircleSymbol(size: number, color: string): string {\n const cx = size / 2;\n const cy = size / 2;\n const r = size / 2 - 3;\n const borderColor = darkenColor(color, 0.3);\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"${cx}\" cy=\"${cy}\" r=\"${r}\" fill=\"${color}\"\n stroke=\"${borderColor}\" stroke-width=\"1\"/>\n </svg>`;\n}\n\n/**\n * Create a marker/pin symbol for symbol layers\n */\nfunction createMarkerSymbol(size: number, color: string): string {\n const borderColor = darkenColor(color, 0.3);\n // Simple pin/marker shape\n const cx = size / 2;\n const pinWidth = size * 0.5;\n const pinHeight = size * 0.7;\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M${cx} ${size - 2}\n L${cx - pinWidth / 2} ${size - pinHeight}\n A${pinWidth / 2} ${pinWidth / 2} 0 1 1 ${cx + pinWidth / 2} ${size - pinHeight}\n Z\"\n fill=\"${color}\" stroke=\"${borderColor}\" stroke-width=\"1\"/>\n <circle cx=\"${cx}\" cy=\"${size - pinHeight - pinWidth / 4}\" r=\"${pinWidth / 5}\" fill=\"white\"/>\n </svg>`;\n}\n\n/**\n * Create a raster symbol (gradient pattern)\n */\nfunction createRasterSymbol(size: number): string {\n const padding = 2;\n const id = `rasterGrad_${Math.random().toString(36).slice(2, 9)}`;\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <linearGradient id=\"${id}\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"100%\">\n <stop offset=\"0%\" stop-color=\"#e0e0e0\"/>\n <stop offset=\"50%\" stop-color=\"#808080\"/>\n <stop offset=\"100%\" stop-color=\"#404040\"/>\n </linearGradient>\n </defs>\n <rect x=\"${padding}\" y=\"${padding}\" width=\"${size - padding * 2}\" height=\"${size - padding * 2}\"\n fill=\"url(#${id})\" rx=\"1\"/>\n </svg>`;\n}\n\n/**\n * Create a background symbol (rectangle with inner indicator)\n */\nfunction createBackgroundSymbol(size: number, color: string): string {\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"1\" y=\"1\" width=\"${size - 2}\" height=\"${size - 2}\" fill=\"${color}\" rx=\"2\"/>\n <rect x=\"3\" y=\"3\" width=\"${size - 6}\" height=\"${size - 6}\" fill=\"none\"\n stroke=\"white\" stroke-width=\"1\" stroke-opacity=\"0.5\" rx=\"1\"/>\n </svg>`;\n}\n\n/**\n * Create a heatmap symbol (orange-red gradient)\n */\nfunction createHeatmapSymbol(size: number): string {\n const padding = 2;\n const id = `heatmapGrad_${Math.random().toString(36).slice(2, 9)}`;\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <radialGradient id=\"${id}\" cx=\"50%\" cy=\"50%\" r=\"50%\">\n <stop offset=\"0%\" stop-color=\"#ffff00\"/>\n <stop offset=\"50%\" stop-color=\"#ff8800\"/>\n <stop offset=\"100%\" stop-color=\"#ff0000\"/>\n </radialGradient>\n </defs>\n <rect x=\"${padding}\" y=\"${padding}\" width=\"${size - padding * 2}\" height=\"${size - padding * 2}\"\n fill=\"url(#${id})\" rx=\"1\"/>\n </svg>`;\n}\n\n/**\n * Create a hillshade symbol (gray gradient)\n */\nfunction createHillshadeSymbol(size: number): string {\n const padding = 2;\n const id = `hillshadeGrad_${Math.random().toString(36).slice(2, 9)}`;\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <linearGradient id=\"${id}\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"100%\">\n <stop offset=\"0%\" stop-color=\"#ffffff\"/>\n <stop offset=\"100%\" stop-color=\"#666666\"/>\n </linearGradient>\n </defs>\n <rect x=\"${padding}\" y=\"${padding}\" width=\"${size - padding * 2}\" height=\"${size - padding * 2}\"\n fill=\"url(#${id})\" rx=\"1\"/>\n </svg>`;\n}\n\n/**\n * Create a fill-extrusion symbol (3D-ish rectangle)\n */\nfunction createFillExtrusionSymbol(size: number, color: string): string {\n const borderColor = darkenColor(color, 0.3);\n const topColor = color;\n const sideColor = darkenColor(color, 0.2);\n const depth = 3;\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <polygon points=\"${2 + depth},2 ${size - 2},2 ${size - 2},${size - 2 - depth} ${size - 2 - depth},${size - 2} 2,${size - 2} 2,${2 + depth}\"\n fill=\"${topColor}\" stroke=\"${borderColor}\" stroke-width=\"1\"/>\n <polygon points=\"2,${2 + depth} ${2 + depth},2 ${2 + depth},${size - 2 - depth} 2,${size - 2}\"\n fill=\"${sideColor}\" stroke=\"${borderColor}\" stroke-width=\"0.5\"/>\n <polygon points=\"${2 + depth},${size - 2 - depth} ${size - 2},${size - 2 - depth} ${size - 2 - depth},${size - 2} 2,${size - 2}\"\n fill=\"${sideColor}\" stroke=\"${borderColor}\" stroke-width=\"0.5\"/>\n </svg>`;\n}\n\n/**\n * Create a default symbol (simple square)\n */\nfunction createDefaultSymbol(size: number, color: string): string {\n const padding = 2;\n const borderColor = darkenColor(color, 0.3);\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"${padding}\" y=\"${padding}\" width=\"${size - padding * 2}\" height=\"${size - padding * 2}\"\n fill=\"${color}\" stroke=\"${borderColor}\" stroke-width=\"1\"/>\n </svg>`;\n}\n\n/**\n * Create a COG (Cloud Optimized GeoTIFF) symbol\n * Grid pattern representing raster tiles\n */\nfunction createCOGSymbol(size: number, color: string): string {\n const padding = 2;\n const borderColor = darkenColor(color, 0.3);\n const cellSize = (size - padding * 2) / 2;\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"${padding}\" y=\"${padding}\" width=\"${cellSize}\" height=\"${cellSize}\" fill=\"${color}\" stroke=\"${borderColor}\" stroke-width=\"0.5\"/>\n <rect x=\"${padding + cellSize}\" y=\"${padding}\" width=\"${cellSize}\" height=\"${cellSize}\" fill=\"${color}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" opacity=\"0.8\"/>\n <rect x=\"${padding}\" y=\"${padding + cellSize}\" width=\"${cellSize}\" height=\"${cellSize}\" fill=\"${color}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" opacity=\"0.6\"/>\n <rect x=\"${padding + cellSize}\" y=\"${padding + cellSize}\" width=\"${cellSize}\" height=\"${cellSize}\" fill=\"${color}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" opacity=\"0.4\"/>\n </svg>`;\n}\n\n/**\n * Create a Zarr symbol\n * Layered grid pattern representing multidimensional data\n */\nfunction createZarrSymbol(size: number, color: string): string {\n const padding = 2;\n const borderColor = darkenColor(color, 0.3);\n const innerSize = size - padding * 2;\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"${padding + 2}\" y=\"${padding}\" width=\"${innerSize - 2}\" height=\"${innerSize - 2}\" fill=\"${darkenColor(color, 0.2)}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" rx=\"1\"/>\n <rect x=\"${padding + 1}\" y=\"${padding + 1}\" width=\"${innerSize - 2}\" height=\"${innerSize - 2}\" fill=\"${darkenColor(color, 0.1)}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" rx=\"1\"/>\n <rect x=\"${padding}\" y=\"${padding + 2}\" width=\"${innerSize - 2}\" height=\"${innerSize - 2}\" fill=\"${color}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" rx=\"1\"/>\n <line x1=\"${padding + 3}\" y1=\"${padding + 5}\" x2=\"${padding + innerSize - 5}\" y2=\"${padding + 5}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" opacity=\"0.5\"/>\n <line x1=\"${padding + 3}\" y1=\"${padding + 8}\" x2=\"${padding + innerSize - 5}\" y2=\"${padding + 8}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" opacity=\"0.5\"/>\n </svg>`;\n}\n\n/**\n * Create a generic custom raster symbol\n * Gradient grid representing custom raster layers\n */\nfunction createCustomRasterSymbol(size: number, color: string): string {\n const padding = 2;\n const borderColor = darkenColor(color, 0.3);\n const id = `customRasterGrad_${Math.random().toString(36).slice(2, 9)}`;\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <linearGradient id=\"${id}\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"100%\">\n <stop offset=\"0%\" stop-color=\"${color}\"/>\n <stop offset=\"100%\" stop-color=\"${darkenColor(color, 0.4)}\"/>\n </linearGradient>\n </defs>\n <rect x=\"${padding}\" y=\"${padding}\" width=\"${size - padding * 2}\" height=\"${size - padding * 2}\"\n fill=\"url(#${id})\" stroke=\"${borderColor}\" stroke-width=\"1\" rx=\"1\"/>\n <line x1=\"${size / 2}\" y1=\"${padding}\" x2=\"${size / 2}\" y2=\"${size - padding}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" opacity=\"0.3\"/>\n <line x1=\"${padding}\" y1=\"${size / 2}\" x2=\"${size - padding}\" y2=\"${size / 2}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" opacity=\"0.3\"/>\n </svg>`;\n}\n\n/**\n * Create a stacked layers symbol for background layer groups\n * Shows multiple overlapping rectangles to represent multiple layers\n */\nfunction createStackedLayersSymbol(size: number): string {\n const colors = ['#a8d4a8', '#8ec4e8', '#d4c4a8'];\n const borderColor = '#666666';\n // Three stacked rectangles offset diagonally\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"4\" y=\"1\" width=\"${size - 6}\" height=\"${size - 6}\" fill=\"${colors[2]}\" stroke=\"${borderColor}\" stroke-width=\"0.75\" rx=\"1\"/>\n <rect x=\"2\" y=\"3\" width=\"${size - 6}\" height=\"${size - 6}\" fill=\"${colors[1]}\" stroke=\"${borderColor}\" stroke-width=\"0.75\" rx=\"1\"/>\n <rect x=\"0\" y=\"5\" width=\"${size - 6}\" height=\"${size - 6}\" fill=\"${colors[0]}\" stroke=\"${borderColor}\" stroke-width=\"0.75\" rx=\"1\"/>\n </svg>`;\n}\n\n/**\n * Symbol generation options\n */\nexport interface SymbolOptions {\n /** Symbol size in pixels (default: 16) */\n size?: number;\n /** Stroke width for line symbols (default: 2) */\n strokeWidth?: number;\n}\n\n/**\n * Create an SVG symbol for a layer type\n * @param layerType The MapLibre layer type\n * @param color The primary color (hex format), or null for default\n * @param options Optional configuration\n * @returns SVG markup string\n */\nexport function createLayerSymbolSVG(\n layerType: string,\n color: string | null,\n options: SymbolOptions = {}\n): string {\n const size = options.size || 16;\n const strokeWidth = options.strokeWidth || 2;\n const fillColor = color || '#888888'; // Fallback gray\n\n switch (layerType) {\n case 'fill':\n return createFillSymbol(size, fillColor);\n case 'line':\n return createLineSymbol(size, fillColor, strokeWidth);\n case 'circle':\n return createCircleSymbol(size, fillColor);\n case 'symbol':\n return createMarkerSymbol(size, fillColor);\n case 'raster':\n return createRasterSymbol(size);\n case 'background':\n return createBackgroundSymbol(size, fillColor);\n case 'heatmap':\n return createHeatmapSymbol(size);\n case 'hillshade':\n return createHillshadeSymbol(size);\n case 'fill-extrusion':\n return createFillExtrusionSymbol(size, fillColor);\n case 'background-group':\n return createStackedLayersSymbol(size);\n case 'cog':\n return createCOGSymbol(size, fillColor);\n case 'zarr':\n return createZarrSymbol(size, fillColor);\n case 'custom-raster':\n return createCustomRasterSymbol(size, fillColor);\n default:\n return createDefaultSymbol(size, fillColor);\n }\n}\n\n/**\n * Create an SVG symbol for the Background layer group\n * @param size Symbol size in pixels (default: 16)\n * @returns SVG markup string\n */\nexport function createBackgroundGroupSymbolSVG(size: number = 16): string {\n return createStackedLayersSymbol(size);\n}\n","import type {\n IControl,\n Map as MapLibreMap,\n LayerSpecification,\n} from \"maplibre-gl\";\nimport type {\n LayerControlOptions,\n LayerState,\n PartialLayerStates,\n OriginalStyle,\n InternalControlState,\n CustomLayerAdapter,\n BackgroundLayerVisibility,\n BackgroundPresets,\n} from \"./types\";\nimport { CustomLayerRegistry } from \"./CustomLayerRegistry\";\nimport {\n getLayerType,\n getLayerOpacity,\n setLayerOpacity,\n} from \"../utils/layerUtils\";\nimport {\n cacheOriginalLayerStyle,\n restoreOriginalStyle,\n} from \"../utils/styleCache\";\nimport { normalizeColor } from \"../utils/colorUtils\";\nimport { formatNumericValue, clamp } from \"../utils/formatters\";\nimport {\n getLayerColor,\n getLayerColorFromSpec,\n createLayerSymbolSVG,\n createBackgroundGroupSymbolSVG,\n} from \"../utils/symbolUtils\";\n\n/**\n * LayerControl - A comprehensive layer control for MapLibre GL\n * Provides visibility toggle, opacity control, and advanced style editing\n */\nexport class LayerControl implements IControl {\n private map!: MapLibreMap;\n private mapContainer!: HTMLElement;\n private container!: HTMLDivElement;\n private button!: HTMLButtonElement;\n private panel!: HTMLDivElement;\n\n // Panel positioning\n private resizeHandler: (() => void) | null = null;\n private mapResizeHandler: (() => void) | null = null;\n\n // State management\n private state: InternalControlState;\n private targetLayers: string[];\n private styleEditors: Map<string, HTMLElement>;\n private initialSourceIds: Set<string> | null = null;\n private initialLayerIds: Set<string> | null = null;\n private initialLayerStates: PartialLayerStates;\n\n // Panel width management\n private minPanelWidth: number;\n private maxPanelWidth: number;\n private initialPanelWidth: number;\n private maxPanelHeight: number;\n private showStyleEditor: boolean;\n private showOpacitySlider: boolean;\n private showLayerSymbol: boolean;\n private excludeDrawnLayers: boolean;\n private excludeLayerPatterns: RegExp[];\n private customLayerRegistry: CustomLayerRegistry | null = null;\n private customLayerUnsubscribe: (() => void) | null = null;\n private removedCustomLayerIds: Set<string> = new Set();\n private nativeLayerGroups: Map<string, string[]> = new Map();\n private basemapStyleUrl: string | null = null;\n private basemapLayerIds: Set<string> | null = null;\n private widthSliderEl: HTMLElement | null = null;\n private widthThumbEl: HTMLElement | null = null;\n private widthValueEl: HTMLElement | null = null;\n private isWidthSliderActive = false;\n private widthDragRectWidth: number | null = null;\n private widthDragStartX: number | null = null;\n private widthDragStartWidth: number | null = null;\n private widthFrame: number | null = null;\n\n // Exact-opacity input popup\n private opacityInputEl: HTMLDivElement | null = null;\n\n // Panel edge-drag resizing (handles on both the left and right edges)\n private resizeHandleEls: HTMLDivElement[] = [];\n /** Which edge is anchored to the control corner (the other edge is \"free\") */\n private panelAnchorSide: \"left\" | \"right\" = \"right\";\n private isPanelResizing = false;\n /** The physical edge being dragged in the current resize gesture */\n private panelResizeEdge: \"left\" | \"right\" = \"left\";\n private panelResizeStartX: number | null = null;\n private panelResizeStartWidth: number | null = null;\n private panelResizeStartOffset = 0;\n\n // Context menu and drag-drop\n private contextMenuEl: HTMLDivElement | null = null;\n private enableContextMenu: boolean;\n private enableDragAndDrop: boolean;\n private onLayerRename?: (\n layerId: string,\n oldName: string,\n newName: string,\n ) => void;\n private onLayerReorder?: (layerOrder: string[]) => void;\n private onLayerRemove?: (layerId: string) => void;\n\n // Background-layer visibility presets\n private enableBackgroundPresets: boolean;\n private backgroundPresetStorageKey: string;\n private onBackgroundPresetsChange?: (presets: BackgroundPresets) => void;\n\n constructor(options: LayerControlOptions = {}) {\n this.minPanelWidth = options.panelMinWidth || 240;\n this.maxPanelWidth = options.panelMaxWidth || 420;\n this.initialPanelWidth = options.panelWidth || 350;\n this.maxPanelHeight = options.panelMaxHeight || 600;\n this.showStyleEditor = options.showStyleEditor !== false;\n this.showOpacitySlider = options.showOpacitySlider !== false;\n this.showLayerSymbol = options.showLayerSymbol !== false;\n this.excludeDrawnLayers = options.excludeDrawnLayers !== false;\n this.excludeLayerPatterns = this.wildcardPatternsToRegex(\n options.excludeLayers || [],\n );\n\n // Context menu and drag-drop options\n this.enableContextMenu = options.enableContextMenu !== false;\n this.enableDragAndDrop = options.enableDragAndDrop !== false;\n this.onLayerRename = options.onLayerRename;\n this.onLayerReorder = options.onLayerReorder;\n this.onLayerRemove = options.onLayerRemove;\n\n // Background-layer visibility presets\n this.enableBackgroundPresets = options.enableBackgroundPresets !== false;\n this.backgroundPresetStorageKey =\n options.backgroundPresetStorageKey ||\n \"maplibre-layer-control:background-presets\";\n this.onBackgroundPresetsChange = options.onBackgroundPresetsChange;\n\n this.initialLayerStates = options.layerStates || {};\n\n this.state = {\n collapsed: options.collapsed !== false,\n panelWidth: options.panelWidth || 350,\n activeStyleEditor: null,\n layerStates: {},\n originalStyles: new Map<string, OriginalStyle>(),\n userInteractingWithSlider: false,\n backgroundLegendOpen: false,\n backgroundLayerVisibility: new Map<string, boolean>(),\n onlyRenderedFilter: false,\n contextMenu: {\n visible: false,\n targetLayerId: null,\n x: 0,\n y: 0,\n },\n renamingLayerId: null,\n customLayerNames: new Map<string, string>(),\n drag: {\n active: false,\n layerId: null,\n startY: 0,\n currentY: 0,\n placeholder: null,\n draggedElement: null,\n },\n isStyleOperationInProgress: false,\n };\n\n this.targetLayers = options.layers || Object.keys(this.initialLayerStates);\n this.styleEditors = new Map<string, HTMLElement>();\n\n // Initialize custom layer registry if adapters are provided\n if (options.customLayerAdapters && options.customLayerAdapters.length > 0) {\n this.customLayerRegistry = new CustomLayerRegistry();\n options.customLayerAdapters.forEach((adapter) => {\n this.customLayerRegistry!.register(adapter);\n });\n }\n\n // Store basemap style URL for reliable layer detection\n this.basemapStyleUrl = options.basemapStyleUrl || null;\n }\n\n /**\n * Called when the control is added to the map\n */\n onAdd(map: MapLibreMap): HTMLElement {\n this.map = map;\n this.mapContainer = map.getContainer();\n\n // Capture initial source IDs and layer IDs (basemap) before auto-detecting layers\n // Sources and layers added after this point are considered user-added\n const style = this.map.getStyle();\n if (style && style.sources) {\n this.initialSourceIds = new Set(Object.keys(style.sources));\n } else {\n this.initialSourceIds = new Set();\n }\n\n // Capture initial layer IDs - any layer added after this is user-added\n if (style && style.layers) {\n this.initialLayerIds = new Set(style.layers.map((layer) => layer.id));\n } else {\n this.initialLayerIds = new Set();\n }\n\n this.container = this.createContainer();\n this.button = this.createToggleButton();\n this.panel = this.createPanel();\n\n this.container.appendChild(this.button);\n // Append panel to map container for independent positioning (avoids overlap with other controls)\n this.mapContainer.appendChild(this.panel);\n\n // Create context menu element (appended to map container)\n if (this.enableContextMenu) {\n this.contextMenuEl = this.createContextMenu();\n this.mapContainer.appendChild(this.contextMenuEl);\n }\n\n // Now that panel is attached, update width display\n this.updateWidthDisplay();\n\n // Setup event listeners\n this.setupEventListeners();\n\n // If basemapStyleUrl is provided, fetch it first for reliable layer detection\n if (this.basemapStyleUrl && !this.basemapLayerIds) {\n this.fetchBasemapStyle()\n .then(() => {\n // Auto-detect layers after basemap style is fetched\n if (Object.keys(this.state.layerStates).length === 0) {\n this.autoDetectLayers();\n }\n // Build layer items\n this.buildLayerItems();\n })\n .catch((error) => {\n console.warn(\n \"Failed to fetch basemap style, falling back to heuristic detection:\",\n error,\n );\n // Fall back to heuristic detection\n if (Object.keys(this.state.layerStates).length === 0) {\n this.autoDetectLayers();\n }\n this.buildLayerItems();\n });\n } else {\n // Auto-detect layers using source-based heuristics\n if (Object.keys(this.state.layerStates).length === 0) {\n this.autoDetectLayers();\n }\n // Build layer items\n this.buildLayerItems();\n }\n\n // If panel starts expanded, update position after control is added to DOM\n if (!this.state.collapsed) {\n // Use requestAnimationFrame to wait until container is in DOM and positioned\n requestAnimationFrame(() => {\n this.updatePanelPosition();\n });\n }\n\n return this.container;\n }\n\n /**\n * Fetch the basemap style JSON and extract layer IDs.\n * This provides reliable distinction between basemap and user-added layers.\n */\n private async fetchBasemapStyle(): Promise<void> {\n if (!this.basemapStyleUrl) return;\n\n try {\n const response = await fetch(this.basemapStyleUrl);\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n const styleJson = await response.json();\n\n // Extract layer IDs from the basemap style\n if (styleJson && Array.isArray(styleJson.layers)) {\n this.basemapLayerIds = new Set(\n styleJson.layers.map((layer: { id: string }) => layer.id),\n );\n } else {\n this.basemapLayerIds = new Set();\n }\n } catch (error) {\n console.warn(\n \"Failed to fetch basemap style from URL:\",\n this.basemapStyleUrl,\n error,\n );\n throw error;\n }\n }\n\n /**\n * Called when the control is removed from the map\n */\n onRemove(): void {\n // Clean up custom layer registry subscription\n if (this.customLayerUnsubscribe) {\n this.customLayerUnsubscribe();\n this.customLayerUnsubscribe = null;\n }\n if (this.customLayerRegistry) {\n this.customLayerRegistry.destroy();\n this.customLayerRegistry = null;\n }\n\n // Remove resize event listeners\n if (this.resizeHandler) {\n window.removeEventListener(\"resize\", this.resizeHandler);\n this.resizeHandler = null;\n }\n if (this.mapResizeHandler) {\n this.map.off(\"resize\", this.mapResizeHandler);\n this.mapResizeHandler = null;\n }\n\n // Clean up context menu\n if (this.contextMenuEl) {\n this.contextMenuEl.parentNode?.removeChild(this.contextMenuEl);\n this.contextMenuEl = null;\n }\n\n // Clean up the exact-opacity input popup\n this.hideOpacityInput();\n\n // Clean up any active drag state\n this.cleanupDragState();\n\n // Remove panel from map container\n this.panel.parentNode?.removeChild(this.panel);\n\n // Remove button container from control stack\n this.container.parentNode?.removeChild(this.container);\n }\n\n /**\n * Auto-detect layers from the map and populate layerStates\n */\n private autoDetectLayers(): void {\n const style = this.map.getStyle();\n if (!style || !style.layers) {\n return;\n }\n\n // Get all layer IDs from the map\n const allLayerIds = style.layers.map((layer) => layer.id);\n\n if (this.targetLayers.length === 0) {\n // No layers specified - auto-detect user-added layers vs background layers\n const userAddedLayers: string[] = [];\n const backgroundLayerIds: string[] = [];\n\n // Detection priority for INITIAL detection:\n // 1. basemapLayerIds (from basemapStyleUrl) - most reliable\n // 2. Source-based heuristics - works for layers added before OR after control\n // Note: initialLayerIds is NOT used here because it would incorrectly classify\n // user layers added BEFORE the control as basemap layers\n const useBasemapStyleDetection =\n this.basemapLayerIds !== null && this.basemapLayerIds.size > 0;\n\n // Identify which sources are user-added (for source-based heuristic detection)\n const userAddedSourceIds = useBasemapStyleDetection\n ? new Set<string>()\n : this.detectUserAddedSources();\n\n allLayerIds.forEach((layerId) => {\n const layer = this.map.getLayer(layerId);\n if (!layer) return;\n\n // Skip drawn layers if excludeDrawnLayers is enabled\n if (this.excludeDrawnLayers && this.isDrawnLayer(layerId)) {\n backgroundLayerIds.push(layerId);\n return;\n }\n\n // Skip layers matching user-defined exclusion patterns\n if (this.isExcludedByPattern(layerId)) {\n backgroundLayerIds.push(layerId);\n return;\n }\n\n if (useBasemapStyleDetection) {\n // Use basemap style layer IDs for reliable detection\n if (this.basemapLayerIds!.has(layerId)) {\n // This layer is from the basemap style\n backgroundLayerIds.push(layerId);\n } else {\n // This layer is not in the basemap style - it's user-added\n userAddedLayers.push(layerId);\n }\n } else {\n // Use source-based heuristics\n // Check if this layer uses a user-added source\n const sourceId = (layer as any).source;\n if (sourceId && userAddedSourceIds.has(sourceId)) {\n userAddedLayers.push(layerId);\n } else {\n // Layer uses a basemap source or has no source (like background color layer)\n backgroundLayerIds.push(layerId);\n }\n }\n });\n\n // Add Background entry if there are background layers\n if (backgroundLayerIds.length > 0) {\n this.state.layerStates[\"Background\"] = {\n visible: true,\n opacity: 1.0,\n name: \"Background\",\n };\n }\n\n // Add entries for auto-detected user layers\n userAddedLayers.forEach((layerId) => {\n const layer = this.map.getLayer(layerId);\n if (!layer) return;\n\n const visibility = this.map.getLayoutProperty(layerId, \"visibility\");\n const isVisible = visibility !== \"none\";\n const layerType = layer.type;\n const opacity = getLayerOpacity(this.map, layerId, layerType);\n const friendlyName = this.generateFriendlyName(layerId);\n\n this.state.layerStates[layerId] = this.mergeWithUserState(layerId, {\n visible: isVisible,\n opacity: opacity,\n name: friendlyName,\n });\n });\n } else {\n // Specific layers requested - separate into user layers + Background\n const userLayers: string[] = [];\n const basemapLayers: string[] = [];\n\n allLayerIds.forEach((layerId) => {\n // Skip layers matching user-defined exclusion patterns\n if (this.isExcludedByPattern(layerId)) {\n basemapLayers.push(layerId);\n return;\n }\n\n if (this.targetLayers.includes(layerId)) {\n userLayers.push(layerId);\n } else {\n basemapLayers.push(layerId);\n }\n });\n\n // Add Background entry if there are basemap layers\n if (basemapLayers.length > 0) {\n this.state.layerStates[\"Background\"] = {\n visible: true,\n opacity: 1.0,\n name: \"Background\",\n };\n }\n\n // Add entries for user-specified layers\n userLayers.forEach((layerId) => {\n const layer = this.map.getLayer(layerId);\n if (!layer) return;\n\n const visibility = this.map.getLayoutProperty(layerId, \"visibility\");\n const isVisible = visibility !== \"none\";\n const layerType = layer.type;\n const opacity = getLayerOpacity(this.map, layerId, layerType);\n const friendlyName = this.generateFriendlyName(layerId);\n\n this.state.layerStates[layerId] = this.mergeWithUserState(layerId, {\n visible: isVisible,\n opacity: opacity,\n name: friendlyName,\n });\n });\n }\n\n // Detect custom layers from registry\n if (this.customLayerRegistry) {\n const customLayerIds = this.customLayerRegistry.getAllLayerIds();\n customLayerIds.forEach((layerId) => {\n // Skip if already in state\n if (this.state.layerStates[layerId]) return;\n\n const customState = this.customLayerRegistry!.getLayerState(layerId);\n if (customState) {\n this.state.layerStates[layerId] = {\n visible: customState.visible,\n opacity: customState.opacity,\n name: customState.name,\n isCustomLayer: true,\n customLayerType:\n this.customLayerRegistry!.getSymbolType(layerId) || undefined,\n };\n }\n });\n }\n\n // Update targetLayers to include detected layers\n this.targetLayers = Object.keys(this.state.layerStates);\n }\n\n /**\n * Detect which sources are user-added (not from the basemap style)\n * User-added sources are identified by:\n * - Sources that were NOT present when the control was first added\n * - Additionally for sources added later:\n * - GeoJSON sources with inline data objects (not URL strings)\n * - Image, video, canvas sources\n * - Raster, raster-dem, vector sources from non-basemap tile providers\n */\n private detectUserAddedSources(): Set<string> {\n const userAddedSources = new Set<string>();\n const style = this.map.getStyle();\n if (!style || !style.sources) return userAddedSources;\n\n // First, detect the basemap's domain from sprite/glyphs URLs\n const basemapDomains = new Set<string>();\n\n // Known basemap providers\n const knownBasemapProviders = [\n \"demotiles.maplibre.org\",\n \"api.maptiler.com\",\n \"tiles.stadiamaps.com\",\n \"api.mapbox.com\",\n \"basemaps.cartocdn.com\",\n \"tiles.mapbox.com\",\n \"a.basemaps.cartocdn.com\",\n \"b.basemaps.cartocdn.com\",\n \"c.basemaps.cartocdn.com\",\n \"d.basemaps.cartocdn.com\",\n \"tiles.arcgis.com\",\n \"server.arcgisonline.com\",\n \"services.arcgisonline.com\",\n ];\n\n // Detect domains from sprite/glyphs URLs (these are likely basemap domains)\n const spriteUrl = style.sprite as string | undefined;\n if (spriteUrl && typeof spriteUrl === \"string\") {\n try {\n const url = new URL(spriteUrl);\n basemapDomains.add(url.hostname);\n } catch {\n /* ignore */\n }\n }\n if (style.glyphs) {\n try {\n const url = new URL(\n style.glyphs.replace(\"{fontstack}\", \"x\").replace(\"{range}\", \"x\"),\n );\n basemapDomains.add(url.hostname);\n } catch {\n /* ignore */\n }\n }\n\n // Check each source\n for (const [sourceId, source] of Object.entries(style.sources)) {\n // If we have a snapshot of initial sources, use that as the primary check\n // Sources that existed when the control was added are basemap sources\n if (this.initialSourceIds && this.initialSourceIds.has(sourceId)) {\n // This source was present in the initial style, it's a basemap source\n continue;\n }\n\n const src = source as any;\n const sourceType = src.type;\n\n // Image, video, and canvas sources are always user-added\n if (\n sourceType === \"image\" ||\n sourceType === \"video\" ||\n sourceType === \"canvas\"\n ) {\n userAddedSources.add(sourceId);\n continue;\n }\n\n // GeoJSON sources with inline data objects are user-added (if added after initial load)\n if (sourceType === \"geojson\") {\n if (src.data && typeof src.data === \"object\") {\n userAddedSources.add(sourceId);\n } else if (src.data && typeof src.data === \"string\") {\n // GeoJSON with URL - check if it's from a basemap domain\n try {\n const url = new URL(src.data);\n const isBasemap =\n knownBasemapProviders.some((p) => url.hostname.includes(p)) ||\n basemapDomains.has(url.hostname);\n if (!isBasemap) {\n userAddedSources.add(sourceId);\n }\n } catch {\n // Relative URL or invalid - assume user-added\n userAddedSources.add(sourceId);\n }\n }\n continue;\n }\n\n // Check tile URLs for raster, raster-dem, and vector sources\n if (\n sourceType === \"raster\" ||\n sourceType === \"raster-dem\" ||\n sourceType === \"vector\"\n ) {\n const tileUrl = src.url || (src.tiles && src.tiles[0]) || \"\";\n if (tileUrl) {\n try {\n const url = new URL(tileUrl.replace(/{[^}]+}/g, \"0\"));\n const hostname = url.hostname;\n\n // Check if this is a known basemap provider\n const isKnownBasemap = knownBasemapProviders.some(\n (provider) =>\n hostname === provider || hostname.endsWith(\".\" + provider),\n );\n\n // Check if this matches detected basemap domains\n const matchesBasemapDomain = basemapDomains.has(hostname);\n\n // If not a basemap source, it's user-added\n if (!isKnownBasemap && !matchesBasemapDomain) {\n userAddedSources.add(sourceId);\n }\n } catch {\n // If URL parsing fails, assume it could be user-added\n userAddedSources.add(sourceId);\n }\n }\n }\n }\n\n return userAddedSources;\n }\n\n /**\n * Generate a friendly display name from a layer ID\n */\n private generateFriendlyName(layerId: string): string {\n // Remove common prefixes\n let name = layerId.replace(/^(layer[-_]?|gl[-_]?)/, \"\");\n\n // Replace dashes and underscores with spaces\n name = name.replace(/[-_]/g, \" \");\n\n // Capitalize first letter of each word\n name = name.replace(/\\b\\w/g, (char) => char.toUpperCase());\n\n return name || layerId; // Fallback to original if empty\n }\n\n /**\n * Merge auto-detected layer state with user-provided initial state.\n * User-provided values take precedence over detected values.\n */\n private mergeWithUserState(\n layerId: string,\n detected: LayerState,\n ): LayerState {\n const userState = this.initialLayerStates[layerId];\n if (!userState) return detected;\n\n return {\n visible: userState.visible ?? detected.visible,\n opacity: userState.opacity ?? detected.opacity,\n name: userState.name ?? detected.name,\n ...(userState.isCustomLayer !== undefined && {\n isCustomLayer: userState.isCustomLayer,\n }),\n ...(userState.customLayerType !== undefined && {\n customLayerType: userState.customLayerType,\n }),\n };\n }\n\n /**\n * Check if a layer ID belongs to a drawing library (Geoman, Mapbox GL Draw, etc.)\n * @param layerId The layer ID to check\n * @returns true if the layer is from a drawing library\n */\n private isDrawnLayer(layerId: string): boolean {\n const drawnLayerPatterns = [\n // Drawing libraries\n /^gm[-_\\s]/i, // Geoman (gm-main-*, gm_*, Gm Temporary...)\n /^gl-draw[-_]/i, // Mapbox GL Draw\n /^mapbox-gl-draw[-_]/i, // Mapbox GL Draw alternative\n /^terra-draw[-_]/i, // Terra Draw\n /^maplibre-gl-draw[-_]/i, // MapLibre GL Draw\n /^draw[-_]layer/i, // Generic draw layers\n // maplibre-gl-components internal layers\n /^measure-/i, // MeasureControl (measure-{id}-fill, measure-{id}-line)\n /^pmtiles-source-/i, // PMTilesLayerControl (managed via adapter)\n /^stac-search-footprints/i, // StacSearchControl footprint layers\n ];\n\n return drawnLayerPatterns.some((pattern) => pattern.test(layerId));\n }\n\n /**\n * Convert wildcard patterns (e.g., '*-temp-*', 'debug-*') to RegExp objects\n */\n private wildcardPatternsToRegex(patterns: string[]): RegExp[] {\n return patterns.map((pattern) => {\n // Escape special regex characters except *\n const escaped = pattern.replace(/[.+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n // Convert * to .* for wildcard matching\n const regexStr = escaped.replace(/\\*/g, \".*\");\n return new RegExp(`^${regexStr}$`, \"i\");\n });\n }\n\n /**\n * Check if a layer matches any of the user-defined exclusion patterns\n */\n private isExcludedByPattern(layerId: string): boolean {\n return this.excludeLayerPatterns.some((pattern) => pattern.test(layerId));\n }\n\n /**\n * Create the main container element\n */\n private createContainer(): HTMLDivElement {\n const container = document.createElement(\"div\");\n container.className =\n \"maplibregl-ctrl maplibregl-ctrl-group maplibregl-ctrl-layer-control\";\n return container;\n }\n\n /**\n * Create the toggle button\n */\n private createToggleButton(): HTMLButtonElement {\n const button = document.createElement(\"button\");\n button.type = \"button\";\n button.title = \"Layer Control\";\n button.setAttribute(\"aria-label\", \"Layer Control\");\n\n // Create layers icon (SVG)\n const icon = document.createElement(\"span\");\n icon.className = \"layer-control-icon\";\n icon.innerHTML =\n '<svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\" ' +\n 'fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">' +\n '<polygon points=\"12 3 3 8.25 12 13.5 21 8.25 12 3\"></polygon>' +\n '<polyline points=\"3 12.75 12 18 21 12.75\"></polyline>' +\n '<polyline points=\"3 17.25 12 22 21 17.25\"></polyline>' +\n \"</svg>\";\n\n button.appendChild(icon);\n return button;\n }\n\n /**\n * Create the panel element\n */\n private createPanel(): HTMLDivElement {\n const panel = document.createElement(\"div\");\n panel.className = \"layer-control-panel\";\n\n // Set initial width and max height directly on the element\n panel.style.width = `${this.state.panelWidth}px`;\n panel.style.maxHeight = `${this.maxPanelHeight}px`;\n\n if (!this.state.collapsed) {\n panel.classList.add(\"expanded\");\n }\n\n // Add header\n const header = this.createPanelHeader();\n panel.appendChild(header);\n\n // Add action buttons (Show All / Hide All)\n const actionButtons = this.createActionButtons();\n panel.appendChild(actionButtons);\n\n // Add draggable edge handles (both sides) for resizing the panel width\n panel.appendChild(this.createResizeHandle(\"left\"));\n panel.appendChild(this.createResizeHandle(\"right\"));\n\n return panel;\n }\n\n /**\n * Create a draggable edge handle for resizing the panel width. A handle is\n * added on each side so the panel can be resized by dragging either edge,\n * like a conventional resizable window.\n *\n * @param side Which physical edge of the panel the handle sits on\n */\n private createResizeHandle(side: \"left\" | \"right\"): HTMLDivElement {\n const handle = document.createElement(\"div\");\n handle.className = `layer-control-resize-handle layer-control-resize-handle-${side}`;\n handle.title = \"Drag to resize panel\";\n handle.setAttribute(\"role\", \"separator\");\n handle.setAttribute(\"aria-orientation\", \"vertical\");\n this.resizeHandleEls.push(handle);\n this.setupResizeHandleEvents(handle, side);\n return handle;\n }\n\n /**\n * Wire pointer events for an edge resize handle.\n *\n * @param handle The handle element\n * @param side Which physical edge of the panel the handle sits on\n */\n private setupResizeHandleEvents(\n handle: HTMLDivElement,\n side: \"left\" | \"right\",\n ): void {\n handle.addEventListener(\"pointerdown\", (event) => {\n event.preventDefault();\n event.stopPropagation();\n this.isPanelResizing = true;\n this.panelResizeEdge = side;\n this.panelResizeStartX = event.clientX;\n this.panelResizeStartWidth = this.state.panelWidth;\n // Remember the current offset of the anchored edge so we can keep the\n // opposite (free) edge fixed when the anchored edge is dragged.\n this.panelResizeStartOffset =\n parseFloat(this.panel.style[this.panelAnchorSide]) || 0;\n handle.setPointerCapture(event.pointerId);\n this.panel.classList.add(\"resizing-active\");\n });\n\n handle.addEventListener(\"pointermove\", (event) => {\n if (!this.isPanelResizing) return;\n this.resizePanelFromPointer(event.clientX);\n });\n\n const endResize = (event: PointerEvent) => {\n if (!this.isPanelResizing) return;\n if (event.pointerId !== undefined) {\n try {\n handle.releasePointerCapture(event.pointerId);\n } catch {\n // Ignore release errors\n }\n }\n this.isPanelResizing = false;\n this.panelResizeStartX = null;\n this.panelResizeStartWidth = null;\n this.panel.classList.remove(\"resizing-active\");\n };\n\n handle.addEventListener(\"pointerup\", endResize);\n handle.addEventListener(\"pointercancel\", endResize);\n handle.addEventListener(\"lostpointercapture\", endResize);\n\n // Double-click resets to the default/initial width\n handle.addEventListener(\"dblclick\", (event) => {\n event.preventDefault();\n event.stopPropagation();\n this.applyPanelWidth(this.initialPanelWidth, true);\n });\n }\n\n /**\n * Compute and apply a new panel width from the pointer position during an\n * edge drag. Dragging the free edge changes the width while the anchored\n * edge stays put; dragging the anchored edge shifts the anchor so the free\n * edge stays put — both feel like resizing a normal window.\n */\n private resizePanelFromPointer(clientX: number): void {\n const dx = clientX - (this.panelResizeStartX ?? clientX);\n const startWidth = this.panelResizeStartWidth ?? this.state.panelWidth;\n\n // Dragging the left edge left widens; dragging the right edge right widens.\n const desiredWidth =\n this.panelResizeEdge === \"left\" ? startWidth - dx : startWidth + dx;\n const clamped = Math.round(\n Math.min(this.maxPanelWidth, Math.max(this.minPanelWidth, desiredWidth)),\n );\n\n // When the dragged edge is the anchored edge, move the anchor so the\n // opposite edge does not drift.\n if (this.panelResizeEdge === this.panelAnchorSide) {\n let appliedDelta = clamped - startWidth;\n let newOffset = this.panelResizeStartOffset - appliedDelta;\n if (newOffset < 0) {\n // Don't push the panel past the map edge; cap the growth instead.\n newOffset = 0;\n appliedDelta = this.panelResizeStartOffset;\n }\n const finalWidth = Math.round(\n Math.min(\n this.maxPanelWidth,\n Math.max(this.minPanelWidth, startWidth + appliedDelta),\n ),\n );\n this.applyPanelWidth(finalWidth, true);\n this.panel.style[this.panelAnchorSide] = `${newOffset}px`;\n } else {\n this.applyPanelWidth(clamped, true);\n }\n }\n\n /**\n * Record which panel edge is anchored to the control corner, based on the\n * corner the control occupies. Right corners anchor the right edge (panel\n * grows leftward); left corners anchor the left edge (panel grows rightward).\n */\n private updatePanelAnchorSide(\n position: \"top-left\" | \"top-right\" | \"bottom-left\" | \"bottom-right\",\n ): void {\n this.panelAnchorSide =\n position === \"top-right\" || position === \"bottom-right\"\n ? \"right\"\n : \"left\";\n }\n\n /**\n * Detect which corner the control is positioned in\n * @returns The position: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'\n */\n private getControlPosition():\n | \"top-left\"\n | \"top-right\"\n | \"bottom-left\"\n | \"bottom-right\" {\n const parent = this.container.parentElement;\n if (!parent) return \"top-right\"; // Default\n\n if (parent.classList.contains(\"maplibregl-ctrl-top-left\"))\n return \"top-left\";\n if (parent.classList.contains(\"maplibregl-ctrl-top-right\"))\n return \"top-right\";\n if (parent.classList.contains(\"maplibregl-ctrl-bottom-left\"))\n return \"bottom-left\";\n if (parent.classList.contains(\"maplibregl-ctrl-bottom-right\"))\n return \"bottom-right\";\n\n return \"top-right\"; // Default\n }\n\n /**\n * Update the panel position based on button location and control corner\n * Positions the panel next to the button, expanding in the appropriate direction\n */\n private updatePanelPosition(): void {\n if (!this.button || !this.panel || !this.mapContainer) return;\n\n const buttonRect = this.button.getBoundingClientRect();\n const mapRect = this.mapContainer.getBoundingClientRect();\n const position = this.getControlPosition();\n\n // Track which edge is anchored to the control corner (for edge-drag resize)\n this.updatePanelAnchorSide(position);\n\n // Calculate button position relative to map container\n const buttonTop = buttonRect.top - mapRect.top;\n const buttonBottom = mapRect.bottom - buttonRect.bottom;\n const buttonLeft = buttonRect.left - mapRect.left;\n const buttonRight = mapRect.right - buttonRect.right;\n\n const panelGap = 5; // Gap between button and panel\n\n // Reset all positioning\n this.panel.style.top = \"\";\n this.panel.style.bottom = \"\";\n this.panel.style.left = \"\";\n this.panel.style.right = \"\";\n\n switch (position) {\n case \"top-left\":\n // Panel expands down and to the right\n this.panel.style.top = `${buttonTop + buttonRect.height + panelGap}px`;\n this.panel.style.left = `${buttonLeft}px`;\n break;\n\n case \"top-right\":\n // Panel expands down and to the left\n this.panel.style.top = `${buttonTop + buttonRect.height + panelGap}px`;\n this.panel.style.right = `${buttonRight}px`;\n break;\n\n case \"bottom-left\":\n // Panel expands up and to the right\n this.panel.style.bottom = `${buttonBottom + buttonRect.height + panelGap}px`;\n this.panel.style.left = `${buttonLeft}px`;\n break;\n\n case \"bottom-right\":\n // Panel expands up and to the left\n this.panel.style.bottom = `${buttonBottom + buttonRect.height + panelGap}px`;\n this.panel.style.right = `${buttonRight}px`;\n break;\n }\n }\n\n /**\n * Create action buttons for Show All / Hide All\n */\n private createActionButtons(): HTMLElement {\n const container = document.createElement(\"div\");\n container.className = \"layer-control-actions\";\n\n const showAllBtn = document.createElement(\"button\");\n showAllBtn.type = \"button\";\n showAllBtn.className = \"layer-control-action-btn\";\n showAllBtn.textContent = \"Show All\";\n showAllBtn.title = \"Show all layers\";\n showAllBtn.addEventListener(\"click\", () =>\n this.setAllLayersVisibility(true),\n );\n\n const hideAllBtn = document.createElement(\"button\");\n hideAllBtn.type = \"button\";\n hideAllBtn.className = \"layer-control-action-btn\";\n hideAllBtn.textContent = \"Hide All\";\n hideAllBtn.title = \"Hide all layers\";\n hideAllBtn.addEventListener(\"click\", () =>\n this.setAllLayersVisibility(false),\n );\n\n container.appendChild(showAllBtn);\n container.appendChild(hideAllBtn);\n\n return container;\n }\n\n /**\n * Set visibility of all layers\n */\n private setAllLayersVisibility(visible: boolean): void {\n Object.keys(this.state.layerStates).forEach((layerId) => {\n // Use toggleLayerVisibility which handles both native and custom layers\n this.toggleLayerVisibility(layerId, visible);\n\n // Update checkbox in UI\n const itemEl = this.panel.querySelector(`[data-layer-id=\"${layerId}\"]`);\n if (itemEl) {\n const checkbox = itemEl.querySelector(\n \".layer-control-checkbox\",\n ) as HTMLInputElement;\n if (checkbox) {\n checkbox.checked = visible;\n checkbox.indeterminate = false;\n }\n }\n });\n }\n\n /**\n * Create the panel header with title and width control\n */\n private createPanelHeader(): HTMLElement {\n const header = document.createElement(\"div\");\n header.className = \"layer-control-panel-header\";\n\n const title = document.createElement(\"span\");\n title.className = \"layer-control-panel-title\";\n title.textContent = \"Layers\";\n header.appendChild(title);\n\n // Add width control\n const widthControl = this.createWidthControl();\n header.appendChild(widthControl);\n\n return header;\n }\n\n /**\n * Create the width control slider\n */\n private createWidthControl(): HTMLElement {\n const widthControl = document.createElement(\"label\");\n widthControl.className = \"layer-control-width-control\";\n widthControl.title = \"Adjust layer panel width\";\n\n const widthLabel = document.createElement(\"span\");\n widthLabel.textContent = \"Width\";\n widthControl.appendChild(widthLabel);\n\n const widthSlider = document.createElement(\"div\");\n widthSlider.className = \"layer-control-width-slider\";\n widthSlider.setAttribute(\"role\", \"slider\");\n widthSlider.setAttribute(\"aria-valuemin\", String(this.minPanelWidth));\n widthSlider.setAttribute(\"aria-valuemax\", String(this.maxPanelWidth));\n widthSlider.setAttribute(\"aria-valuenow\", String(this.state.panelWidth));\n widthSlider.setAttribute(\"aria-valuestep\", \"10\");\n widthSlider.setAttribute(\"aria-label\", \"Layer panel width\");\n widthSlider.tabIndex = 0;\n\n const widthTrack = document.createElement(\"div\");\n widthTrack.className = \"layer-control-width-track\";\n const widthThumb = document.createElement(\"div\");\n widthThumb.className = \"layer-control-width-thumb\";\n\n widthSlider.appendChild(widthTrack);\n widthSlider.appendChild(widthThumb);\n\n this.widthSliderEl = widthSlider;\n this.widthThumbEl = widthThumb;\n\n // Add width value display\n const widthValue = document.createElement(\"span\");\n widthValue.className = \"layer-control-width-value\";\n this.widthValueEl = widthValue;\n\n widthControl.appendChild(widthSlider);\n widthControl.appendChild(widthValue);\n\n this.updateWidthDisplay();\n this.setupWidthSliderEvents(widthSlider);\n\n return widthControl;\n }\n\n /**\n * Setup event listeners for width slider\n */\n private setupWidthSliderEvents(widthSlider: HTMLElement): void {\n // Pointer events for dragging\n widthSlider.addEventListener(\"pointerdown\", (event) => {\n event.preventDefault();\n const rect = widthSlider.getBoundingClientRect();\n this.widthDragRectWidth = rect.width || 1;\n this.widthDragStartX = event.clientX;\n this.widthDragStartWidth = this.state.panelWidth;\n this.isWidthSliderActive = true;\n widthSlider.setPointerCapture(event.pointerId);\n this.updateWidthFromPointer(event, true);\n });\n\n widthSlider.addEventListener(\"pointermove\", (event) => {\n if (!this.isWidthSliderActive) return;\n this.updateWidthFromPointer(event);\n });\n\n const endPointerDrag = (event: PointerEvent) => {\n if (!this.isWidthSliderActive) return;\n if (event.pointerId !== undefined) {\n try {\n widthSlider.releasePointerCapture(event.pointerId);\n } catch (error) {\n // Ignore release errors\n }\n }\n this.isWidthSliderActive = false;\n this.widthDragRectWidth = null;\n this.widthDragStartX = null;\n this.widthDragStartWidth = null;\n this.updateWidthDisplay();\n };\n\n widthSlider.addEventListener(\"pointerup\", endPointerDrag);\n widthSlider.addEventListener(\"pointercancel\", endPointerDrag);\n widthSlider.addEventListener(\"lostpointercapture\", endPointerDrag);\n\n // Keyboard navigation\n widthSlider.addEventListener(\"keydown\", (event) => {\n let handled = true;\n const step = event.shiftKey ? 20 : 10;\n\n switch (event.key) {\n case \"ArrowLeft\":\n case \"ArrowDown\":\n this.applyPanelWidth(this.state.panelWidth - step, true);\n break;\n case \"ArrowRight\":\n case \"ArrowUp\":\n this.applyPanelWidth(this.state.panelWidth + step, true);\n break;\n case \"Home\":\n this.applyPanelWidth(this.minPanelWidth, true);\n break;\n case \"End\":\n this.applyPanelWidth(this.maxPanelWidth, true);\n break;\n case \"PageUp\":\n this.applyPanelWidth(this.state.panelWidth + 50, true);\n break;\n case \"PageDown\":\n this.applyPanelWidth(this.state.panelWidth - 50, true);\n break;\n default:\n handled = false;\n }\n\n if (handled) {\n event.preventDefault();\n this.updateWidthDisplay();\n }\n });\n }\n\n /**\n * Update panel width from pointer event\n */\n private updateWidthFromPointer(\n event: PointerEvent,\n resetBaseline = false,\n ): void {\n if (!this.widthSliderEl) return;\n\n const sliderWidth =\n this.widthDragRectWidth ||\n this.widthSliderEl.getBoundingClientRect().width ||\n 1;\n const widthRange = this.maxPanelWidth - this.minPanelWidth;\n\n let width: number;\n if (resetBaseline) {\n const rect = this.widthSliderEl.getBoundingClientRect();\n const relative =\n rect.width > 0 ? (event.clientX - rect.left) / rect.width : 0;\n const clampedRatio = Math.min(1, Math.max(0, relative));\n width = this.minPanelWidth + clampedRatio * widthRange;\n this.widthDragStartWidth = width;\n this.widthDragStartX = event.clientX;\n } else {\n const delta = event.clientX - (this.widthDragStartX || event.clientX);\n width =\n (this.widthDragStartWidth || this.state.panelWidth) +\n (delta / sliderWidth) * widthRange;\n }\n\n this.applyPanelWidth(width, this.isWidthSliderActive);\n }\n\n /**\n * Apply panel width (clamped to min/max)\n */\n private applyPanelWidth(width: number, immediate = false): void {\n const clamped = Math.round(\n Math.min(this.maxPanelWidth, Math.max(this.minPanelWidth, width)),\n );\n\n const applyWidth = () => {\n this.state.panelWidth = clamped;\n const px = `${clamped}px`;\n this.panel.style.width = px;\n this.updateWidthDisplay();\n };\n\n if (immediate) {\n applyWidth();\n return;\n }\n\n if (this.widthFrame) {\n cancelAnimationFrame(this.widthFrame);\n }\n this.widthFrame = requestAnimationFrame(() => {\n applyWidth();\n this.widthFrame = null;\n });\n }\n\n /**\n * Update width display (value label and thumb position)\n */\n private updateWidthDisplay(): void {\n if (this.widthValueEl) {\n this.widthValueEl.textContent = `${this.state.panelWidth}px`;\n }\n if (this.widthSliderEl) {\n this.widthSliderEl.setAttribute(\n \"aria-valuenow\",\n String(this.state.panelWidth),\n );\n const ratio =\n (this.state.panelWidth - this.minPanelWidth) /\n (this.maxPanelWidth - this.minPanelWidth || 1);\n if (this.widthThumbEl) {\n const sliderWidth = this.widthSliderEl.clientWidth;\n // If element not yet rendered, defer the update\n if (sliderWidth === 0) {\n requestAnimationFrame(() => this.updateWidthDisplay());\n return;\n }\n const thumbWidth = this.widthThumbEl.offsetWidth || 14;\n const padding = 16;\n const available = Math.max(0, sliderWidth - padding - thumbWidth);\n const clampedRatio = Math.min(1, Math.max(0, ratio));\n const leftPx = 8 + available * clampedRatio;\n this.widthThumbEl.style.left = `${leftPx}px`;\n }\n }\n }\n\n /**\n * Setup main event listeners\n */\n private setupEventListeners(): void {\n // Toggle button click\n this.button.addEventListener(\"click\", () => this.toggle());\n\n // Click outside to close panel and context menu\n document.addEventListener(\"click\", (e) => {\n const target = e.target as Node;\n\n // Close context menu if clicking outside of it\n if (this.contextMenuEl && this.state.contextMenu.visible) {\n if (!this.contextMenuEl.contains(target)) {\n this.hideContextMenu();\n }\n }\n\n // Close panel if clicking outside\n if (!this.container.contains(target) && !this.panel.contains(target)) {\n this.collapse();\n }\n });\n\n // Update panel position on window resize\n this.resizeHandler = () => {\n if (!this.state.collapsed) {\n this.updatePanelPosition();\n }\n };\n window.addEventListener(\"resize\", this.resizeHandler);\n\n // Update panel position on map resize (e.g., sidebar toggle)\n this.mapResizeHandler = () => {\n if (!this.state.collapsed) {\n this.updatePanelPosition();\n }\n };\n this.map.on(\"resize\", this.mapResizeHandler);\n\n // Listen for map layer changes\n this.setupLayerChangeListeners();\n }\n\n /**\n * Setup listeners for map layer changes\n */\n private setupLayerChangeListeners(): void {\n this.map.on(\"styledata\", () => {\n setTimeout(() => {\n this.updateLayerStatesFromMap();\n this.checkForNewLayers();\n }, 100);\n });\n\n this.map.on(\"data\", (e) => {\n if (e.sourceDataType === \"content\") {\n setTimeout(() => {\n this.updateLayerStatesFromMap();\n this.checkForNewLayers();\n }, 100);\n }\n });\n\n this.map.on(\"sourcedata\", (e) => {\n if (e.sourceDataType === \"metadata\") {\n setTimeout(() => {\n this.checkForNewLayers();\n }, 150);\n }\n });\n\n // Subscribe to custom layer registry changes\n if (this.customLayerRegistry) {\n this.customLayerUnsubscribe = this.customLayerRegistry.onChange(\n (event, layerId) => {\n // If a previously removed layer is re-added, allow it to appear again\n if (event === \"add\" && layerId) {\n this.removedCustomLayerIds.delete(layerId);\n }\n setTimeout(() => this.checkForNewLayers(), 100);\n },\n );\n }\n }\n\n /**\n * Toggle panel expanded/collapsed state\n */\n private toggle(): void {\n if (this.state.collapsed) {\n this.expand();\n } else {\n this.collapse();\n }\n }\n\n /**\n * Expand the panel\n */\n private expand(): void {\n this.state.collapsed = false;\n this.panel.classList.add(\"expanded\");\n this.updatePanelPosition();\n }\n\n /**\n * Collapse the panel\n */\n private collapse(): void {\n this.state.collapsed = true;\n this.panel.classList.remove(\"expanded\");\n }\n\n /**\n * Build layer items (called initially and when layers change)\n */\n private buildLayerItems(): void {\n // Clear existing items\n const existingItems = this.panel.querySelectorAll(\".layer-control-item\");\n existingItems.forEach((item) => item.remove());\n this.styleEditors.clear();\n\n // Add items for all layers in our state\n Object.entries(this.state.layerStates).forEach(([layerId, state]) => {\n if (\n this.targetLayers.length === 0 ||\n this.targetLayers.includes(layerId)\n ) {\n this.addLayerItem(layerId, state);\n }\n });\n }\n\n /**\n * Add a single layer item to the panel\n */\n private addLayerItem(layerId: string, state: LayerState): void {\n const item = document.createElement(\"div\");\n item.className = \"layer-control-item\";\n item.setAttribute(\"data-layer-id\", layerId);\n\n const row = document.createElement(\"div\");\n row.className = \"layer-control-row\";\n\n // Add drag handle (disabled for Background layer for alignment)\n if (this.enableDragAndDrop) {\n if (layerId === \"Background\") {\n const disabledHandle = this.createDisabledDragHandle();\n row.appendChild(disabledHandle);\n } else {\n const dragHandle = this.createDragHandle(layerId);\n row.appendChild(dragHandle);\n }\n }\n\n // Visibility checkbox\n const checkbox = document.createElement(\"input\");\n checkbox.type = \"checkbox\";\n checkbox.className = \"layer-control-checkbox\";\n checkbox.checked = state.visible;\n checkbox.addEventListener(\"change\", () => {\n this.toggleLayerVisibility(layerId, checkbox.checked);\n });\n\n // Layer name - use custom name if set\n const displayName =\n this.state.customLayerNames.get(layerId) || state.name || layerId;\n const name = document.createElement(\"span\");\n name.className = \"layer-control-name\";\n name.textContent = displayName;\n name.title = displayName;\n\n row.appendChild(checkbox);\n\n // Add layer symbol (if enabled)\n if (this.showLayerSymbol) {\n if (layerId === \"Background\") {\n // Special stacked layers symbol for background group\n const symbol = this.createBackgroundGroupSymbol();\n row.appendChild(symbol);\n } else {\n const symbol = this.createLayerSymbol(layerId);\n if (symbol) {\n row.appendChild(symbol);\n }\n }\n }\n\n row.appendChild(name);\n\n // Opacity slider (conditionally shown)\n if (this.showOpacitySlider) {\n const opacity = document.createElement(\"input\");\n opacity.type = \"range\";\n opacity.className = \"layer-control-opacity\";\n opacity.min = \"0\";\n opacity.max = \"1\";\n opacity.step = \"0.01\";\n opacity.value = String(state.opacity);\n opacity.title = `Opacity: ${Math.round(state.opacity * 100)}%`;\n\n // Handle slider interaction tracking\n opacity.addEventListener(\"mousedown\", () => {\n this.state.userInteractingWithSlider = true;\n });\n opacity.addEventListener(\"mouseup\", () => {\n this.state.userInteractingWithSlider = false;\n });\n\n opacity.addEventListener(\"input\", () => {\n this.changeLayerOpacity(layerId, parseFloat(opacity.value));\n opacity.title = `Opacity: ${Math.round(parseFloat(opacity.value) * 100)}%`;\n });\n\n // Double-click to enter an exact opacity percentage (0-100)\n opacity.addEventListener(\"dblclick\", (event) => {\n event.preventDefault();\n this.showOpacityInput(layerId, opacity);\n });\n\n row.appendChild(opacity);\n }\n\n // Style button for regular layers, legend button for Background\n if (this.showStyleEditor) {\n if (layerId === \"Background\") {\n const legendButton = this.createBackgroundLegendButton();\n row.appendChild(legendButton);\n } else {\n const styleButton = this.createStyleButton(layerId);\n if (styleButton) {\n row.appendChild(styleButton);\n }\n }\n }\n\n item.appendChild(row);\n\n // Add context menu event listener (skip for Background layer)\n if (this.enableContextMenu && layerId !== \"Background\") {\n row.addEventListener(\"contextmenu\", (e) => {\n e.preventDefault();\n e.stopPropagation();\n this.showContextMenu(layerId, e.clientX, e.clientY);\n });\n }\n\n this.panel.appendChild(item);\n }\n\n /**\n * Create a symbol element for a layer\n * @param layerId The layer ID\n * @returns The symbol HTML element, or null if layer not found\n */\n private createLayerSymbol(layerId: string): HTMLElement | null {\n // Check if it's a custom layer first\n const layerState = this.state.layerStates[layerId];\n if (layerState?.isCustomLayer) {\n const symbolType = layerState.customLayerType || \"custom-raster\";\n // Use a default color for custom layers\n const color = \"#4a90d9\";\n const svgMarkup = createLayerSymbolSVG(symbolType, color);\n\n const symbolContainer = document.createElement(\"span\");\n symbolContainer.className = \"layer-control-symbol\";\n symbolContainer.innerHTML = svgMarkup;\n symbolContainer.title = `Layer type: ${symbolType}`;\n\n return symbolContainer;\n }\n\n // Fall back to MapLibre layer\n const layer = this.map.getLayer(layerId);\n if (!layer) return null;\n\n const layerType = layer.type;\n const color = getLayerColor(this.map, layerId, layerType);\n const svgMarkup = createLayerSymbolSVG(layerType, color);\n\n const symbolContainer = document.createElement(\"span\");\n symbolContainer.className = \"layer-control-symbol\";\n symbolContainer.innerHTML = svgMarkup;\n symbolContainer.title = `Layer type: ${layerType}`;\n\n return symbolContainer;\n }\n\n /**\n * Create a symbol element for a background layer\n * @param layer The layer specification\n * @returns The symbol HTML element\n */\n private createBackgroundLayerSymbol(layer: LayerSpecification): HTMLElement {\n const color = getLayerColorFromSpec(layer);\n const svgMarkup = createLayerSymbolSVG(layer.type, color, { size: 14 });\n\n const symbolContainer = document.createElement(\"span\");\n symbolContainer.className = \"background-legend-layer-symbol\";\n symbolContainer.innerHTML = svgMarkup;\n symbolContainer.title = `Layer type: ${layer.type}`;\n\n return symbolContainer;\n }\n\n /**\n * Create a symbol element for the Background layer group\n * Shows a stacked layers icon to represent multiple background layers\n * @returns The symbol HTML element\n */\n private createBackgroundGroupSymbol(): HTMLElement {\n const svgMarkup = createBackgroundGroupSymbolSVG(16);\n\n const symbolContainer = document.createElement(\"span\");\n symbolContainer.className = \"layer-control-symbol\";\n symbolContainer.innerHTML = svgMarkup;\n symbolContainer.title = \"Background layers\";\n\n return symbolContainer;\n }\n\n /**\n * Toggle layer visibility\n */\n private toggleLayerVisibility(layerId: string, visible: boolean): void {\n // Handle Background layer group\n if (layerId === \"Background\") {\n this.toggleBackgroundVisibility(visible);\n return;\n }\n\n // Set flag to prevent checkForNewLayers from running during visibility change\n this.state.isStyleOperationInProgress = true;\n\n // Update local state\n if (this.state.layerStates[layerId]) {\n this.state.layerStates[layerId].visible = visible;\n }\n\n // Try custom layer registry first\n if (this.customLayerRegistry?.setVisibility(layerId, visible)) {\n // Clear flag after a delay for custom layers\n setTimeout(() => {\n this.state.isStyleOperationInProgress = false;\n }, 200);\n return;\n }\n\n // Fallback to native MapLibre layer\n this.map.setLayoutProperty(\n layerId,\n \"visibility\",\n visible ? \"visible\" : \"none\",\n );\n\n // Clear flag after styledata events have settled\n setTimeout(() => {\n this.state.isStyleOperationInProgress = false;\n }, 200);\n }\n\n /**\n * Show a small popup that lets the user type an exact opacity percentage\n * (0-100) for a layer. Triggered by double-clicking the opacity slider.\n *\n * @param layerId The layer ID whose opacity is being edited\n * @param slider The opacity range input associated with the layer row\n */\n private showOpacityInput(layerId: string, slider: HTMLInputElement): void {\n // Close any existing opacity popup first\n this.hideOpacityInput();\n\n const popup = document.createElement(\"div\");\n popup.className = \"layer-control-opacity-input\";\n\n const label = document.createElement(\"span\");\n label.className = \"layer-control-opacity-input-label\";\n label.textContent = \"Opacity\";\n\n const field = document.createElement(\"div\");\n field.className = \"layer-control-opacity-input-field\";\n\n const input = document.createElement(\"input\");\n input.type = \"number\";\n input.min = \"0\";\n input.max = \"100\";\n input.step = \"1\";\n input.value = String(Math.round(parseFloat(slider.value) * 100));\n\n const suffix = document.createElement(\"span\");\n suffix.className = \"layer-control-opacity-input-suffix\";\n suffix.textContent = \"%\";\n\n field.appendChild(input);\n field.appendChild(suffix);\n popup.appendChild(label);\n popup.appendChild(field);\n\n // Prevent clicks inside the popup from collapsing the panel\n popup.addEventListener(\"click\", (event) => event.stopPropagation());\n popup.addEventListener(\"pointerdown\", (event) => event.stopPropagation());\n\n let settled = false;\n const apply = () => {\n if (settled) return;\n settled = true;\n const pct = clamp(Math.round(parseFloat(input.value)), 0, 100);\n if (!Number.isNaN(pct)) {\n const opacity = pct / 100;\n slider.value = String(opacity);\n slider.title = `Opacity: ${pct}%`;\n this.changeLayerOpacity(layerId, opacity);\n }\n this.hideOpacityInput();\n };\n const cancel = () => {\n if (settled) return;\n settled = true;\n this.hideOpacityInput();\n };\n\n input.addEventListener(\"keydown\", (event) => {\n if (event.key === \"Enter\") {\n event.preventDefault();\n apply();\n slider.focus();\n } else if (event.key === \"Escape\") {\n event.preventDefault();\n cancel();\n slider.focus();\n }\n });\n input.addEventListener(\"blur\", apply);\n\n this.mapContainer.appendChild(popup);\n this.opacityInputEl = popup;\n\n // Position the popup near the slider, relative to the map container\n const sliderRect = slider.getBoundingClientRect();\n const mapRect = this.mapContainer.getBoundingClientRect();\n const popupRect = popup.getBoundingClientRect();\n\n let left = sliderRect.left - mapRect.left;\n let top = sliderRect.bottom - mapRect.top + 4;\n\n // Keep the popup within the map bounds\n if (left + popupRect.width > mapRect.width) {\n left = Math.max(0, mapRect.width - popupRect.width - 5);\n }\n if (top + popupRect.height > mapRect.height) {\n top = sliderRect.top - mapRect.top - popupRect.height - 4;\n }\n\n popup.style.left = `${Math.max(0, left)}px`;\n popup.style.top = `${Math.max(0, top)}px`;\n\n input.focus();\n input.select();\n }\n\n /**\n * Remove the exact-opacity input popup if it is open.\n */\n private hideOpacityInput(): void {\n if (this.opacityInputEl) {\n this.opacityInputEl.remove();\n this.opacityInputEl = null;\n }\n }\n\n /**\n * Change layer opacity\n */\n private changeLayerOpacity(layerId: string, opacity: number): void {\n // Handle Background layer group\n if (layerId === \"Background\") {\n this.changeBackgroundOpacity(opacity);\n return;\n }\n\n // Set flag to prevent checkForNewLayers from running during opacity change\n this.state.isStyleOperationInProgress = true;\n\n // Update local state\n if (this.state.layerStates[layerId]) {\n this.state.layerStates[layerId].opacity = opacity;\n }\n\n // Try custom layer registry first\n if (this.customLayerRegistry?.setOpacity(layerId, opacity)) {\n // Clear flag after a delay for custom layers\n setTimeout(() => {\n this.state.isStyleOperationInProgress = false;\n }, 200);\n return;\n }\n\n // Fallback to native MapLibre layer\n const layerType = getLayerType(this.map, layerId);\n if (layerType) {\n setLayerOpacity(this.map, layerId, layerType, opacity);\n }\n\n // Clear flag after styledata events have settled\n setTimeout(() => {\n this.state.isStyleOperationInProgress = false;\n }, 200);\n }\n\n /**\n * Check if a layer is a user-added layer (vs basemap layer)\n * Used primarily for the background legend to determine which layers are background\n */\n private isUserAddedLayer(layerId: string): boolean {\n // If this layer is in our state (and not Background), it's user-added\n if (\n this.state.layerStates[layerId] !== undefined &&\n layerId !== \"Background\"\n ) {\n return true;\n }\n\n // If we have basemapLayerIds (from basemapStyleUrl), check if the layer is NOT in the basemap\n if (this.basemapLayerIds !== null && this.basemapLayerIds.size > 0) {\n return !this.basemapLayerIds.has(layerId);\n }\n\n // For layers not in our state, check if the layer was added after control initialization\n // or uses a user-added source\n if (this.initialLayerIds !== null && !this.initialLayerIds.has(layerId)) {\n // Layer was added after control - it's user-added\n return true;\n }\n\n // Check source-based heuristics\n const layer = this.map.getLayer(layerId);\n if (layer) {\n const sourceId = (layer as any).source;\n if (sourceId) {\n const userAddedSourceIds = this.detectUserAddedSources();\n return userAddedSourceIds.has(sourceId);\n }\n }\n\n return false;\n }\n\n /**\n * Toggle visibility for all background layers (basemap layers)\n */\n private toggleBackgroundVisibility(visible: boolean): void {\n // Update local state\n if (this.state.layerStates[\"Background\"]) {\n this.state.layerStates[\"Background\"].visible = visible;\n }\n\n // Apply to all basemap layers (layers not in layerStates)\n const styleLayers = this.map.getStyle().layers || [];\n styleLayers.forEach((layer) => {\n if (!this.isUserAddedLayer(layer.id)) {\n // Update visibility cache\n this.state.backgroundLayerVisibility.set(layer.id, visible);\n this.map.setLayoutProperty(\n layer.id,\n \"visibility\",\n visible ? \"visible\" : \"none\",\n );\n }\n });\n\n // Update legend panel checkboxes if open\n if (this.state.backgroundLegendOpen) {\n const legendPanel = this.panel.querySelector(\n \".layer-control-background-legend\",\n );\n if (legendPanel) {\n const checkboxes = legendPanel.querySelectorAll(\n \".background-legend-checkbox\",\n ) as NodeListOf<HTMLInputElement>;\n checkboxes.forEach((checkbox) => {\n checkbox.checked = visible;\n });\n }\n }\n }\n\n /**\n * Change opacity for all background layers (basemap layers)\n */\n private changeBackgroundOpacity(opacity: number): void {\n // Update local state\n if (this.state.layerStates[\"Background\"]) {\n this.state.layerStates[\"Background\"].opacity = opacity;\n }\n\n // Apply to all basemap layers (layers not in layerStates)\n const styleLayers = this.map.getStyle().layers || [];\n styleLayers.forEach((styleLayer) => {\n if (!this.isUserAddedLayer(styleLayer.id)) {\n const layerType = getLayerType(this.map, styleLayer.id);\n if (layerType) {\n setLayerOpacity(this.map, styleLayer.id, layerType, opacity);\n }\n }\n });\n }\n\n // ===== Background Legend Methods =====\n\n /**\n * Create legend button for Background layer\n */\n private createBackgroundLegendButton(): HTMLButtonElement {\n const button = document.createElement(\"button\");\n button.className =\n \"layer-control-style-button layer-control-background-legend-button\";\n button.innerHTML = \"⚙\"; // Gear icon (same as style button)\n button.title = \"Show background layer details\";\n button.setAttribute(\n \"aria-label\",\n \"Show background layer visibility controls\",\n );\n button.setAttribute(\n \"aria-expanded\",\n String(this.state.backgroundLegendOpen),\n );\n\n button.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.toggleBackgroundLegend();\n });\n\n return button;\n }\n\n /**\n * Toggle background legend panel visibility\n */\n private toggleBackgroundLegend(): void {\n if (this.state.backgroundLegendOpen) {\n this.closeBackgroundLegend();\n } else {\n this.openBackgroundLegend();\n }\n }\n\n /**\n * Open background legend panel\n */\n private openBackgroundLegend(): void {\n // Close any open style editor first\n if (this.state.activeStyleEditor) {\n this.closeStyleEditor(this.state.activeStyleEditor);\n }\n\n const itemEl = this.panel.querySelector('[data-layer-id=\"Background\"]');\n if (!itemEl) return;\n\n // Check if panel already exists\n let legendPanel = itemEl.querySelector(\".layer-control-background-legend\");\n if (legendPanel) {\n // Refresh the list\n const layerList = legendPanel.querySelector(\n \".background-legend-layer-list\",\n );\n if (layerList) {\n this.populateBackgroundLayerList(layerList as HTMLElement);\n }\n } else {\n // Create new panel\n legendPanel = this.createBackgroundLegendPanel();\n itemEl.appendChild(legendPanel);\n }\n\n this.state.backgroundLegendOpen = true;\n\n // Update button aria state\n const button = itemEl.querySelector(\n \".layer-control-background-legend-button\",\n );\n if (button) {\n button.setAttribute(\"aria-expanded\", \"true\");\n button.classList.add(\"active\");\n }\n\n // Scroll into view\n setTimeout(() => {\n legendPanel?.scrollIntoView({ behavior: \"smooth\", block: \"nearest\" });\n }, 50);\n }\n\n /**\n * Close background legend panel\n */\n private closeBackgroundLegend(): void {\n const itemEl = this.panel.querySelector('[data-layer-id=\"Background\"]');\n if (!itemEl) return;\n\n const legendPanel = itemEl.querySelector(\n \".layer-control-background-legend\",\n );\n if (legendPanel) {\n legendPanel.remove();\n }\n\n this.state.backgroundLegendOpen = false;\n\n // Update button aria state\n const button = itemEl.querySelector(\n \".layer-control-background-legend-button\",\n );\n if (button) {\n button.setAttribute(\"aria-expanded\", \"false\");\n button.classList.remove(\"active\");\n }\n }\n\n /**\n * Create the background legend panel with individual layer controls\n */\n private createBackgroundLegendPanel(): HTMLDivElement {\n const panel = document.createElement(\"div\");\n panel.className = \"layer-control-background-legend\";\n\n // Header\n const header = document.createElement(\"div\");\n header.className = \"background-legend-header\";\n\n const title = document.createElement(\"span\");\n title.className = \"background-legend-title\";\n title.textContent = \"Background Layers\";\n\n const closeBtn = document.createElement(\"button\");\n closeBtn.className = \"background-legend-close\";\n closeBtn.innerHTML = \"×\";\n closeBtn.title = \"Close\";\n closeBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.closeBackgroundLegend();\n });\n\n header.appendChild(title);\n header.appendChild(closeBtn);\n\n // Quick actions row\n const actionsRow = document.createElement(\"div\");\n actionsRow.className = \"background-legend-actions\";\n\n const showAllBtn = document.createElement(\"button\");\n showAllBtn.className = \"background-legend-action-btn\";\n showAllBtn.textContent = \"Show All\";\n showAllBtn.addEventListener(\"click\", () =>\n this.setAllBackgroundLayersVisibility(true),\n );\n\n const hideAllBtn = document.createElement(\"button\");\n hideAllBtn.className = \"background-legend-action-btn\";\n hideAllBtn.textContent = \"Hide All\";\n hideAllBtn.addEventListener(\"click\", () =>\n this.setAllBackgroundLayersVisibility(false),\n );\n\n actionsRow.appendChild(showAllBtn);\n actionsRow.appendChild(hideAllBtn);\n\n // Filter row - \"Only rendered\" checkbox\n const filterRow = document.createElement(\"div\");\n filterRow.className = \"background-legend-filter\";\n\n const filterCheckbox = document.createElement(\"input\");\n filterCheckbox.type = \"checkbox\";\n filterCheckbox.className = \"background-legend-filter-checkbox\";\n filterCheckbox.id = \"background-legend-only-rendered\";\n filterCheckbox.checked = this.state.onlyRenderedFilter;\n filterCheckbox.addEventListener(\"change\", () => {\n this.state.onlyRenderedFilter = filterCheckbox.checked;\n const layerList = panel.querySelector(\".background-legend-layer-list\");\n if (layerList) {\n this.populateBackgroundLayerList(layerList as HTMLElement);\n }\n });\n\n const filterLabel = document.createElement(\"label\");\n filterLabel.className = \"background-legend-filter-label\";\n filterLabel.htmlFor = \"background-legend-only-rendered\";\n filterLabel.textContent = \"Only rendered\";\n\n filterRow.appendChild(filterCheckbox);\n filterRow.appendChild(filterLabel);\n\n // Layer list container (scrollable)\n const layerList = document.createElement(\"div\");\n layerList.className = \"background-legend-layer-list\";\n\n // Populate with background layers\n this.populateBackgroundLayerList(layerList);\n\n panel.appendChild(header);\n panel.appendChild(actionsRow);\n panel.appendChild(filterRow);\n panel.appendChild(layerList);\n\n // Saved configurations (presets) row\n if (this.enableBackgroundPresets) {\n panel.appendChild(this.createBackgroundPresetsRow());\n }\n\n return panel;\n }\n\n /**\n * Build the \"Saved configurations\" controls: a dropdown of saved presets with\n * Apply/Delete actions, plus a name field and Save button to capture the\n * current basemap element visibility as a reusable, persisted preset.\n */\n private createBackgroundPresetsRow(): HTMLElement {\n const section = document.createElement(\"div\");\n section.className = \"background-legend-presets\";\n\n const label = document.createElement(\"div\");\n label.className = \"background-legend-presets-label\";\n label.textContent = \"Saved configurations\";\n section.appendChild(label);\n\n // Row 1: preset selector + apply/delete\n const selectRow = document.createElement(\"div\");\n selectRow.className = \"background-legend-presets-row\";\n\n const select = document.createElement(\"select\");\n select.className = \"background-legend-presets-select\";\n select.title = \"Saved configurations\";\n\n const applyBtn = document.createElement(\"button\");\n applyBtn.className = \"background-legend-action-btn\";\n applyBtn.textContent = \"Apply\";\n applyBtn.title = \"Apply the selected configuration\";\n\n const deleteBtn = document.createElement(\"button\");\n deleteBtn.className = \"background-legend-action-btn\";\n deleteBtn.textContent = \"Delete\";\n deleteBtn.title = \"Delete the selected configuration\";\n\n const refreshSelect = (selected?: string) => {\n const presets = this.getBackgroundPresets();\n const names = Object.keys(presets).sort((a, b) =>\n a.localeCompare(b, undefined, { sensitivity: \"base\" }),\n );\n select.innerHTML = \"\";\n\n const placeholder = document.createElement(\"option\");\n placeholder.value = \"\";\n placeholder.textContent = names.length\n ? \"Select a configuration…\"\n : \"No saved configurations\";\n placeholder.disabled = names.length > 0;\n select.appendChild(placeholder);\n\n names.forEach((name) => {\n const option = document.createElement(\"option\");\n option.value = name;\n option.textContent = name;\n select.appendChild(option);\n });\n\n select.value = selected && names.includes(selected) ? selected : \"\";\n const hasSelection = select.value !== \"\";\n applyBtn.disabled = !hasSelection;\n deleteBtn.disabled = !hasSelection;\n };\n\n select.addEventListener(\"change\", () => {\n const hasSelection = select.value !== \"\";\n applyBtn.disabled = !hasSelection;\n deleteBtn.disabled = !hasSelection;\n });\n\n applyBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n if (select.value) this.applyBackgroundPreset(select.value);\n });\n\n deleteBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n if (select.value) {\n this.deleteBackgroundPreset(select.value);\n refreshSelect();\n }\n });\n\n selectRow.appendChild(select);\n selectRow.appendChild(applyBtn);\n selectRow.appendChild(deleteBtn);\n\n // Row 2: name input + save\n const saveRow = document.createElement(\"div\");\n saveRow.className = \"background-legend-presets-row\";\n\n const nameInput = document.createElement(\"input\");\n nameInput.type = \"text\";\n nameInput.className = \"background-legend-presets-input\";\n nameInput.placeholder = \"Configuration name…\";\n nameInput.maxLength = 60;\n\n const saveBtn = document.createElement(\"button\");\n saveBtn.className = \"background-legend-action-btn\";\n saveBtn.textContent = \"Save\";\n saveBtn.title = \"Save the current visibility as a configuration\";\n\n const commitSave = () => {\n const name = nameInput.value.trim();\n if (!name) return;\n this.saveBackgroundPreset(name);\n nameInput.value = \"\";\n refreshSelect(name);\n };\n\n saveBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n commitSave();\n });\n nameInput.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n commitSave();\n }\n });\n\n saveRow.appendChild(nameInput);\n saveRow.appendChild(saveBtn);\n\n section.appendChild(selectRow);\n section.appendChild(saveRow);\n\n refreshSelect();\n\n return section;\n }\n\n /**\n * Check if a layer is currently rendered in the map viewport\n */\n private isLayerRendered(layerId: string): boolean {\n try {\n const layer = this.map.getLayer(layerId);\n if (!layer) return false;\n\n // Check if layer is visible first\n const visibility = this.map.getLayoutProperty(layerId, \"visibility\");\n if (visibility === \"none\") return false;\n\n // For raster layers, check if tiles are loaded\n if (layer.type === \"raster\" || layer.type === \"hillshade\") {\n // Raster layers are considered rendered if visible\n return true;\n }\n\n // For background layers (solid color), they're always rendered if visible\n if (layer.type === \"background\") {\n return true;\n }\n\n // For vector layers, use queryRenderedFeatures to check if any features are visible\n const features = this.map.queryRenderedFeatures({ layers: [layerId] });\n return features.length > 0;\n } catch (error) {\n // If query fails, assume layer is rendered if we can see it\n return true;\n }\n }\n\n /**\n * Populate the background layer list with individual layers\n */\n private populateBackgroundLayerList(container: HTMLElement): void {\n container.innerHTML = \"\"; // Clear existing\n\n const styleLayers = this.map.getStyle().layers || [];\n\n styleLayers.forEach((layer) => {\n if (!this.isUserAddedLayer(layer.id)) {\n // Skip drawn layers if excludeDrawnLayers is enabled\n if (this.excludeDrawnLayers && this.isDrawnLayer(layer.id)) {\n return;\n }\n\n // Skip layers matching user-defined exclusion patterns\n if (this.isExcludedByPattern(layer.id)) {\n return;\n }\n\n // If \"Only rendered\" filter is enabled, skip layers that aren't rendered\n if (this.state.onlyRenderedFilter && !this.isLayerRendered(layer.id)) {\n return;\n }\n\n // This is a background layer\n const layerRow = document.createElement(\"div\");\n layerRow.className = \"background-legend-layer-row\";\n layerRow.setAttribute(\"data-background-layer-id\", layer.id);\n\n // Checkbox\n const checkbox = document.createElement(\"input\");\n checkbox.type = \"checkbox\";\n checkbox.className = \"background-legend-checkbox\";\n\n // Get visibility from map or cache\n const visibility = this.map.getLayoutProperty(layer.id, \"visibility\");\n const isVisible = visibility !== \"none\";\n checkbox.checked = isVisible;\n\n // Update cache\n this.state.backgroundLayerVisibility.set(layer.id, isVisible);\n\n checkbox.addEventListener(\"change\", () => {\n this.toggleIndividualBackgroundLayer(layer.id, checkbox.checked);\n });\n\n // Layer name\n const name = document.createElement(\"span\");\n name.className = \"background-legend-layer-name\";\n name.textContent = this.generateFriendlyName(layer.id);\n name.title = layer.id; // Show full ID on hover\n\n // Layer type indicator\n const typeIndicator = document.createElement(\"span\");\n typeIndicator.className = \"background-legend-layer-type\";\n typeIndicator.textContent = layer.type;\n\n layerRow.appendChild(checkbox);\n\n // Add layer symbol (if enabled)\n if (this.showLayerSymbol) {\n const symbol = this.createBackgroundLayerSymbol(layer);\n if (symbol) {\n layerRow.appendChild(symbol);\n }\n }\n\n layerRow.appendChild(name);\n layerRow.appendChild(typeIndicator);\n container.appendChild(layerRow);\n }\n });\n\n // Show message if no background layers\n if (container.children.length === 0) {\n const emptyMsg = document.createElement(\"p\");\n emptyMsg.className = \"background-legend-empty\";\n emptyMsg.textContent = this.state.onlyRenderedFilter\n ? \"No rendered layers in current view.\"\n : \"No background layers found.\";\n container.appendChild(emptyMsg);\n }\n }\n\n /**\n * Toggle visibility of an individual background layer\n */\n private toggleIndividualBackgroundLayer(\n layerId: string,\n visible: boolean,\n ): void {\n // Update visibility cache\n this.state.backgroundLayerVisibility.set(layerId, visible);\n\n // Apply to map\n this.map.setLayoutProperty(\n layerId,\n \"visibility\",\n visible ? \"visible\" : \"none\",\n );\n\n // Update the main Background checkbox state\n this.updateBackgroundCheckboxState();\n }\n\n /**\n * Set visibility for all background layers\n */\n private setAllBackgroundLayersVisibility(visible: boolean): void {\n const styleLayers = this.map.getStyle().layers || [];\n\n styleLayers.forEach((layer) => {\n if (!this.isUserAddedLayer(layer.id)) {\n this.state.backgroundLayerVisibility.set(layer.id, visible);\n this.map.setLayoutProperty(\n layer.id,\n \"visibility\",\n visible ? \"visible\" : \"none\",\n );\n }\n });\n\n // Update checkboxes in the legend panel\n const legendPanel = this.panel.querySelector(\n \".layer-control-background-legend\",\n );\n if (legendPanel) {\n const checkboxes = legendPanel.querySelectorAll(\n \".background-legend-checkbox\",\n ) as NodeListOf<HTMLInputElement>;\n checkboxes.forEach((checkbox) => {\n checkbox.checked = visible;\n });\n }\n\n // Update main Background checkbox\n this.updateBackgroundCheckboxState();\n }\n\n /**\n * Update the main Background checkbox based on individual layer states\n */\n private updateBackgroundCheckboxState(): void {\n const styleLayers = this.map.getStyle().layers || [];\n let anyVisible = false;\n let allVisible = true;\n\n styleLayers.forEach((layer) => {\n if (!this.isUserAddedLayer(layer.id)) {\n const visible = this.state.backgroundLayerVisibility.get(layer.id);\n if (visible === true) anyVisible = true;\n if (visible === false) allVisible = false;\n }\n });\n\n // Update main checkbox\n const backgroundItem = this.panel.querySelector(\n '[data-layer-id=\"Background\"]',\n );\n if (backgroundItem) {\n const checkbox = backgroundItem.querySelector(\n \".layer-control-checkbox\",\n ) as HTMLInputElement;\n if (checkbox) {\n checkbox.checked = anyVisible;\n checkbox.indeterminate = anyVisible && !allVisible;\n }\n }\n\n // Update layerState\n if (this.state.layerStates[\"Background\"]) {\n this.state.layerStates[\"Background\"].visible = anyVisible;\n }\n }\n\n /**\n * Return the IDs of the background (basemap) style layers the control can\n * toggle, honoring the drawn-layer and user-defined exclusion filters but not\n * the transient \"only rendered\" view filter.\n */\n private getControllableBackgroundLayerIds(): string[] {\n const styleLayers = this.map.getStyle().layers || [];\n return styleLayers\n .filter((layer) => {\n if (this.isUserAddedLayer(layer.id)) return false;\n if (this.excludeDrawnLayers && this.isDrawnLayer(layer.id)) return false;\n if (this.isExcludedByPattern(layer.id)) return false;\n return true;\n })\n .map((layer) => layer.id);\n }\n\n /**\n * Get the current visibility of every controllable background (basemap) layer.\n *\n * @returns A map of style-layer ID to whether it is currently visible.\n */\n getBackgroundLayerVisibility(): BackgroundLayerVisibility {\n const visibility: BackgroundLayerVisibility = {};\n for (const layerId of this.getControllableBackgroundLayerIds()) {\n const value = this.map.getLayoutProperty(layerId, \"visibility\");\n visibility[layerId] = value !== \"none\";\n }\n return visibility;\n }\n\n /**\n * Apply a saved background-layer visibility configuration to the map. Only\n * layers that currently exist in the style are affected, so a configuration\n * captured on one basemap degrades gracefully when applied to another.\n *\n * @param visibility - Map of style-layer ID to desired visibility.\n */\n applyBackgroundLayerVisibility(visibility: BackgroundLayerVisibility): void {\n for (const [layerId, visible] of Object.entries(visibility)) {\n if (this.isUserAddedLayer(layerId)) continue;\n if (!this.map.getLayer(layerId)) continue;\n this.state.backgroundLayerVisibility.set(layerId, visible);\n this.map.setLayoutProperty(\n layerId,\n \"visibility\",\n visible ? \"visible\" : \"none\",\n );\n }\n\n // Refresh the open legend panel (if any) and the main Background checkbox.\n const legendPanel = this.panel.querySelector(\n \".background-legend-layer-list\",\n );\n if (legendPanel) {\n this.populateBackgroundLayerList(legendPanel as HTMLElement);\n }\n this.updateBackgroundCheckboxState();\n }\n\n /**\n * Read all saved background-layer presets from localStorage. Returns an empty\n * object when storage is unavailable or the stored value is malformed.\n */\n getBackgroundPresets(): BackgroundPresets {\n try {\n const raw =\n typeof localStorage !== \"undefined\"\n ? localStorage.getItem(this.backgroundPresetStorageKey)\n : null;\n if (!raw) return {};\n const parsed = JSON.parse(raw);\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n return {};\n }\n // Keep only safe, own keys mapping to plain objects, so a hand-crafted\n // storage value cannot smuggle in dangerous keys (e.g. `__proto__`).\n const presets: BackgroundPresets = {};\n for (const [name, value] of Object.entries(parsed)) {\n if (this.isUnsafePresetKey(name)) continue;\n if (value && typeof value === \"object\" && !Array.isArray(value)) {\n presets[name] = value as BackgroundLayerVisibility;\n }\n }\n return presets;\n } catch {\n return {};\n }\n }\n\n /**\n * Reject preset names that, used as object keys, could pollute the prototype\n * chain or otherwise alias built-in object members.\n */\n private isUnsafePresetKey(name: string): boolean {\n return (\n name === \"__proto__\" || name === \"constructor\" || name === \"prototype\"\n );\n }\n\n /**\n * Persist the full preset map to localStorage and notify listeners.\n */\n private writeBackgroundPresets(presets: BackgroundPresets): void {\n try {\n if (typeof localStorage !== \"undefined\") {\n localStorage.setItem(\n this.backgroundPresetStorageKey,\n JSON.stringify(presets),\n );\n }\n } catch {\n // Storage may be unavailable (private mode, quota); presets stay in-memory\n // for this session via the UI but cannot be persisted.\n }\n this.onBackgroundPresetsChange?.(presets);\n }\n\n /**\n * Save the current background-layer visibility as a named preset. Reusing an\n * existing name overwrites that preset.\n *\n * @param name - Preset name; whitespace is trimmed. Empty names are ignored.\n * @returns The updated preset map.\n */\n saveBackgroundPreset(name: string): BackgroundPresets {\n const trimmed = name.trim();\n const presets = this.getBackgroundPresets();\n if (!trimmed || this.isUnsafePresetKey(trimmed)) return presets;\n presets[trimmed] = this.getBackgroundLayerVisibility();\n this.writeBackgroundPresets(presets);\n return presets;\n }\n\n /**\n * Apply a previously saved preset to the map.\n *\n * @param name - The preset name to apply.\n * @returns `true` if a preset with that name existed and was applied.\n */\n applyBackgroundPreset(name: string): boolean {\n const presets = this.getBackgroundPresets();\n if (!Object.prototype.hasOwnProperty.call(presets, name)) return false;\n this.applyBackgroundLayerVisibility(presets[name]);\n return true;\n }\n\n /**\n * Delete a saved preset.\n *\n * @param name - The preset name to remove.\n * @returns The updated preset map.\n */\n deleteBackgroundPreset(name: string): BackgroundPresets {\n const presets = this.getBackgroundPresets();\n if (Object.prototype.hasOwnProperty.call(presets, name)) {\n delete presets[name];\n this.writeBackgroundPresets(presets);\n }\n return presets;\n }\n\n /**\n * Create style button for a layer\n */\n private createStyleButton(layerId: string): HTMLButtonElement | null {\n // Don't create button for Background layer\n if (layerId === \"Background\") {\n return null;\n }\n\n const layerState = this.state.layerStates[layerId];\n const isCustomLayer = layerState?.isCustomLayer === true;\n\n const button = document.createElement(\"button\");\n button.className = \"layer-control-style-button\";\n button.innerHTML = \"⚙\"; // Gear icon\n\n if (isCustomLayer) {\n // Custom layers don't support style editing - show info panel instead\n button.title = \"Layer info (style editing not available)\";\n button.setAttribute(\"aria-label\", `Layer info for ${layerId}`);\n } else {\n button.title = \"Edit layer style\";\n button.setAttribute(\"aria-label\", `Edit style for ${layerId}`);\n }\n\n button.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.toggleStyleEditor(layerId);\n });\n\n return button;\n }\n\n /**\n * Toggle style editor for a layer\n */\n private toggleStyleEditor(layerId: string): void {\n // If this editor is already open, close it\n if (this.state.activeStyleEditor === layerId) {\n this.closeStyleEditor(layerId);\n return;\n }\n\n // Close any other open editor\n if (this.state.activeStyleEditor) {\n this.closeStyleEditor(this.state.activeStyleEditor);\n }\n\n // Open this editor\n this.openStyleEditor(layerId);\n }\n\n /**\n * Open style editor for a layer\n */\n private openStyleEditor(layerId: string): void {\n const itemEl = this.panel.querySelector(`[data-layer-id=\"${layerId}\"]`);\n if (!itemEl) return;\n\n // Check if this is a custom layer\n const layerState = this.state.layerStates[layerId];\n if (layerState?.isCustomLayer) {\n // Check if the adapter provides native MapLibre layer IDs for style editing\n const nativeLayerIds =\n this.customLayerRegistry?.getNativeLayerIds(layerId);\n if (nativeLayerIds && nativeLayerIds.length > 0) {\n // Cache original styles for all native sublayers\n for (const nativeId of nativeLayerIds) {\n if (!this.state.originalStyles.has(nativeId)) {\n const nativeLayer = this.map.getLayer(nativeId);\n if (nativeLayer) {\n cacheOriginalLayerStyle(\n this.map,\n nativeId,\n this.state.originalStyles,\n );\n }\n }\n }\n\n // Create combined style editor for native sublayers\n const editor = this.createNativeSubLayerStyleEditor(\n layerId,\n nativeLayerIds,\n );\n if (editor) {\n itemEl.appendChild(editor);\n this.styleEditors.set(layerId, editor);\n this.state.activeStyleEditor = layerId;\n\n setTimeout(() => {\n editor.scrollIntoView({ behavior: \"smooth\", block: \"nearest\" });\n }, 50);\n return;\n }\n }\n\n // Fallback: show info message for custom layers without native sublayers\n const editor = this.createCustomLayerInfoPanel(layerId);\n itemEl.appendChild(editor);\n this.styleEditors.set(layerId, editor);\n this.state.activeStyleEditor = layerId;\n\n // Scroll into view\n setTimeout(() => {\n editor.scrollIntoView({ behavior: \"smooth\", block: \"nearest\" });\n }, 50);\n return;\n }\n\n // Cache original style if not already cached\n if (!this.state.originalStyles.has(layerId)) {\n const layer = this.map.getLayer(layerId);\n if (layer) {\n cacheOriginalLayerStyle(this.map, layerId, this.state.originalStyles);\n }\n }\n\n // Create style editor UI\n const editor = this.createStyleEditor(layerId);\n if (!editor) return;\n\n itemEl.appendChild(editor);\n this.styleEditors.set(layerId, editor);\n this.state.activeStyleEditor = layerId;\n\n // Scroll editor into view\n setTimeout(() => {\n editor.scrollIntoView({ behavior: \"smooth\", block: \"nearest\" });\n }, 50);\n }\n\n /**\n * Create info panel for custom layers (style editing not supported)\n */\n private createCustomLayerInfoPanel(layerId: string): HTMLDivElement {\n const editor = document.createElement(\"div\");\n editor.className = \"layer-control-style-editor layer-control-custom-info\";\n\n // Header\n const header = document.createElement(\"div\");\n header.className = \"style-editor-header\";\n\n const title = document.createElement(\"span\");\n title.className = \"style-editor-title\";\n title.textContent = \"Layer Info\";\n\n const closeBtn = document.createElement(\"button\");\n closeBtn.className = \"style-editor-close\";\n closeBtn.innerHTML = \"×\";\n closeBtn.title = \"Close\";\n closeBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.closeStyleEditor(layerId);\n });\n\n header.appendChild(title);\n header.appendChild(closeBtn);\n\n // Info content\n const content = document.createElement(\"div\");\n content.className = \"style-editor-controls\";\n\n const infoText = document.createElement(\"p\");\n infoText.className = \"layer-control-custom-info-text\";\n infoText.textContent = `This is a custom layer. Style editing is not available for this layer type. Use the visibility toggle and opacity slider to control the layer.`;\n\n content.appendChild(infoText);\n\n // Action buttons\n const actions = document.createElement(\"div\");\n actions.className = \"style-editor-actions\";\n\n const removeBtn = document.createElement(\"button\");\n removeBtn.className = \"style-editor-button style-editor-button-remove\";\n removeBtn.textContent = \"Remove\";\n removeBtn.title = \"Remove layer from map\";\n removeBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.showRemoveConfirmation(editor, () => {\n this.closeStyleEditor(layerId);\n this.removeLayer(layerId);\n });\n });\n\n const closeActionBtn = document.createElement(\"button\");\n closeActionBtn.className = \"style-editor-button style-editor-button-close\";\n closeActionBtn.textContent = \"Close\";\n closeActionBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.closeStyleEditor(layerId);\n });\n\n actions.appendChild(removeBtn);\n actions.appendChild(closeActionBtn);\n\n editor.appendChild(header);\n editor.appendChild(content);\n editor.appendChild(actions);\n\n return editor;\n }\n\n /**\n * Create a combined style editor for custom layers with native MapLibre sublayers.\n * Groups controls by sublayer type (fill, line, circle, etc.).\n */\n private createNativeSubLayerStyleEditor(\n layerId: string,\n nativeLayerIds: string[],\n ): HTMLDivElement | null {\n // Group native layers by type\n const layersByType = new Map<string, string[]>();\n for (const nativeId of nativeLayerIds) {\n const layer = this.map.getLayer(nativeId);\n if (layer) {\n const type = layer.type;\n if (!layersByType.has(type)) {\n layersByType.set(type, []);\n }\n layersByType.get(type)!.push(nativeId);\n }\n }\n\n if (layersByType.size === 0) return null;\n\n const editor = document.createElement(\"div\");\n editor.className = \"layer-control-style-editor\";\n\n // Header\n const header = document.createElement(\"div\");\n header.className = \"style-editor-header\";\n\n const title = document.createElement(\"span\");\n title.className = \"style-editor-title\";\n title.textContent = \"Edit Style\";\n\n const closeBtn = document.createElement(\"button\");\n closeBtn.className = \"style-editor-close\";\n closeBtn.innerHTML = \"×\";\n closeBtn.title = \"Close\";\n closeBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.closeStyleEditor(layerId);\n });\n\n header.appendChild(title);\n header.appendChild(closeBtn);\n editor.appendChild(header);\n\n // Controls container\n const controls = document.createElement(\"div\");\n controls.className = \"style-editor-controls\";\n\n // Type display names\n const typeLabels: Record<string, string> = {\n fill: \"Fill\",\n line: \"Line\",\n circle: \"Circle\",\n symbol: \"Symbol\",\n raster: \"Raster\",\n };\n\n // Add controls for each layer type, using the first native layer of that type\n for (const [type, ids] of layersByType) {\n // Add section header if there are multiple types\n if (layersByType.size > 1) {\n const sectionHeader = document.createElement(\"div\");\n sectionHeader.className = \"style-editor-section-header\";\n sectionHeader.textContent = typeLabels[type] || type;\n controls.appendChild(sectionHeader);\n }\n\n // Use the first layer of this type for controls\n // Changes will be applied to all layers of the same type\n const primaryId = ids[0];\n this.addStyleControlsForNativeGroup(controls, ids, primaryId, type);\n }\n\n // Action buttons\n const actions = document.createElement(\"div\");\n actions.className = \"style-editor-actions\";\n\n const resetBtn = document.createElement(\"button\");\n resetBtn.className = \"style-editor-button style-editor-button-reset\";\n resetBtn.textContent = \"Reset\";\n resetBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n // Reset all native sublayers\n for (const nativeId of nativeLayerIds) {\n restoreOriginalStyle(this.map, nativeId, this.state.originalStyles);\n }\n // Refresh the editor\n this.closeStyleEditor(layerId);\n this.openStyleEditor(layerId);\n });\n\n const removeBtn = document.createElement(\"button\");\n removeBtn.className = \"style-editor-button style-editor-button-remove\";\n removeBtn.textContent = \"Remove\";\n removeBtn.title = \"Remove layer from map\";\n removeBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.showRemoveConfirmation(editor, () => {\n this.closeStyleEditor(layerId);\n this.removeLayer(layerId);\n });\n });\n\n const closeActionBtn = document.createElement(\"button\");\n closeActionBtn.className = \"style-editor-button style-editor-button-close\";\n closeActionBtn.textContent = \"Close\";\n closeActionBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.closeStyleEditor(layerId);\n });\n\n actions.appendChild(resetBtn);\n actions.appendChild(removeBtn);\n actions.appendChild(closeActionBtn);\n\n editor.appendChild(controls);\n editor.appendChild(actions);\n\n return editor;\n }\n\n /**\n * Add style controls for a group of native layers of the same type.\n * Changes to any control are applied to all layers in the group.\n */\n private addStyleControlsForNativeGroup(\n container: HTMLElement,\n layerIds: string[],\n primaryLayerId: string,\n layerType: string,\n ): void {\n // Register the group mapping so createColorControl/createSliderControl\n // will apply changes to all layers in the group\n this.nativeLayerGroups.set(primaryLayerId, layerIds);\n\n this.addStyleControlsForLayerType(container, primaryLayerId, layerType);\n }\n\n /**\n * Close style editor for a layer\n */\n private closeStyleEditor(layerId: string): void {\n const editor = this.styleEditors.get(layerId);\n if (editor) {\n editor.remove();\n this.styleEditors.delete(layerId);\n }\n\n // Clean up any native layer group mappings\n this.nativeLayerGroups.clear();\n\n if (this.state.activeStyleEditor === layerId) {\n this.state.activeStyleEditor = null;\n }\n }\n\n /**\n * Create style editor UI\n */\n private createStyleEditor(layerId: string): HTMLDivElement | null {\n const layer = this.map.getLayer(layerId);\n if (!layer) return null;\n\n const editor = document.createElement(\"div\");\n editor.className = \"layer-control-style-editor\";\n\n // Header\n const header = document.createElement(\"div\");\n header.className = \"style-editor-header\";\n\n const title = document.createElement(\"span\");\n title.className = \"style-editor-title\";\n title.textContent = \"Edit Style\";\n\n const closeBtn = document.createElement(\"button\");\n closeBtn.className = \"style-editor-close\";\n closeBtn.innerHTML = \"×\";\n closeBtn.title = \"Close\";\n closeBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.closeStyleEditor(layerId);\n });\n\n header.appendChild(title);\n header.appendChild(closeBtn);\n\n // Controls container - populate based on layer type\n const controls = document.createElement(\"div\");\n controls.className = \"style-editor-controls\";\n\n const layerType = layer.type;\n this.addStyleControlsForLayerType(controls, layerId, layerType);\n\n // Action buttons\n const actions = document.createElement(\"div\");\n actions.className = \"style-editor-actions\";\n\n const resetBtn = document.createElement(\"button\");\n resetBtn.className = \"style-editor-button style-editor-button-reset\";\n resetBtn.textContent = \"Reset\";\n resetBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.resetLayerStyle(layerId);\n });\n\n const removeBtn = document.createElement(\"button\");\n removeBtn.className = \"style-editor-button style-editor-button-remove\";\n removeBtn.textContent = \"Remove\";\n removeBtn.title = \"Remove layer from map\";\n removeBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.showRemoveConfirmation(editor, () => {\n this.closeStyleEditor(layerId);\n this.removeLayer(layerId);\n });\n });\n\n const closeActionBtn = document.createElement(\"button\");\n closeActionBtn.className = \"style-editor-button style-editor-button-close\";\n closeActionBtn.textContent = \"Close\";\n closeActionBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.closeStyleEditor(layerId);\n });\n\n actions.appendChild(resetBtn);\n actions.appendChild(removeBtn);\n actions.appendChild(closeActionBtn);\n\n editor.appendChild(header);\n editor.appendChild(controls);\n editor.appendChild(actions);\n\n return editor;\n }\n\n /**\n * Add style controls based on layer type\n */\n private addStyleControlsForLayerType(\n container: HTMLElement,\n layerId: string,\n layerType: string,\n ): void {\n switch (layerType) {\n case \"fill\":\n this.addFillControls(container, layerId);\n break;\n case \"line\":\n this.addLineControls(container, layerId);\n break;\n case \"circle\":\n this.addCircleControls(container, layerId);\n break;\n case \"raster\":\n this.addRasterControls(container, layerId);\n break;\n case \"symbol\":\n this.addSymbolControls(container, layerId);\n break;\n default:\n container.textContent = `Style controls for ${layerType} layers not yet implemented.`;\n }\n }\n\n /**\n * Add controls for fill layers\n */\n private addFillControls(container: HTMLElement, layerId: string): void {\n // Fill Color - try layer definition first, then runtime property\n const style = this.map.getStyle();\n const layer = style.layers?.find((l) => l.id === layerId);\n let fillColor: any = undefined;\n\n // First try to get from layer definition\n if (\n layer &&\n \"paint\" in layer &&\n layer.paint &&\n \"fill-color\" in layer.paint\n ) {\n fillColor = layer.paint[\"fill-color\"];\n }\n\n // Fallback to runtime property if not in definition\n if (!fillColor) {\n fillColor = this.map.getPaintProperty(layerId, \"fill-color\");\n }\n\n this.createColorControl(\n container,\n layerId,\n \"fill-color\",\n \"Fill Color\",\n normalizeColor(fillColor || \"#088\"),\n );\n\n // Fill Opacity\n const fillOpacity = this.map.getPaintProperty(layerId, \"fill-opacity\");\n if (fillOpacity !== undefined && typeof fillOpacity === \"number\") {\n this.createSliderControl(\n container,\n layerId,\n \"fill-opacity\",\n \"Fill Opacity\",\n fillOpacity,\n 0,\n 1,\n 0.05,\n );\n }\n\n // Fill Outline Color\n const outlineColor = this.map.getPaintProperty(\n layerId,\n \"fill-outline-color\",\n );\n if (outlineColor !== undefined) {\n this.createColorControl(\n container,\n layerId,\n \"fill-outline-color\",\n \"Outline Color\",\n normalizeColor(outlineColor),\n );\n }\n }\n\n /**\n * Add controls for line layers\n */\n private addLineControls(container: HTMLElement, layerId: string): void {\n // Line Color - try layer definition first, then runtime property\n const style = this.map.getStyle();\n const layer = style.layers?.find((l) => l.id === layerId);\n let lineColor: any = undefined;\n\n // First try to get from layer definition\n if (\n layer &&\n \"paint\" in layer &&\n layer.paint &&\n \"line-color\" in layer.paint\n ) {\n lineColor = layer.paint[\"line-color\"];\n }\n\n // Fallback to runtime property if not in definition\n if (!lineColor) {\n lineColor = this.map.getPaintProperty(layerId, \"line-color\");\n }\n\n this.createColorControl(\n container,\n layerId,\n \"line-color\",\n \"Line Color\",\n normalizeColor(lineColor || \"#000\"),\n );\n\n // Line Width\n const lineWidth = this.map.getPaintProperty(layerId, \"line-width\");\n this.createSliderControl(\n container,\n layerId,\n \"line-width\",\n \"Line Width\",\n typeof lineWidth === \"number\" ? lineWidth : 1,\n 0,\n 20,\n 0.5,\n );\n\n // Line Opacity\n const lineOpacity = this.map.getPaintProperty(layerId, \"line-opacity\");\n if (lineOpacity !== undefined && typeof lineOpacity === \"number\") {\n this.createSliderControl(\n container,\n layerId,\n \"line-opacity\",\n \"Line Opacity\",\n lineOpacity,\n 0,\n 1,\n 0.05,\n );\n }\n\n // Line Blur\n const lineBlur = this.map.getPaintProperty(layerId, \"line-blur\");\n if (lineBlur !== undefined && typeof lineBlur === \"number\") {\n this.createSliderControl(\n container,\n layerId,\n \"line-blur\",\n \"Line Blur\",\n lineBlur,\n 0,\n 5,\n 0.1,\n );\n }\n }\n\n /**\n * Add controls for circle layers\n */\n private addCircleControls(container: HTMLElement, layerId: string): void {\n // Circle Color - try layer definition first, then runtime property\n const style = this.map.getStyle();\n const layer = style.layers?.find((l) => l.id === layerId);\n let circleColor: any = undefined;\n\n // First try to get from layer definition\n if (\n layer &&\n \"paint\" in layer &&\n layer.paint &&\n \"circle-color\" in layer.paint\n ) {\n circleColor = layer.paint[\"circle-color\"];\n }\n\n // Fallback to runtime property if not in definition\n if (!circleColor) {\n circleColor = this.map.getPaintProperty(layerId, \"circle-color\");\n }\n\n this.createColorControl(\n container,\n layerId,\n \"circle-color\",\n \"Circle Color\",\n normalizeColor(circleColor || \"#000\"),\n );\n\n // Circle Radius\n const circleRadius = this.map.getPaintProperty(layerId, \"circle-radius\");\n this.createSliderControl(\n container,\n layerId,\n \"circle-radius\",\n \"Radius\",\n typeof circleRadius === \"number\" ? circleRadius : 5,\n 0,\n 40,\n 0.5,\n );\n\n // Circle Opacity\n const circleOpacity = this.map.getPaintProperty(layerId, \"circle-opacity\");\n if (circleOpacity !== undefined && typeof circleOpacity === \"number\") {\n this.createSliderControl(\n container,\n layerId,\n \"circle-opacity\",\n \"Opacity\",\n circleOpacity,\n 0,\n 1,\n 0.05,\n );\n }\n\n // Circle Stroke Color\n const strokeColor = this.map.getPaintProperty(\n layerId,\n \"circle-stroke-color\",\n );\n if (strokeColor !== undefined) {\n this.createColorControl(\n container,\n layerId,\n \"circle-stroke-color\",\n \"Stroke Color\",\n normalizeColor(strokeColor),\n );\n }\n\n // Circle Stroke Width\n const strokeWidth = this.map.getPaintProperty(\n layerId,\n \"circle-stroke-width\",\n );\n if (strokeWidth !== undefined && typeof strokeWidth === \"number\") {\n this.createSliderControl(\n container,\n layerId,\n \"circle-stroke-width\",\n \"Stroke Width\",\n strokeWidth,\n 0,\n 10,\n 0.1,\n );\n }\n }\n\n /**\n * Add controls for raster layers\n */\n private addRasterControls(container: HTMLElement, layerId: string): void {\n // Raster Opacity\n const rasterOpacity = this.map.getPaintProperty(layerId, \"raster-opacity\");\n this.createSliderControl(\n container,\n layerId,\n \"raster-opacity\",\n \"Opacity\",\n typeof rasterOpacity === \"number\" ? rasterOpacity : 1,\n 0,\n 1,\n 0.05,\n );\n\n // Raster Brightness Min\n const brightnessMin = this.map.getPaintProperty(\n layerId,\n \"raster-brightness-min\",\n );\n this.createSliderControl(\n container,\n layerId,\n \"raster-brightness-min\",\n \"Brightness Min\",\n typeof brightnessMin === \"number\" ? brightnessMin : 0,\n -1,\n 1,\n 0.05,\n );\n\n // Raster Brightness Max\n const brightnessMax = this.map.getPaintProperty(\n layerId,\n \"raster-brightness-max\",\n );\n this.createSliderControl(\n container,\n layerId,\n \"raster-brightness-max\",\n \"Brightness Max\",\n typeof brightnessMax === \"number\" ? brightnessMax : 1,\n -1,\n 1,\n 0.05,\n );\n\n // Raster Saturation\n const saturation = this.map.getPaintProperty(layerId, \"raster-saturation\");\n this.createSliderControl(\n container,\n layerId,\n \"raster-saturation\",\n \"Saturation\",\n typeof saturation === \"number\" ? saturation : 0,\n -1,\n 1,\n 0.05,\n );\n\n // Raster Contrast\n const contrast = this.map.getPaintProperty(layerId, \"raster-contrast\");\n this.createSliderControl(\n container,\n layerId,\n \"raster-contrast\",\n \"Contrast\",\n typeof contrast === \"number\" ? contrast : 0,\n -1,\n 1,\n 0.05,\n );\n\n // Raster Hue Rotate\n const hueRotate = this.map.getPaintProperty(layerId, \"raster-hue-rotate\");\n this.createSliderControl(\n container,\n layerId,\n \"raster-hue-rotate\",\n \"Hue Rotate\",\n typeof hueRotate === \"number\" ? hueRotate : 0,\n 0,\n 350,\n 5,\n );\n }\n\n /**\n * Add controls for symbol layers\n */\n private addSymbolControls(container: HTMLElement, layerId: string): void {\n // Text Color\n const textColor = this.map.getPaintProperty(layerId, \"text-color\");\n if (textColor !== undefined) {\n this.createColorControl(\n container,\n layerId,\n \"text-color\",\n \"Text Color\",\n normalizeColor(textColor),\n );\n }\n\n // Text Opacity\n const textOpacity = this.map.getPaintProperty(layerId, \"text-opacity\");\n if (textOpacity !== undefined && typeof textOpacity === \"number\") {\n this.createSliderControl(\n container,\n layerId,\n \"text-opacity\",\n \"Text Opacity\",\n textOpacity,\n 0,\n 1,\n 0.05,\n );\n }\n\n // Icon Opacity\n const iconOpacity = this.map.getPaintProperty(layerId, \"icon-opacity\");\n if (iconOpacity !== undefined && typeof iconOpacity === \"number\") {\n this.createSliderControl(\n container,\n layerId,\n \"icon-opacity\",\n \"Icon Opacity\",\n iconOpacity,\n 0,\n 1,\n 0.05,\n );\n }\n }\n\n /**\n * Create a color control\n */\n private createColorControl(\n container: HTMLElement,\n layerId: string,\n property: string,\n label: string,\n initialValue: string,\n ): void {\n const controlGroup = document.createElement(\"div\");\n controlGroup.className = \"style-control-group\";\n\n const labelEl = document.createElement(\"label\");\n labelEl.className = \"style-control-label\";\n labelEl.textContent = label;\n\n const inputWrapper = document.createElement(\"div\");\n inputWrapper.className = \"style-control-color-group\";\n\n const colorInput = document.createElement(\"input\");\n colorInput.type = \"color\";\n colorInput.className = \"style-control-color-picker\";\n colorInput.value = initialValue;\n colorInput.dataset.property = property;\n\n const hexDisplay = document.createElement(\"input\");\n hexDisplay.type = \"text\";\n hexDisplay.className = \"style-control-color-value\";\n hexDisplay.value = initialValue;\n hexDisplay.readOnly = true;\n\n colorInput.addEventListener(\"input\", () => {\n const color = colorInput.value;\n hexDisplay.value = color;\n const targetIds = this.nativeLayerGroups.get(layerId) || [layerId];\n for (const id of targetIds) {\n this.map.setPaintProperty(id, property, color);\n }\n });\n\n inputWrapper.appendChild(colorInput);\n inputWrapper.appendChild(hexDisplay);\n\n controlGroup.appendChild(labelEl);\n controlGroup.appendChild(inputWrapper);\n\n container.appendChild(controlGroup);\n }\n\n /**\n * Create a slider control\n */\n private createSliderControl(\n container: HTMLElement,\n layerId: string,\n property: string,\n label: string,\n initialValue: number,\n min: number,\n max: number,\n step: number,\n ): void {\n const controlGroup = document.createElement(\"div\");\n controlGroup.className = \"style-control-group\";\n\n const labelEl = document.createElement(\"label\");\n labelEl.className = \"style-control-label\";\n labelEl.textContent = label;\n\n const inputWrapper = document.createElement(\"div\");\n inputWrapper.className = \"style-control-input-wrapper\";\n\n const slider = document.createElement(\"input\");\n slider.type = \"range\";\n slider.className = \"style-control-slider\";\n slider.min = String(min);\n slider.max = String(max);\n slider.step = String(step);\n slider.value = String(initialValue);\n slider.dataset.property = property;\n\n const valueDisplay = document.createElement(\"span\");\n valueDisplay.className = \"style-control-value\";\n valueDisplay.textContent = formatNumericValue(initialValue, step);\n\n slider.addEventListener(\"input\", () => {\n const value = parseFloat(slider.value);\n valueDisplay.textContent = formatNumericValue(value, step);\n const targetIds = this.nativeLayerGroups.get(layerId) || [layerId];\n for (const id of targetIds) {\n this.map.setPaintProperty(id, property, value);\n }\n });\n\n inputWrapper.appendChild(slider);\n inputWrapper.appendChild(valueDisplay);\n\n controlGroup.appendChild(labelEl);\n controlGroup.appendChild(inputWrapper);\n\n container.appendChild(controlGroup);\n }\n\n /**\n * Reset layer style to original\n */\n private resetLayerStyle(layerId: string): void {\n const originalStyle = this.state.originalStyles.get(layerId);\n if (!originalStyle) return;\n\n // Restore original paint properties\n restoreOriginalStyle(this.map, layerId, this.state.originalStyles);\n\n // Update UI controls to reflect the reset values\n const editor = this.styleEditors.get(layerId);\n if (editor) {\n // Update all slider controls\n const sliders = editor.querySelectorAll(\n \".style-control-slider\",\n ) as NodeListOf<HTMLInputElement>;\n sliders.forEach((slider) => {\n const property = slider.dataset.property;\n if (property) {\n const value = this.map.getPaintProperty(layerId, property);\n if (value !== undefined && typeof value === \"number\") {\n slider.value = String(value);\n // Update value display\n const valueDisplay = slider.parentElement?.querySelector(\n \".style-control-value\",\n );\n if (valueDisplay) {\n const step = parseFloat(slider.step);\n valueDisplay.textContent = formatNumericValue(value, step);\n }\n }\n }\n });\n\n // Update all color controls\n const colorPickers = editor.querySelectorAll(\n \".style-control-color-picker\",\n ) as NodeListOf<HTMLInputElement>;\n colorPickers.forEach((picker) => {\n const property = picker.dataset.property;\n if (property) {\n const value = this.map.getPaintProperty(layerId, property);\n if (value !== undefined) {\n const hexColor = normalizeColor(value);\n picker.value = hexColor;\n // Update hex display\n const hexDisplay = picker.parentElement?.querySelector(\n \".style-control-color-value\",\n );\n if (hexDisplay) {\n hexDisplay.textContent = hexColor;\n }\n }\n }\n });\n }\n }\n\n /**\n * Update layer states from map (sync UI with map)\n */\n private updateLayerStatesFromMap(): void {\n if (this.state.userInteractingWithSlider) {\n return; // Don't update while user is dragging\n }\n\n Object.keys(this.state.layerStates).forEach((layerId) => {\n try {\n // Skip custom layers - they manage their own state via adapters\n if (this.state.layerStates[layerId]?.isCustomLayer) {\n return;\n }\n\n // Skip Background layer group\n if (layerId === \"Background\") {\n return;\n }\n\n const layer = this.map.getLayer(layerId);\n if (!layer) return;\n\n // Check visibility\n const visibility = this.map.getLayoutProperty(layerId, \"visibility\");\n const isVisible = visibility !== \"none\";\n\n // Get opacity\n const layerType = layer.type;\n const opacity = getLayerOpacity(this.map, layerId, layerType);\n\n // Update local state\n if (this.state.layerStates[layerId]) {\n this.state.layerStates[layerId].visible = isVisible;\n this.state.layerStates[layerId].opacity = opacity;\n }\n\n // Update UI\n this.updateUIForLayer(layerId, isVisible, opacity);\n } catch (error) {\n console.warn(`Failed to update state for layer ${layerId}:`, error);\n }\n });\n }\n\n /**\n * Update UI elements for a specific layer\n */\n private updateUIForLayer(\n layerId: string,\n visible: boolean,\n opacity: number,\n ): void {\n const layerItems = this.panel.querySelectorAll(\".layer-control-item\");\n\n layerItems.forEach((item) => {\n if ((item as HTMLElement).dataset.layerId === layerId) {\n const checkbox = item.querySelector(\n \".layer-control-checkbox\",\n ) as HTMLInputElement;\n const opacitySlider = item.querySelector(\n \".layer-control-opacity\",\n ) as HTMLInputElement;\n\n if (checkbox) {\n checkbox.checked = visible;\n }\n\n if (opacitySlider) {\n opacitySlider.value = String(opacity);\n opacitySlider.title = `Opacity: ${Math.round(opacity * 100)}%`;\n }\n }\n });\n }\n\n /**\n * Check for new layers and add them to the control, remove deleted layers\n */\n private checkForNewLayers(): void {\n // Skip checking for new layers during style operations to prevent race conditions\n // that could incorrectly delete custom layers\n if (this.state.isStyleOperationInProgress) {\n return;\n }\n\n try {\n const style = this.map.getStyle();\n if (!style || !style.layers) {\n return;\n }\n\n const currentMapLayerIds = new Set(style.layers.map((layer) => layer.id));\n\n // Check if we're in auto-detect mode (no specific layers were specified)\n const isAutoDetectMode =\n this.targetLayers.length === 0 ||\n (this.targetLayers.length === 1 &&\n this.targetLayers[0] === \"Background\") ||\n this.targetLayers.every(\n (id) => id === \"Background\" || this.state.layerStates[id],\n );\n\n // Find new layers that aren't in our state yet\n const newLayers: string[] = [];\n\n // Detection priority for NEW layers (added after control):\n // 1. basemapLayerIds (from basemapStyleUrl) - most reliable\n // 2. initialLayerIds - layer NOT in initialLayerIds means it was added after control\n // 3. Source-based heuristics - fallback\n const useBasemapStyleDetection =\n this.basemapLayerIds !== null && this.basemapLayerIds.size > 0;\n const useInitialLayerDetection =\n !useBasemapStyleDetection &&\n this.initialLayerIds !== null &&\n this.initialLayerIds.size > 0;\n\n currentMapLayerIds.forEach((layerId) => {\n if (layerId !== \"Background\" && !this.state.layerStates[layerId]) {\n const layer = this.map.getLayer(layerId);\n if (layer) {\n // Always skip layers that were present when control was initialized\n // These are background/basemap layers and should stay grouped under \"Background\"\n if (\n this.initialLayerIds !== null &&\n this.initialLayerIds.has(layerId)\n ) {\n // Layer was in initial set - it's a background layer, skip it\n return;\n }\n\n // In auto-detect mode, apply additional filtering\n if (isAutoDetectMode) {\n // Skip drawn layers if excludeDrawnLayers is enabled\n if (this.excludeDrawnLayers && this.isDrawnLayer(layerId)) {\n return;\n }\n\n // Skip layers matching user-defined exclusion patterns\n if (this.isExcludedByPattern(layerId)) {\n return;\n }\n\n // Skip layers that are not user-added (i.e., background/basemap layers)\n if (!this.isUserAddedLayer(layerId)) {\n return;\n }\n\n if (useBasemapStyleDetection) {\n // Use basemap style layer IDs - if layer is in basemap, skip it\n if (this.basemapLayerIds!.has(layerId)) {\n return;\n }\n } else if (useInitialLayerDetection) {\n // Layer NOT in initialLayerIds means it was added AFTER control\n // These are definitely user-added layers and should be included\n if (this.initialLayerIds!.has(layerId)) {\n // Layer was in initial set - check source-based heuristics\n const userAddedSourceIds = this.detectUserAddedSources();\n const sourceId = (layer as any).source;\n if (!sourceId || !userAddedSourceIds.has(sourceId)) {\n return;\n }\n }\n // Layer NOT in initialLayerIds - it's new, include it\n } else {\n // Fall back to source-based heuristics\n const userAddedSourceIds = this.detectUserAddedSources();\n const sourceId = (layer as any).source;\n if (!sourceId || !userAddedSourceIds.has(sourceId)) {\n return;\n }\n }\n }\n newLayers.push(layerId);\n }\n }\n });\n\n // Find removed layers that are still in our state\n // Skip custom layers - they have their own removal mechanism via the adapter\n const removedLayers: string[] = [];\n Object.keys(this.state.layerStates).forEach((layerId) => {\n const state = this.state.layerStates[layerId];\n // Skip Background, custom layers, and layers still in the map\n if (\n layerId !== \"Background\" &&\n !state.isCustomLayer &&\n !currentMapLayerIds.has(layerId)\n ) {\n removedLayers.push(layerId);\n }\n });\n\n // Remove deleted layers from UI and state\n if (removedLayers.length > 0) {\n removedLayers.forEach((layerId) => {\n // Remove from state\n delete this.state.layerStates[layerId];\n\n // Remove from UI\n const itemEl = this.panel.querySelector(\n `[data-layer-id=\"${layerId}\"]`,\n );\n if (itemEl) {\n itemEl.remove();\n }\n\n // Clean up style editor if open\n if (this.state.activeStyleEditor === layerId) {\n this.state.activeStyleEditor = null;\n }\n this.styleEditors.delete(layerId);\n });\n }\n\n // Add UI for new layers\n if (newLayers.length > 0) {\n newLayers.forEach((layerId) => {\n const layer = this.map.getLayer(layerId);\n if (!layer) return;\n\n // Get layer type and opacity\n const layerType = layer.type;\n const opacity = getLayerOpacity(this.map, layerId, layerType);\n const visibility = this.map.getLayoutProperty(layerId, \"visibility\");\n const isVisible = visibility !== \"none\";\n\n // Add to state\n this.state.layerStates[layerId] = {\n visible: isVisible,\n opacity: opacity,\n name: this.generateFriendlyName(layerId),\n };\n\n // Add to UI\n this.addLayerItem(layerId, this.state.layerStates[layerId]);\n });\n }\n\n // Check for new/removed custom layers\n if (this.customLayerRegistry) {\n const customLayerIds = this.customLayerRegistry.getAllLayerIds();\n\n // Find new custom layers (skip ones explicitly removed by the user)\n customLayerIds.forEach((layerId) => {\n if (\n !this.state.layerStates[layerId] &&\n !this.removedCustomLayerIds.has(layerId)\n ) {\n const customState =\n this.customLayerRegistry!.getLayerState(layerId);\n if (customState) {\n this.state.layerStates[layerId] = {\n visible: customState.visible,\n opacity: customState.opacity,\n name: customState.name,\n isCustomLayer: true,\n customLayerType:\n this.customLayerRegistry!.getSymbolType(layerId) || undefined,\n };\n this.addLayerItem(layerId, this.state.layerStates[layerId]);\n }\n }\n });\n\n // Find removed custom layers\n Object.keys(this.state.layerStates).forEach((layerId) => {\n const state = this.state.layerStates[layerId];\n if (state.isCustomLayer && !customLayerIds.includes(layerId)) {\n // Remove from state\n delete this.state.layerStates[layerId];\n\n // Remove from UI\n const itemEl = this.panel.querySelector(\n `[data-layer-id=\"${layerId}\"]`,\n );\n if (itemEl) {\n itemEl.remove();\n }\n\n // Clean up style editor if open\n if (this.state.activeStyleEditor === layerId) {\n this.state.activeStyleEditor = null;\n }\n this.styleEditors.delete(layerId);\n }\n });\n }\n } catch (error) {\n console.warn(\"Failed to check for new layers:\", error);\n }\n }\n\n /**\n * Register a custom layer adapter dynamically.\n * This allows adding adapters after the LayerControl has been initialized.\n * @param adapter The custom layer adapter to register\n */\n registerCustomAdapter(adapter: CustomLayerAdapter): void {\n // Create registry if it doesn't exist\n if (!this.customLayerRegistry) {\n this.customLayerRegistry = new CustomLayerRegistry();\n // Subscribe to registry changes\n this.customLayerUnsubscribe = this.customLayerRegistry.onChange(\n (event, layerId) => {\n if (event === \"add\" && layerId) {\n this.removedCustomLayerIds.delete(layerId);\n }\n this.checkForNewLayers();\n },\n );\n }\n\n // Register the adapter\n this.customLayerRegistry.register(adapter);\n\n // Rebuild layer items to include the new adapter's layers\n if (this.panel) {\n this.checkForNewLayers();\n }\n }\n\n // ===== Context Menu Methods =====\n\n /**\n * Create context menu element\n */\n private createContextMenu(): HTMLDivElement {\n const menu = document.createElement(\"div\");\n menu.className = \"layer-control-context-menu\";\n menu.style.display = \"none\";\n\n // Rename\n const renameItem = this.createContextMenuItem(\"Rename\", \"✏️\", () => {\n if (this.state.contextMenu.targetLayerId) {\n this.startRenaming(this.state.contextMenu.targetLayerId);\n }\n this.hideContextMenu();\n });\n\n // Zoom to layer\n const zoomItem = this.createContextMenuItem(\"Zoom to Layer\", \"🔍\", () => {\n if (this.state.contextMenu.targetLayerId) {\n this.zoomToLayer(this.state.contextMenu.targetLayerId);\n }\n this.hideContextMenu();\n });\n\n // Separator\n const sep1 = document.createElement(\"div\");\n sep1.className = \"context-menu-separator\";\n\n // Move up\n const moveUpItem = this.createContextMenuItem(\"Move Up\", \"↑\", () => {\n if (this.state.contextMenu.targetLayerId) {\n this.moveLayerUp(this.state.contextMenu.targetLayerId);\n }\n this.hideContextMenu();\n });\n\n // Move to top\n const moveTopItem = this.createContextMenuItem(\"Move to Top\", \"⤒\", () => {\n if (this.state.contextMenu.targetLayerId) {\n this.moveLayerToTop(this.state.contextMenu.targetLayerId);\n }\n this.hideContextMenu();\n });\n\n // Move down\n const moveDownItem = this.createContextMenuItem(\"Move Down\", \"↓\", () => {\n if (this.state.contextMenu.targetLayerId) {\n this.moveLayerDown(this.state.contextMenu.targetLayerId);\n }\n this.hideContextMenu();\n });\n\n // Move to bottom\n const moveBottomItem = this.createContextMenuItem(\n \"Move to Bottom\",\n \"⤓\",\n () => {\n if (this.state.contextMenu.targetLayerId) {\n this.moveLayerToBottom(this.state.contextMenu.targetLayerId);\n }\n this.hideContextMenu();\n },\n );\n\n // Separator\n const sep2 = document.createElement(\"div\");\n sep2.className = \"context-menu-separator\";\n\n // Remove layer\n const removeItem = this.createContextMenuItem(\n \"Remove Layer\",\n \"🗑️\",\n () => {\n if (this.state.contextMenu.targetLayerId) {\n this.removeLayer(this.state.contextMenu.targetLayerId);\n }\n this.hideContextMenu();\n },\n true,\n );\n\n menu.appendChild(renameItem);\n menu.appendChild(zoomItem);\n menu.appendChild(sep1);\n menu.appendChild(moveUpItem);\n menu.appendChild(moveTopItem);\n menu.appendChild(moveDownItem);\n menu.appendChild(moveBottomItem);\n menu.appendChild(sep2);\n menu.appendChild(removeItem);\n\n return menu;\n }\n\n /**\n * Create a context menu item\n */\n private createContextMenuItem(\n label: string,\n icon: string,\n onClick: () => void,\n isDanger = false,\n ): HTMLDivElement {\n const item = document.createElement(\"div\");\n item.className =\n \"context-menu-item\" + (isDanger ? \" context-menu-item-danger\" : \"\");\n\n const iconEl = document.createElement(\"span\");\n iconEl.className = \"context-menu-item-icon\";\n iconEl.textContent = icon;\n\n const labelEl = document.createElement(\"span\");\n labelEl.className = \"context-menu-item-label\";\n labelEl.textContent = label;\n\n item.appendChild(iconEl);\n item.appendChild(labelEl);\n\n item.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n onClick();\n });\n\n return item;\n }\n\n /**\n * Show context menu at position\n */\n private showContextMenu(layerId: string, x: number, y: number): void {\n if (!this.contextMenuEl) return;\n\n // Update state\n this.state.contextMenu = {\n visible: true,\n targetLayerId: layerId,\n x,\n y,\n };\n\n // Position the menu relative to the map container\n const mapRect = this.mapContainer.getBoundingClientRect();\n let menuX = x - mapRect.left;\n let menuY = y - mapRect.top;\n\n // Show menu to get dimensions\n this.contextMenuEl.style.display = \"block\";\n\n // Adjust if menu would go off screen\n const menuRect = this.contextMenuEl.getBoundingClientRect();\n if (menuX + menuRect.width > mapRect.width) {\n menuX = mapRect.width - menuRect.width - 5;\n }\n if (menuY + menuRect.height > mapRect.height) {\n menuY = mapRect.height - menuRect.height - 5;\n }\n\n this.contextMenuEl.style.left = `${menuX}px`;\n this.contextMenuEl.style.top = `${menuY}px`;\n }\n\n /**\n * Hide context menu\n */\n private hideContextMenu(): void {\n if (!this.contextMenuEl) return;\n\n this.state.contextMenu = {\n visible: false,\n targetLayerId: null,\n x: 0,\n y: 0,\n };\n\n this.contextMenuEl.style.display = \"none\";\n }\n\n /**\n * Start renaming a layer\n */\n private startRenaming(layerId: string): void {\n const itemEl = this.panel.querySelector(`[data-layer-id=\"${layerId}\"]`);\n if (!itemEl) return;\n\n const nameEl = itemEl.querySelector(\".layer-control-name\");\n if (!nameEl) return;\n\n this.state.renamingLayerId = layerId;\n\n const currentName =\n this.state.customLayerNames.get(layerId) ||\n this.state.layerStates[layerId]?.name ||\n layerId;\n\n // Replace name span with input\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.className = \"layer-control-name-input\";\n input.value = currentName;\n\n const finishRename = () => {\n const newName = input.value.trim() || currentName;\n const oldName = currentName;\n\n if (newName !== oldName) {\n this.state.customLayerNames.set(layerId, newName);\n if (this.state.layerStates[layerId]) {\n this.state.layerStates[layerId].name = newName;\n }\n this.onLayerRename?.(layerId, oldName, newName);\n }\n\n // Restore name span\n const newNameEl = document.createElement(\"span\");\n newNameEl.className = \"layer-control-name\";\n newNameEl.textContent = newName;\n newNameEl.title = newName;\n input.replaceWith(newNameEl);\n\n this.state.renamingLayerId = null;\n };\n\n input.addEventListener(\"blur\", finishRename);\n input.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n finishRename();\n } else if (e.key === \"Escape\") {\n e.preventDefault();\n // Restore original name\n const newNameEl = document.createElement(\"span\");\n newNameEl.className = \"layer-control-name\";\n newNameEl.textContent = currentName;\n newNameEl.title = currentName;\n input.replaceWith(newNameEl);\n this.state.renamingLayerId = null;\n }\n });\n\n nameEl.replaceWith(input);\n input.focus();\n input.select();\n }\n\n /**\n * Zoom to a layer's bounds\n */\n private zoomToLayer(layerId: string): void {\n // Check if it's a custom layer with getBounds support\n const layerState = this.state.layerStates[layerId];\n if (layerState?.isCustomLayer && this.customLayerRegistry) {\n const bounds = this.customLayerRegistry.getBounds(layerId);\n if (bounds) {\n this.map.fitBounds(bounds as [number, number, number, number], {\n padding: 50,\n });\n return;\n }\n }\n\n // For native MapLibre layers, try to get bounds from features\n const layer = this.map.getLayer(layerId);\n if (!layer) return;\n\n try {\n // First try querySourceFeatures for all features\n const sourceId = (layer as any).source;\n let features = sourceId ? this.map.querySourceFeatures(sourceId) : [];\n\n // If no source features, try rendered features\n if (features.length === 0) {\n features = this.map.queryRenderedFeatures({ layers: [layerId] });\n }\n\n if (features.length === 0) return;\n\n // Calculate bounds\n let minLng = Infinity,\n minLat = Infinity,\n maxLng = -Infinity,\n maxLat = -Infinity;\n\n features.forEach((feature) => {\n if (!feature.geometry) return;\n\n const processCoords = (coords: any) => {\n if (typeof coords[0] === \"number\") {\n const [lng, lat] = coords;\n minLng = Math.min(minLng, lng);\n minLat = Math.min(minLat, lat);\n maxLng = Math.max(maxLng, lng);\n maxLat = Math.max(maxLat, lat);\n } else {\n coords.forEach(processCoords);\n }\n };\n\n if (feature.geometry.type === \"Point\") {\n processCoords((feature.geometry as any).coordinates);\n } else if (\n feature.geometry.type === \"LineString\" ||\n feature.geometry.type === \"MultiPoint\"\n ) {\n (feature.geometry as any).coordinates.forEach(processCoords);\n } else if (\n feature.geometry.type === \"Polygon\" ||\n feature.geometry.type === \"MultiLineString\"\n ) {\n (feature.geometry as any).coordinates.forEach((ring: any) =>\n ring.forEach(processCoords),\n );\n } else if (feature.geometry.type === \"MultiPolygon\") {\n (feature.geometry as any).coordinates.forEach((polygon: any) =>\n polygon.forEach((ring: any) => ring.forEach(processCoords)),\n );\n }\n });\n\n if (\n minLng !== Infinity &&\n minLat !== Infinity &&\n maxLng !== -Infinity &&\n maxLat !== -Infinity\n ) {\n this.map.fitBounds(\n [\n [minLng, minLat],\n [maxLng, maxLat],\n ],\n { padding: 50 },\n );\n }\n } catch (error) {\n console.warn(`Failed to zoom to layer ${layerId}:`, error);\n }\n }\n\n /**\n * Get user layer IDs in current map order (top to bottom in UI = high z-index to low)\n * Includes both MapLibre layers and custom layers managed by adapters.\n */\n private getUserLayerIdsInMapOrder(): string[] {\n const style = this.map.getStyle();\n if (!style?.layers) return [];\n\n // Get map layers in their actual order (low index = rendered first/bottom)\n const mapLayerIds = style.layers.map((l) => l.id);\n\n // Filter to only user layers that are in our state\n const userLayerIds = Object.keys(this.state.layerStates).filter(\n (id) => id !== \"Background\",\n );\n\n // Separate MapLibre layers and custom layers\n const mapLibreLayers = userLayerIds.filter((id) =>\n mapLayerIds.includes(id),\n );\n const customLayers = userLayerIds.filter(\n (id) =>\n this.state.layerStates[id]?.isCustomLayer && !mapLayerIds.includes(id),\n );\n\n // Sort MapLibre layers by map order (reversed: high index = top in UI)\n const sortedMapLibreLayers = mapLibreLayers.sort(\n (a, b) => mapLayerIds.indexOf(b) - mapLayerIds.indexOf(a),\n );\n\n // Custom layers are placed at the top (rendered last/on top)\n // Maintain their relative order from the state\n return [...customLayers, ...sortedMapLibreLayers];\n }\n\n /**\n * Check if a layer is a MapLibre layer (not a custom layer)\n */\n private isMapLibreLayer(layerId: string): boolean {\n return this.map.getLayer(layerId) !== undefined;\n }\n\n /**\n * Find the next MapLibre layer ID in a direction from a given index\n * @param layerIds Array of layer IDs\n * @param startIndex Index to start searching from\n * @param direction 1 for forward (toward bottom), -1 for backward (toward top)\n * @returns MapLibre layer ID or undefined if not found\n */\n private findNextMapLibreLayer(\n layerIds: string[],\n startIndex: number,\n direction: 1 | -1,\n ): string | undefined {\n for (\n let i = startIndex;\n direction === 1 ? i < layerIds.length : i >= 0;\n i += direction\n ) {\n if (this.isMapLibreLayer(layerIds[i])) {\n return layerIds[i];\n }\n }\n return undefined;\n }\n\n /**\n * Move a layer up in UI (higher rendering order = move to higher z-index)\n */\n private moveLayerUp(layerId: string): void {\n const layerIds = this.getUserLayerIdsInMapOrder();\n const index = layerIds.indexOf(layerId);\n if (index <= 0) return; // Already at top or not found\n\n // Check if this is a custom layer\n const isCustom = this.state.layerStates[layerId]?.isCustomLayer;\n\n if (!isCustom && this.isMapLibreLayer(layerId)) {\n // For MapLibre layers, we need to move them in the map\n // UI: [0]=top, [1], [2], ... [n]=bottom\n // Map array: bottom to top (low index = low z-index)\n // moveLayer(id, beforeId) moves id to render BELOW beforeId\n\n try {\n // Find the MapLibre layer to move before (2 positions above if exists)\n // If moving to top, use undefined as beforeId\n const targetBeforeId =\n index >= 2\n ? this.findNextMapLibreLayer(layerIds, index - 2, -1)\n : undefined;\n this.map.moveLayer(layerId, targetBeforeId);\n } catch (e) {\n // Ignore errors\n }\n }\n\n // For custom layers, just update the internal order\n // Swap positions in the state\n const newLayerStates: { [key: string]: LayerState } = {};\n const orderedIds = [...layerIds];\n [orderedIds[index], orderedIds[index - 1]] = [\n orderedIds[index - 1],\n orderedIds[index],\n ];\n\n // Add Background first if it exists\n if (this.state.layerStates[\"Background\"]) {\n newLayerStates[\"Background\"] = this.state.layerStates[\"Background\"];\n }\n orderedIds.forEach((id) => {\n if (this.state.layerStates[id]) {\n newLayerStates[id] = this.state.layerStates[id];\n }\n });\n this.state.layerStates = newLayerStates;\n\n // Rebuild UI\n this.buildLayerItems();\n this.onLayerReorder?.(this.getUserLayerIdsInMapOrder());\n }\n\n /**\n * Move a layer to the top (highest rendering order)\n */\n private moveLayerToTop(layerId: string): void {\n const layerIds = this.getUserLayerIdsInMapOrder();\n const index = layerIds.indexOf(layerId);\n if (index <= 0) return; // Already at top or not found\n\n // Check if this is a custom layer\n const isCustom = this.state.layerStates[layerId]?.isCustomLayer;\n\n if (!isCustom && this.isMapLibreLayer(layerId)) {\n // Move in MapLibre - no beforeId means move to top (highest z-index)\n try {\n this.map.moveLayer(layerId);\n } catch (e) {\n // Ignore errors\n }\n }\n\n // Update internal order - move to front\n const newLayerStates: { [key: string]: LayerState } = {};\n const orderedIds = [...layerIds];\n orderedIds.splice(index, 1);\n orderedIds.unshift(layerId);\n\n // Add Background first if it exists\n if (this.state.layerStates[\"Background\"]) {\n newLayerStates[\"Background\"] = this.state.layerStates[\"Background\"];\n }\n orderedIds.forEach((id) => {\n if (this.state.layerStates[id]) {\n newLayerStates[id] = this.state.layerStates[id];\n }\n });\n this.state.layerStates = newLayerStates;\n\n // Rebuild UI\n this.buildLayerItems();\n this.onLayerReorder?.(this.getUserLayerIdsInMapOrder());\n }\n\n /**\n * Move a layer down in UI (lower rendering order = move to lower z-index)\n */\n private moveLayerDown(layerId: string): void {\n const layerIds = this.getUserLayerIdsInMapOrder();\n const index = layerIds.indexOf(layerId);\n if (index < 0 || index >= layerIds.length - 1) return; // Already at bottom or not found\n\n // Check if this is a custom layer\n const isCustom = this.state.layerStates[layerId]?.isCustomLayer;\n\n if (!isCustom && this.isMapLibreLayer(layerId)) {\n // The layer below in UI is at index + 1, which has lower z-index in map\n // To move our layer below it, we call moveLayer(layerId, belowLayerId)\n // This puts layerId just below belowLayerId in rendering order\n // Find the next MapLibre layer below\n const belowLayerId = this.findNextMapLibreLayer(layerIds, index + 1, 1);\n\n if (belowLayerId) {\n try {\n this.map.moveLayer(layerId, belowLayerId);\n } catch (e) {\n // Ignore errors\n }\n }\n }\n\n // Update internal order - swap positions\n const newLayerStates: { [key: string]: LayerState } = {};\n const orderedIds = [...layerIds];\n [orderedIds[index], orderedIds[index + 1]] = [\n orderedIds[index + 1],\n orderedIds[index],\n ];\n\n // Add Background first if it exists\n if (this.state.layerStates[\"Background\"]) {\n newLayerStates[\"Background\"] = this.state.layerStates[\"Background\"];\n }\n orderedIds.forEach((id) => {\n if (this.state.layerStates[id]) {\n newLayerStates[id] = this.state.layerStates[id];\n }\n });\n this.state.layerStates = newLayerStates;\n\n // Rebuild UI\n this.buildLayerItems();\n this.onLayerReorder?.(this.getUserLayerIdsInMapOrder());\n }\n\n /**\n * Move a layer to the bottom (lowest rendering order among user layers)\n */\n private moveLayerToBottom(layerId: string): void {\n const layerIds = this.getUserLayerIdsInMapOrder();\n if (layerIds.length <= 1) return;\n\n const index = layerIds.indexOf(layerId);\n if (index < 0 || index === layerIds.length - 1) return; // Not found or already at bottom\n\n // Check if this is a custom layer\n const isCustom = this.state.layerStates[layerId]?.isCustomLayer;\n\n if (!isCustom && this.isMapLibreLayer(layerId)) {\n // The bottom layer in UI has the lowest z-index among user layers\n // Find the bottom-most MapLibre layer\n const bottomLayerId = this.findNextMapLibreLayer(\n layerIds,\n layerIds.length - 1,\n -1,\n );\n\n if (bottomLayerId && bottomLayerId !== layerId) {\n try {\n // Move this layer to be just below the current bottom layer\n this.map.moveLayer(layerId, bottomLayerId);\n } catch (e) {\n // Ignore errors\n }\n }\n }\n\n // Update internal order - move to end\n const newLayerStates: { [key: string]: LayerState } = {};\n const orderedIds = [...layerIds];\n orderedIds.splice(index, 1);\n orderedIds.push(layerId);\n\n // Add Background first if it exists\n if (this.state.layerStates[\"Background\"]) {\n newLayerStates[\"Background\"] = this.state.layerStates[\"Background\"];\n }\n orderedIds.forEach((id) => {\n if (this.state.layerStates[id]) {\n newLayerStates[id] = this.state.layerStates[id];\n }\n });\n this.state.layerStates = newLayerStates;\n\n // Rebuild UI\n this.buildLayerItems();\n this.onLayerReorder?.(this.getUserLayerIdsInMapOrder());\n }\n\n /**\n * Show inline remove confirmation instead of browser confirm() dialog.\n * Works in Jupyter notebooks where native dialogs may not appear.\n */\n private showRemoveConfirmation(\n container: HTMLElement,\n onConfirm: () => void,\n ): void {\n // Remove any existing confirmation in this container\n const existing = container.querySelector(\".layer-control-remove-confirm\");\n if (existing) {\n existing.remove();\n }\n\n const confirmEl = document.createElement(\"div\");\n confirmEl.className = \"layer-control-remove-confirm\";\n\n const message = document.createElement(\"div\");\n message.className = \"layer-control-remove-confirm-message\";\n message.innerHTML = `\n <svg class=\"layer-control-remove-confirm-icon\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path fill-rule=\"evenodd\" d=\"M8.485 2.495c.673-1.167 2.357-1.167 3.03 0l6.28 10.875c.673 1.167-.17 2.625-1.516 2.625H3.72c-1.347 0-2.189-1.458-1.515-2.625L8.485 2.495zM10 5a.75.75 0 01.75.75v3.5a.75.75 0 01-1.5 0v-3.5A.75.75 0 0110 5zm0 9a1 1 0 100-2 1 1 0 000 2z\" clip-rule=\"evenodd\"/>\n </svg>\n <span>Remove this layer?</span>\n `;\n\n const buttons = document.createElement(\"div\");\n buttons.className = \"layer-control-remove-confirm-buttons\";\n\n const cancelBtn = document.createElement(\"button\");\n cancelBtn.className =\n \"layer-control-remove-confirm-btn layer-control-remove-confirm-btn-cancel\";\n cancelBtn.textContent = \"Cancel\";\n cancelBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n confirmEl.remove();\n });\n\n const confirmBtn = document.createElement(\"button\");\n confirmBtn.className =\n \"layer-control-remove-confirm-btn layer-control-remove-confirm-btn-confirm\";\n confirmBtn.textContent = \"Remove\";\n confirmBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n confirmEl.remove();\n onConfirm();\n });\n\n buttons.appendChild(cancelBtn);\n buttons.appendChild(confirmBtn);\n\n confirmEl.appendChild(message);\n confirmEl.appendChild(buttons);\n\n container.appendChild(confirmEl);\n\n // Scroll the confirmation into view\n requestAnimationFrame(() => {\n confirmEl.scrollIntoView({ behavior: \"smooth\", block: \"nearest\" });\n });\n }\n\n /**\n * Remove a layer from the map\n */\n private removeLayer(layerId: string): void {\n // Prevent checkForNewLayers() from running during removal\n // (removing a layer triggers styledata events that could cause race conditions)\n this.state.isStyleOperationInProgress = true;\n\n const layerState = this.state.layerStates[layerId];\n\n // Handle custom layer removal\n if (layerState?.isCustomLayer && this.customLayerRegistry) {\n // Track this ID so checkForNewLayers() won't re-add it\n this.removedCustomLayerIds.add(layerId);\n\n // Hide the layer immediately as a visual fallback\n this.customLayerRegistry.setVisibility(layerId, false);\n\n // Let the adapter perform its own cleanup\n this.customLayerRegistry.removeLayer(layerId);\n }\n\n // Remove native MapLibre layer from the map\n try {\n const layer = this.map.getLayer(layerId);\n if (layer) {\n const sourceId = (layer as any).source;\n this.map.removeLayer(layerId);\n\n // Check if source is still used by other layers\n if (sourceId) {\n const style = this.map.getStyle();\n const sourceStillUsed = style?.layers?.some(\n (l) => (l as any).source === sourceId,\n );\n if (!sourceStillUsed) {\n try {\n this.map.removeSource(sourceId);\n } catch (e) {\n // Source might not exist or be in use\n }\n }\n }\n }\n } catch (error) {\n console.warn(`Failed to remove layer ${layerId}:`, error);\n }\n\n // Remove from state\n delete this.state.layerStates[layerId];\n this.state.customLayerNames.delete(layerId);\n\n // Remove from UI\n const itemEl = this.panel.querySelector(`[data-layer-id=\"${layerId}\"]`);\n if (itemEl) {\n itemEl.remove();\n }\n\n // Call callback\n this.onLayerRemove?.(layerId);\n\n // Clear flag after style events have settled\n setTimeout(() => {\n this.state.isStyleOperationInProgress = false;\n }, 200);\n }\n\n // ===== Drag and Drop Methods =====\n\n /**\n * Create drag handle element\n */\n private createDragHandle(layerId: string): HTMLDivElement {\n const handle = document.createElement(\"div\");\n handle.className = \"layer-control-drag-handle\";\n handle.innerHTML = `<svg viewBox=\"0 0 16 16\" fill=\"currentColor\">\n <circle cx=\"5\" cy=\"3\" r=\"1.5\"/>\n <circle cx=\"11\" cy=\"3\" r=\"1.5\"/>\n <circle cx=\"5\" cy=\"8\" r=\"1.5\"/>\n <circle cx=\"11\" cy=\"8\" r=\"1.5\"/>\n <circle cx=\"5\" cy=\"13\" r=\"1.5\"/>\n <circle cx=\"11\" cy=\"13\" r=\"1.5\"/>\n </svg>`;\n handle.title = \"Drag to reorder\";\n\n // Pointer events for dragging\n handle.addEventListener(\"pointerdown\", (e) => {\n e.preventDefault();\n e.stopPropagation();\n this.startDrag(layerId, e);\n });\n\n return handle;\n }\n\n /**\n * Create a disabled drag handle for alignment (used for Background layer)\n */\n private createDisabledDragHandle(): HTMLDivElement {\n const handle = document.createElement(\"div\");\n handle.className =\n \"layer-control-drag-handle layer-control-drag-handle-disabled\";\n handle.innerHTML = `<svg viewBox=\"0 0 16 16\" fill=\"currentColor\">\n <circle cx=\"5\" cy=\"3\" r=\"1.5\"/>\n <circle cx=\"11\" cy=\"3\" r=\"1.5\"/>\n <circle cx=\"5\" cy=\"8\" r=\"1.5\"/>\n <circle cx=\"11\" cy=\"8\" r=\"1.5\"/>\n <circle cx=\"5\" cy=\"13\" r=\"1.5\"/>\n <circle cx=\"11\" cy=\"13\" r=\"1.5\"/>\n </svg>`;\n return handle;\n }\n\n /**\n * Start dragging a layer\n */\n private startDrag(layerId: string, e: PointerEvent): void {\n const itemEl = this.panel.querySelector(\n `[data-layer-id=\"${layerId}\"]`,\n ) as HTMLElement;\n if (!itemEl) return;\n\n // Get item rect before any modifications\n const rect = itemEl.getBoundingClientRect();\n\n // Set up drag state\n this.state.drag = {\n active: true,\n layerId,\n startY: e.clientY,\n currentY: e.clientY,\n placeholder: null,\n draggedElement: null,\n };\n\n // Add dragging class to panel\n this.panel.classList.add(\"dragging-active\");\n\n // Hide original first (before creating clone to avoid visual jump)\n itemEl.classList.add(\"dragging\");\n\n // Create placeholder at original position\n const placeholder = document.createElement(\"div\");\n placeholder.className = \"layer-control-drop-placeholder\";\n placeholder.style.height = `${rect.height}px`;\n itemEl.parentNode?.insertBefore(placeholder, itemEl);\n this.state.drag.placeholder = placeholder;\n\n // Create floating clone\n const clone = itemEl.cloneNode(true) as HTMLElement;\n clone.classList.remove(\"dragging\");\n clone.className = \"layer-control-item layer-control-item-dragging\";\n clone.style.width = `${rect.width}px`;\n clone.style.left = `${rect.left}px`;\n clone.style.top = `${rect.top}px`;\n document.body.appendChild(clone);\n this.state.drag.draggedElement = clone;\n\n // Set up move and end handlers on document\n const onMove = (moveE: PointerEvent) => this.onDragMove(moveE);\n const onEnd = (endE: PointerEvent) => {\n document.removeEventListener(\"pointermove\", onMove);\n document.removeEventListener(\"pointerup\", onEnd);\n document.removeEventListener(\"pointercancel\", onEnd);\n this.endDrag(endE);\n };\n\n document.addEventListener(\"pointermove\", onMove);\n document.addEventListener(\"pointerup\", onEnd);\n document.addEventListener(\"pointercancel\", onEnd);\n }\n\n /**\n * Handle drag move\n */\n private onDragMove(e: PointerEvent): void {\n if (!this.state.drag.active || !this.state.drag.draggedElement) return;\n\n const placeholder = this.state.drag.placeholder;\n if (!placeholder) return;\n\n // Move the floating element\n const deltaY = e.clientY - this.state.drag.startY;\n const clone = this.state.drag.draggedElement;\n const currentTop = parseFloat(clone.style.top) || 0;\n clone.style.top = `${currentTop + deltaY}px`;\n this.state.drag.startY = e.clientY;\n this.state.drag.currentY = e.clientY;\n\n // Get all layer items (excluding the one being dragged and Background)\n const items = Array.from(\n this.panel.querySelectorAll(\".layer-control-item:not(.dragging)\"),\n ).filter(\n (item) => (item as HTMLElement).dataset.layerId !== \"Background\",\n ) as HTMLElement[];\n\n // Find which item we're hovering over\n for (const item of items) {\n const itemRect = item.getBoundingClientRect();\n\n // Check if cursor is within this item's vertical bounds\n if (e.clientY >= itemRect.top && e.clientY <= itemRect.bottom) {\n const itemMiddle = itemRect.top + itemRect.height / 2;\n\n if (e.clientY < itemMiddle) {\n // Insert placeholder before this item (if not already there)\n if (placeholder.nextSibling !== item) {\n item.parentNode?.insertBefore(placeholder, item);\n }\n } else {\n // Insert placeholder after this item (if not already there)\n if (placeholder.previousSibling !== item) {\n item.parentNode?.insertBefore(placeholder, item.nextSibling);\n }\n }\n break;\n }\n }\n }\n\n /**\n * End dragging\n */\n private endDrag(_e: PointerEvent): void {\n if (!this.state.drag.active) return;\n\n const layerId = this.state.drag.layerId;\n const placeholder = this.state.drag.placeholder;\n\n // Get the original item\n const itemEl = this.panel.querySelector(\n `[data-layer-id=\"${layerId}\"]`,\n ) as HTMLElement;\n\n if (itemEl && placeholder) {\n // Move item to placeholder position\n placeholder.parentNode?.insertBefore(itemEl, placeholder);\n itemEl.classList.remove(\"dragging\");\n }\n\n // Clean up\n this.cleanupDragState();\n\n // Update map layer order based on UI order\n this.applyUIOrderToMap();\n }\n\n /**\n * Clean up drag state\n */\n private cleanupDragState(): void {\n // Remove floating element\n if (this.state.drag.draggedElement) {\n this.state.drag.draggedElement.remove();\n }\n\n // Remove placeholder\n if (this.state.drag.placeholder) {\n this.state.drag.placeholder.remove();\n }\n\n // Remove dragging class from panel\n this.panel.classList.remove(\"dragging-active\");\n\n // Remove dragging class from any items\n this.panel\n .querySelectorAll(\".layer-control-item.dragging\")\n .forEach((el) => {\n el.classList.remove(\"dragging\");\n });\n\n // Reset drag state\n this.state.drag = {\n active: false,\n layerId: null,\n startY: 0,\n currentY: 0,\n placeholder: null,\n draggedElement: null,\n };\n }\n\n /**\n * Apply UI order to map layers\n */\n private applyUIOrderToMap(): void {\n // Set flag to prevent checkForNewLayers from running during reordering\n // This prevents custom layers from being incorrectly deleted due to race conditions\n this.state.isStyleOperationInProgress = true;\n\n // Get layer items in current UI order\n const items = this.panel.querySelectorAll(\".layer-control-item\");\n const uiLayerIds: string[] = [];\n\n items.forEach((item) => {\n const layerId = (item as HTMLElement).dataset.layerId;\n if (layerId && layerId !== \"Background\") {\n uiLayerIds.push(layerId);\n }\n });\n\n // UI shows top layer first, but we need to move layers in reverse order\n // to maintain the correct stacking\n const reversedIds = [...uiLayerIds].reverse();\n\n // Build a set of MapLibre layer IDs for quick lookup\n const style = this.map.getStyle();\n const mapLibreLayerIds = new Set(style?.layers?.map((l) => l.id) || []);\n\n // Move each layer to its correct position\n for (let i = 0; i < reversedIds.length; i++) {\n const layerId = reversedIds[i];\n\n // Check if layer exists in MapLibre (skip custom layers)\n if (!mapLibreLayerIds.has(layerId)) {\n continue;\n }\n\n // Find the next MapLibre layer to use as beforeId\n // Skip any custom layers that might be between this layer and the next\n let beforeId: string | undefined = undefined;\n for (let j = i - 1; j >= 0; j--) {\n if (mapLibreLayerIds.has(reversedIds[j])) {\n beforeId = reversedIds[j];\n break;\n }\n }\n\n try {\n this.map.moveLayer(layerId, beforeId);\n } catch (e) {\n // Ignore errors\n }\n }\n\n // Call callback\n this.onLayerReorder?.(uiLayerIds);\n\n // Clear flag after styledata events have settled\n // The 200ms delay accounts for the 100ms timeout in the styledata event handler\n setTimeout(() => {\n this.state.isStyleOperationInProgress = false;\n }, 200);\n }\n}\n"],"names":["opacity","clamp","color","svgMarkup","symbolContainer","layerList","editor","_a"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../src/lib/core/CustomLayerRegistry.ts","../src/lib/utils/layerUtils.ts","../src/lib/utils/styleCache.ts","../src/lib/utils/colorUtils.ts","../src/lib/utils/formatters.ts","../src/lib/utils/symbolUtils.ts","../src/lib/core/LayerControl.ts"],"sourcesContent":["import type { CustomLayerAdapter, LayerState } from './types';\n\n/**\n * Registry for managing custom layer adapters.\n * Routes layer operations to the appropriate adapter based on layer ID.\n */\nexport class CustomLayerRegistry {\n private adapters: Map<string, CustomLayerAdapter> = new Map();\n private changeListeners: Array<(event: 'add' | 'remove', layerId: string) => void> = [];\n private unsubscribers: Map<string, () => void> = new Map();\n\n /**\n * Register a custom layer adapter.\n * @param adapter The adapter to register\n */\n register(adapter: CustomLayerAdapter): void {\n this.adapters.set(adapter.type, adapter);\n\n // Subscribe to adapter's layer changes if supported\n if (adapter.onLayerChange) {\n const unsubscribe = adapter.onLayerChange((event, layerId) => {\n this.notifyChange(event, layerId);\n });\n this.unsubscribers.set(adapter.type, unsubscribe);\n }\n }\n\n /**\n * Unregister an adapter by type.\n * @param type The adapter type to unregister\n */\n unregister(type: string): void {\n // Clean up the subscription for this adapter\n const unsubscribe = this.unsubscribers.get(type);\n if (unsubscribe) {\n unsubscribe();\n this.unsubscribers.delete(type);\n }\n this.adapters.delete(type);\n }\n\n /**\n * Get all custom layer IDs across all adapters.\n * @returns Array of layer IDs\n */\n getAllLayerIds(): string[] {\n const ids: string[] = [];\n this.adapters.forEach(adapter => {\n ids.push(...adapter.getLayerIds());\n });\n return ids;\n }\n\n /**\n * Check if a layer ID is managed by any adapter.\n * @param layerId The layer ID to check\n * @returns true if the layer is managed by an adapter\n */\n hasLayer(layerId: string): boolean {\n for (const adapter of this.adapters.values()) {\n if (adapter.getLayerIds().includes(layerId)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Get the adapter responsible for a specific layer.\n * @param layerId The layer ID\n * @returns The adapter or null if not found\n */\n getAdapterForLayer(layerId: string): CustomLayerAdapter | null {\n for (const adapter of this.adapters.values()) {\n if (adapter.getLayerIds().includes(layerId)) {\n return adapter;\n }\n }\n return null;\n }\n\n /**\n * Get the state of a custom layer.\n * @param layerId The layer ID\n * @returns The layer state or null if not found\n */\n getLayerState(layerId: string): LayerState | null {\n const adapter = this.getAdapterForLayer(layerId);\n return adapter ? adapter.getLayerState(layerId) : null;\n }\n\n /**\n * Set visibility of a custom layer.\n * @param layerId The layer ID\n * @param visible Whether the layer should be visible\n * @returns true if the operation was handled by an adapter\n */\n setVisibility(layerId: string, visible: boolean): boolean {\n const adapter = this.getAdapterForLayer(layerId);\n if (adapter) {\n adapter.setVisibility(layerId, visible);\n return true;\n }\n return false;\n }\n\n /**\n * Set opacity of a custom layer.\n * @param layerId The layer ID\n * @param opacity The opacity value (0-1)\n * @returns true if the operation was handled by an adapter\n */\n setOpacity(layerId: string, opacity: number): boolean {\n const adapter = this.getAdapterForLayer(layerId);\n if (adapter) {\n adapter.setOpacity(layerId, opacity);\n return true;\n }\n return false;\n }\n\n /**\n * Get the symbol type for a custom layer (for UI display).\n * @param layerId The layer ID\n * @returns The symbol type or null if not available\n */\n getSymbolType(layerId: string): string | null {\n const adapter = this.getAdapterForLayer(layerId);\n if (adapter && adapter.getSymbolType) {\n return adapter.getSymbolType(layerId);\n }\n return null;\n }\n\n /**\n * Get the bounds of a custom layer (for zoom-to-layer).\n * @param layerId The layer ID\n * @returns The bounds [west, south, east, north] or null if not available\n */\n getBounds(layerId: string): [number, number, number, number] | null {\n const adapter = this.getAdapterForLayer(layerId);\n if (adapter && adapter.getBounds) {\n return adapter.getBounds(layerId);\n }\n return null;\n }\n\n /**\n * Get native MapLibre layer IDs for a custom layer.\n * @param layerId The custom layer ID\n * @returns Array of native layer IDs, or null if not available\n */\n getNativeLayerIds(layerId: string): string[] | null {\n const adapter = this.getAdapterForLayer(layerId);\n if (adapter && adapter.getNativeLayerIds) {\n return adapter.getNativeLayerIds(layerId);\n }\n return null;\n }\n\n /**\n * Remove a custom layer through its adapter.\n * @param layerId The layer ID to remove\n * @returns true if the operation was handled by an adapter\n */\n removeLayer(layerId: string): boolean {\n const adapter = this.getAdapterForLayer(layerId);\n if (adapter && adapter.removeLayer) {\n adapter.removeLayer(layerId);\n return true;\n }\n return false;\n }\n\n /**\n * Subscribe to layer changes across all adapters.\n * @param callback Function called when layers are added or removed\n * @returns Unsubscribe function\n */\n onChange(callback: (event: 'add' | 'remove', layerId: string) => void): () => void {\n this.changeListeners.push(callback);\n return () => {\n const idx = this.changeListeners.indexOf(callback);\n if (idx >= 0) {\n this.changeListeners.splice(idx, 1);\n }\n };\n }\n\n private notifyChange(event: 'add' | 'remove', layerId: string): void {\n this.changeListeners.forEach(cb => cb(event, layerId));\n }\n\n /**\n * Clean up all subscriptions and adapters.\n */\n destroy(): void {\n this.unsubscribers.forEach(unsub => unsub());\n this.unsubscribers.clear();\n this.adapters.clear();\n this.changeListeners = [];\n }\n}\n","import type { Map as MapLibreMap } from 'maplibre-gl';\nimport type { StyleableLayerType } from '../core/types';\n\n/**\n * Get the opacity property name for a given layer type\n * Supports all MapLibre layer types: fill, line, symbol, circle, heatmap,\n * fill-extrusion, raster, hillshade, color-relief, background\n * @param layerType MapLibre layer type\n * @returns Opacity property name(s), or null if the layer type doesn't support opacity\n */\nexport function getOpacityProperty(layerType: string): string | string[] | null {\n switch (layerType) {\n case 'fill':\n return 'fill-opacity';\n case 'line':\n return 'line-opacity';\n case 'circle':\n return 'circle-opacity';\n case 'symbol':\n // Symbol layers have both icon and text opacity\n return ['icon-opacity', 'text-opacity'];\n case 'raster':\n return 'raster-opacity';\n case 'background':\n return 'background-opacity';\n case 'heatmap':\n return 'heatmap-opacity';\n case 'fill-extrusion':\n return 'fill-extrusion-opacity';\n case 'hillshade':\n // Hillshade uses exaggeration for intensity, not opacity\n return 'hillshade-exaggeration';\n case 'color-relief':\n // Color-relief doesn't have a standard opacity property\n return null;\n default:\n // For custom layer types, try the standard pattern\n return `${layerType}-opacity`;\n }\n}\n\n/**\n * Get the current opacity value for a layer\n * @param map MapLibre map instance\n * @param layerId Layer ID\n * @param layerType Layer type\n * @returns Current opacity value (0-1), or 1.0 if the layer type doesn't support opacity\n */\nexport function getLayerOpacity(\n map: MapLibreMap,\n layerId: string,\n layerType: string\n): number {\n const opacityProp = getOpacityProperty(layerType);\n\n // Layer type doesn't support opacity\n if (opacityProp === null) {\n return 1.0;\n }\n\n if (Array.isArray(opacityProp)) {\n // For symbol layers, use icon-opacity as the primary value\n const opacity = map.getPaintProperty(layerId, opacityProp[0]);\n return (opacity !== undefined && opacity !== null) ? opacity as number : 1.0;\n }\n\n const opacity = map.getPaintProperty(layerId, opacityProp);\n return (opacity !== undefined && opacity !== null) ? opacity as number : 1.0;\n}\n\n/**\n * Set the opacity for a layer\n * @param map MapLibre map instance\n * @param layerId Layer ID\n * @param layerType Layer type\n * @param opacity Opacity value (0-1)\n */\nexport function setLayerOpacity(\n map: MapLibreMap,\n layerId: string,\n layerType: string,\n opacity: number\n): void {\n const opacityProp = getOpacityProperty(layerType);\n\n // Layer type doesn't support opacity\n if (opacityProp === null) {\n return;\n }\n\n if (Array.isArray(opacityProp)) {\n // For symbol layers, set both icon and text opacity\n opacityProp.forEach((prop) => {\n map.setPaintProperty(layerId, prop, opacity);\n });\n } else {\n map.setPaintProperty(layerId, opacityProp, opacity);\n }\n}\n\n/**\n * Check if a layer type supports style editing\n * @param layerType Layer type\n * @returns True if the layer type supports style editing\n */\nexport function isStyleableLayerType(layerType: string): layerType is StyleableLayerType {\n return [\n 'fill',\n 'line',\n 'circle',\n 'symbol',\n 'raster',\n 'heatmap',\n 'fill-extrusion',\n 'hillshade',\n ].includes(layerType);\n}\n\n/**\n * Get layer type from map\n * @param map MapLibre map instance\n * @param layerId Layer ID\n * @returns Layer type or null if layer not found\n */\nexport function getLayerType(map: MapLibreMap, layerId: string): string | null {\n try {\n const layer = map.getLayer(layerId);\n return layer ? layer.type : null;\n } catch (error) {\n console.warn(`Failed to get layer type for ${layerId}:`, error);\n return null;\n }\n}\n","import type { Map as MapLibreMap } from 'maplibre-gl';\nimport type { OriginalStyle } from '../core/types';\n\n/**\n * Deep clone a paint value (handles complex MapLibre expressions)\n * @param value Paint value to clone\n * @returns Cloned value\n */\nexport function clonePaintValue(value: any): any {\n if (Array.isArray(value)) {\n return value.map((item) => clonePaintValue(item));\n }\n if (value && typeof value === 'object') {\n try {\n return JSON.parse(JSON.stringify(value));\n } catch (error) {\n return value;\n }\n }\n return value;\n}\n\n/**\n * Cache the original paint properties for a layer\n * @param map MapLibre map instance\n * @param layerId Layer ID\n * @param originalStyles Map to store original styles\n */\nexport function cacheOriginalLayerStyle(\n map: MapLibreMap,\n layerId: string,\n originalStyles: Map<string, OriginalStyle>\n): void {\n if (originalStyles.has(layerId)) {\n return; // Already cached\n }\n\n try {\n const layer = map.getLayer(layerId);\n if (!layer) {\n return;\n }\n\n const paint: Record<string, any> = {};\n const style = map.getStyle();\n const layerDef = style.layers?.find(l => l.id === layerId);\n\n // For raster layers, handle all properties with defaults\n if (layer.type === 'raster') {\n // Default values from MapLibre GL spec\n const rasterDefaults: Record<string, number> = {\n 'raster-opacity': 1,\n 'raster-brightness-min': 0,\n 'raster-brightness-max': 1,\n 'raster-saturation': 0,\n 'raster-contrast': 0,\n 'raster-hue-rotate': 0\n };\n\n // Start with defaults\n Object.assign(paint, rasterDefaults);\n\n // Override with values from layer definition\n if (layerDef && 'paint' in layerDef && layerDef.paint) {\n Object.entries(layerDef.paint).forEach(([prop, value]) => {\n if (prop.startsWith('raster-')) {\n paint[prop] = clonePaintValue(value);\n }\n });\n }\n } else {\n // For non-raster layers, just get values from the layer definition\n if (layerDef && 'paint' in layerDef && layerDef.paint) {\n Object.entries(layerDef.paint).forEach(([prop, value]) => {\n paint[prop] = clonePaintValue(value);\n });\n }\n }\n\n originalStyles.set(layerId, { paint });\n } catch (error) {\n console.warn(`Failed to cache original style for ${layerId}:`, error);\n }\n}\n\n/**\n * Get the current value of a paint property\n * @param map MapLibre map instance\n * @param layerId Layer ID\n * @param property Property name\n * @param fallback Fallback value if property is not set\n * @returns Current property value\n */\nexport function getCurrentPaintValue(\n map: MapLibreMap,\n layerId: string,\n property: string,\n fallback?: any\n): any {\n try {\n const value = map.getPaintProperty(layerId, property);\n return value !== undefined ? value : fallback;\n } catch (error) {\n return fallback;\n }\n}\n\n/**\n * Restore original paint properties for a layer\n * @param map MapLibre map instance\n * @param layerId Layer ID\n * @param originalStyles Map of original styles\n * @returns Object with restored properties\n */\nexport function restoreOriginalStyle(\n map: MapLibreMap,\n layerId: string,\n originalStyles: Map<string, OriginalStyle>\n): Record<string, any> {\n const original = originalStyles.get(layerId);\n if (!original) {\n return {};\n }\n\n const applied: Record<string, any> = {};\n\n Object.entries(original.paint).forEach(([property, value]) => {\n try {\n const restoredValue = clonePaintValue(value);\n map.setPaintProperty(layerId, property, restoredValue);\n applied[property] = restoredValue;\n } catch (error) {\n console.warn(`Failed to restore ${property} for ${layerId}:`, error);\n }\n });\n\n return applied;\n}\n","/**\n * Convert RGB values to hex color string\n * @param r Red component (0-255)\n * @param g Green component (0-255)\n * @param b Blue component (0-255)\n * @returns Hex color string (e.g., '#ff0000')\n */\nexport function rgbToHex(r: number, g: number, b: number): string {\n const clamp = (v: number) => Math.max(0, Math.min(255, Math.round(v)));\n const toHex = (v: number) => {\n const hex = clamp(v).toString(16);\n return hex.length === 1 ? `0${hex}` : hex;\n };\n return `#${toHex(r)}${toHex(g)}${toHex(b)}`;\n}\n\n/**\n * Normalize a color value to hex format\n * Handles hex strings, RGB strings, and RGB arrays\n * @param value Color value in various formats\n * @returns Normalized hex color string (always 6 digits)\n */\nexport function normalizeColor(value: any): string {\n if (typeof value === 'string') {\n // Already hex format\n if (value.startsWith('#')) {\n // Expand shorthand hex (#RGB to #RRGGBB)\n if (value.length === 4) {\n const r = value[1];\n const g = value[2];\n const b = value[3];\n return `#${r}${r}${g}${g}${b}${b}`;\n }\n return value;\n }\n\n // RGB string format: 'rgb(51, 136, 255)'\n if (value.startsWith('rgb')) {\n const match = value.match(/\\d+/g);\n if (match && match.length >= 3) {\n const [r, g, b] = match.map((num) => parseInt(num, 10));\n return rgbToHex(r, g, b);\n }\n }\n } else if (Array.isArray(value) && value.length >= 3) {\n // RGB array format: [51, 136, 255]\n return rgbToHex(value[0], value[1], value[2]);\n }\n\n // Fallback color (MapLibre default blue)\n return '#3388ff';\n}\n","/**\n * Format a numeric value based on the step size\n * @param value Numeric value to format\n * @param step Step size (determines decimal places)\n * @returns Formatted string\n */\nexport function formatNumericValue(value: number, step: number): string {\n let decimals = 0;\n\n if (step && Number(step) !== 1) {\n const stepNumber = Number(step);\n if (stepNumber > 0 && stepNumber < 1) {\n decimals = Math.min(4, Math.ceil(Math.abs(Math.log10(stepNumber))));\n }\n }\n\n return value.toFixed(decimals);\n}\n\n/**\n * Clamp a numeric value between min and max\n * @param value Value to clamp\n * @param min Minimum value\n * @param max Maximum value\n * @returns Clamped value\n */\nexport function clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value));\n}\n","import type { Map as MapLibreMap, LayerSpecification } from 'maplibre-gl';\nimport { normalizeColor, rgbToHex } from './colorUtils';\n\n/**\n * Map of layer types to their primary color property\n */\nconst COLOR_PROPERTY_MAP: Record<string, string[]> = {\n fill: ['fill-color', 'fill-outline-color'],\n line: ['line-color'],\n circle: ['circle-color', 'circle-stroke-color'],\n symbol: ['icon-color', 'text-color'],\n background: ['background-color'],\n heatmap: ['heatmap-color'],\n 'fill-extrusion': ['fill-extrusion-color'],\n};\n\n/**\n * Extract the first color value from a MapLibre expression\n * Handles expressions like ['case', ...], ['match', ...], ['interpolate', ...]\n * @param expression The MapLibre expression to extract color from\n * @returns The first color found, or null\n */\nfunction extractColorFromExpression(expression: any[]): string | null {\n if (!Array.isArray(expression) || expression.length === 0) return null;\n\n // Recursively search for color values\n for (const item of expression) {\n if (typeof item === 'string') {\n // Check if it's a color string\n if (\n item.startsWith('#') ||\n item.startsWith('rgb') ||\n item.startsWith('hsl')\n ) {\n return normalizeColor(item);\n }\n } else if (Array.isArray(item)) {\n const result = extractColorFromExpression(item);\n if (result) return result;\n }\n }\n return null;\n}\n\n/**\n * Get the primary color from a layer's paint properties\n * @param map The MapLibre map instance\n * @param layerId The layer ID\n * @param layerType The layer type\n * @returns The normalized hex color, or null if not found\n */\nexport function getLayerColor(\n map: MapLibreMap,\n layerId: string,\n layerType: string\n): string | null {\n const propertyNames = COLOR_PROPERTY_MAP[layerType];\n if (!propertyNames) return null;\n\n // Try each property in order\n for (const propertyName of propertyNames) {\n // First try runtime property (may have been changed)\n try {\n const runtimeColor = map.getPaintProperty(layerId, propertyName);\n if (runtimeColor) {\n if (typeof runtimeColor === 'string') {\n return normalizeColor(runtimeColor);\n }\n if (Array.isArray(runtimeColor)) {\n // Handle expressions\n const extracted = extractColorFromExpression(runtimeColor);\n if (extracted) return extracted;\n }\n }\n } catch {\n // Property doesn't exist, continue\n }\n\n // Try from layer definition\n const style = map.getStyle();\n const layer = style?.layers?.find(\n (l: LayerSpecification) => l.id === layerId\n );\n if (layer && 'paint' in layer && layer.paint) {\n const paintColor = (layer.paint as Record<string, any>)[propertyName];\n if (paintColor) {\n if (typeof paintColor === 'string') {\n return normalizeColor(paintColor);\n }\n if (Array.isArray(paintColor)) {\n const extracted = extractColorFromExpression(paintColor);\n if (extracted) return extracted;\n }\n }\n }\n }\n\n return null;\n}\n\n/**\n * Get the primary color directly from a layer specification\n * @param layer The layer specification\n * @returns The normalized hex color, or null if not found\n */\nexport function getLayerColorFromSpec(layer: LayerSpecification): string | null {\n const propertyNames = COLOR_PROPERTY_MAP[layer.type];\n if (!propertyNames) return null;\n\n for (const propertyName of propertyNames) {\n if ('paint' in layer && layer.paint) {\n const paintColor = (layer.paint as Record<string, any>)[propertyName];\n if (paintColor) {\n if (typeof paintColor === 'string') {\n return normalizeColor(paintColor);\n }\n if (Array.isArray(paintColor)) {\n const extracted = extractColorFromExpression(paintColor);\n if (extracted) return extracted;\n }\n }\n }\n }\n\n return null;\n}\n\n/**\n * Darken a hex color by a given amount\n * @param hexColor The hex color to darken (e.g., '#ff0000')\n * @param amount Amount to darken (0-1, where 1 is fully black)\n * @returns The darkened hex color\n */\nexport function darkenColor(hexColor: string, amount: number): string {\n // Normalize to 6-digit hex\n let hex = hexColor.replace('#', '');\n if (hex.length === 3) {\n hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];\n }\n\n const r = Math.max(\n 0,\n parseInt(hex.slice(0, 2), 16) - Math.round(255 * amount)\n );\n const g = Math.max(\n 0,\n parseInt(hex.slice(2, 4), 16) - Math.round(255 * amount)\n );\n const b = Math.max(\n 0,\n parseInt(hex.slice(4, 6), 16) - Math.round(255 * amount)\n );\n return rgbToHex(r, g, b);\n}\n\n// SVG Symbol Templates\n\n/**\n * Create a fill symbol (filled rectangle)\n */\nfunction createFillSymbol(size: number, color: string): string {\n const padding = 2;\n const borderColor = darkenColor(color, 0.3);\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"${padding}\" y=\"${padding}\" width=\"${size - padding * 2}\" height=\"${size - padding * 2}\"\n fill=\"${color}\" stroke=\"${borderColor}\" stroke-width=\"1\" rx=\"1\"/>\n </svg>`;\n}\n\n/**\n * Create a line symbol (horizontal line)\n */\nfunction createLineSymbol(\n size: number,\n color: string,\n strokeWidth: number = 2\n): string {\n const y = size / 2;\n const padding = 2;\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <line x1=\"${padding}\" y1=\"${y}\" x2=\"${size - padding}\" y2=\"${y}\"\n stroke=\"${color}\" stroke-width=\"${strokeWidth}\" stroke-linecap=\"round\"/>\n </svg>`;\n}\n\n/**\n * Create a circle symbol (filled circle)\n */\nfunction createCircleSymbol(size: number, color: string): string {\n const cx = size / 2;\n const cy = size / 2;\n const r = size / 2 - 3;\n const borderColor = darkenColor(color, 0.3);\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"${cx}\" cy=\"${cy}\" r=\"${r}\" fill=\"${color}\"\n stroke=\"${borderColor}\" stroke-width=\"1\"/>\n </svg>`;\n}\n\n/**\n * Create a marker/pin symbol for symbol layers\n */\nfunction createMarkerSymbol(size: number, color: string): string {\n const borderColor = darkenColor(color, 0.3);\n // Simple pin/marker shape\n const cx = size / 2;\n const pinWidth = size * 0.5;\n const pinHeight = size * 0.7;\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M${cx} ${size - 2}\n L${cx - pinWidth / 2} ${size - pinHeight}\n A${pinWidth / 2} ${pinWidth / 2} 0 1 1 ${cx + pinWidth / 2} ${size - pinHeight}\n Z\"\n fill=\"${color}\" stroke=\"${borderColor}\" stroke-width=\"1\"/>\n <circle cx=\"${cx}\" cy=\"${size - pinHeight - pinWidth / 4}\" r=\"${pinWidth / 5}\" fill=\"white\"/>\n </svg>`;\n}\n\n/**\n * Create a raster symbol (gradient pattern)\n */\nfunction createRasterSymbol(size: number): string {\n const padding = 2;\n const id = `rasterGrad_${Math.random().toString(36).slice(2, 9)}`;\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <linearGradient id=\"${id}\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"100%\">\n <stop offset=\"0%\" stop-color=\"#e0e0e0\"/>\n <stop offset=\"50%\" stop-color=\"#808080\"/>\n <stop offset=\"100%\" stop-color=\"#404040\"/>\n </linearGradient>\n </defs>\n <rect x=\"${padding}\" y=\"${padding}\" width=\"${size - padding * 2}\" height=\"${size - padding * 2}\"\n fill=\"url(#${id})\" rx=\"1\"/>\n </svg>`;\n}\n\n/**\n * Create a background symbol (rectangle with inner indicator)\n */\nfunction createBackgroundSymbol(size: number, color: string): string {\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"1\" y=\"1\" width=\"${size - 2}\" height=\"${size - 2}\" fill=\"${color}\" rx=\"2\"/>\n <rect x=\"3\" y=\"3\" width=\"${size - 6}\" height=\"${size - 6}\" fill=\"none\"\n stroke=\"white\" stroke-width=\"1\" stroke-opacity=\"0.5\" rx=\"1\"/>\n </svg>`;\n}\n\n/**\n * Create a heatmap symbol (orange-red gradient)\n */\nfunction createHeatmapSymbol(size: number): string {\n const padding = 2;\n const id = `heatmapGrad_${Math.random().toString(36).slice(2, 9)}`;\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <radialGradient id=\"${id}\" cx=\"50%\" cy=\"50%\" r=\"50%\">\n <stop offset=\"0%\" stop-color=\"#ffff00\"/>\n <stop offset=\"50%\" stop-color=\"#ff8800\"/>\n <stop offset=\"100%\" stop-color=\"#ff0000\"/>\n </radialGradient>\n </defs>\n <rect x=\"${padding}\" y=\"${padding}\" width=\"${size - padding * 2}\" height=\"${size - padding * 2}\"\n fill=\"url(#${id})\" rx=\"1\"/>\n </svg>`;\n}\n\n/**\n * Create a hillshade symbol (gray gradient)\n */\nfunction createHillshadeSymbol(size: number): string {\n const padding = 2;\n const id = `hillshadeGrad_${Math.random().toString(36).slice(2, 9)}`;\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <linearGradient id=\"${id}\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"100%\">\n <stop offset=\"0%\" stop-color=\"#ffffff\"/>\n <stop offset=\"100%\" stop-color=\"#666666\"/>\n </linearGradient>\n </defs>\n <rect x=\"${padding}\" y=\"${padding}\" width=\"${size - padding * 2}\" height=\"${size - padding * 2}\"\n fill=\"url(#${id})\" rx=\"1\"/>\n </svg>`;\n}\n\n/**\n * Create a fill-extrusion symbol (3D-ish rectangle)\n */\nfunction createFillExtrusionSymbol(size: number, color: string): string {\n const borderColor = darkenColor(color, 0.3);\n const topColor = color;\n const sideColor = darkenColor(color, 0.2);\n const depth = 3;\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <polygon points=\"${2 + depth},2 ${size - 2},2 ${size - 2},${size - 2 - depth} ${size - 2 - depth},${size - 2} 2,${size - 2} 2,${2 + depth}\"\n fill=\"${topColor}\" stroke=\"${borderColor}\" stroke-width=\"1\"/>\n <polygon points=\"2,${2 + depth} ${2 + depth},2 ${2 + depth},${size - 2 - depth} 2,${size - 2}\"\n fill=\"${sideColor}\" stroke=\"${borderColor}\" stroke-width=\"0.5\"/>\n <polygon points=\"${2 + depth},${size - 2 - depth} ${size - 2},${size - 2 - depth} ${size - 2 - depth},${size - 2} 2,${size - 2}\"\n fill=\"${sideColor}\" stroke=\"${borderColor}\" stroke-width=\"0.5\"/>\n </svg>`;\n}\n\n/**\n * Create a default symbol (simple square)\n */\nfunction createDefaultSymbol(size: number, color: string): string {\n const padding = 2;\n const borderColor = darkenColor(color, 0.3);\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"${padding}\" y=\"${padding}\" width=\"${size - padding * 2}\" height=\"${size - padding * 2}\"\n fill=\"${color}\" stroke=\"${borderColor}\" stroke-width=\"1\"/>\n </svg>`;\n}\n\n/**\n * Create a COG (Cloud Optimized GeoTIFF) symbol\n * Grid pattern representing raster tiles\n */\nfunction createCOGSymbol(size: number, color: string): string {\n const padding = 2;\n const borderColor = darkenColor(color, 0.3);\n const cellSize = (size - padding * 2) / 2;\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"${padding}\" y=\"${padding}\" width=\"${cellSize}\" height=\"${cellSize}\" fill=\"${color}\" stroke=\"${borderColor}\" stroke-width=\"0.5\"/>\n <rect x=\"${padding + cellSize}\" y=\"${padding}\" width=\"${cellSize}\" height=\"${cellSize}\" fill=\"${color}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" opacity=\"0.8\"/>\n <rect x=\"${padding}\" y=\"${padding + cellSize}\" width=\"${cellSize}\" height=\"${cellSize}\" fill=\"${color}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" opacity=\"0.6\"/>\n <rect x=\"${padding + cellSize}\" y=\"${padding + cellSize}\" width=\"${cellSize}\" height=\"${cellSize}\" fill=\"${color}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" opacity=\"0.4\"/>\n </svg>`;\n}\n\n/**\n * Create a Zarr symbol\n * Layered grid pattern representing multidimensional data\n */\nfunction createZarrSymbol(size: number, color: string): string {\n const padding = 2;\n const borderColor = darkenColor(color, 0.3);\n const innerSize = size - padding * 2;\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"${padding + 2}\" y=\"${padding}\" width=\"${innerSize - 2}\" height=\"${innerSize - 2}\" fill=\"${darkenColor(color, 0.2)}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" rx=\"1\"/>\n <rect x=\"${padding + 1}\" y=\"${padding + 1}\" width=\"${innerSize - 2}\" height=\"${innerSize - 2}\" fill=\"${darkenColor(color, 0.1)}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" rx=\"1\"/>\n <rect x=\"${padding}\" y=\"${padding + 2}\" width=\"${innerSize - 2}\" height=\"${innerSize - 2}\" fill=\"${color}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" rx=\"1\"/>\n <line x1=\"${padding + 3}\" y1=\"${padding + 5}\" x2=\"${padding + innerSize - 5}\" y2=\"${padding + 5}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" opacity=\"0.5\"/>\n <line x1=\"${padding + 3}\" y1=\"${padding + 8}\" x2=\"${padding + innerSize - 5}\" y2=\"${padding + 8}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" opacity=\"0.5\"/>\n </svg>`;\n}\n\n/**\n * Create a generic custom raster symbol\n * Gradient grid representing custom raster layers\n */\nfunction createCustomRasterSymbol(size: number, color: string): string {\n const padding = 2;\n const borderColor = darkenColor(color, 0.3);\n const id = `customRasterGrad_${Math.random().toString(36).slice(2, 9)}`;\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <linearGradient id=\"${id}\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"100%\">\n <stop offset=\"0%\" stop-color=\"${color}\"/>\n <stop offset=\"100%\" stop-color=\"${darkenColor(color, 0.4)}\"/>\n </linearGradient>\n </defs>\n <rect x=\"${padding}\" y=\"${padding}\" width=\"${size - padding * 2}\" height=\"${size - padding * 2}\"\n fill=\"url(#${id})\" stroke=\"${borderColor}\" stroke-width=\"1\" rx=\"1\"/>\n <line x1=\"${size / 2}\" y1=\"${padding}\" x2=\"${size / 2}\" y2=\"${size - padding}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" opacity=\"0.3\"/>\n <line x1=\"${padding}\" y1=\"${size / 2}\" x2=\"${size - padding}\" y2=\"${size / 2}\" stroke=\"${borderColor}\" stroke-width=\"0.5\" opacity=\"0.3\"/>\n </svg>`;\n}\n\n/**\n * Create a stacked layers symbol for background layer groups\n * Shows multiple overlapping rectangles to represent multiple layers\n */\nfunction createStackedLayersSymbol(size: number): string {\n const colors = ['#a8d4a8', '#8ec4e8', '#d4c4a8'];\n const borderColor = '#666666';\n // Three stacked rectangles offset diagonally\n return `<svg width=\"${size}\" height=\"${size}\" viewBox=\"0 0 ${size} ${size}\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"4\" y=\"1\" width=\"${size - 6}\" height=\"${size - 6}\" fill=\"${colors[2]}\" stroke=\"${borderColor}\" stroke-width=\"0.75\" rx=\"1\"/>\n <rect x=\"2\" y=\"3\" width=\"${size - 6}\" height=\"${size - 6}\" fill=\"${colors[1]}\" stroke=\"${borderColor}\" stroke-width=\"0.75\" rx=\"1\"/>\n <rect x=\"0\" y=\"5\" width=\"${size - 6}\" height=\"${size - 6}\" fill=\"${colors[0]}\" stroke=\"${borderColor}\" stroke-width=\"0.75\" rx=\"1\"/>\n </svg>`;\n}\n\n/**\n * Symbol generation options\n */\nexport interface SymbolOptions {\n /** Symbol size in pixels (default: 16) */\n size?: number;\n /** Stroke width for line symbols (default: 2) */\n strokeWidth?: number;\n}\n\n/**\n * Create an SVG symbol for a layer type\n * @param layerType The MapLibre layer type\n * @param color The primary color (hex format), or null for default\n * @param options Optional configuration\n * @returns SVG markup string\n */\nexport function createLayerSymbolSVG(\n layerType: string,\n color: string | null,\n options: SymbolOptions = {}\n): string {\n const size = options.size || 16;\n const strokeWidth = options.strokeWidth || 2;\n const fillColor = color || '#888888'; // Fallback gray\n\n switch (layerType) {\n case 'fill':\n return createFillSymbol(size, fillColor);\n case 'line':\n return createLineSymbol(size, fillColor, strokeWidth);\n case 'circle':\n return createCircleSymbol(size, fillColor);\n case 'symbol':\n return createMarkerSymbol(size, fillColor);\n case 'raster':\n return createRasterSymbol(size);\n case 'background':\n return createBackgroundSymbol(size, fillColor);\n case 'heatmap':\n return createHeatmapSymbol(size);\n case 'hillshade':\n return createHillshadeSymbol(size);\n case 'fill-extrusion':\n return createFillExtrusionSymbol(size, fillColor);\n case 'background-group':\n return createStackedLayersSymbol(size);\n case 'cog':\n return createCOGSymbol(size, fillColor);\n case 'zarr':\n return createZarrSymbol(size, fillColor);\n case 'custom-raster':\n return createCustomRasterSymbol(size, fillColor);\n default:\n return createDefaultSymbol(size, fillColor);\n }\n}\n\n/**\n * Create an SVG symbol for the Background layer group\n * @param size Symbol size in pixels (default: 16)\n * @returns SVG markup string\n */\nexport function createBackgroundGroupSymbolSVG(size: number = 16): string {\n return createStackedLayersSymbol(size);\n}\n","import type {\n IControl,\n Map as MapLibreMap,\n LayerSpecification,\n} from \"maplibre-gl\";\nimport type {\n LayerControlOptions,\n LayerState,\n PartialLayerStates,\n OriginalStyle,\n InternalControlState,\n CustomLayerAdapter,\n BackgroundLayerVisibility,\n BackgroundPresets,\n} from \"./types\";\nimport { CustomLayerRegistry } from \"./CustomLayerRegistry\";\nimport {\n getLayerType,\n getLayerOpacity,\n setLayerOpacity,\n} from \"../utils/layerUtils\";\nimport {\n cacheOriginalLayerStyle,\n restoreOriginalStyle,\n} from \"../utils/styleCache\";\nimport { normalizeColor } from \"../utils/colorUtils\";\nimport { formatNumericValue, clamp } from \"../utils/formatters\";\nimport {\n getLayerColor,\n getLayerColorFromSpec,\n createLayerSymbolSVG,\n createBackgroundGroupSymbolSVG,\n} from \"../utils/symbolUtils\";\n\n/**\n * LayerControl - A comprehensive layer control for MapLibre GL\n * Provides visibility toggle, opacity control, and advanced style editing\n */\nexport class LayerControl implements IControl {\n private map!: MapLibreMap;\n private mapContainer!: HTMLElement;\n private container!: HTMLDivElement;\n private button!: HTMLButtonElement;\n private panel!: HTMLDivElement;\n\n // Panel positioning\n private resizeHandler: (() => void) | null = null;\n private mapResizeHandler: (() => void) | null = null;\n\n // State management\n private state: InternalControlState;\n private targetLayers: string[];\n private styleEditors: Map<string, HTMLElement>;\n private initialSourceIds: Set<string> | null = null;\n private initialLayerIds: Set<string> | null = null;\n private initialLayerStates: PartialLayerStates;\n\n // Panel width management\n private minPanelWidth: number;\n private maxPanelWidth: number;\n private initialPanelWidth: number;\n /** Explicit max panel height; null means fill available vertical space */\n private maxPanelHeight: number | null;\n private showStyleEditor: boolean;\n private showOpacitySlider: boolean;\n private showLayerSymbol: boolean;\n private excludeDrawnLayers: boolean;\n private excludeLayerPatterns: RegExp[];\n private customLayerRegistry: CustomLayerRegistry | null = null;\n private customLayerUnsubscribe: (() => void) | null = null;\n private removedCustomLayerIds: Set<string> = new Set();\n private nativeLayerGroups: Map<string, string[]> = new Map();\n private basemapStyleUrl: string | null = null;\n private basemapLayerIds: Set<string> | null = null;\n private widthFrame: number | null = null;\n\n // Exact-opacity input popup\n private opacityInputEl: HTMLDivElement | null = null;\n\n // Panel edge-drag resizing (handles on both the left and right edges)\n private resizeHandleEls: HTMLDivElement[] = [];\n /** Which edge is anchored to the control corner (the other edge is \"free\") */\n private panelAnchorSide: \"left\" | \"right\" = \"right\";\n private isPanelResizing = false;\n /** The physical edge being dragged in the current resize gesture */\n private panelResizeEdge: \"left\" | \"right\" = \"left\";\n private panelResizeStartX: number | null = null;\n private panelResizeStartWidth: number | null = null;\n private panelResizeStartOffset = 0;\n\n // Context menu and drag-drop\n private contextMenuEl: HTMLDivElement | null = null;\n private enableContextMenu: boolean;\n private enableDragAndDrop: boolean;\n private onLayerRename?: (\n layerId: string,\n oldName: string,\n newName: string,\n ) => void;\n private onLayerReorder?: (layerOrder: string[]) => void;\n private onLayerRemove?: (layerId: string) => void;\n\n // Background-layer visibility presets\n private enableBackgroundPresets: boolean;\n private backgroundPresetStorageKey: string;\n private onBackgroundPresetsChange?: (presets: BackgroundPresets) => void;\n\n constructor(options: LayerControlOptions = {}) {\n this.minPanelWidth = options.panelMinWidth || 240;\n this.maxPanelWidth = options.panelMaxWidth || 960;\n this.initialPanelWidth = options.panelWidth || 350;\n // When no explicit max height is given, the panel grows to fill the\n // available vertical space in the map container (computed in\n // updatePanelPosition) instead of being capped at a fixed height.\n this.maxPanelHeight = options.panelMaxHeight ?? null;\n this.showStyleEditor = options.showStyleEditor !== false;\n this.showOpacitySlider = options.showOpacitySlider !== false;\n this.showLayerSymbol = options.showLayerSymbol !== false;\n this.excludeDrawnLayers = options.excludeDrawnLayers !== false;\n this.excludeLayerPatterns = this.wildcardPatternsToRegex(\n options.excludeLayers || [],\n );\n\n // Context menu and drag-drop options\n this.enableContextMenu = options.enableContextMenu !== false;\n this.enableDragAndDrop = options.enableDragAndDrop !== false;\n this.onLayerRename = options.onLayerRename;\n this.onLayerReorder = options.onLayerReorder;\n this.onLayerRemove = options.onLayerRemove;\n\n // Background-layer visibility presets\n this.enableBackgroundPresets = options.enableBackgroundPresets !== false;\n this.backgroundPresetStorageKey =\n options.backgroundPresetStorageKey ||\n \"maplibre-layer-control:background-presets\";\n this.onBackgroundPresetsChange = options.onBackgroundPresetsChange;\n\n this.initialLayerStates = options.layerStates || {};\n\n this.state = {\n collapsed: options.collapsed !== false,\n panelWidth: options.panelWidth || 350,\n activeStyleEditor: null,\n layerStates: {},\n originalStyles: new Map<string, OriginalStyle>(),\n userInteractingWithSlider: false,\n backgroundLegendOpen: false,\n backgroundLayerVisibility: new Map<string, boolean>(),\n onlyRenderedFilter: false,\n contextMenu: {\n visible: false,\n targetLayerId: null,\n x: 0,\n y: 0,\n },\n renamingLayerId: null,\n customLayerNames: new Map<string, string>(),\n drag: {\n active: false,\n layerId: null,\n startY: 0,\n currentY: 0,\n placeholder: null,\n draggedElement: null,\n },\n isStyleOperationInProgress: false,\n };\n\n this.targetLayers = options.layers || Object.keys(this.initialLayerStates);\n this.styleEditors = new Map<string, HTMLElement>();\n\n // Initialize custom layer registry if adapters are provided\n if (options.customLayerAdapters && options.customLayerAdapters.length > 0) {\n this.customLayerRegistry = new CustomLayerRegistry();\n options.customLayerAdapters.forEach((adapter) => {\n this.customLayerRegistry!.register(adapter);\n });\n }\n\n // Store basemap style URL for reliable layer detection\n this.basemapStyleUrl = options.basemapStyleUrl || null;\n }\n\n /**\n * Called when the control is added to the map\n */\n onAdd(map: MapLibreMap): HTMLElement {\n this.map = map;\n this.mapContainer = map.getContainer();\n\n // Capture initial source IDs and layer IDs (basemap) before auto-detecting layers\n // Sources and layers added after this point are considered user-added\n const style = this.map.getStyle();\n if (style && style.sources) {\n this.initialSourceIds = new Set(Object.keys(style.sources));\n } else {\n this.initialSourceIds = new Set();\n }\n\n // Capture initial layer IDs - any layer added after this is user-added\n if (style && style.layers) {\n this.initialLayerIds = new Set(style.layers.map((layer) => layer.id));\n } else {\n this.initialLayerIds = new Set();\n }\n\n this.container = this.createContainer();\n this.button = this.createToggleButton();\n this.panel = this.createPanel();\n\n this.container.appendChild(this.button);\n // Append panel to map container for independent positioning (avoids overlap with other controls)\n this.mapContainer.appendChild(this.panel);\n\n // Create context menu element (appended to map container)\n if (this.enableContextMenu) {\n this.contextMenuEl = this.createContextMenu();\n this.mapContainer.appendChild(this.contextMenuEl);\n }\n\n // Setup event listeners\n this.setupEventListeners();\n\n // If basemapStyleUrl is provided, fetch it first for reliable layer detection\n if (this.basemapStyleUrl && !this.basemapLayerIds) {\n this.fetchBasemapStyle()\n .then(() => {\n // Auto-detect layers after basemap style is fetched\n if (Object.keys(this.state.layerStates).length === 0) {\n this.autoDetectLayers();\n }\n // Build layer items\n this.buildLayerItems();\n })\n .catch((error) => {\n console.warn(\n \"Failed to fetch basemap style, falling back to heuristic detection:\",\n error,\n );\n // Fall back to heuristic detection\n if (Object.keys(this.state.layerStates).length === 0) {\n this.autoDetectLayers();\n }\n this.buildLayerItems();\n });\n } else {\n // Auto-detect layers using source-based heuristics\n if (Object.keys(this.state.layerStates).length === 0) {\n this.autoDetectLayers();\n }\n // Build layer items\n this.buildLayerItems();\n }\n\n // If panel starts expanded, update position after control is added to DOM\n if (!this.state.collapsed) {\n // Use requestAnimationFrame to wait until container is in DOM and positioned\n requestAnimationFrame(() => {\n this.updatePanelPosition();\n });\n }\n\n return this.container;\n }\n\n /**\n * Fetch the basemap style JSON and extract layer IDs.\n * This provides reliable distinction between basemap and user-added layers.\n */\n private async fetchBasemapStyle(): Promise<void> {\n if (!this.basemapStyleUrl) return;\n\n try {\n const response = await fetch(this.basemapStyleUrl);\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n const styleJson = await response.json();\n\n // Extract layer IDs from the basemap style\n if (styleJson && Array.isArray(styleJson.layers)) {\n this.basemapLayerIds = new Set(\n styleJson.layers.map((layer: { id: string }) => layer.id),\n );\n } else {\n this.basemapLayerIds = new Set();\n }\n } catch (error) {\n console.warn(\n \"Failed to fetch basemap style from URL:\",\n this.basemapStyleUrl,\n error,\n );\n throw error;\n }\n }\n\n /**\n * Called when the control is removed from the map\n */\n onRemove(): void {\n // Clean up custom layer registry subscription\n if (this.customLayerUnsubscribe) {\n this.customLayerUnsubscribe();\n this.customLayerUnsubscribe = null;\n }\n if (this.customLayerRegistry) {\n this.customLayerRegistry.destroy();\n this.customLayerRegistry = null;\n }\n\n // Remove resize event listeners\n if (this.resizeHandler) {\n window.removeEventListener(\"resize\", this.resizeHandler);\n this.resizeHandler = null;\n }\n if (this.mapResizeHandler) {\n this.map.off(\"resize\", this.mapResizeHandler);\n this.mapResizeHandler = null;\n }\n\n // Clean up context menu\n if (this.contextMenuEl) {\n this.contextMenuEl.parentNode?.removeChild(this.contextMenuEl);\n this.contextMenuEl = null;\n }\n\n // Clean up the exact-opacity input popup\n this.hideOpacityInput();\n\n // Clean up any active drag state\n this.cleanupDragState();\n\n // Remove panel from map container\n this.panel.parentNode?.removeChild(this.panel);\n\n // Remove button container from control stack\n this.container.parentNode?.removeChild(this.container);\n }\n\n /**\n * Auto-detect layers from the map and populate layerStates\n */\n private autoDetectLayers(): void {\n const style = this.map.getStyle();\n if (!style || !style.layers) {\n return;\n }\n\n // Get all layer IDs from the map\n const allLayerIds = style.layers.map((layer) => layer.id);\n\n if (this.targetLayers.length === 0) {\n // No layers specified - auto-detect user-added layers vs background layers\n const userAddedLayers: string[] = [];\n const backgroundLayerIds: string[] = [];\n\n // Detection priority for INITIAL detection:\n // 1. basemapLayerIds (from basemapStyleUrl) - most reliable\n // 2. Source-based heuristics - works for layers added before OR after control\n // Note: initialLayerIds is NOT used here because it would incorrectly classify\n // user layers added BEFORE the control as basemap layers\n const useBasemapStyleDetection =\n this.basemapLayerIds !== null && this.basemapLayerIds.size > 0;\n\n // Identify which sources are user-added (for source-based heuristic detection)\n const userAddedSourceIds = useBasemapStyleDetection\n ? new Set<string>()\n : this.detectUserAddedSources();\n\n allLayerIds.forEach((layerId) => {\n const layer = this.map.getLayer(layerId);\n if (!layer) return;\n\n // Skip drawn layers if excludeDrawnLayers is enabled\n if (this.excludeDrawnLayers && this.isDrawnLayer(layerId)) {\n backgroundLayerIds.push(layerId);\n return;\n }\n\n // Skip layers matching user-defined exclusion patterns\n if (this.isExcludedByPattern(layerId)) {\n backgroundLayerIds.push(layerId);\n return;\n }\n\n if (useBasemapStyleDetection) {\n // Use basemap style layer IDs for reliable detection\n if (this.basemapLayerIds!.has(layerId)) {\n // This layer is from the basemap style\n backgroundLayerIds.push(layerId);\n } else {\n // This layer is not in the basemap style - it's user-added\n userAddedLayers.push(layerId);\n }\n } else {\n // Use source-based heuristics\n // Check if this layer uses a user-added source\n const sourceId = (layer as any).source;\n if (sourceId && userAddedSourceIds.has(sourceId)) {\n userAddedLayers.push(layerId);\n } else {\n // Layer uses a basemap source or has no source (like background color layer)\n backgroundLayerIds.push(layerId);\n }\n }\n });\n\n // Add Background entry if there are background layers\n if (backgroundLayerIds.length > 0) {\n this.state.layerStates[\"Background\"] = {\n visible: true,\n opacity: 1.0,\n name: \"Background\",\n };\n }\n\n // Add entries for auto-detected user layers\n userAddedLayers.forEach((layerId) => {\n const layer = this.map.getLayer(layerId);\n if (!layer) return;\n\n const visibility = this.map.getLayoutProperty(layerId, \"visibility\");\n const isVisible = visibility !== \"none\";\n const layerType = layer.type;\n const opacity = getLayerOpacity(this.map, layerId, layerType);\n const friendlyName = this.generateFriendlyName(layerId);\n\n this.state.layerStates[layerId] = this.mergeWithUserState(layerId, {\n visible: isVisible,\n opacity: opacity,\n name: friendlyName,\n });\n });\n } else {\n // Specific layers requested - separate into user layers + Background\n const userLayers: string[] = [];\n const basemapLayers: string[] = [];\n\n allLayerIds.forEach((layerId) => {\n // Skip layers matching user-defined exclusion patterns\n if (this.isExcludedByPattern(layerId)) {\n basemapLayers.push(layerId);\n return;\n }\n\n if (this.targetLayers.includes(layerId)) {\n userLayers.push(layerId);\n } else {\n basemapLayers.push(layerId);\n }\n });\n\n // Add Background entry if there are basemap layers\n if (basemapLayers.length > 0) {\n this.state.layerStates[\"Background\"] = {\n visible: true,\n opacity: 1.0,\n name: \"Background\",\n };\n }\n\n // Add entries for user-specified layers\n userLayers.forEach((layerId) => {\n const layer = this.map.getLayer(layerId);\n if (!layer) return;\n\n const visibility = this.map.getLayoutProperty(layerId, \"visibility\");\n const isVisible = visibility !== \"none\";\n const layerType = layer.type;\n const opacity = getLayerOpacity(this.map, layerId, layerType);\n const friendlyName = this.generateFriendlyName(layerId);\n\n this.state.layerStates[layerId] = this.mergeWithUserState(layerId, {\n visible: isVisible,\n opacity: opacity,\n name: friendlyName,\n });\n });\n }\n\n // Detect custom layers from registry\n if (this.customLayerRegistry) {\n const customLayerIds = this.customLayerRegistry.getAllLayerIds();\n customLayerIds.forEach((layerId) => {\n // Skip if already in state\n if (this.state.layerStates[layerId]) return;\n\n const customState = this.customLayerRegistry!.getLayerState(layerId);\n if (customState) {\n this.state.layerStates[layerId] = {\n visible: customState.visible,\n opacity: customState.opacity,\n name: customState.name,\n isCustomLayer: true,\n customLayerType:\n this.customLayerRegistry!.getSymbolType(layerId) || undefined,\n };\n }\n });\n }\n\n // Update targetLayers to include detected layers\n this.targetLayers = Object.keys(this.state.layerStates);\n }\n\n /**\n * Detect which sources are user-added (not from the basemap style)\n * User-added sources are identified by:\n * - Sources that were NOT present when the control was first added\n * - Additionally for sources added later:\n * - GeoJSON sources with inline data objects (not URL strings)\n * - Image, video, canvas sources\n * - Raster, raster-dem, vector sources from non-basemap tile providers\n */\n private detectUserAddedSources(): Set<string> {\n const userAddedSources = new Set<string>();\n const style = this.map.getStyle();\n if (!style || !style.sources) return userAddedSources;\n\n // First, detect the basemap's domain from sprite/glyphs URLs\n const basemapDomains = new Set<string>();\n\n // Known basemap providers\n const knownBasemapProviders = [\n \"demotiles.maplibre.org\",\n \"api.maptiler.com\",\n \"tiles.stadiamaps.com\",\n \"api.mapbox.com\",\n \"basemaps.cartocdn.com\",\n \"tiles.mapbox.com\",\n \"a.basemaps.cartocdn.com\",\n \"b.basemaps.cartocdn.com\",\n \"c.basemaps.cartocdn.com\",\n \"d.basemaps.cartocdn.com\",\n \"tiles.arcgis.com\",\n \"server.arcgisonline.com\",\n \"services.arcgisonline.com\",\n ];\n\n // Detect domains from sprite/glyphs URLs (these are likely basemap domains)\n const spriteUrl = style.sprite as string | undefined;\n if (spriteUrl && typeof spriteUrl === \"string\") {\n try {\n const url = new URL(spriteUrl);\n basemapDomains.add(url.hostname);\n } catch {\n /* ignore */\n }\n }\n if (style.glyphs) {\n try {\n const url = new URL(\n style.glyphs.replace(\"{fontstack}\", \"x\").replace(\"{range}\", \"x\"),\n );\n basemapDomains.add(url.hostname);\n } catch {\n /* ignore */\n }\n }\n\n // Check each source\n for (const [sourceId, source] of Object.entries(style.sources)) {\n // If we have a snapshot of initial sources, use that as the primary check\n // Sources that existed when the control was added are basemap sources\n if (this.initialSourceIds && this.initialSourceIds.has(sourceId)) {\n // This source was present in the initial style, it's a basemap source\n continue;\n }\n\n const src = source as any;\n const sourceType = src.type;\n\n // Image, video, and canvas sources are always user-added\n if (\n sourceType === \"image\" ||\n sourceType === \"video\" ||\n sourceType === \"canvas\"\n ) {\n userAddedSources.add(sourceId);\n continue;\n }\n\n // GeoJSON sources with inline data objects are user-added (if added after initial load)\n if (sourceType === \"geojson\") {\n if (src.data && typeof src.data === \"object\") {\n userAddedSources.add(sourceId);\n } else if (src.data && typeof src.data === \"string\") {\n // GeoJSON with URL - check if it's from a basemap domain\n try {\n const url = new URL(src.data);\n const isBasemap =\n knownBasemapProviders.some((p) => url.hostname.includes(p)) ||\n basemapDomains.has(url.hostname);\n if (!isBasemap) {\n userAddedSources.add(sourceId);\n }\n } catch {\n // Relative URL or invalid - assume user-added\n userAddedSources.add(sourceId);\n }\n }\n continue;\n }\n\n // Check tile URLs for raster, raster-dem, and vector sources\n if (\n sourceType === \"raster\" ||\n sourceType === \"raster-dem\" ||\n sourceType === \"vector\"\n ) {\n const tileUrl = src.url || (src.tiles && src.tiles[0]) || \"\";\n if (tileUrl) {\n try {\n const url = new URL(tileUrl.replace(/{[^}]+}/g, \"0\"));\n const hostname = url.hostname;\n\n // Check if this is a known basemap provider\n const isKnownBasemap = knownBasemapProviders.some(\n (provider) =>\n hostname === provider || hostname.endsWith(\".\" + provider),\n );\n\n // Check if this matches detected basemap domains\n const matchesBasemapDomain = basemapDomains.has(hostname);\n\n // If not a basemap source, it's user-added\n if (!isKnownBasemap && !matchesBasemapDomain) {\n userAddedSources.add(sourceId);\n }\n } catch {\n // If URL parsing fails, assume it could be user-added\n userAddedSources.add(sourceId);\n }\n }\n }\n }\n\n return userAddedSources;\n }\n\n /**\n * Generate a friendly display name from a layer ID\n */\n private generateFriendlyName(layerId: string): string {\n // Remove common prefixes\n let name = layerId.replace(/^(layer[-_]?|gl[-_]?)/, \"\");\n\n // Replace dashes and underscores with spaces\n name = name.replace(/[-_]/g, \" \");\n\n // Capitalize first letter of each word\n name = name.replace(/\\b\\w/g, (char) => char.toUpperCase());\n\n return name || layerId; // Fallback to original if empty\n }\n\n /**\n * Merge auto-detected layer state with user-provided initial state.\n * User-provided values take precedence over detected values.\n */\n private mergeWithUserState(\n layerId: string,\n detected: LayerState,\n ): LayerState {\n const userState = this.initialLayerStates[layerId];\n if (!userState) return detected;\n\n return {\n visible: userState.visible ?? detected.visible,\n opacity: userState.opacity ?? detected.opacity,\n name: userState.name ?? detected.name,\n ...(userState.isCustomLayer !== undefined && {\n isCustomLayer: userState.isCustomLayer,\n }),\n ...(userState.customLayerType !== undefined && {\n customLayerType: userState.customLayerType,\n }),\n };\n }\n\n /**\n * Check if a layer ID belongs to a drawing library (Geoman, Mapbox GL Draw, etc.)\n * @param layerId The layer ID to check\n * @returns true if the layer is from a drawing library\n */\n private isDrawnLayer(layerId: string): boolean {\n const drawnLayerPatterns = [\n // Drawing libraries\n /^gm[-_\\s]/i, // Geoman (gm-main-*, gm_*, Gm Temporary...)\n /^gl-draw[-_]/i, // Mapbox GL Draw\n /^mapbox-gl-draw[-_]/i, // Mapbox GL Draw alternative\n /^terra-draw[-_]/i, // Terra Draw\n /^maplibre-gl-draw[-_]/i, // MapLibre GL Draw\n /^draw[-_]layer/i, // Generic draw layers\n // maplibre-gl-components internal layers\n /^measure-/i, // MeasureControl (measure-{id}-fill, measure-{id}-line)\n /^pmtiles-source-/i, // PMTilesLayerControl (managed via adapter)\n /^stac-search-footprints/i, // StacSearchControl footprint layers\n ];\n\n return drawnLayerPatterns.some((pattern) => pattern.test(layerId));\n }\n\n /**\n * Convert wildcard patterns (e.g., '*-temp-*', 'debug-*') to RegExp objects\n */\n private wildcardPatternsToRegex(patterns: string[]): RegExp[] {\n return patterns.map((pattern) => {\n // Escape special regex characters except *\n const escaped = pattern.replace(/[.+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n // Convert * to .* for wildcard matching\n const regexStr = escaped.replace(/\\*/g, \".*\");\n return new RegExp(`^${regexStr}$`, \"i\");\n });\n }\n\n /**\n * Check if a layer matches any of the user-defined exclusion patterns\n */\n private isExcludedByPattern(layerId: string): boolean {\n return this.excludeLayerPatterns.some((pattern) => pattern.test(layerId));\n }\n\n /**\n * Create the main container element\n */\n private createContainer(): HTMLDivElement {\n const container = document.createElement(\"div\");\n container.className =\n \"maplibregl-ctrl maplibregl-ctrl-group maplibregl-ctrl-layer-control\";\n return container;\n }\n\n /**\n * Create the toggle button\n */\n private createToggleButton(): HTMLButtonElement {\n const button = document.createElement(\"button\");\n button.type = \"button\";\n button.title = \"Layer Control\";\n button.setAttribute(\"aria-label\", \"Layer Control\");\n\n // Create layers icon (SVG)\n const icon = document.createElement(\"span\");\n icon.className = \"layer-control-icon\";\n icon.innerHTML =\n '<svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\" ' +\n 'fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">' +\n '<polygon points=\"12 3 3 8.25 12 13.5 21 8.25 12 3\"></polygon>' +\n '<polyline points=\"3 12.75 12 18 21 12.75\"></polyline>' +\n '<polyline points=\"3 17.25 12 22 21 17.25\"></polyline>' +\n \"</svg>\";\n\n button.appendChild(icon);\n return button;\n }\n\n /**\n * Create the panel element\n */\n private createPanel(): HTMLDivElement {\n const panel = document.createElement(\"div\");\n panel.className = \"layer-control-panel\";\n\n // Set initial width directly on the element. The max height is computed\n // dynamically in updatePanelPosition so the panel fills the available\n // vertical space.\n panel.style.width = `${this.state.panelWidth}px`;\n if (this.maxPanelHeight != null) {\n panel.style.maxHeight = `${this.maxPanelHeight}px`;\n }\n\n if (!this.state.collapsed) {\n panel.classList.add(\"expanded\");\n }\n\n // Add header\n const header = this.createPanelHeader();\n panel.appendChild(header);\n\n // Add action buttons (Show All / Hide All)\n const actionButtons = this.createActionButtons();\n panel.appendChild(actionButtons);\n\n // Add draggable edge handles (both sides) for resizing the panel width\n panel.appendChild(this.createResizeHandle(\"left\"));\n panel.appendChild(this.createResizeHandle(\"right\"));\n\n return panel;\n }\n\n /**\n * Create a draggable edge handle for resizing the panel width. A handle is\n * added on each side so the panel can be resized by dragging either edge,\n * like a conventional resizable window.\n *\n * @param side Which physical edge of the panel the handle sits on\n */\n private createResizeHandle(side: \"left\" | \"right\"): HTMLDivElement {\n const handle = document.createElement(\"div\");\n handle.className = `layer-control-resize-handle layer-control-resize-handle-${side}`;\n handle.title = \"Drag to resize panel\";\n handle.setAttribute(\"role\", \"separator\");\n handle.setAttribute(\"aria-orientation\", \"vertical\");\n this.resizeHandleEls.push(handle);\n this.setupResizeHandleEvents(handle, side);\n return handle;\n }\n\n /**\n * Wire pointer events for an edge resize handle.\n *\n * @param handle The handle element\n * @param side Which physical edge of the panel the handle sits on\n */\n private setupResizeHandleEvents(\n handle: HTMLDivElement,\n side: \"left\" | \"right\",\n ): void {\n handle.addEventListener(\"pointerdown\", (event) => {\n event.preventDefault();\n event.stopPropagation();\n this.isPanelResizing = true;\n this.panelResizeEdge = side;\n this.panelResizeStartX = event.clientX;\n this.panelResizeStartWidth = this.state.panelWidth;\n // Remember the current offset of the anchored edge so we can keep the\n // opposite (free) edge fixed when the anchored edge is dragged.\n this.panelResizeStartOffset =\n parseFloat(this.panel.style[this.panelAnchorSide]) || 0;\n handle.setPointerCapture(event.pointerId);\n this.panel.classList.add(\"resizing-active\");\n });\n\n handle.addEventListener(\"pointermove\", (event) => {\n if (!this.isPanelResizing) return;\n this.resizePanelFromPointer(event.clientX);\n });\n\n const endResize = (event: PointerEvent) => {\n if (!this.isPanelResizing) return;\n if (event.pointerId !== undefined) {\n try {\n handle.releasePointerCapture(event.pointerId);\n } catch {\n // Ignore release errors\n }\n }\n this.isPanelResizing = false;\n this.panelResizeStartX = null;\n this.panelResizeStartWidth = null;\n this.panel.classList.remove(\"resizing-active\");\n };\n\n handle.addEventListener(\"pointerup\", endResize);\n handle.addEventListener(\"pointercancel\", endResize);\n handle.addEventListener(\"lostpointercapture\", endResize);\n\n // Double-click resets to the default/initial width\n handle.addEventListener(\"dblclick\", (event) => {\n event.preventDefault();\n event.stopPropagation();\n this.applyPanelWidth(this.initialPanelWidth, true);\n });\n }\n\n /**\n * Compute and apply a new panel width from the pointer position during an\n * edge drag. Dragging the free edge changes the width while the anchored\n * edge stays put; dragging the anchored edge shifts the anchor so the free\n * edge stays put — both feel like resizing a normal window.\n */\n private resizePanelFromPointer(clientX: number): void {\n const dx = clientX - (this.panelResizeStartX ?? clientX);\n const startWidth = this.panelResizeStartWidth ?? this.state.panelWidth;\n\n // Dragging the left edge left widens; dragging the right edge right widens.\n const desiredWidth =\n this.panelResizeEdge === \"left\" ? startWidth - dx : startWidth + dx;\n const clamped = Math.round(\n Math.min(this.maxPanelWidth, Math.max(this.minPanelWidth, desiredWidth)),\n );\n\n // When the dragged edge is the anchored edge, move the anchor so the\n // opposite edge does not drift.\n if (this.panelResizeEdge === this.panelAnchorSide) {\n let appliedDelta = clamped - startWidth;\n let newOffset = this.panelResizeStartOffset - appliedDelta;\n if (newOffset < 0) {\n // Don't push the panel past the map edge; cap the growth instead.\n newOffset = 0;\n appliedDelta = this.panelResizeStartOffset;\n }\n const finalWidth = Math.round(\n Math.min(\n this.maxPanelWidth,\n Math.max(this.minPanelWidth, startWidth + appliedDelta),\n ),\n );\n this.applyPanelWidth(finalWidth, true);\n this.panel.style[this.panelAnchorSide] = `${newOffset}px`;\n } else {\n this.applyPanelWidth(clamped, true);\n }\n }\n\n /**\n * Record which panel edge is anchored to the control corner, based on the\n * corner the control occupies. Right corners anchor the right edge (panel\n * grows leftward); left corners anchor the left edge (panel grows rightward).\n */\n private updatePanelAnchorSide(\n position: \"top-left\" | \"top-right\" | \"bottom-left\" | \"bottom-right\",\n ): void {\n this.panelAnchorSide =\n position === \"top-right\" || position === \"bottom-right\"\n ? \"right\"\n : \"left\";\n }\n\n /**\n * Detect which corner the control is positioned in\n * @returns The position: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'\n */\n private getControlPosition():\n | \"top-left\"\n | \"top-right\"\n | \"bottom-left\"\n | \"bottom-right\" {\n const parent = this.container.parentElement;\n if (!parent) return \"top-right\"; // Default\n\n if (parent.classList.contains(\"maplibregl-ctrl-top-left\"))\n return \"top-left\";\n if (parent.classList.contains(\"maplibregl-ctrl-top-right\"))\n return \"top-right\";\n if (parent.classList.contains(\"maplibregl-ctrl-bottom-left\"))\n return \"bottom-left\";\n if (parent.classList.contains(\"maplibregl-ctrl-bottom-right\"))\n return \"bottom-right\";\n\n return \"top-right\"; // Default\n }\n\n /**\n * Update the panel position based on button location and control corner\n * Positions the panel next to the button, expanding in the appropriate direction\n */\n private updatePanelPosition(): void {\n if (!this.button || !this.panel || !this.mapContainer) return;\n\n const buttonRect = this.button.getBoundingClientRect();\n const mapRect = this.mapContainer.getBoundingClientRect();\n const position = this.getControlPosition();\n\n // Track which edge is anchored to the control corner (for edge-drag resize)\n this.updatePanelAnchorSide(position);\n\n // Calculate button position relative to map container\n const buttonTop = buttonRect.top - mapRect.top;\n const buttonBottom = mapRect.bottom - buttonRect.bottom;\n const buttonLeft = buttonRect.left - mapRect.left;\n const buttonRight = mapRect.right - buttonRect.right;\n\n const panelGap = 5; // Gap between button and panel\n\n // Reset all positioning\n this.panel.style.top = \"\";\n this.panel.style.bottom = \"\";\n this.panel.style.left = \"\";\n this.panel.style.right = \"\";\n\n switch (position) {\n case \"top-left\":\n // Panel expands down and to the right\n this.panel.style.top = `${buttonTop + buttonRect.height + panelGap}px`;\n this.panel.style.left = `${buttonLeft}px`;\n break;\n\n case \"top-right\":\n // Panel expands down and to the left\n this.panel.style.top = `${buttonTop + buttonRect.height + panelGap}px`;\n this.panel.style.right = `${buttonRight}px`;\n break;\n\n case \"bottom-left\":\n // Panel expands up and to the right\n this.panel.style.bottom = `${buttonBottom + buttonRect.height + panelGap}px`;\n this.panel.style.left = `${buttonLeft}px`;\n break;\n\n case \"bottom-right\":\n // Panel expands up and to the left\n this.panel.style.bottom = `${buttonBottom + buttonRect.height + panelGap}px`;\n this.panel.style.right = `${buttonRight}px`;\n break;\n }\n\n // Let the panel use all the available vertical space in the map container\n // so a long layer list fills the space before a scrollbar appears, rather\n // than being capped at a fixed height. A user-provided panelMaxHeight still\n // caps the panel.\n const edgeMargin = 8; // keep the panel off the opposite map edge\n const isTopAnchored = position === \"top-left\" || position === \"top-right\";\n const occupiedFromEdge = isTopAnchored\n ? buttonTop + buttonRect.height + panelGap\n : buttonBottom + buttonRect.height + panelGap;\n const availableHeight = Math.max(\n 120,\n Math.round(mapRect.height - occupiedFromEdge - edgeMargin),\n );\n const maxHeight =\n this.maxPanelHeight != null\n ? Math.min(this.maxPanelHeight, availableHeight)\n : availableHeight;\n this.panel.style.maxHeight = `${maxHeight}px`;\n }\n\n /**\n * Create action buttons for Show All / Hide All\n */\n private createActionButtons(): HTMLElement {\n const container = document.createElement(\"div\");\n container.className = \"layer-control-actions\";\n\n const showAllBtn = document.createElement(\"button\");\n showAllBtn.type = \"button\";\n showAllBtn.className = \"layer-control-action-btn\";\n showAllBtn.textContent = \"Show All\";\n showAllBtn.title = \"Show all layers\";\n showAllBtn.addEventListener(\"click\", () =>\n this.setAllLayersVisibility(true),\n );\n\n const hideAllBtn = document.createElement(\"button\");\n hideAllBtn.type = \"button\";\n hideAllBtn.className = \"layer-control-action-btn\";\n hideAllBtn.textContent = \"Hide All\";\n hideAllBtn.title = \"Hide all layers\";\n hideAllBtn.addEventListener(\"click\", () =>\n this.setAllLayersVisibility(false),\n );\n\n container.appendChild(showAllBtn);\n container.appendChild(hideAllBtn);\n\n return container;\n }\n\n /**\n * Set visibility of all layers\n */\n private setAllLayersVisibility(visible: boolean): void {\n Object.keys(this.state.layerStates).forEach((layerId) => {\n // Use toggleLayerVisibility which handles both native and custom layers\n this.toggleLayerVisibility(layerId, visible);\n\n // Update checkbox in UI\n const itemEl = this.panel.querySelector(`[data-layer-id=\"${layerId}\"]`);\n if (itemEl) {\n const checkbox = itemEl.querySelector(\n \".layer-control-checkbox\",\n ) as HTMLInputElement;\n if (checkbox) {\n checkbox.checked = visible;\n checkbox.indeterminate = false;\n }\n }\n });\n }\n\n /**\n * Create the panel header with the title. Panel width is adjusted by\n * dragging either edge of the panel (see createResizeHandle).\n */\n private createPanelHeader(): HTMLElement {\n const header = document.createElement(\"div\");\n header.className = \"layer-control-panel-header\";\n\n const title = document.createElement(\"span\");\n title.className = \"layer-control-panel-title\";\n title.textContent = \"Layers\";\n header.appendChild(title);\n\n return header;\n }\n\n /**\n * Apply panel width (clamped to min/max)\n */\n private applyPanelWidth(width: number, immediate = false): void {\n const clamped = Math.round(\n Math.min(this.maxPanelWidth, Math.max(this.minPanelWidth, width)),\n );\n\n const applyWidth = () => {\n this.state.panelWidth = clamped;\n const px = `${clamped}px`;\n this.panel.style.width = px;\n };\n\n if (immediate) {\n applyWidth();\n return;\n }\n\n if (this.widthFrame) {\n cancelAnimationFrame(this.widthFrame);\n }\n this.widthFrame = requestAnimationFrame(() => {\n applyWidth();\n this.widthFrame = null;\n });\n }\n\n /**\n * Setup main event listeners\n */\n private setupEventListeners(): void {\n // Toggle button click\n this.button.addEventListener(\"click\", () => this.toggle());\n\n // Click outside to close panel and context menu\n document.addEventListener(\"click\", (e) => {\n const target = e.target as Node;\n\n // Close context menu if clicking outside of it\n if (this.contextMenuEl && this.state.contextMenu.visible) {\n if (!this.contextMenuEl.contains(target)) {\n this.hideContextMenu();\n }\n }\n\n // Close panel if clicking outside\n if (!this.container.contains(target) && !this.panel.contains(target)) {\n this.collapse();\n }\n });\n\n // Update panel position on window resize\n this.resizeHandler = () => {\n if (!this.state.collapsed) {\n this.updatePanelPosition();\n }\n };\n window.addEventListener(\"resize\", this.resizeHandler);\n\n // Update panel position on map resize (e.g., sidebar toggle)\n this.mapResizeHandler = () => {\n if (!this.state.collapsed) {\n this.updatePanelPosition();\n }\n };\n this.map.on(\"resize\", this.mapResizeHandler);\n\n // Listen for map layer changes\n this.setupLayerChangeListeners();\n }\n\n /**\n * Setup listeners for map layer changes\n */\n private setupLayerChangeListeners(): void {\n this.map.on(\"styledata\", () => {\n setTimeout(() => {\n this.updateLayerStatesFromMap();\n this.checkForNewLayers();\n }, 100);\n });\n\n this.map.on(\"data\", (e) => {\n if (e.sourceDataType === \"content\") {\n setTimeout(() => {\n this.updateLayerStatesFromMap();\n this.checkForNewLayers();\n }, 100);\n }\n });\n\n this.map.on(\"sourcedata\", (e) => {\n if (e.sourceDataType === \"metadata\") {\n setTimeout(() => {\n this.checkForNewLayers();\n }, 150);\n }\n });\n\n // Subscribe to custom layer registry changes\n if (this.customLayerRegistry) {\n this.customLayerUnsubscribe = this.customLayerRegistry.onChange(\n (event, layerId) => {\n // If a previously removed layer is re-added, allow it to appear again\n if (event === \"add\" && layerId) {\n this.removedCustomLayerIds.delete(layerId);\n }\n setTimeout(() => this.checkForNewLayers(), 100);\n },\n );\n }\n }\n\n /**\n * Toggle panel expanded/collapsed state\n */\n private toggle(): void {\n if (this.state.collapsed) {\n this.expand();\n } else {\n this.collapse();\n }\n }\n\n /**\n * Expand the panel\n */\n private expand(): void {\n this.state.collapsed = false;\n this.panel.classList.add(\"expanded\");\n this.updatePanelPosition();\n }\n\n /**\n * Collapse the panel\n */\n private collapse(): void {\n this.state.collapsed = true;\n this.panel.classList.remove(\"expanded\");\n }\n\n /**\n * Build layer items (called initially and when layers change)\n */\n private buildLayerItems(): void {\n // Clear existing items\n const existingItems = this.panel.querySelectorAll(\".layer-control-item\");\n existingItems.forEach((item) => item.remove());\n this.styleEditors.clear();\n\n // Render in map stacking order: the top of the panel is the top-most layer\n // (highest z-index, rendered last) and the bottom is the lowest. The\n // Background group always sits at the very bottom, matching the basemap\n // being the bottom-most map layer. Iterating layerStates in insertion order\n // would instead put Background on top and reverse the user layers, so the\n // panel order would not match the actual map order (issue #449).\n const orderedLayerIds = this.getUserLayerIdsInMapOrder();\n\n // Include any user layers that map-order detection did not capture (e.g.\n // transient states where the layer is not yet on the map) so nothing\n // silently disappears from the panel.\n const captured = new Set(orderedLayerIds);\n for (const layerId of Object.keys(this.state.layerStates)) {\n if (layerId !== \"Background\" && !captured.has(layerId)) {\n orderedLayerIds.push(layerId);\n }\n }\n\n // Background always renders last so it appears at the bottom of the panel.\n if (this.state.layerStates[\"Background\"]) {\n orderedLayerIds.push(\"Background\");\n }\n\n // Add items for all layers in our state\n orderedLayerIds.forEach((layerId) => {\n const state = this.state.layerStates[layerId];\n if (!state) {\n return;\n }\n if (\n this.targetLayers.length === 0 ||\n this.targetLayers.includes(layerId)\n ) {\n this.addLayerItem(layerId, state);\n }\n });\n }\n\n /**\n * Add a single layer item to the panel\n */\n private addLayerItem(layerId: string, state: LayerState): void {\n const item = document.createElement(\"div\");\n item.className = \"layer-control-item\";\n item.setAttribute(\"data-layer-id\", layerId);\n\n const row = document.createElement(\"div\");\n row.className = \"layer-control-row\";\n\n // Add drag handle (disabled for Background layer for alignment)\n if (this.enableDragAndDrop) {\n if (layerId === \"Background\") {\n const disabledHandle = this.createDisabledDragHandle();\n row.appendChild(disabledHandle);\n } else {\n const dragHandle = this.createDragHandle(layerId);\n row.appendChild(dragHandle);\n }\n }\n\n // Visibility checkbox\n const checkbox = document.createElement(\"input\");\n checkbox.type = \"checkbox\";\n checkbox.className = \"layer-control-checkbox\";\n checkbox.checked = state.visible;\n checkbox.addEventListener(\"change\", () => {\n this.toggleLayerVisibility(layerId, checkbox.checked);\n });\n\n // Layer name - use custom name if set\n const displayName =\n this.state.customLayerNames.get(layerId) || state.name || layerId;\n const name = document.createElement(\"span\");\n name.className = \"layer-control-name\";\n name.textContent = displayName;\n name.title = displayName;\n\n row.appendChild(checkbox);\n\n // Add layer symbol (if enabled)\n if (this.showLayerSymbol) {\n if (layerId === \"Background\") {\n // Special stacked layers symbol for background group\n const symbol = this.createBackgroundGroupSymbol();\n row.appendChild(symbol);\n } else {\n const symbol = this.createLayerSymbol(layerId);\n if (symbol) {\n row.appendChild(symbol);\n }\n }\n }\n\n row.appendChild(name);\n\n // Opacity slider (conditionally shown)\n if (this.showOpacitySlider) {\n const opacity = document.createElement(\"input\");\n opacity.type = \"range\";\n opacity.className = \"layer-control-opacity\";\n opacity.min = \"0\";\n opacity.max = \"1\";\n opacity.step = \"0.01\";\n opacity.value = String(state.opacity);\n opacity.title = `Opacity: ${Math.round(state.opacity * 100)}%`;\n\n // Handle slider interaction tracking\n opacity.addEventListener(\"mousedown\", () => {\n this.state.userInteractingWithSlider = true;\n });\n opacity.addEventListener(\"mouseup\", () => {\n this.state.userInteractingWithSlider = false;\n });\n\n opacity.addEventListener(\"input\", () => {\n this.changeLayerOpacity(layerId, parseFloat(opacity.value));\n opacity.title = `Opacity: ${Math.round(parseFloat(opacity.value) * 100)}%`;\n });\n\n // Double-click to enter an exact opacity percentage (0-100)\n opacity.addEventListener(\"dblclick\", (event) => {\n event.preventDefault();\n this.showOpacityInput(layerId, opacity);\n });\n\n row.appendChild(opacity);\n }\n\n // Style button for regular layers, legend button for Background\n if (this.showStyleEditor) {\n if (layerId === \"Background\") {\n const legendButton = this.createBackgroundLegendButton();\n row.appendChild(legendButton);\n } else {\n const styleButton = this.createStyleButton(layerId);\n if (styleButton) {\n row.appendChild(styleButton);\n }\n }\n }\n\n item.appendChild(row);\n\n // Add context menu event listener (skip for Background layer)\n if (this.enableContextMenu && layerId !== \"Background\") {\n row.addEventListener(\"contextmenu\", (e) => {\n e.preventDefault();\n e.stopPropagation();\n this.showContextMenu(layerId, e.clientX, e.clientY);\n });\n }\n\n this.panel.appendChild(item);\n }\n\n /**\n * Create a symbol element for a layer\n * @param layerId The layer ID\n * @returns The symbol HTML element, or null if layer not found\n */\n private createLayerSymbol(layerId: string): HTMLElement | null {\n // Check if it's a custom layer first\n const layerState = this.state.layerStates[layerId];\n if (layerState?.isCustomLayer) {\n const symbolType = layerState.customLayerType || \"custom-raster\";\n // Use a default color for custom layers\n const color = \"#4a90d9\";\n const svgMarkup = createLayerSymbolSVG(symbolType, color);\n\n const symbolContainer = document.createElement(\"span\");\n symbolContainer.className = \"layer-control-symbol\";\n symbolContainer.innerHTML = svgMarkup;\n symbolContainer.title = `Layer type: ${symbolType}`;\n\n return symbolContainer;\n }\n\n // Fall back to MapLibre layer\n const layer = this.map.getLayer(layerId);\n if (!layer) return null;\n\n const layerType = layer.type;\n const color = getLayerColor(this.map, layerId, layerType);\n const svgMarkup = createLayerSymbolSVG(layerType, color);\n\n const symbolContainer = document.createElement(\"span\");\n symbolContainer.className = \"layer-control-symbol\";\n symbolContainer.innerHTML = svgMarkup;\n symbolContainer.title = `Layer type: ${layerType}`;\n\n return symbolContainer;\n }\n\n /**\n * Create a symbol element for a background layer\n * @param layer The layer specification\n * @returns The symbol HTML element\n */\n private createBackgroundLayerSymbol(layer: LayerSpecification): HTMLElement {\n const color = getLayerColorFromSpec(layer);\n const svgMarkup = createLayerSymbolSVG(layer.type, color, { size: 14 });\n\n const symbolContainer = document.createElement(\"span\");\n symbolContainer.className = \"background-legend-layer-symbol\";\n symbolContainer.innerHTML = svgMarkup;\n symbolContainer.title = `Layer type: ${layer.type}`;\n\n return symbolContainer;\n }\n\n /**\n * Create a symbol element for the Background layer group\n * Shows a stacked layers icon to represent multiple background layers\n * @returns The symbol HTML element\n */\n private createBackgroundGroupSymbol(): HTMLElement {\n const svgMarkup = createBackgroundGroupSymbolSVG(16);\n\n const symbolContainer = document.createElement(\"span\");\n symbolContainer.className = \"layer-control-symbol\";\n symbolContainer.innerHTML = svgMarkup;\n symbolContainer.title = \"Background layers\";\n\n return symbolContainer;\n }\n\n /**\n * Toggle layer visibility\n */\n private toggleLayerVisibility(layerId: string, visible: boolean): void {\n // Handle Background layer group\n if (layerId === \"Background\") {\n this.toggleBackgroundVisibility(visible);\n return;\n }\n\n // Set flag to prevent checkForNewLayers from running during visibility change\n this.state.isStyleOperationInProgress = true;\n\n // Update local state\n if (this.state.layerStates[layerId]) {\n this.state.layerStates[layerId].visible = visible;\n }\n\n // Try custom layer registry first\n if (this.customLayerRegistry?.setVisibility(layerId, visible)) {\n // Clear flag after a delay for custom layers\n setTimeout(() => {\n this.state.isStyleOperationInProgress = false;\n }, 200);\n return;\n }\n\n // Fallback to native MapLibre layer\n this.map.setLayoutProperty(\n layerId,\n \"visibility\",\n visible ? \"visible\" : \"none\",\n );\n\n // Clear flag after styledata events have settled\n setTimeout(() => {\n this.state.isStyleOperationInProgress = false;\n }, 200);\n }\n\n /**\n * Show a small popup that lets the user type an exact opacity percentage\n * (0-100) for a layer. Triggered by double-clicking the opacity slider.\n *\n * @param layerId The layer ID whose opacity is being edited\n * @param slider The opacity range input associated with the layer row\n */\n private showOpacityInput(layerId: string, slider: HTMLInputElement): void {\n // Close any existing opacity popup first\n this.hideOpacityInput();\n\n const popup = document.createElement(\"div\");\n popup.className = \"layer-control-opacity-input\";\n\n const label = document.createElement(\"span\");\n label.className = \"layer-control-opacity-input-label\";\n label.textContent = \"Opacity\";\n\n const field = document.createElement(\"div\");\n field.className = \"layer-control-opacity-input-field\";\n\n const input = document.createElement(\"input\");\n input.type = \"number\";\n input.min = \"0\";\n input.max = \"100\";\n input.step = \"1\";\n input.value = String(Math.round(parseFloat(slider.value) * 100));\n\n const suffix = document.createElement(\"span\");\n suffix.className = \"layer-control-opacity-input-suffix\";\n suffix.textContent = \"%\";\n\n field.appendChild(input);\n field.appendChild(suffix);\n popup.appendChild(label);\n popup.appendChild(field);\n\n // Prevent clicks inside the popup from collapsing the panel\n popup.addEventListener(\"click\", (event) => event.stopPropagation());\n popup.addEventListener(\"pointerdown\", (event) => event.stopPropagation());\n\n let settled = false;\n const apply = () => {\n if (settled) return;\n settled = true;\n const pct = clamp(Math.round(parseFloat(input.value)), 0, 100);\n if (!Number.isNaN(pct)) {\n const opacity = pct / 100;\n slider.value = String(opacity);\n slider.title = `Opacity: ${pct}%`;\n this.changeLayerOpacity(layerId, opacity);\n }\n this.hideOpacityInput();\n };\n const cancel = () => {\n if (settled) return;\n settled = true;\n this.hideOpacityInput();\n };\n\n input.addEventListener(\"keydown\", (event) => {\n if (event.key === \"Enter\") {\n event.preventDefault();\n apply();\n slider.focus();\n } else if (event.key === \"Escape\") {\n event.preventDefault();\n cancel();\n slider.focus();\n }\n });\n input.addEventListener(\"blur\", apply);\n\n this.mapContainer.appendChild(popup);\n this.opacityInputEl = popup;\n\n // Position the popup near the slider, relative to the map container\n const sliderRect = slider.getBoundingClientRect();\n const mapRect = this.mapContainer.getBoundingClientRect();\n const popupRect = popup.getBoundingClientRect();\n\n let left = sliderRect.left - mapRect.left;\n let top = sliderRect.bottom - mapRect.top + 4;\n\n // Keep the popup within the map bounds\n if (left + popupRect.width > mapRect.width) {\n left = Math.max(0, mapRect.width - popupRect.width - 5);\n }\n if (top + popupRect.height > mapRect.height) {\n top = sliderRect.top - mapRect.top - popupRect.height - 4;\n }\n\n popup.style.left = `${Math.max(0, left)}px`;\n popup.style.top = `${Math.max(0, top)}px`;\n\n input.focus();\n input.select();\n }\n\n /**\n * Remove the exact-opacity input popup if it is open.\n */\n private hideOpacityInput(): void {\n if (this.opacityInputEl) {\n this.opacityInputEl.remove();\n this.opacityInputEl = null;\n }\n }\n\n /**\n * Change layer opacity\n */\n private changeLayerOpacity(layerId: string, opacity: number): void {\n // Handle Background layer group\n if (layerId === \"Background\") {\n this.changeBackgroundOpacity(opacity);\n return;\n }\n\n // Set flag to prevent checkForNewLayers from running during opacity change\n this.state.isStyleOperationInProgress = true;\n\n // Update local state\n if (this.state.layerStates[layerId]) {\n this.state.layerStates[layerId].opacity = opacity;\n }\n\n // Try custom layer registry first\n if (this.customLayerRegistry?.setOpacity(layerId, opacity)) {\n // Clear flag after a delay for custom layers\n setTimeout(() => {\n this.state.isStyleOperationInProgress = false;\n }, 200);\n return;\n }\n\n // Fallback to native MapLibre layer\n const layerType = getLayerType(this.map, layerId);\n if (layerType) {\n setLayerOpacity(this.map, layerId, layerType, opacity);\n }\n\n // Clear flag after styledata events have settled\n setTimeout(() => {\n this.state.isStyleOperationInProgress = false;\n }, 200);\n }\n\n /**\n * Check if a layer is a user-added layer (vs basemap layer)\n * Used primarily for the background legend to determine which layers are background\n */\n private isUserAddedLayer(layerId: string): boolean {\n // If this layer is in our state (and not Background), it's user-added\n if (\n this.state.layerStates[layerId] !== undefined &&\n layerId !== \"Background\"\n ) {\n return true;\n }\n\n // If we have basemapLayerIds (from basemapStyleUrl), check if the layer is NOT in the basemap\n if (this.basemapLayerIds !== null && this.basemapLayerIds.size > 0) {\n return !this.basemapLayerIds.has(layerId);\n }\n\n // For layers not in our state, check if the layer was added after control initialization\n // or uses a user-added source\n if (this.initialLayerIds !== null && !this.initialLayerIds.has(layerId)) {\n // Layer was added after control - it's user-added\n return true;\n }\n\n // Check source-based heuristics\n const layer = this.map.getLayer(layerId);\n if (layer) {\n const sourceId = (layer as any).source;\n if (sourceId) {\n const userAddedSourceIds = this.detectUserAddedSources();\n return userAddedSourceIds.has(sourceId);\n }\n }\n\n return false;\n }\n\n /**\n * Toggle visibility for all background layers (basemap layers)\n */\n private toggleBackgroundVisibility(visible: boolean): void {\n // Update local state\n if (this.state.layerStates[\"Background\"]) {\n this.state.layerStates[\"Background\"].visible = visible;\n }\n\n // Apply to all basemap layers (layers not in layerStates)\n const styleLayers = this.map.getStyle().layers || [];\n styleLayers.forEach((layer) => {\n if (!this.isUserAddedLayer(layer.id)) {\n // Update visibility cache\n this.state.backgroundLayerVisibility.set(layer.id, visible);\n this.map.setLayoutProperty(\n layer.id,\n \"visibility\",\n visible ? \"visible\" : \"none\",\n );\n }\n });\n\n // Update legend panel checkboxes if open\n if (this.state.backgroundLegendOpen) {\n const legendPanel = this.panel.querySelector(\n \".layer-control-background-legend\",\n );\n if (legendPanel) {\n const checkboxes = legendPanel.querySelectorAll(\n \".background-legend-checkbox\",\n ) as NodeListOf<HTMLInputElement>;\n checkboxes.forEach((checkbox) => {\n checkbox.checked = visible;\n });\n }\n }\n }\n\n /**\n * Change opacity for all background layers (basemap layers)\n */\n private changeBackgroundOpacity(opacity: number): void {\n // Update local state\n if (this.state.layerStates[\"Background\"]) {\n this.state.layerStates[\"Background\"].opacity = opacity;\n }\n\n // Apply to all basemap layers (layers not in layerStates)\n const styleLayers = this.map.getStyle().layers || [];\n styleLayers.forEach((styleLayer) => {\n if (!this.isUserAddedLayer(styleLayer.id)) {\n const layerType = getLayerType(this.map, styleLayer.id);\n if (layerType) {\n setLayerOpacity(this.map, styleLayer.id, layerType, opacity);\n }\n }\n });\n }\n\n // ===== Background Legend Methods =====\n\n /**\n * Create legend button for Background layer\n */\n private createBackgroundLegendButton(): HTMLButtonElement {\n const button = document.createElement(\"button\");\n button.className =\n \"layer-control-style-button layer-control-background-legend-button\";\n button.innerHTML = \"⚙\"; // Gear icon (same as style button)\n button.title = \"Show background layer details\";\n button.setAttribute(\n \"aria-label\",\n \"Show background layer visibility controls\",\n );\n button.setAttribute(\n \"aria-expanded\",\n String(this.state.backgroundLegendOpen),\n );\n\n button.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.toggleBackgroundLegend();\n });\n\n return button;\n }\n\n /**\n * Toggle background legend panel visibility\n */\n private toggleBackgroundLegend(): void {\n if (this.state.backgroundLegendOpen) {\n this.closeBackgroundLegend();\n } else {\n this.openBackgroundLegend();\n }\n }\n\n /**\n * Open background legend panel\n */\n private openBackgroundLegend(): void {\n // Close any open style editor first\n if (this.state.activeStyleEditor) {\n this.closeStyleEditor(this.state.activeStyleEditor);\n }\n\n const itemEl = this.panel.querySelector('[data-layer-id=\"Background\"]');\n if (!itemEl) return;\n\n // Check if panel already exists\n let legendPanel = itemEl.querySelector(\".layer-control-background-legend\");\n if (legendPanel) {\n // Refresh the list\n const layerList = legendPanel.querySelector(\n \".background-legend-layer-list\",\n );\n if (layerList) {\n this.populateBackgroundLayerList(layerList as HTMLElement);\n }\n } else {\n // Create new panel\n legendPanel = this.createBackgroundLegendPanel();\n itemEl.appendChild(legendPanel);\n }\n\n this.state.backgroundLegendOpen = true;\n\n // Update button aria state\n const button = itemEl.querySelector(\n \".layer-control-background-legend-button\",\n );\n if (button) {\n button.setAttribute(\"aria-expanded\", \"true\");\n button.classList.add(\"active\");\n }\n\n // Scroll into view\n setTimeout(() => {\n legendPanel?.scrollIntoView({ behavior: \"smooth\", block: \"nearest\" });\n }, 50);\n }\n\n /**\n * Close background legend panel\n */\n private closeBackgroundLegend(): void {\n const itemEl = this.panel.querySelector('[data-layer-id=\"Background\"]');\n if (!itemEl) return;\n\n const legendPanel = itemEl.querySelector(\n \".layer-control-background-legend\",\n );\n if (legendPanel) {\n legendPanel.remove();\n }\n\n this.state.backgroundLegendOpen = false;\n\n // Update button aria state\n const button = itemEl.querySelector(\n \".layer-control-background-legend-button\",\n );\n if (button) {\n button.setAttribute(\"aria-expanded\", \"false\");\n button.classList.remove(\"active\");\n }\n }\n\n /**\n * Create the background legend panel with individual layer controls\n */\n private createBackgroundLegendPanel(): HTMLDivElement {\n const panel = document.createElement(\"div\");\n panel.className = \"layer-control-background-legend\";\n\n // Header\n const header = document.createElement(\"div\");\n header.className = \"background-legend-header\";\n\n const title = document.createElement(\"span\");\n title.className = \"background-legend-title\";\n title.textContent = \"Background Layers\";\n\n const closeBtn = document.createElement(\"button\");\n closeBtn.className = \"background-legend-close\";\n closeBtn.innerHTML = \"×\";\n closeBtn.title = \"Close\";\n closeBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.closeBackgroundLegend();\n });\n\n header.appendChild(title);\n header.appendChild(closeBtn);\n\n // Quick actions row\n const actionsRow = document.createElement(\"div\");\n actionsRow.className = \"background-legend-actions\";\n\n const showAllBtn = document.createElement(\"button\");\n showAllBtn.className = \"background-legend-action-btn\";\n showAllBtn.textContent = \"Show All\";\n showAllBtn.addEventListener(\"click\", () =>\n this.setAllBackgroundLayersVisibility(true),\n );\n\n const hideAllBtn = document.createElement(\"button\");\n hideAllBtn.className = \"background-legend-action-btn\";\n hideAllBtn.textContent = \"Hide All\";\n hideAllBtn.addEventListener(\"click\", () =>\n this.setAllBackgroundLayersVisibility(false),\n );\n\n actionsRow.appendChild(showAllBtn);\n actionsRow.appendChild(hideAllBtn);\n\n // Filter row - \"Only rendered\" checkbox\n const filterRow = document.createElement(\"div\");\n filterRow.className = \"background-legend-filter\";\n\n const filterCheckbox = document.createElement(\"input\");\n filterCheckbox.type = \"checkbox\";\n filterCheckbox.className = \"background-legend-filter-checkbox\";\n filterCheckbox.id = \"background-legend-only-rendered\";\n filterCheckbox.checked = this.state.onlyRenderedFilter;\n filterCheckbox.addEventListener(\"change\", () => {\n this.state.onlyRenderedFilter = filterCheckbox.checked;\n const layerList = panel.querySelector(\".background-legend-layer-list\");\n if (layerList) {\n this.populateBackgroundLayerList(layerList as HTMLElement);\n }\n });\n\n const filterLabel = document.createElement(\"label\");\n filterLabel.className = \"background-legend-filter-label\";\n filterLabel.htmlFor = \"background-legend-only-rendered\";\n filterLabel.textContent = \"Only rendered\";\n\n filterRow.appendChild(filterCheckbox);\n filterRow.appendChild(filterLabel);\n\n // Layer list container (scrollable)\n const layerList = document.createElement(\"div\");\n layerList.className = \"background-legend-layer-list\";\n\n // Populate with background layers\n this.populateBackgroundLayerList(layerList);\n\n panel.appendChild(header);\n panel.appendChild(actionsRow);\n panel.appendChild(filterRow);\n panel.appendChild(layerList);\n\n // Saved configurations (presets) row\n if (this.enableBackgroundPresets) {\n panel.appendChild(this.createBackgroundPresetsRow());\n }\n\n return panel;\n }\n\n /**\n * Build the \"Saved configurations\" controls: a dropdown of saved presets with\n * Apply/Delete actions, plus a name field and Save button to capture the\n * current basemap element visibility as a reusable, persisted preset.\n */\n private createBackgroundPresetsRow(): HTMLElement {\n const section = document.createElement(\"div\");\n section.className = \"background-legend-presets\";\n\n const label = document.createElement(\"div\");\n label.className = \"background-legend-presets-label\";\n label.textContent = \"Saved configurations\";\n section.appendChild(label);\n\n // Row 1: preset selector + apply/delete\n const selectRow = document.createElement(\"div\");\n selectRow.className = \"background-legend-presets-row\";\n\n const select = document.createElement(\"select\");\n select.className = \"background-legend-presets-select\";\n select.title = \"Saved configurations\";\n\n const applyBtn = document.createElement(\"button\");\n applyBtn.className = \"background-legend-action-btn\";\n applyBtn.textContent = \"Apply\";\n applyBtn.title = \"Apply the selected configuration\";\n\n const deleteBtn = document.createElement(\"button\");\n deleteBtn.className = \"background-legend-action-btn\";\n deleteBtn.textContent = \"Delete\";\n deleteBtn.title = \"Delete the selected configuration\";\n\n const refreshSelect = (selected?: string) => {\n const presets = this.getBackgroundPresets();\n const names = Object.keys(presets).sort((a, b) =>\n a.localeCompare(b, undefined, { sensitivity: \"base\" }),\n );\n select.innerHTML = \"\";\n\n const placeholder = document.createElement(\"option\");\n placeholder.value = \"\";\n placeholder.textContent = names.length\n ? \"Select a configuration…\"\n : \"No saved configurations\";\n placeholder.disabled = names.length > 0;\n select.appendChild(placeholder);\n\n names.forEach((name) => {\n const option = document.createElement(\"option\");\n option.value = name;\n option.textContent = name;\n select.appendChild(option);\n });\n\n select.value = selected && names.includes(selected) ? selected : \"\";\n const hasSelection = select.value !== \"\";\n applyBtn.disabled = !hasSelection;\n deleteBtn.disabled = !hasSelection;\n };\n\n select.addEventListener(\"change\", () => {\n const hasSelection = select.value !== \"\";\n applyBtn.disabled = !hasSelection;\n deleteBtn.disabled = !hasSelection;\n });\n\n applyBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n if (select.value) this.applyBackgroundPreset(select.value);\n });\n\n deleteBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n if (select.value) {\n this.deleteBackgroundPreset(select.value);\n refreshSelect();\n }\n });\n\n selectRow.appendChild(select);\n selectRow.appendChild(applyBtn);\n selectRow.appendChild(deleteBtn);\n\n // Row 2: name input + save\n const saveRow = document.createElement(\"div\");\n saveRow.className = \"background-legend-presets-row\";\n\n const nameInput = document.createElement(\"input\");\n nameInput.type = \"text\";\n nameInput.className = \"background-legend-presets-input\";\n nameInput.placeholder = \"Configuration name…\";\n nameInput.maxLength = 60;\n\n const saveBtn = document.createElement(\"button\");\n saveBtn.className = \"background-legend-action-btn\";\n saveBtn.textContent = \"Save\";\n saveBtn.title = \"Save the current visibility as a configuration\";\n\n const commitSave = () => {\n const name = nameInput.value.trim();\n if (!name) return;\n this.saveBackgroundPreset(name);\n nameInput.value = \"\";\n refreshSelect(name);\n };\n\n saveBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n commitSave();\n });\n nameInput.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n commitSave();\n }\n });\n\n saveRow.appendChild(nameInput);\n saveRow.appendChild(saveBtn);\n\n section.appendChild(selectRow);\n section.appendChild(saveRow);\n\n refreshSelect();\n\n return section;\n }\n\n /**\n * Check if a layer is currently rendered in the map viewport\n */\n private isLayerRendered(layerId: string): boolean {\n try {\n const layer = this.map.getLayer(layerId);\n if (!layer) return false;\n\n // Check if layer is visible first\n const visibility = this.map.getLayoutProperty(layerId, \"visibility\");\n if (visibility === \"none\") return false;\n\n // For raster layers, check if tiles are loaded\n if (layer.type === \"raster\" || layer.type === \"hillshade\") {\n // Raster layers are considered rendered if visible\n return true;\n }\n\n // For background layers (solid color), they're always rendered if visible\n if (layer.type === \"background\") {\n return true;\n }\n\n // For vector layers, use queryRenderedFeatures to check if any features are visible\n const features = this.map.queryRenderedFeatures({ layers: [layerId] });\n return features.length > 0;\n } catch (error) {\n // If query fails, assume layer is rendered if we can see it\n return true;\n }\n }\n\n /**\n * Populate the background layer list with individual layers\n */\n private populateBackgroundLayerList(container: HTMLElement): void {\n container.innerHTML = \"\"; // Clear existing\n\n const styleLayers = this.map.getStyle().layers || [];\n\n styleLayers.forEach((layer) => {\n if (!this.isUserAddedLayer(layer.id)) {\n // Skip drawn layers if excludeDrawnLayers is enabled\n if (this.excludeDrawnLayers && this.isDrawnLayer(layer.id)) {\n return;\n }\n\n // Skip layers matching user-defined exclusion patterns\n if (this.isExcludedByPattern(layer.id)) {\n return;\n }\n\n // If \"Only rendered\" filter is enabled, skip layers that aren't rendered\n if (this.state.onlyRenderedFilter && !this.isLayerRendered(layer.id)) {\n return;\n }\n\n // This is a background layer\n const layerRow = document.createElement(\"div\");\n layerRow.className = \"background-legend-layer-row\";\n layerRow.setAttribute(\"data-background-layer-id\", layer.id);\n\n // Checkbox\n const checkbox = document.createElement(\"input\");\n checkbox.type = \"checkbox\";\n checkbox.className = \"background-legend-checkbox\";\n\n // Get visibility from map or cache\n const visibility = this.map.getLayoutProperty(layer.id, \"visibility\");\n const isVisible = visibility !== \"none\";\n checkbox.checked = isVisible;\n\n // Update cache\n this.state.backgroundLayerVisibility.set(layer.id, isVisible);\n\n checkbox.addEventListener(\"change\", () => {\n this.toggleIndividualBackgroundLayer(layer.id, checkbox.checked);\n });\n\n // Layer name\n const name = document.createElement(\"span\");\n name.className = \"background-legend-layer-name\";\n name.textContent = this.generateFriendlyName(layer.id);\n name.title = layer.id; // Show full ID on hover\n\n // Layer type indicator\n const typeIndicator = document.createElement(\"span\");\n typeIndicator.className = \"background-legend-layer-type\";\n typeIndicator.textContent = layer.type;\n\n layerRow.appendChild(checkbox);\n\n // Add layer symbol (if enabled)\n if (this.showLayerSymbol) {\n const symbol = this.createBackgroundLayerSymbol(layer);\n if (symbol) {\n layerRow.appendChild(symbol);\n }\n }\n\n layerRow.appendChild(name);\n layerRow.appendChild(typeIndicator);\n container.appendChild(layerRow);\n }\n });\n\n // Show message if no background layers\n if (container.children.length === 0) {\n const emptyMsg = document.createElement(\"p\");\n emptyMsg.className = \"background-legend-empty\";\n emptyMsg.textContent = this.state.onlyRenderedFilter\n ? \"No rendered layers in current view.\"\n : \"No background layers found.\";\n container.appendChild(emptyMsg);\n }\n }\n\n /**\n * Toggle visibility of an individual background layer\n */\n private toggleIndividualBackgroundLayer(\n layerId: string,\n visible: boolean,\n ): void {\n // Update visibility cache\n this.state.backgroundLayerVisibility.set(layerId, visible);\n\n // Apply to map\n this.map.setLayoutProperty(\n layerId,\n \"visibility\",\n visible ? \"visible\" : \"none\",\n );\n\n // Update the main Background checkbox state\n this.updateBackgroundCheckboxState();\n }\n\n /**\n * Set visibility for all background layers\n */\n private setAllBackgroundLayersVisibility(visible: boolean): void {\n const styleLayers = this.map.getStyle().layers || [];\n\n styleLayers.forEach((layer) => {\n if (!this.isUserAddedLayer(layer.id)) {\n this.state.backgroundLayerVisibility.set(layer.id, visible);\n this.map.setLayoutProperty(\n layer.id,\n \"visibility\",\n visible ? \"visible\" : \"none\",\n );\n }\n });\n\n // Update checkboxes in the legend panel\n const legendPanel = this.panel.querySelector(\n \".layer-control-background-legend\",\n );\n if (legendPanel) {\n const checkboxes = legendPanel.querySelectorAll(\n \".background-legend-checkbox\",\n ) as NodeListOf<HTMLInputElement>;\n checkboxes.forEach((checkbox) => {\n checkbox.checked = visible;\n });\n }\n\n // Update main Background checkbox\n this.updateBackgroundCheckboxState();\n }\n\n /**\n * Update the main Background checkbox based on individual layer states\n */\n private updateBackgroundCheckboxState(): void {\n const styleLayers = this.map.getStyle().layers || [];\n let anyVisible = false;\n let allVisible = true;\n\n styleLayers.forEach((layer) => {\n if (!this.isUserAddedLayer(layer.id)) {\n const visible = this.state.backgroundLayerVisibility.get(layer.id);\n if (visible === true) anyVisible = true;\n if (visible === false) allVisible = false;\n }\n });\n\n // Update main checkbox\n const backgroundItem = this.panel.querySelector(\n '[data-layer-id=\"Background\"]',\n );\n if (backgroundItem) {\n const checkbox = backgroundItem.querySelector(\n \".layer-control-checkbox\",\n ) as HTMLInputElement;\n if (checkbox) {\n checkbox.checked = anyVisible;\n checkbox.indeterminate = anyVisible && !allVisible;\n }\n }\n\n // Update layerState\n if (this.state.layerStates[\"Background\"]) {\n this.state.layerStates[\"Background\"].visible = anyVisible;\n }\n }\n\n /**\n * Return the IDs of the background (basemap) style layers the control can\n * toggle, honoring the drawn-layer and user-defined exclusion filters but not\n * the transient \"only rendered\" view filter.\n */\n private getControllableBackgroundLayerIds(): string[] {\n const styleLayers = this.map.getStyle().layers || [];\n return styleLayers\n .filter((layer) => {\n if (this.isUserAddedLayer(layer.id)) return false;\n if (this.excludeDrawnLayers && this.isDrawnLayer(layer.id))\n return false;\n if (this.isExcludedByPattern(layer.id)) return false;\n return true;\n })\n .map((layer) => layer.id);\n }\n\n /**\n * Get the current visibility of every controllable background (basemap) layer.\n *\n * @returns A map of style-layer ID to whether it is currently visible.\n */\n getBackgroundLayerVisibility(): BackgroundLayerVisibility {\n const visibility: BackgroundLayerVisibility = {};\n for (const layerId of this.getControllableBackgroundLayerIds()) {\n const value = this.map.getLayoutProperty(layerId, \"visibility\");\n visibility[layerId] = value !== \"none\";\n }\n return visibility;\n }\n\n /**\n * Apply a saved background-layer visibility configuration to the map. Only\n * layers that currently exist in the style are affected, so a configuration\n * captured on one basemap degrades gracefully when applied to another.\n *\n * @param visibility - Map of style-layer ID to desired visibility.\n */\n applyBackgroundLayerVisibility(visibility: BackgroundLayerVisibility): void {\n for (const [layerId, visible] of Object.entries(visibility)) {\n if (this.isUserAddedLayer(layerId)) continue;\n if (!this.map.getLayer(layerId)) continue;\n this.state.backgroundLayerVisibility.set(layerId, visible);\n this.map.setLayoutProperty(\n layerId,\n \"visibility\",\n visible ? \"visible\" : \"none\",\n );\n }\n\n // Refresh the open legend panel (if any) and the main Background checkbox.\n const legendPanel = this.panel.querySelector(\n \".background-legend-layer-list\",\n );\n if (legendPanel) {\n this.populateBackgroundLayerList(legendPanel as HTMLElement);\n }\n this.updateBackgroundCheckboxState();\n }\n\n /**\n * Read all saved background-layer presets from localStorage. Returns an empty\n * object when storage is unavailable or the stored value is malformed.\n */\n getBackgroundPresets(): BackgroundPresets {\n try {\n const raw =\n typeof localStorage !== \"undefined\"\n ? localStorage.getItem(this.backgroundPresetStorageKey)\n : null;\n if (!raw) return {};\n const parsed = JSON.parse(raw);\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n return {};\n }\n // Keep only safe, own keys mapping to plain objects, so a hand-crafted\n // storage value cannot smuggle in dangerous keys (e.g. `__proto__`).\n const presets: BackgroundPresets = {};\n for (const [name, value] of Object.entries(parsed)) {\n if (this.isUnsafePresetKey(name)) continue;\n if (value && typeof value === \"object\" && !Array.isArray(value)) {\n presets[name] = value as BackgroundLayerVisibility;\n }\n }\n return presets;\n } catch {\n return {};\n }\n }\n\n /**\n * Reject preset names that, used as object keys, could pollute the prototype\n * chain or otherwise alias built-in object members.\n */\n private isUnsafePresetKey(name: string): boolean {\n return (\n name === \"__proto__\" || name === \"constructor\" || name === \"prototype\"\n );\n }\n\n /**\n * Persist the full preset map to localStorage and notify listeners.\n */\n private writeBackgroundPresets(presets: BackgroundPresets): void {\n try {\n if (typeof localStorage !== \"undefined\") {\n localStorage.setItem(\n this.backgroundPresetStorageKey,\n JSON.stringify(presets),\n );\n }\n } catch {\n // Storage may be unavailable (private mode, quota); presets stay in-memory\n // for this session via the UI but cannot be persisted.\n }\n this.onBackgroundPresetsChange?.(presets);\n }\n\n /**\n * Save the current background-layer visibility as a named preset. Reusing an\n * existing name overwrites that preset.\n *\n * @param name - Preset name; whitespace is trimmed. Empty names are ignored.\n * @returns The updated preset map.\n */\n saveBackgroundPreset(name: string): BackgroundPresets {\n const trimmed = name.trim();\n const presets = this.getBackgroundPresets();\n if (!trimmed || this.isUnsafePresetKey(trimmed)) return presets;\n presets[trimmed] = this.getBackgroundLayerVisibility();\n this.writeBackgroundPresets(presets);\n return presets;\n }\n\n /**\n * Apply a previously saved preset to the map.\n *\n * @param name - The preset name to apply.\n * @returns `true` if a preset with that name existed and was applied.\n */\n applyBackgroundPreset(name: string): boolean {\n const presets = this.getBackgroundPresets();\n if (!Object.prototype.hasOwnProperty.call(presets, name)) return false;\n this.applyBackgroundLayerVisibility(presets[name]);\n return true;\n }\n\n /**\n * Delete a saved preset.\n *\n * @param name - The preset name to remove.\n * @returns The updated preset map.\n */\n deleteBackgroundPreset(name: string): BackgroundPresets {\n const presets = this.getBackgroundPresets();\n if (Object.prototype.hasOwnProperty.call(presets, name)) {\n delete presets[name];\n this.writeBackgroundPresets(presets);\n }\n return presets;\n }\n\n /**\n * Create style button for a layer\n */\n private createStyleButton(layerId: string): HTMLButtonElement | null {\n // Don't create button for Background layer\n if (layerId === \"Background\") {\n return null;\n }\n\n const layerState = this.state.layerStates[layerId];\n const isCustomLayer = layerState?.isCustomLayer === true;\n\n const button = document.createElement(\"button\");\n button.className = \"layer-control-style-button\";\n button.innerHTML = \"⚙\"; // Gear icon\n\n if (isCustomLayer) {\n // Custom layers don't support style editing - show info panel instead\n button.title = \"Layer info (style editing not available)\";\n button.setAttribute(\"aria-label\", `Layer info for ${layerId}`);\n } else {\n button.title = \"Edit layer style\";\n button.setAttribute(\"aria-label\", `Edit style for ${layerId}`);\n }\n\n button.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.toggleStyleEditor(layerId);\n });\n\n return button;\n }\n\n /**\n * Toggle style editor for a layer\n */\n private toggleStyleEditor(layerId: string): void {\n // If this editor is already open, close it\n if (this.state.activeStyleEditor === layerId) {\n this.closeStyleEditor(layerId);\n return;\n }\n\n // Close any other open editor\n if (this.state.activeStyleEditor) {\n this.closeStyleEditor(this.state.activeStyleEditor);\n }\n\n // Open this editor\n this.openStyleEditor(layerId);\n }\n\n /**\n * Open style editor for a layer\n */\n private openStyleEditor(layerId: string): void {\n const itemEl = this.panel.querySelector(`[data-layer-id=\"${layerId}\"]`);\n if (!itemEl) return;\n\n // Check if this is a custom layer\n const layerState = this.state.layerStates[layerId];\n if (layerState?.isCustomLayer) {\n // Check if the adapter provides native MapLibre layer IDs for style editing\n const nativeLayerIds =\n this.customLayerRegistry?.getNativeLayerIds(layerId);\n if (nativeLayerIds && nativeLayerIds.length > 0) {\n // Cache original styles for all native sublayers\n for (const nativeId of nativeLayerIds) {\n if (!this.state.originalStyles.has(nativeId)) {\n const nativeLayer = this.map.getLayer(nativeId);\n if (nativeLayer) {\n cacheOriginalLayerStyle(\n this.map,\n nativeId,\n this.state.originalStyles,\n );\n }\n }\n }\n\n // Create combined style editor for native sublayers\n const editor = this.createNativeSubLayerStyleEditor(\n layerId,\n nativeLayerIds,\n );\n if (editor) {\n itemEl.appendChild(editor);\n this.styleEditors.set(layerId, editor);\n this.state.activeStyleEditor = layerId;\n\n setTimeout(() => {\n editor.scrollIntoView({ behavior: \"smooth\", block: \"nearest\" });\n }, 50);\n return;\n }\n }\n\n // Fallback: show info message for custom layers without native sublayers\n const editor = this.createCustomLayerInfoPanel(layerId);\n itemEl.appendChild(editor);\n this.styleEditors.set(layerId, editor);\n this.state.activeStyleEditor = layerId;\n\n // Scroll into view\n setTimeout(() => {\n editor.scrollIntoView({ behavior: \"smooth\", block: \"nearest\" });\n }, 50);\n return;\n }\n\n // Cache original style if not already cached\n if (!this.state.originalStyles.has(layerId)) {\n const layer = this.map.getLayer(layerId);\n if (layer) {\n cacheOriginalLayerStyle(this.map, layerId, this.state.originalStyles);\n }\n }\n\n // Create style editor UI\n const editor = this.createStyleEditor(layerId);\n if (!editor) return;\n\n itemEl.appendChild(editor);\n this.styleEditors.set(layerId, editor);\n this.state.activeStyleEditor = layerId;\n\n // Scroll editor into view\n setTimeout(() => {\n editor.scrollIntoView({ behavior: \"smooth\", block: \"nearest\" });\n }, 50);\n }\n\n /**\n * Create info panel for custom layers (style editing not supported)\n */\n private createCustomLayerInfoPanel(layerId: string): HTMLDivElement {\n const editor = document.createElement(\"div\");\n editor.className = \"layer-control-style-editor layer-control-custom-info\";\n\n // Header\n const header = document.createElement(\"div\");\n header.className = \"style-editor-header\";\n\n const title = document.createElement(\"span\");\n title.className = \"style-editor-title\";\n title.textContent = \"Layer Info\";\n\n const closeBtn = document.createElement(\"button\");\n closeBtn.className = \"style-editor-close\";\n closeBtn.innerHTML = \"×\";\n closeBtn.title = \"Close\";\n closeBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.closeStyleEditor(layerId);\n });\n\n header.appendChild(title);\n header.appendChild(closeBtn);\n\n // Info content\n const content = document.createElement(\"div\");\n content.className = \"style-editor-controls\";\n\n const infoText = document.createElement(\"p\");\n infoText.className = \"layer-control-custom-info-text\";\n infoText.textContent = `This is a custom layer. Style editing is not available for this layer type. Use the visibility toggle and opacity slider to control the layer.`;\n\n content.appendChild(infoText);\n\n // Action buttons\n const actions = document.createElement(\"div\");\n actions.className = \"style-editor-actions\";\n\n const removeBtn = document.createElement(\"button\");\n removeBtn.className = \"style-editor-button style-editor-button-remove\";\n removeBtn.textContent = \"Remove\";\n removeBtn.title = \"Remove layer from map\";\n removeBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.showRemoveConfirmation(editor, () => {\n this.closeStyleEditor(layerId);\n this.removeLayer(layerId);\n });\n });\n\n const closeActionBtn = document.createElement(\"button\");\n closeActionBtn.className = \"style-editor-button style-editor-button-close\";\n closeActionBtn.textContent = \"Close\";\n closeActionBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.closeStyleEditor(layerId);\n });\n\n actions.appendChild(removeBtn);\n actions.appendChild(closeActionBtn);\n\n editor.appendChild(header);\n editor.appendChild(content);\n editor.appendChild(actions);\n\n return editor;\n }\n\n /**\n * Create a combined style editor for custom layers with native MapLibre sublayers.\n * Groups controls by sublayer type (fill, line, circle, etc.).\n */\n private createNativeSubLayerStyleEditor(\n layerId: string,\n nativeLayerIds: string[],\n ): HTMLDivElement | null {\n // Group native layers by type\n const layersByType = new Map<string, string[]>();\n for (const nativeId of nativeLayerIds) {\n const layer = this.map.getLayer(nativeId);\n if (layer) {\n const type = layer.type;\n if (!layersByType.has(type)) {\n layersByType.set(type, []);\n }\n layersByType.get(type)!.push(nativeId);\n }\n }\n\n if (layersByType.size === 0) return null;\n\n const editor = document.createElement(\"div\");\n editor.className = \"layer-control-style-editor\";\n\n // Header\n const header = document.createElement(\"div\");\n header.className = \"style-editor-header\";\n\n const title = document.createElement(\"span\");\n title.className = \"style-editor-title\";\n title.textContent = \"Edit Style\";\n\n const closeBtn = document.createElement(\"button\");\n closeBtn.className = \"style-editor-close\";\n closeBtn.innerHTML = \"×\";\n closeBtn.title = \"Close\";\n closeBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.closeStyleEditor(layerId);\n });\n\n header.appendChild(title);\n header.appendChild(closeBtn);\n editor.appendChild(header);\n\n // Controls container\n const controls = document.createElement(\"div\");\n controls.className = \"style-editor-controls\";\n\n // Type display names\n const typeLabels: Record<string, string> = {\n fill: \"Fill\",\n line: \"Line\",\n circle: \"Circle\",\n symbol: \"Symbol\",\n raster: \"Raster\",\n };\n\n // Add controls for each layer type, using the first native layer of that type\n for (const [type, ids] of layersByType) {\n // Add section header if there are multiple types\n if (layersByType.size > 1) {\n const sectionHeader = document.createElement(\"div\");\n sectionHeader.className = \"style-editor-section-header\";\n sectionHeader.textContent = typeLabels[type] || type;\n controls.appendChild(sectionHeader);\n }\n\n // Use the first layer of this type for controls\n // Changes will be applied to all layers of the same type\n const primaryId = ids[0];\n this.addStyleControlsForNativeGroup(controls, ids, primaryId, type);\n }\n\n // Action buttons\n const actions = document.createElement(\"div\");\n actions.className = \"style-editor-actions\";\n\n const resetBtn = document.createElement(\"button\");\n resetBtn.className = \"style-editor-button style-editor-button-reset\";\n resetBtn.textContent = \"Reset\";\n resetBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n // Reset all native sublayers\n for (const nativeId of nativeLayerIds) {\n restoreOriginalStyle(this.map, nativeId, this.state.originalStyles);\n }\n // Refresh the editor\n this.closeStyleEditor(layerId);\n this.openStyleEditor(layerId);\n });\n\n const removeBtn = document.createElement(\"button\");\n removeBtn.className = \"style-editor-button style-editor-button-remove\";\n removeBtn.textContent = \"Remove\";\n removeBtn.title = \"Remove layer from map\";\n removeBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.showRemoveConfirmation(editor, () => {\n this.closeStyleEditor(layerId);\n this.removeLayer(layerId);\n });\n });\n\n const closeActionBtn = document.createElement(\"button\");\n closeActionBtn.className = \"style-editor-button style-editor-button-close\";\n closeActionBtn.textContent = \"Close\";\n closeActionBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.closeStyleEditor(layerId);\n });\n\n actions.appendChild(resetBtn);\n actions.appendChild(removeBtn);\n actions.appendChild(closeActionBtn);\n\n editor.appendChild(controls);\n editor.appendChild(actions);\n\n return editor;\n }\n\n /**\n * Add style controls for a group of native layers of the same type.\n * Changes to any control are applied to all layers in the group.\n */\n private addStyleControlsForNativeGroup(\n container: HTMLElement,\n layerIds: string[],\n primaryLayerId: string,\n layerType: string,\n ): void {\n // Register the group mapping so createColorControl/createSliderControl\n // will apply changes to all layers in the group\n this.nativeLayerGroups.set(primaryLayerId, layerIds);\n\n this.addStyleControlsForLayerType(container, primaryLayerId, layerType);\n }\n\n /**\n * Close style editor for a layer\n */\n private closeStyleEditor(layerId: string): void {\n const editor = this.styleEditors.get(layerId);\n if (editor) {\n editor.remove();\n this.styleEditors.delete(layerId);\n }\n\n // Clean up any native layer group mappings\n this.nativeLayerGroups.clear();\n\n if (this.state.activeStyleEditor === layerId) {\n this.state.activeStyleEditor = null;\n }\n }\n\n /**\n * Create style editor UI\n */\n private createStyleEditor(layerId: string): HTMLDivElement | null {\n const layer = this.map.getLayer(layerId);\n if (!layer) return null;\n\n const editor = document.createElement(\"div\");\n editor.className = \"layer-control-style-editor\";\n\n // Header\n const header = document.createElement(\"div\");\n header.className = \"style-editor-header\";\n\n const title = document.createElement(\"span\");\n title.className = \"style-editor-title\";\n title.textContent = \"Edit Style\";\n\n const closeBtn = document.createElement(\"button\");\n closeBtn.className = \"style-editor-close\";\n closeBtn.innerHTML = \"×\";\n closeBtn.title = \"Close\";\n closeBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.closeStyleEditor(layerId);\n });\n\n header.appendChild(title);\n header.appendChild(closeBtn);\n\n // Controls container - populate based on layer type\n const controls = document.createElement(\"div\");\n controls.className = \"style-editor-controls\";\n\n const layerType = layer.type;\n this.addStyleControlsForLayerType(controls, layerId, layerType);\n\n // Action buttons\n const actions = document.createElement(\"div\");\n actions.className = \"style-editor-actions\";\n\n const resetBtn = document.createElement(\"button\");\n resetBtn.className = \"style-editor-button style-editor-button-reset\";\n resetBtn.textContent = \"Reset\";\n resetBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.resetLayerStyle(layerId);\n });\n\n const removeBtn = document.createElement(\"button\");\n removeBtn.className = \"style-editor-button style-editor-button-remove\";\n removeBtn.textContent = \"Remove\";\n removeBtn.title = \"Remove layer from map\";\n removeBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.showRemoveConfirmation(editor, () => {\n this.closeStyleEditor(layerId);\n this.removeLayer(layerId);\n });\n });\n\n const closeActionBtn = document.createElement(\"button\");\n closeActionBtn.className = \"style-editor-button style-editor-button-close\";\n closeActionBtn.textContent = \"Close\";\n closeActionBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n this.closeStyleEditor(layerId);\n });\n\n actions.appendChild(resetBtn);\n actions.appendChild(removeBtn);\n actions.appendChild(closeActionBtn);\n\n editor.appendChild(header);\n editor.appendChild(controls);\n editor.appendChild(actions);\n\n return editor;\n }\n\n /**\n * Add style controls based on layer type\n */\n private addStyleControlsForLayerType(\n container: HTMLElement,\n layerId: string,\n layerType: string,\n ): void {\n switch (layerType) {\n case \"fill\":\n this.addFillControls(container, layerId);\n break;\n case \"line\":\n this.addLineControls(container, layerId);\n break;\n case \"circle\":\n this.addCircleControls(container, layerId);\n break;\n case \"raster\":\n this.addRasterControls(container, layerId);\n break;\n case \"symbol\":\n this.addSymbolControls(container, layerId);\n break;\n default:\n container.textContent = `Style controls for ${layerType} layers not yet implemented.`;\n }\n }\n\n /**\n * Add controls for fill layers\n */\n private addFillControls(container: HTMLElement, layerId: string): void {\n // Fill Color - try layer definition first, then runtime property\n const style = this.map.getStyle();\n const layer = style.layers?.find((l) => l.id === layerId);\n let fillColor: any = undefined;\n\n // First try to get from layer definition\n if (\n layer &&\n \"paint\" in layer &&\n layer.paint &&\n \"fill-color\" in layer.paint\n ) {\n fillColor = layer.paint[\"fill-color\"];\n }\n\n // Fallback to runtime property if not in definition\n if (!fillColor) {\n fillColor = this.map.getPaintProperty(layerId, \"fill-color\");\n }\n\n this.createColorControl(\n container,\n layerId,\n \"fill-color\",\n \"Fill Color\",\n normalizeColor(fillColor || \"#088\"),\n );\n\n // Fill Opacity\n const fillOpacity = this.map.getPaintProperty(layerId, \"fill-opacity\");\n if (fillOpacity !== undefined && typeof fillOpacity === \"number\") {\n this.createSliderControl(\n container,\n layerId,\n \"fill-opacity\",\n \"Fill Opacity\",\n fillOpacity,\n 0,\n 1,\n 0.05,\n );\n }\n\n // Fill Outline Color\n const outlineColor = this.map.getPaintProperty(\n layerId,\n \"fill-outline-color\",\n );\n if (outlineColor !== undefined) {\n this.createColorControl(\n container,\n layerId,\n \"fill-outline-color\",\n \"Outline Color\",\n normalizeColor(outlineColor),\n );\n }\n }\n\n /**\n * Add controls for line layers\n */\n private addLineControls(container: HTMLElement, layerId: string): void {\n // Line Color - try layer definition first, then runtime property\n const style = this.map.getStyle();\n const layer = style.layers?.find((l) => l.id === layerId);\n let lineColor: any = undefined;\n\n // First try to get from layer definition\n if (\n layer &&\n \"paint\" in layer &&\n layer.paint &&\n \"line-color\" in layer.paint\n ) {\n lineColor = layer.paint[\"line-color\"];\n }\n\n // Fallback to runtime property if not in definition\n if (!lineColor) {\n lineColor = this.map.getPaintProperty(layerId, \"line-color\");\n }\n\n this.createColorControl(\n container,\n layerId,\n \"line-color\",\n \"Line Color\",\n normalizeColor(lineColor || \"#000\"),\n );\n\n // Line Width\n const lineWidth = this.map.getPaintProperty(layerId, \"line-width\");\n this.createSliderControl(\n container,\n layerId,\n \"line-width\",\n \"Line Width\",\n typeof lineWidth === \"number\" ? lineWidth : 1,\n 0,\n 20,\n 0.5,\n );\n\n // Line Opacity\n const lineOpacity = this.map.getPaintProperty(layerId, \"line-opacity\");\n if (lineOpacity !== undefined && typeof lineOpacity === \"number\") {\n this.createSliderControl(\n container,\n layerId,\n \"line-opacity\",\n \"Line Opacity\",\n lineOpacity,\n 0,\n 1,\n 0.05,\n );\n }\n\n // Line Blur\n const lineBlur = this.map.getPaintProperty(layerId, \"line-blur\");\n if (lineBlur !== undefined && typeof lineBlur === \"number\") {\n this.createSliderControl(\n container,\n layerId,\n \"line-blur\",\n \"Line Blur\",\n lineBlur,\n 0,\n 5,\n 0.1,\n );\n }\n }\n\n /**\n * Add controls for circle layers\n */\n private addCircleControls(container: HTMLElement, layerId: string): void {\n // Circle Color - try layer definition first, then runtime property\n const style = this.map.getStyle();\n const layer = style.layers?.find((l) => l.id === layerId);\n let circleColor: any = undefined;\n\n // First try to get from layer definition\n if (\n layer &&\n \"paint\" in layer &&\n layer.paint &&\n \"circle-color\" in layer.paint\n ) {\n circleColor = layer.paint[\"circle-color\"];\n }\n\n // Fallback to runtime property if not in definition\n if (!circleColor) {\n circleColor = this.map.getPaintProperty(layerId, \"circle-color\");\n }\n\n this.createColorControl(\n container,\n layerId,\n \"circle-color\",\n \"Circle Color\",\n normalizeColor(circleColor || \"#000\"),\n );\n\n // Circle Radius\n const circleRadius = this.map.getPaintProperty(layerId, \"circle-radius\");\n this.createSliderControl(\n container,\n layerId,\n \"circle-radius\",\n \"Radius\",\n typeof circleRadius === \"number\" ? circleRadius : 5,\n 0,\n 40,\n 0.5,\n );\n\n // Circle Opacity\n const circleOpacity = this.map.getPaintProperty(layerId, \"circle-opacity\");\n if (circleOpacity !== undefined && typeof circleOpacity === \"number\") {\n this.createSliderControl(\n container,\n layerId,\n \"circle-opacity\",\n \"Opacity\",\n circleOpacity,\n 0,\n 1,\n 0.05,\n );\n }\n\n // Circle Stroke Color\n const strokeColor = this.map.getPaintProperty(\n layerId,\n \"circle-stroke-color\",\n );\n if (strokeColor !== undefined) {\n this.createColorControl(\n container,\n layerId,\n \"circle-stroke-color\",\n \"Stroke Color\",\n normalizeColor(strokeColor),\n );\n }\n\n // Circle Stroke Width\n const strokeWidth = this.map.getPaintProperty(\n layerId,\n \"circle-stroke-width\",\n );\n if (strokeWidth !== undefined && typeof strokeWidth === \"number\") {\n this.createSliderControl(\n container,\n layerId,\n \"circle-stroke-width\",\n \"Stroke Width\",\n strokeWidth,\n 0,\n 10,\n 0.1,\n );\n }\n }\n\n /**\n * Add controls for raster layers\n */\n private addRasterControls(container: HTMLElement, layerId: string): void {\n // Raster Opacity\n const rasterOpacity = this.map.getPaintProperty(layerId, \"raster-opacity\");\n this.createSliderControl(\n container,\n layerId,\n \"raster-opacity\",\n \"Opacity\",\n typeof rasterOpacity === \"number\" ? rasterOpacity : 1,\n 0,\n 1,\n 0.05,\n );\n\n // Raster Brightness Min\n const brightnessMin = this.map.getPaintProperty(\n layerId,\n \"raster-brightness-min\",\n );\n this.createSliderControl(\n container,\n layerId,\n \"raster-brightness-min\",\n \"Brightness Min\",\n typeof brightnessMin === \"number\" ? brightnessMin : 0,\n -1,\n 1,\n 0.05,\n );\n\n // Raster Brightness Max\n const brightnessMax = this.map.getPaintProperty(\n layerId,\n \"raster-brightness-max\",\n );\n this.createSliderControl(\n container,\n layerId,\n \"raster-brightness-max\",\n \"Brightness Max\",\n typeof brightnessMax === \"number\" ? brightnessMax : 1,\n -1,\n 1,\n 0.05,\n );\n\n // Raster Saturation\n const saturation = this.map.getPaintProperty(layerId, \"raster-saturation\");\n this.createSliderControl(\n container,\n layerId,\n \"raster-saturation\",\n \"Saturation\",\n typeof saturation === \"number\" ? saturation : 0,\n -1,\n 1,\n 0.05,\n );\n\n // Raster Contrast\n const contrast = this.map.getPaintProperty(layerId, \"raster-contrast\");\n this.createSliderControl(\n container,\n layerId,\n \"raster-contrast\",\n \"Contrast\",\n typeof contrast === \"number\" ? contrast : 0,\n -1,\n 1,\n 0.05,\n );\n\n // Raster Hue Rotate\n const hueRotate = this.map.getPaintProperty(layerId, \"raster-hue-rotate\");\n this.createSliderControl(\n container,\n layerId,\n \"raster-hue-rotate\",\n \"Hue Rotate\",\n typeof hueRotate === \"number\" ? hueRotate : 0,\n 0,\n 350,\n 5,\n );\n }\n\n /**\n * Add controls for symbol layers\n */\n private addSymbolControls(container: HTMLElement, layerId: string): void {\n // Text Color\n const textColor = this.map.getPaintProperty(layerId, \"text-color\");\n if (textColor !== undefined) {\n this.createColorControl(\n container,\n layerId,\n \"text-color\",\n \"Text Color\",\n normalizeColor(textColor),\n );\n }\n\n // Text Opacity\n const textOpacity = this.map.getPaintProperty(layerId, \"text-opacity\");\n if (textOpacity !== undefined && typeof textOpacity === \"number\") {\n this.createSliderControl(\n container,\n layerId,\n \"text-opacity\",\n \"Text Opacity\",\n textOpacity,\n 0,\n 1,\n 0.05,\n );\n }\n\n // Icon Opacity\n const iconOpacity = this.map.getPaintProperty(layerId, \"icon-opacity\");\n if (iconOpacity !== undefined && typeof iconOpacity === \"number\") {\n this.createSliderControl(\n container,\n layerId,\n \"icon-opacity\",\n \"Icon Opacity\",\n iconOpacity,\n 0,\n 1,\n 0.05,\n );\n }\n }\n\n /**\n * Create a color control\n */\n private createColorControl(\n container: HTMLElement,\n layerId: string,\n property: string,\n label: string,\n initialValue: string,\n ): void {\n const controlGroup = document.createElement(\"div\");\n controlGroup.className = \"style-control-group\";\n\n const labelEl = document.createElement(\"label\");\n labelEl.className = \"style-control-label\";\n labelEl.textContent = label;\n\n const inputWrapper = document.createElement(\"div\");\n inputWrapper.className = \"style-control-color-group\";\n\n const colorInput = document.createElement(\"input\");\n colorInput.type = \"color\";\n colorInput.className = \"style-control-color-picker\";\n colorInput.value = initialValue;\n colorInput.dataset.property = property;\n\n const hexDisplay = document.createElement(\"input\");\n hexDisplay.type = \"text\";\n hexDisplay.className = \"style-control-color-value\";\n hexDisplay.value = initialValue;\n hexDisplay.readOnly = true;\n\n colorInput.addEventListener(\"input\", () => {\n const color = colorInput.value;\n hexDisplay.value = color;\n const targetIds = this.nativeLayerGroups.get(layerId) || [layerId];\n for (const id of targetIds) {\n this.map.setPaintProperty(id, property, color);\n }\n });\n\n inputWrapper.appendChild(colorInput);\n inputWrapper.appendChild(hexDisplay);\n\n controlGroup.appendChild(labelEl);\n controlGroup.appendChild(inputWrapper);\n\n container.appendChild(controlGroup);\n }\n\n /**\n * Create a slider control\n */\n private createSliderControl(\n container: HTMLElement,\n layerId: string,\n property: string,\n label: string,\n initialValue: number,\n min: number,\n max: number,\n step: number,\n ): void {\n const controlGroup = document.createElement(\"div\");\n controlGroup.className = \"style-control-group\";\n\n const labelEl = document.createElement(\"label\");\n labelEl.className = \"style-control-label\";\n labelEl.textContent = label;\n\n const inputWrapper = document.createElement(\"div\");\n inputWrapper.className = \"style-control-input-wrapper\";\n\n const slider = document.createElement(\"input\");\n slider.type = \"range\";\n slider.className = \"style-control-slider\";\n slider.min = String(min);\n slider.max = String(max);\n slider.step = String(step);\n slider.value = String(initialValue);\n slider.dataset.property = property;\n\n const valueDisplay = document.createElement(\"span\");\n valueDisplay.className = \"style-control-value\";\n valueDisplay.textContent = formatNumericValue(initialValue, step);\n\n slider.addEventListener(\"input\", () => {\n const value = parseFloat(slider.value);\n valueDisplay.textContent = formatNumericValue(value, step);\n const targetIds = this.nativeLayerGroups.get(layerId) || [layerId];\n for (const id of targetIds) {\n this.map.setPaintProperty(id, property, value);\n }\n });\n\n inputWrapper.appendChild(slider);\n inputWrapper.appendChild(valueDisplay);\n\n controlGroup.appendChild(labelEl);\n controlGroup.appendChild(inputWrapper);\n\n container.appendChild(controlGroup);\n }\n\n /**\n * Reset layer style to original\n */\n private resetLayerStyle(layerId: string): void {\n const originalStyle = this.state.originalStyles.get(layerId);\n if (!originalStyle) return;\n\n // Restore original paint properties\n restoreOriginalStyle(this.map, layerId, this.state.originalStyles);\n\n // Update UI controls to reflect the reset values\n const editor = this.styleEditors.get(layerId);\n if (editor) {\n // Update all slider controls\n const sliders = editor.querySelectorAll(\n \".style-control-slider\",\n ) as NodeListOf<HTMLInputElement>;\n sliders.forEach((slider) => {\n const property = slider.dataset.property;\n if (property) {\n const value = this.map.getPaintProperty(layerId, property);\n if (value !== undefined && typeof value === \"number\") {\n slider.value = String(value);\n // Update value display\n const valueDisplay = slider.parentElement?.querySelector(\n \".style-control-value\",\n );\n if (valueDisplay) {\n const step = parseFloat(slider.step);\n valueDisplay.textContent = formatNumericValue(value, step);\n }\n }\n }\n });\n\n // Update all color controls\n const colorPickers = editor.querySelectorAll(\n \".style-control-color-picker\",\n ) as NodeListOf<HTMLInputElement>;\n colorPickers.forEach((picker) => {\n const property = picker.dataset.property;\n if (property) {\n const value = this.map.getPaintProperty(layerId, property);\n if (value !== undefined) {\n const hexColor = normalizeColor(value);\n picker.value = hexColor;\n // Update hex display\n const hexDisplay = picker.parentElement?.querySelector(\n \".style-control-color-value\",\n );\n if (hexDisplay) {\n hexDisplay.textContent = hexColor;\n }\n }\n }\n });\n }\n }\n\n /**\n * Update layer states from map (sync UI with map)\n */\n private updateLayerStatesFromMap(): void {\n if (this.state.userInteractingWithSlider) {\n return; // Don't update while user is dragging\n }\n\n Object.keys(this.state.layerStates).forEach((layerId) => {\n try {\n // Skip custom layers - they manage their own state via adapters\n if (this.state.layerStates[layerId]?.isCustomLayer) {\n return;\n }\n\n // Skip Background layer group\n if (layerId === \"Background\") {\n return;\n }\n\n const layer = this.map.getLayer(layerId);\n if (!layer) return;\n\n // Check visibility\n const visibility = this.map.getLayoutProperty(layerId, \"visibility\");\n const isVisible = visibility !== \"none\";\n\n // Get opacity\n const layerType = layer.type;\n const opacity = getLayerOpacity(this.map, layerId, layerType);\n\n // Update local state\n if (this.state.layerStates[layerId]) {\n this.state.layerStates[layerId].visible = isVisible;\n this.state.layerStates[layerId].opacity = opacity;\n }\n\n // Update UI\n this.updateUIForLayer(layerId, isVisible, opacity);\n } catch (error) {\n console.warn(`Failed to update state for layer ${layerId}:`, error);\n }\n });\n }\n\n /**\n * Update UI elements for a specific layer\n */\n private updateUIForLayer(\n layerId: string,\n visible: boolean,\n opacity: number,\n ): void {\n const layerItems = this.panel.querySelectorAll(\".layer-control-item\");\n\n layerItems.forEach((item) => {\n if ((item as HTMLElement).dataset.layerId === layerId) {\n const checkbox = item.querySelector(\n \".layer-control-checkbox\",\n ) as HTMLInputElement;\n const opacitySlider = item.querySelector(\n \".layer-control-opacity\",\n ) as HTMLInputElement;\n\n if (checkbox) {\n checkbox.checked = visible;\n }\n\n if (opacitySlider) {\n opacitySlider.value = String(opacity);\n opacitySlider.title = `Opacity: ${Math.round(opacity * 100)}%`;\n }\n }\n });\n }\n\n /**\n * Check for new layers and add them to the control, remove deleted layers\n */\n private checkForNewLayers(): void {\n // Skip checking for new layers during style operations to prevent race conditions\n // that could incorrectly delete custom layers\n if (this.state.isStyleOperationInProgress) {\n return;\n }\n\n try {\n const style = this.map.getStyle();\n if (!style || !style.layers) {\n return;\n }\n\n const currentMapLayerIds = new Set(style.layers.map((layer) => layer.id));\n\n // Check if we're in auto-detect mode (no specific layers were specified)\n const isAutoDetectMode =\n this.targetLayers.length === 0 ||\n (this.targetLayers.length === 1 &&\n this.targetLayers[0] === \"Background\") ||\n this.targetLayers.every(\n (id) => id === \"Background\" || this.state.layerStates[id],\n );\n\n // Find new layers that aren't in our state yet\n const newLayers: string[] = [];\n\n // Detection priority for NEW layers (added after control):\n // 1. basemapLayerIds (from basemapStyleUrl) - most reliable\n // 2. initialLayerIds - layer NOT in initialLayerIds means it was added after control\n // 3. Source-based heuristics - fallback\n const useBasemapStyleDetection =\n this.basemapLayerIds !== null && this.basemapLayerIds.size > 0;\n const useInitialLayerDetection =\n !useBasemapStyleDetection &&\n this.initialLayerIds !== null &&\n this.initialLayerIds.size > 0;\n\n currentMapLayerIds.forEach((layerId) => {\n if (layerId !== \"Background\" && !this.state.layerStates[layerId]) {\n const layer = this.map.getLayer(layerId);\n if (layer) {\n // Always skip layers that were present when control was initialized\n // These are background/basemap layers and should stay grouped under \"Background\"\n if (\n this.initialLayerIds !== null &&\n this.initialLayerIds.has(layerId)\n ) {\n // Layer was in initial set - it's a background layer, skip it\n return;\n }\n\n // In auto-detect mode, apply additional filtering\n if (isAutoDetectMode) {\n // Skip drawn layers if excludeDrawnLayers is enabled\n if (this.excludeDrawnLayers && this.isDrawnLayer(layerId)) {\n return;\n }\n\n // Skip layers matching user-defined exclusion patterns\n if (this.isExcludedByPattern(layerId)) {\n return;\n }\n\n // Skip layers that are not user-added (i.e., background/basemap layers)\n if (!this.isUserAddedLayer(layerId)) {\n return;\n }\n\n if (useBasemapStyleDetection) {\n // Use basemap style layer IDs - if layer is in basemap, skip it\n if (this.basemapLayerIds!.has(layerId)) {\n return;\n }\n } else if (useInitialLayerDetection) {\n // Layer NOT in initialLayerIds means it was added AFTER control\n // These are definitely user-added layers and should be included\n if (this.initialLayerIds!.has(layerId)) {\n // Layer was in initial set - check source-based heuristics\n const userAddedSourceIds = this.detectUserAddedSources();\n const sourceId = (layer as any).source;\n if (!sourceId || !userAddedSourceIds.has(sourceId)) {\n return;\n }\n }\n // Layer NOT in initialLayerIds - it's new, include it\n } else {\n // Fall back to source-based heuristics\n const userAddedSourceIds = this.detectUserAddedSources();\n const sourceId = (layer as any).source;\n if (!sourceId || !userAddedSourceIds.has(sourceId)) {\n return;\n }\n }\n }\n newLayers.push(layerId);\n }\n }\n });\n\n // Find removed layers that are still in our state\n // Skip custom layers - they have their own removal mechanism via the adapter\n const removedLayers: string[] = [];\n Object.keys(this.state.layerStates).forEach((layerId) => {\n const state = this.state.layerStates[layerId];\n // Skip Background, custom layers, and layers still in the map\n if (\n layerId !== \"Background\" &&\n !state.isCustomLayer &&\n !currentMapLayerIds.has(layerId)\n ) {\n removedLayers.push(layerId);\n }\n });\n\n // Remove deleted layers from UI and state\n if (removedLayers.length > 0) {\n removedLayers.forEach((layerId) => {\n // Remove from state\n delete this.state.layerStates[layerId];\n\n // Remove from UI\n const itemEl = this.panel.querySelector(\n `[data-layer-id=\"${layerId}\"]`,\n );\n if (itemEl) {\n itemEl.remove();\n }\n\n // Clean up style editor if open\n if (this.state.activeStyleEditor === layerId) {\n this.state.activeStyleEditor = null;\n }\n this.styleEditors.delete(layerId);\n });\n }\n\n // Add UI for new layers\n if (newLayers.length > 0) {\n newLayers.forEach((layerId) => {\n const layer = this.map.getLayer(layerId);\n if (!layer) return;\n\n // Get layer type and opacity\n const layerType = layer.type;\n const opacity = getLayerOpacity(this.map, layerId, layerType);\n const visibility = this.map.getLayoutProperty(layerId, \"visibility\");\n const isVisible = visibility !== \"none\";\n\n // Add to state\n this.state.layerStates[layerId] = {\n visible: isVisible,\n opacity: opacity,\n name: this.generateFriendlyName(layerId),\n };\n\n // Add to UI\n this.addLayerItem(layerId, this.state.layerStates[layerId]);\n });\n }\n\n // Check for new/removed custom layers\n if (this.customLayerRegistry) {\n const customLayerIds = this.customLayerRegistry.getAllLayerIds();\n\n // Find new custom layers (skip ones explicitly removed by the user)\n customLayerIds.forEach((layerId) => {\n if (\n !this.state.layerStates[layerId] &&\n !this.removedCustomLayerIds.has(layerId)\n ) {\n const customState =\n this.customLayerRegistry!.getLayerState(layerId);\n if (customState) {\n this.state.layerStates[layerId] = {\n visible: customState.visible,\n opacity: customState.opacity,\n name: customState.name,\n isCustomLayer: true,\n customLayerType:\n this.customLayerRegistry!.getSymbolType(layerId) || undefined,\n };\n this.addLayerItem(layerId, this.state.layerStates[layerId]);\n }\n }\n });\n\n // Find removed custom layers\n Object.keys(this.state.layerStates).forEach((layerId) => {\n const state = this.state.layerStates[layerId];\n if (state.isCustomLayer && !customLayerIds.includes(layerId)) {\n // Remove from state\n delete this.state.layerStates[layerId];\n\n // Remove from UI\n const itemEl = this.panel.querySelector(\n `[data-layer-id=\"${layerId}\"]`,\n );\n if (itemEl) {\n itemEl.remove();\n }\n\n // Clean up style editor if open\n if (this.state.activeStyleEditor === layerId) {\n this.state.activeStyleEditor = null;\n }\n this.styleEditors.delete(layerId);\n }\n });\n }\n } catch (error) {\n console.warn(\"Failed to check for new layers:\", error);\n }\n }\n\n /**\n * Register a custom layer adapter dynamically.\n * This allows adding adapters after the LayerControl has been initialized.\n * @param adapter The custom layer adapter to register\n */\n registerCustomAdapter(adapter: CustomLayerAdapter): void {\n // Create registry if it doesn't exist\n if (!this.customLayerRegistry) {\n this.customLayerRegistry = new CustomLayerRegistry();\n // Subscribe to registry changes\n this.customLayerUnsubscribe = this.customLayerRegistry.onChange(\n (event, layerId) => {\n if (event === \"add\" && layerId) {\n this.removedCustomLayerIds.delete(layerId);\n }\n this.checkForNewLayers();\n },\n );\n }\n\n // Register the adapter\n this.customLayerRegistry.register(adapter);\n\n // Rebuild layer items to include the new adapter's layers\n if (this.panel) {\n this.checkForNewLayers();\n }\n }\n\n // ===== Context Menu Methods =====\n\n /**\n * Create context menu element\n */\n private createContextMenu(): HTMLDivElement {\n const menu = document.createElement(\"div\");\n menu.className = \"layer-control-context-menu\";\n menu.style.display = \"none\";\n\n // Rename\n const renameItem = this.createContextMenuItem(\"Rename\", \"✏️\", () => {\n if (this.state.contextMenu.targetLayerId) {\n this.startRenaming(this.state.contextMenu.targetLayerId);\n }\n this.hideContextMenu();\n });\n\n // Zoom to layer\n const zoomItem = this.createContextMenuItem(\"Zoom to Layer\", \"🔍\", () => {\n if (this.state.contextMenu.targetLayerId) {\n this.zoomToLayer(this.state.contextMenu.targetLayerId);\n }\n this.hideContextMenu();\n });\n\n // Separator\n const sep1 = document.createElement(\"div\");\n sep1.className = \"context-menu-separator\";\n\n // Move up\n const moveUpItem = this.createContextMenuItem(\"Move Up\", \"↑\", () => {\n if (this.state.contextMenu.targetLayerId) {\n this.moveLayerUp(this.state.contextMenu.targetLayerId);\n }\n this.hideContextMenu();\n });\n\n // Move to top\n const moveTopItem = this.createContextMenuItem(\"Move to Top\", \"⤒\", () => {\n if (this.state.contextMenu.targetLayerId) {\n this.moveLayerToTop(this.state.contextMenu.targetLayerId);\n }\n this.hideContextMenu();\n });\n\n // Move down\n const moveDownItem = this.createContextMenuItem(\"Move Down\", \"↓\", () => {\n if (this.state.contextMenu.targetLayerId) {\n this.moveLayerDown(this.state.contextMenu.targetLayerId);\n }\n this.hideContextMenu();\n });\n\n // Move to bottom\n const moveBottomItem = this.createContextMenuItem(\n \"Move to Bottom\",\n \"⤓\",\n () => {\n if (this.state.contextMenu.targetLayerId) {\n this.moveLayerToBottom(this.state.contextMenu.targetLayerId);\n }\n this.hideContextMenu();\n },\n );\n\n // Separator\n const sep2 = document.createElement(\"div\");\n sep2.className = \"context-menu-separator\";\n\n // Remove layer\n const removeItem = this.createContextMenuItem(\n \"Remove Layer\",\n \"🗑️\",\n () => {\n if (this.state.contextMenu.targetLayerId) {\n this.removeLayer(this.state.contextMenu.targetLayerId);\n }\n this.hideContextMenu();\n },\n true,\n );\n\n menu.appendChild(renameItem);\n menu.appendChild(zoomItem);\n menu.appendChild(sep1);\n menu.appendChild(moveUpItem);\n menu.appendChild(moveTopItem);\n menu.appendChild(moveDownItem);\n menu.appendChild(moveBottomItem);\n menu.appendChild(sep2);\n menu.appendChild(removeItem);\n\n return menu;\n }\n\n /**\n * Create a context menu item\n */\n private createContextMenuItem(\n label: string,\n icon: string,\n onClick: () => void,\n isDanger = false,\n ): HTMLDivElement {\n const item = document.createElement(\"div\");\n item.className =\n \"context-menu-item\" + (isDanger ? \" context-menu-item-danger\" : \"\");\n\n const iconEl = document.createElement(\"span\");\n iconEl.className = \"context-menu-item-icon\";\n iconEl.textContent = icon;\n\n const labelEl = document.createElement(\"span\");\n labelEl.className = \"context-menu-item-label\";\n labelEl.textContent = label;\n\n item.appendChild(iconEl);\n item.appendChild(labelEl);\n\n item.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n onClick();\n });\n\n return item;\n }\n\n /**\n * Show context menu at position\n */\n private showContextMenu(layerId: string, x: number, y: number): void {\n if (!this.contextMenuEl) return;\n\n // Update state\n this.state.contextMenu = {\n visible: true,\n targetLayerId: layerId,\n x,\n y,\n };\n\n // Position the menu relative to the map container\n const mapRect = this.mapContainer.getBoundingClientRect();\n let menuX = x - mapRect.left;\n let menuY = y - mapRect.top;\n\n // Show menu to get dimensions\n this.contextMenuEl.style.display = \"block\";\n\n // Adjust if menu would go off screen\n const menuRect = this.contextMenuEl.getBoundingClientRect();\n if (menuX + menuRect.width > mapRect.width) {\n menuX = mapRect.width - menuRect.width - 5;\n }\n if (menuY + menuRect.height > mapRect.height) {\n menuY = mapRect.height - menuRect.height - 5;\n }\n\n this.contextMenuEl.style.left = `${menuX}px`;\n this.contextMenuEl.style.top = `${menuY}px`;\n }\n\n /**\n * Hide context menu\n */\n private hideContextMenu(): void {\n if (!this.contextMenuEl) return;\n\n this.state.contextMenu = {\n visible: false,\n targetLayerId: null,\n x: 0,\n y: 0,\n };\n\n this.contextMenuEl.style.display = \"none\";\n }\n\n /**\n * Start renaming a layer\n */\n private startRenaming(layerId: string): void {\n const itemEl = this.panel.querySelector(`[data-layer-id=\"${layerId}\"]`);\n if (!itemEl) return;\n\n const nameEl = itemEl.querySelector(\".layer-control-name\");\n if (!nameEl) return;\n\n this.state.renamingLayerId = layerId;\n\n const currentName =\n this.state.customLayerNames.get(layerId) ||\n this.state.layerStates[layerId]?.name ||\n layerId;\n\n // Replace name span with input\n const input = document.createElement(\"input\");\n input.type = \"text\";\n input.className = \"layer-control-name-input\";\n input.value = currentName;\n\n const finishRename = () => {\n const newName = input.value.trim() || currentName;\n const oldName = currentName;\n\n if (newName !== oldName) {\n this.state.customLayerNames.set(layerId, newName);\n if (this.state.layerStates[layerId]) {\n this.state.layerStates[layerId].name = newName;\n }\n this.onLayerRename?.(layerId, oldName, newName);\n }\n\n // Restore name span\n const newNameEl = document.createElement(\"span\");\n newNameEl.className = \"layer-control-name\";\n newNameEl.textContent = newName;\n newNameEl.title = newName;\n input.replaceWith(newNameEl);\n\n this.state.renamingLayerId = null;\n };\n\n input.addEventListener(\"blur\", finishRename);\n input.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n finishRename();\n } else if (e.key === \"Escape\") {\n e.preventDefault();\n // Restore original name\n const newNameEl = document.createElement(\"span\");\n newNameEl.className = \"layer-control-name\";\n newNameEl.textContent = currentName;\n newNameEl.title = currentName;\n input.replaceWith(newNameEl);\n this.state.renamingLayerId = null;\n }\n });\n\n nameEl.replaceWith(input);\n input.focus();\n input.select();\n }\n\n /**\n * Zoom to a layer's bounds\n */\n private zoomToLayer(layerId: string): void {\n // Check if it's a custom layer with getBounds support\n const layerState = this.state.layerStates[layerId];\n if (layerState?.isCustomLayer && this.customLayerRegistry) {\n const bounds = this.customLayerRegistry.getBounds(layerId);\n if (bounds) {\n this.map.fitBounds(bounds as [number, number, number, number], {\n padding: 50,\n });\n return;\n }\n }\n\n // For native MapLibre layers, try to get bounds from features\n const layer = this.map.getLayer(layerId);\n if (!layer) return;\n\n try {\n // First try querySourceFeatures for all features\n const sourceId = (layer as any).source;\n let features = sourceId ? this.map.querySourceFeatures(sourceId) : [];\n\n // If no source features, try rendered features\n if (features.length === 0) {\n features = this.map.queryRenderedFeatures({ layers: [layerId] });\n }\n\n if (features.length === 0) return;\n\n // Calculate bounds\n let minLng = Infinity,\n minLat = Infinity,\n maxLng = -Infinity,\n maxLat = -Infinity;\n\n features.forEach((feature) => {\n if (!feature.geometry) return;\n\n const processCoords = (coords: any) => {\n if (typeof coords[0] === \"number\") {\n const [lng, lat] = coords;\n minLng = Math.min(minLng, lng);\n minLat = Math.min(minLat, lat);\n maxLng = Math.max(maxLng, lng);\n maxLat = Math.max(maxLat, lat);\n } else {\n coords.forEach(processCoords);\n }\n };\n\n if (feature.geometry.type === \"Point\") {\n processCoords((feature.geometry as any).coordinates);\n } else if (\n feature.geometry.type === \"LineString\" ||\n feature.geometry.type === \"MultiPoint\"\n ) {\n (feature.geometry as any).coordinates.forEach(processCoords);\n } else if (\n feature.geometry.type === \"Polygon\" ||\n feature.geometry.type === \"MultiLineString\"\n ) {\n (feature.geometry as any).coordinates.forEach((ring: any) =>\n ring.forEach(processCoords),\n );\n } else if (feature.geometry.type === \"MultiPolygon\") {\n (feature.geometry as any).coordinates.forEach((polygon: any) =>\n polygon.forEach((ring: any) => ring.forEach(processCoords)),\n );\n }\n });\n\n if (\n minLng !== Infinity &&\n minLat !== Infinity &&\n maxLng !== -Infinity &&\n maxLat !== -Infinity\n ) {\n this.map.fitBounds(\n [\n [minLng, minLat],\n [maxLng, maxLat],\n ],\n { padding: 50 },\n );\n }\n } catch (error) {\n console.warn(`Failed to zoom to layer ${layerId}:`, error);\n }\n }\n\n /**\n * Get user layer IDs in current map order (top to bottom in UI = high z-index to low)\n * Includes both MapLibre layers and custom layers managed by adapters.\n */\n private getUserLayerIdsInMapOrder(): string[] {\n const style = this.map.getStyle();\n if (!style?.layers) return [];\n\n // Get map layers in their actual order (low index = rendered first/bottom)\n const mapLayerIds = style.layers.map((l) => l.id);\n\n // Filter to only user layers that are in our state\n const userLayerIds = Object.keys(this.state.layerStates).filter(\n (id) => id !== \"Background\",\n );\n\n // Separate MapLibre layers and custom layers\n const mapLibreLayers = userLayerIds.filter((id) =>\n mapLayerIds.includes(id),\n );\n const customLayers = userLayerIds.filter(\n (id) =>\n this.state.layerStates[id]?.isCustomLayer && !mapLayerIds.includes(id),\n );\n\n // Sort MapLibre layers by map order (reversed: high index = top in UI)\n const sortedMapLibreLayers = mapLibreLayers.sort(\n (a, b) => mapLayerIds.indexOf(b) - mapLayerIds.indexOf(a),\n );\n\n // Custom layers are placed at the top (rendered last/on top)\n // Maintain their relative order from the state\n return [...customLayers, ...sortedMapLibreLayers];\n }\n\n /**\n * Check if a layer is a MapLibre layer (not a custom layer)\n */\n private isMapLibreLayer(layerId: string): boolean {\n return this.map.getLayer(layerId) !== undefined;\n }\n\n /**\n * Find the next MapLibre layer ID in a direction from a given index\n * @param layerIds Array of layer IDs\n * @param startIndex Index to start searching from\n * @param direction 1 for forward (toward bottom), -1 for backward (toward top)\n * @returns MapLibre layer ID or undefined if not found\n */\n private findNextMapLibreLayer(\n layerIds: string[],\n startIndex: number,\n direction: 1 | -1,\n ): string | undefined {\n for (\n let i = startIndex;\n direction === 1 ? i < layerIds.length : i >= 0;\n i += direction\n ) {\n if (this.isMapLibreLayer(layerIds[i])) {\n return layerIds[i];\n }\n }\n return undefined;\n }\n\n /**\n * Move a layer up in UI (higher rendering order = move to higher z-index)\n */\n private moveLayerUp(layerId: string): void {\n const layerIds = this.getUserLayerIdsInMapOrder();\n const index = layerIds.indexOf(layerId);\n if (index <= 0) return; // Already at top or not found\n\n // Check if this is a custom layer\n const isCustom = this.state.layerStates[layerId]?.isCustomLayer;\n\n if (!isCustom && this.isMapLibreLayer(layerId)) {\n // For MapLibre layers, we need to move them in the map\n // UI: [0]=top, [1], [2], ... [n]=bottom\n // Map array: bottom to top (low index = low z-index)\n // moveLayer(id, beforeId) moves id to render BELOW beforeId\n\n try {\n // Find the MapLibre layer to move before (2 positions above if exists)\n // If moving to top, use undefined as beforeId\n const targetBeforeId =\n index >= 2\n ? this.findNextMapLibreLayer(layerIds, index - 2, -1)\n : undefined;\n this.map.moveLayer(layerId, targetBeforeId);\n } catch (e) {\n // Ignore errors\n }\n }\n\n // For custom layers, just update the internal order\n // Swap positions in the state\n const newLayerStates: { [key: string]: LayerState } = {};\n const orderedIds = [...layerIds];\n [orderedIds[index], orderedIds[index - 1]] = [\n orderedIds[index - 1],\n orderedIds[index],\n ];\n\n // Add Background first if it exists\n if (this.state.layerStates[\"Background\"]) {\n newLayerStates[\"Background\"] = this.state.layerStates[\"Background\"];\n }\n orderedIds.forEach((id) => {\n if (this.state.layerStates[id]) {\n newLayerStates[id] = this.state.layerStates[id];\n }\n });\n this.state.layerStates = newLayerStates;\n\n // Rebuild UI\n this.buildLayerItems();\n this.onLayerReorder?.(this.getUserLayerIdsInMapOrder());\n }\n\n /**\n * Move a layer to the top (highest rendering order)\n */\n private moveLayerToTop(layerId: string): void {\n const layerIds = this.getUserLayerIdsInMapOrder();\n const index = layerIds.indexOf(layerId);\n if (index <= 0) return; // Already at top or not found\n\n // Check if this is a custom layer\n const isCustom = this.state.layerStates[layerId]?.isCustomLayer;\n\n if (!isCustom && this.isMapLibreLayer(layerId)) {\n // Move in MapLibre - no beforeId means move to top (highest z-index)\n try {\n this.map.moveLayer(layerId);\n } catch (e) {\n // Ignore errors\n }\n }\n\n // Update internal order - move to front\n const newLayerStates: { [key: string]: LayerState } = {};\n const orderedIds = [...layerIds];\n orderedIds.splice(index, 1);\n orderedIds.unshift(layerId);\n\n // Add Background first if it exists\n if (this.state.layerStates[\"Background\"]) {\n newLayerStates[\"Background\"] = this.state.layerStates[\"Background\"];\n }\n orderedIds.forEach((id) => {\n if (this.state.layerStates[id]) {\n newLayerStates[id] = this.state.layerStates[id];\n }\n });\n this.state.layerStates = newLayerStates;\n\n // Rebuild UI\n this.buildLayerItems();\n this.onLayerReorder?.(this.getUserLayerIdsInMapOrder());\n }\n\n /**\n * Move a layer down in UI (lower rendering order = move to lower z-index)\n */\n private moveLayerDown(layerId: string): void {\n const layerIds = this.getUserLayerIdsInMapOrder();\n const index = layerIds.indexOf(layerId);\n if (index < 0 || index >= layerIds.length - 1) return; // Already at bottom or not found\n\n // Check if this is a custom layer\n const isCustom = this.state.layerStates[layerId]?.isCustomLayer;\n\n if (!isCustom && this.isMapLibreLayer(layerId)) {\n // The layer below in UI is at index + 1, which has lower z-index in map\n // To move our layer below it, we call moveLayer(layerId, belowLayerId)\n // This puts layerId just below belowLayerId in rendering order\n // Find the next MapLibre layer below\n const belowLayerId = this.findNextMapLibreLayer(layerIds, index + 1, 1);\n\n if (belowLayerId) {\n try {\n this.map.moveLayer(layerId, belowLayerId);\n } catch (e) {\n // Ignore errors\n }\n }\n }\n\n // Update internal order - swap positions\n const newLayerStates: { [key: string]: LayerState } = {};\n const orderedIds = [...layerIds];\n [orderedIds[index], orderedIds[index + 1]] = [\n orderedIds[index + 1],\n orderedIds[index],\n ];\n\n // Add Background first if it exists\n if (this.state.layerStates[\"Background\"]) {\n newLayerStates[\"Background\"] = this.state.layerStates[\"Background\"];\n }\n orderedIds.forEach((id) => {\n if (this.state.layerStates[id]) {\n newLayerStates[id] = this.state.layerStates[id];\n }\n });\n this.state.layerStates = newLayerStates;\n\n // Rebuild UI\n this.buildLayerItems();\n this.onLayerReorder?.(this.getUserLayerIdsInMapOrder());\n }\n\n /**\n * Move a layer to the bottom (lowest rendering order among user layers)\n */\n private moveLayerToBottom(layerId: string): void {\n const layerIds = this.getUserLayerIdsInMapOrder();\n if (layerIds.length <= 1) return;\n\n const index = layerIds.indexOf(layerId);\n if (index < 0 || index === layerIds.length - 1) return; // Not found or already at bottom\n\n // Check if this is a custom layer\n const isCustom = this.state.layerStates[layerId]?.isCustomLayer;\n\n if (!isCustom && this.isMapLibreLayer(layerId)) {\n // The bottom layer in UI has the lowest z-index among user layers\n // Find the bottom-most MapLibre layer\n const bottomLayerId = this.findNextMapLibreLayer(\n layerIds,\n layerIds.length - 1,\n -1,\n );\n\n if (bottomLayerId && bottomLayerId !== layerId) {\n try {\n // Move this layer to be just below the current bottom layer\n this.map.moveLayer(layerId, bottomLayerId);\n } catch (e) {\n // Ignore errors\n }\n }\n }\n\n // Update internal order - move to end\n const newLayerStates: { [key: string]: LayerState } = {};\n const orderedIds = [...layerIds];\n orderedIds.splice(index, 1);\n orderedIds.push(layerId);\n\n // Add Background first if it exists\n if (this.state.layerStates[\"Background\"]) {\n newLayerStates[\"Background\"] = this.state.layerStates[\"Background\"];\n }\n orderedIds.forEach((id) => {\n if (this.state.layerStates[id]) {\n newLayerStates[id] = this.state.layerStates[id];\n }\n });\n this.state.layerStates = newLayerStates;\n\n // Rebuild UI\n this.buildLayerItems();\n this.onLayerReorder?.(this.getUserLayerIdsInMapOrder());\n }\n\n /**\n * Show inline remove confirmation instead of browser confirm() dialog.\n * Works in Jupyter notebooks where native dialogs may not appear.\n */\n private showRemoveConfirmation(\n container: HTMLElement,\n onConfirm: () => void,\n ): void {\n // Remove any existing confirmation in this container\n const existing = container.querySelector(\".layer-control-remove-confirm\");\n if (existing) {\n existing.remove();\n }\n\n const confirmEl = document.createElement(\"div\");\n confirmEl.className = \"layer-control-remove-confirm\";\n\n const message = document.createElement(\"div\");\n message.className = \"layer-control-remove-confirm-message\";\n message.innerHTML = `\n <svg class=\"layer-control-remove-confirm-icon\" viewBox=\"0 0 20 20\" fill=\"currentColor\">\n <path fill-rule=\"evenodd\" d=\"M8.485 2.495c.673-1.167 2.357-1.167 3.03 0l6.28 10.875c.673 1.167-.17 2.625-1.516 2.625H3.72c-1.347 0-2.189-1.458-1.515-2.625L8.485 2.495zM10 5a.75.75 0 01.75.75v3.5a.75.75 0 01-1.5 0v-3.5A.75.75 0 0110 5zm0 9a1 1 0 100-2 1 1 0 000 2z\" clip-rule=\"evenodd\"/>\n </svg>\n <span>Remove this layer?</span>\n `;\n\n const buttons = document.createElement(\"div\");\n buttons.className = \"layer-control-remove-confirm-buttons\";\n\n const cancelBtn = document.createElement(\"button\");\n cancelBtn.className =\n \"layer-control-remove-confirm-btn layer-control-remove-confirm-btn-cancel\";\n cancelBtn.textContent = \"Cancel\";\n cancelBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n confirmEl.remove();\n });\n\n const confirmBtn = document.createElement(\"button\");\n confirmBtn.className =\n \"layer-control-remove-confirm-btn layer-control-remove-confirm-btn-confirm\";\n confirmBtn.textContent = \"Remove\";\n confirmBtn.addEventListener(\"click\", (e) => {\n e.stopPropagation();\n confirmEl.remove();\n onConfirm();\n });\n\n buttons.appendChild(cancelBtn);\n buttons.appendChild(confirmBtn);\n\n confirmEl.appendChild(message);\n confirmEl.appendChild(buttons);\n\n container.appendChild(confirmEl);\n\n // Scroll the confirmation into view\n requestAnimationFrame(() => {\n confirmEl.scrollIntoView({ behavior: \"smooth\", block: \"nearest\" });\n });\n }\n\n /**\n * Remove a layer from the map\n */\n private removeLayer(layerId: string): void {\n // Prevent checkForNewLayers() from running during removal\n // (removing a layer triggers styledata events that could cause race conditions)\n this.state.isStyleOperationInProgress = true;\n\n const layerState = this.state.layerStates[layerId];\n\n // Handle custom layer removal\n if (layerState?.isCustomLayer && this.customLayerRegistry) {\n // Track this ID so checkForNewLayers() won't re-add it\n this.removedCustomLayerIds.add(layerId);\n\n // Hide the layer immediately as a visual fallback\n this.customLayerRegistry.setVisibility(layerId, false);\n\n // Let the adapter perform its own cleanup\n this.customLayerRegistry.removeLayer(layerId);\n }\n\n // Remove native MapLibre layer from the map\n try {\n const layer = this.map.getLayer(layerId);\n if (layer) {\n const sourceId = (layer as any).source;\n this.map.removeLayer(layerId);\n\n // Check if source is still used by other layers\n if (sourceId) {\n const style = this.map.getStyle();\n const sourceStillUsed = style?.layers?.some(\n (l) => (l as any).source === sourceId,\n );\n if (!sourceStillUsed) {\n try {\n this.map.removeSource(sourceId);\n } catch (e) {\n // Source might not exist or be in use\n }\n }\n }\n }\n } catch (error) {\n console.warn(`Failed to remove layer ${layerId}:`, error);\n }\n\n // Remove from state\n delete this.state.layerStates[layerId];\n this.state.customLayerNames.delete(layerId);\n\n // Remove from UI\n const itemEl = this.panel.querySelector(`[data-layer-id=\"${layerId}\"]`);\n if (itemEl) {\n itemEl.remove();\n }\n\n // Call callback\n this.onLayerRemove?.(layerId);\n\n // Clear flag after style events have settled\n setTimeout(() => {\n this.state.isStyleOperationInProgress = false;\n }, 200);\n }\n\n // ===== Drag and Drop Methods =====\n\n /**\n * Create drag handle element\n */\n private createDragHandle(layerId: string): HTMLDivElement {\n const handle = document.createElement(\"div\");\n handle.className = \"layer-control-drag-handle\";\n handle.innerHTML = `<svg viewBox=\"0 0 16 16\" fill=\"currentColor\">\n <circle cx=\"5\" cy=\"3\" r=\"1.5\"/>\n <circle cx=\"11\" cy=\"3\" r=\"1.5\"/>\n <circle cx=\"5\" cy=\"8\" r=\"1.5\"/>\n <circle cx=\"11\" cy=\"8\" r=\"1.5\"/>\n <circle cx=\"5\" cy=\"13\" r=\"1.5\"/>\n <circle cx=\"11\" cy=\"13\" r=\"1.5\"/>\n </svg>`;\n handle.title = \"Drag to reorder\";\n\n // Pointer events for dragging\n handle.addEventListener(\"pointerdown\", (e) => {\n e.preventDefault();\n e.stopPropagation();\n this.startDrag(layerId, e);\n });\n\n return handle;\n }\n\n /**\n * Create a disabled drag handle for alignment (used for Background layer)\n */\n private createDisabledDragHandle(): HTMLDivElement {\n const handle = document.createElement(\"div\");\n handle.className =\n \"layer-control-drag-handle layer-control-drag-handle-disabled\";\n handle.innerHTML = `<svg viewBox=\"0 0 16 16\" fill=\"currentColor\">\n <circle cx=\"5\" cy=\"3\" r=\"1.5\"/>\n <circle cx=\"11\" cy=\"3\" r=\"1.5\"/>\n <circle cx=\"5\" cy=\"8\" r=\"1.5\"/>\n <circle cx=\"11\" cy=\"8\" r=\"1.5\"/>\n <circle cx=\"5\" cy=\"13\" r=\"1.5\"/>\n <circle cx=\"11\" cy=\"13\" r=\"1.5\"/>\n </svg>`;\n return handle;\n }\n\n /**\n * Start dragging a layer\n */\n private startDrag(layerId: string, e: PointerEvent): void {\n const itemEl = this.panel.querySelector(\n `[data-layer-id=\"${layerId}\"]`,\n ) as HTMLElement;\n if (!itemEl) return;\n\n // Get item rect before any modifications\n const rect = itemEl.getBoundingClientRect();\n\n // Set up drag state\n this.state.drag = {\n active: true,\n layerId,\n startY: e.clientY,\n currentY: e.clientY,\n placeholder: null,\n draggedElement: null,\n };\n\n // Add dragging class to panel\n this.panel.classList.add(\"dragging-active\");\n\n // Hide original first (before creating clone to avoid visual jump)\n itemEl.classList.add(\"dragging\");\n\n // Create placeholder at original position\n const placeholder = document.createElement(\"div\");\n placeholder.className = \"layer-control-drop-placeholder\";\n placeholder.style.height = `${rect.height}px`;\n itemEl.parentNode?.insertBefore(placeholder, itemEl);\n this.state.drag.placeholder = placeholder;\n\n // Create floating clone\n const clone = itemEl.cloneNode(true) as HTMLElement;\n clone.classList.remove(\"dragging\");\n clone.className = \"layer-control-item layer-control-item-dragging\";\n clone.style.width = `${rect.width}px`;\n clone.style.left = `${rect.left}px`;\n clone.style.top = `${rect.top}px`;\n document.body.appendChild(clone);\n this.state.drag.draggedElement = clone;\n\n // Set up move and end handlers on document\n const onMove = (moveE: PointerEvent) => this.onDragMove(moveE);\n const onEnd = (endE: PointerEvent) => {\n document.removeEventListener(\"pointermove\", onMove);\n document.removeEventListener(\"pointerup\", onEnd);\n document.removeEventListener(\"pointercancel\", onEnd);\n this.endDrag(endE);\n };\n\n document.addEventListener(\"pointermove\", onMove);\n document.addEventListener(\"pointerup\", onEnd);\n document.addEventListener(\"pointercancel\", onEnd);\n }\n\n /**\n * Handle drag move\n */\n private onDragMove(e: PointerEvent): void {\n if (!this.state.drag.active || !this.state.drag.draggedElement) return;\n\n const placeholder = this.state.drag.placeholder;\n if (!placeholder) return;\n\n // Move the floating element\n const deltaY = e.clientY - this.state.drag.startY;\n const clone = this.state.drag.draggedElement;\n const currentTop = parseFloat(clone.style.top) || 0;\n clone.style.top = `${currentTop + deltaY}px`;\n this.state.drag.startY = e.clientY;\n this.state.drag.currentY = e.clientY;\n\n // Get all layer items (excluding the one being dragged and Background)\n const items = Array.from(\n this.panel.querySelectorAll(\".layer-control-item:not(.dragging)\"),\n ).filter(\n (item) => (item as HTMLElement).dataset.layerId !== \"Background\",\n ) as HTMLElement[];\n\n // Find which item we're hovering over\n for (const item of items) {\n const itemRect = item.getBoundingClientRect();\n\n // Check if cursor is within this item's vertical bounds\n if (e.clientY >= itemRect.top && e.clientY <= itemRect.bottom) {\n const itemMiddle = itemRect.top + itemRect.height / 2;\n\n if (e.clientY < itemMiddle) {\n // Insert placeholder before this item (if not already there)\n if (placeholder.nextSibling !== item) {\n item.parentNode?.insertBefore(placeholder, item);\n }\n } else {\n // Insert placeholder after this item (if not already there)\n if (placeholder.previousSibling !== item) {\n item.parentNode?.insertBefore(placeholder, item.nextSibling);\n }\n }\n break;\n }\n }\n }\n\n /**\n * End dragging\n */\n private endDrag(_e: PointerEvent): void {\n if (!this.state.drag.active) return;\n\n const layerId = this.state.drag.layerId;\n const placeholder = this.state.drag.placeholder;\n\n // Get the original item\n const itemEl = this.panel.querySelector(\n `[data-layer-id=\"${layerId}\"]`,\n ) as HTMLElement;\n\n if (itemEl && placeholder) {\n // Move item to placeholder position\n placeholder.parentNode?.insertBefore(itemEl, placeholder);\n itemEl.classList.remove(\"dragging\");\n }\n\n // Clean up\n this.cleanupDragState();\n\n // Update map layer order based on UI order\n this.applyUIOrderToMap();\n }\n\n /**\n * Clean up drag state\n */\n private cleanupDragState(): void {\n // Remove floating element\n if (this.state.drag.draggedElement) {\n this.state.drag.draggedElement.remove();\n }\n\n // Remove placeholder\n if (this.state.drag.placeholder) {\n this.state.drag.placeholder.remove();\n }\n\n // Remove dragging class from panel\n this.panel.classList.remove(\"dragging-active\");\n\n // Remove dragging class from any items\n this.panel\n .querySelectorAll(\".layer-control-item.dragging\")\n .forEach((el) => {\n el.classList.remove(\"dragging\");\n });\n\n // Reset drag state\n this.state.drag = {\n active: false,\n layerId: null,\n startY: 0,\n currentY: 0,\n placeholder: null,\n draggedElement: null,\n };\n }\n\n /**\n * Apply UI order to map layers\n */\n private applyUIOrderToMap(): void {\n // Set flag to prevent checkForNewLayers from running during reordering\n // This prevents custom layers from being incorrectly deleted due to race conditions\n this.state.isStyleOperationInProgress = true;\n\n // Get layer items in current UI order\n const items = this.panel.querySelectorAll(\".layer-control-item\");\n const uiLayerIds: string[] = [];\n\n items.forEach((item) => {\n const layerId = (item as HTMLElement).dataset.layerId;\n if (layerId && layerId !== \"Background\") {\n uiLayerIds.push(layerId);\n }\n });\n\n // uiLayerIds is the panel order top-to-bottom, where the top row is the\n // top-most layer (highest z-index, rendered last / on top). MapLibre's\n // moveLayer(id, beforeId) places `id` visually beneath `beforeId`, so\n // iterating from the top of the panel downward and anchoring each layer\n // beneath the previous one reproduces that stacking on the map: the first\n // item goes to the top, each subsequent item just below it.\n const style = this.map.getStyle();\n const mapLibreLayerIds = new Set(style?.layers?.map((l) => l.id) || []);\n\n for (let i = 0; i < uiLayerIds.length; i++) {\n const layerId = uiLayerIds[i];\n\n // Skip custom (non-MapLibre) layers; they are managed by their adapters.\n if (!mapLibreLayerIds.has(layerId)) {\n continue;\n }\n\n // Anchor beneath the nearest higher (already-placed) MapLibre layer,\n // skipping any custom layers between them.\n let beforeId: string | undefined = undefined;\n for (let j = i - 1; j >= 0; j--) {\n if (mapLibreLayerIds.has(uiLayerIds[j])) {\n beforeId = uiLayerIds[j];\n break;\n }\n }\n\n try {\n this.map.moveLayer(layerId, beforeId);\n } catch (e) {\n // Ignore errors\n }\n }\n\n // Call callback\n this.onLayerReorder?.(uiLayerIds);\n\n // Clear flag after styledata events have settled\n // The 200ms delay accounts for the 100ms timeout in the styledata event handler\n setTimeout(() => {\n this.state.isStyleOperationInProgress = false;\n }, 200);\n }\n}\n"],"names":["opacity","clamp","color","svgMarkup","symbolContainer","layerList","editor","_a"],"mappings":"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"}
|