maplibre-gl-components 0.8.0 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ControlGrid-CbLTUHJu.js.map +1 -1
- package/dist/ControlGrid-CeLIAj43.cjs.map +1 -1
- package/dist/types/lib/core/Basemap.d.ts.map +1 -1
- package/dist/types/lib/core/Colorbar.d.ts.map +1 -1
- package/dist/types/lib/core/ControlGrid.d.ts.map +1 -1
- package/dist/types/lib/core/HtmlControl.d.ts.map +1 -1
- package/dist/types/lib/core/InspectControl.d.ts.map +1 -1
- package/dist/types/lib/core/Legend.d.ts.map +1 -1
- package/dist/types/lib/core/SearchControl.d.ts.map +1 -1
- package/dist/types/lib/core/Terrain.d.ts.map +1 -1
- package/dist/types/lib/core/VectorDataset.d.ts.map +1 -1
- package/dist/types/lib/core/ViewStateControl.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ControlGrid-CbLTUHJu.js","sources":["../src/lib/colormaps/sequential.ts","../src/lib/colormaps/diverging.ts","../src/lib/colormaps/misc.ts","../src/lib/colormaps/index.ts","../src/lib/utils/helpers.ts","../src/lib/utils/providers.ts","../src/lib/core/Colorbar.ts","../src/lib/core/Legend.ts","../src/lib/core/HtmlControl.ts","../src/lib/core/Basemap.ts","../src/lib/core/Terrain.ts","../src/lib/core/SearchControl.ts","../src/lib/utils/fileHelpers.ts","../src/lib/core/VectorDataset.ts","../src/lib/core/InspectControl.ts","../src/lib/core/ViewStateControl.ts","../src/lib/core/ControlGrid.ts"],"sourcesContent":["import type { ColorStop } from '../core/types';\n\n/**\n * Viridis colormap - perceptually uniform, colorblind-friendly.\n */\nexport const viridis: ColorStop[] = [\n { position: 0.0, color: '#440154' },\n { position: 0.1, color: '#482878' },\n { position: 0.2, color: '#3e4a89' },\n { position: 0.3, color: '#31688e' },\n { position: 0.4, color: '#26838f' },\n { position: 0.5, color: '#1f9e89' },\n { position: 0.6, color: '#35b779' },\n { position: 0.7, color: '#6ece58' },\n { position: 0.8, color: '#b5de2b' },\n { position: 0.9, color: '#fde725' },\n { position: 1.0, color: '#fde725' },\n];\n\n/**\n * Plasma colormap - perceptually uniform.\n */\nexport const plasma: ColorStop[] = [\n { position: 0.0, color: '#0d0887' },\n { position: 0.1, color: '#41049d' },\n { position: 0.2, color: '#6a00a8' },\n { position: 0.3, color: '#8f0da4' },\n { position: 0.4, color: '#b12a90' },\n { position: 0.5, color: '#cc4778' },\n { position: 0.6, color: '#e16462' },\n { position: 0.7, color: '#f2844b' },\n { position: 0.8, color: '#fca636' },\n { position: 0.9, color: '#fcce25' },\n { position: 1.0, color: '#f0f921' },\n];\n\n/**\n * Inferno colormap - perceptually uniform.\n */\nexport const inferno: ColorStop[] = [\n { position: 0.0, color: '#000004' },\n { position: 0.1, color: '#1b0c41' },\n { position: 0.2, color: '#4a0c6b' },\n { position: 0.3, color: '#781c6d' },\n { position: 0.4, color: '#a52c60' },\n { position: 0.5, color: '#cf4446' },\n { position: 0.6, color: '#ed6925' },\n { position: 0.7, color: '#fb9b06' },\n { position: 0.8, color: '#f7d13d' },\n { position: 0.9, color: '#fcffa4' },\n { position: 1.0, color: '#fcffa4' },\n];\n\n/**\n * Magma colormap - perceptually uniform.\n */\nexport const magma: ColorStop[] = [\n { position: 0.0, color: '#000004' },\n { position: 0.1, color: '#180f3d' },\n { position: 0.2, color: '#440f76' },\n { position: 0.3, color: '#721f81' },\n { position: 0.4, color: '#9e2f7f' },\n { position: 0.5, color: '#cd4071' },\n { position: 0.6, color: '#f1605d' },\n { position: 0.7, color: '#fd9668' },\n { position: 0.8, color: '#fec98d' },\n { position: 0.9, color: '#fcfdbf' },\n { position: 1.0, color: '#fcfdbf' },\n];\n\n/**\n * Cividis colormap - colorblind-friendly.\n */\nexport const cividis: ColorStop[] = [\n { position: 0.0, color: '#00204d' },\n { position: 0.1, color: '#00306f' },\n { position: 0.2, color: '#2a406c' },\n { position: 0.3, color: '#4a5068' },\n { position: 0.4, color: '#636166' },\n { position: 0.5, color: '#7b7362' },\n { position: 0.6, color: '#94865c' },\n { position: 0.7, color: '#af9b51' },\n { position: 0.8, color: '#cab040' },\n { position: 0.9, color: '#e6c628' },\n { position: 1.0, color: '#ffdd00' },\n];\n","import type { ColorStop } from '../core/types';\n\n/**\n * Coolwarm diverging colormap.\n */\nexport const coolwarm: ColorStop[] = [\n { position: 0.0, color: '#3b4cc0' },\n { position: 0.1, color: '#5977e3' },\n { position: 0.2, color: '#7b9ff9' },\n { position: 0.3, color: '#9ebeff' },\n { position: 0.4, color: '#c0d4f5' },\n { position: 0.5, color: '#dddcdc' },\n { position: 0.6, color: '#f2cbb7' },\n { position: 0.7, color: '#f7ac8e' },\n { position: 0.8, color: '#ee8468' },\n { position: 0.9, color: '#d65244' },\n { position: 1.0, color: '#b40426' },\n];\n\n/**\n * Blue-White-Red diverging colormap.\n */\nexport const bwr: ColorStop[] = [\n { position: 0.0, color: '#0000ff' },\n { position: 0.5, color: '#ffffff' },\n { position: 1.0, color: '#ff0000' },\n];\n\n/**\n * Seismic diverging colormap.\n */\nexport const seismic: ColorStop[] = [\n { position: 0.0, color: '#00004d' },\n { position: 0.25, color: '#0000ff' },\n { position: 0.5, color: '#ffffff' },\n { position: 0.75, color: '#ff0000' },\n { position: 1.0, color: '#4d0000' },\n];\n\n/**\n * Red-Blue diverging colormap.\n */\nexport const RdBu: ColorStop[] = [\n { position: 0.0, color: '#67001f' },\n { position: 0.1, color: '#b2182b' },\n { position: 0.2, color: '#d6604d' },\n { position: 0.3, color: '#f4a582' },\n { position: 0.4, color: '#fddbc7' },\n { position: 0.5, color: '#f7f7f7' },\n { position: 0.6, color: '#d1e5f0' },\n { position: 0.7, color: '#92c5de' },\n { position: 0.8, color: '#4393c3' },\n { position: 0.9, color: '#2166ac' },\n { position: 1.0, color: '#053061' },\n];\n\n/**\n * Red-Yellow-Blue diverging colormap.\n */\nexport const RdYlBu: ColorStop[] = [\n { position: 0.0, color: '#a50026' },\n { position: 0.1, color: '#d73027' },\n { position: 0.2, color: '#f46d43' },\n { position: 0.3, color: '#fdae61' },\n { position: 0.4, color: '#fee090' },\n { position: 0.5, color: '#ffffbf' },\n { position: 0.6, color: '#e0f3f8' },\n { position: 0.7, color: '#abd9e9' },\n { position: 0.8, color: '#74add1' },\n { position: 0.9, color: '#4575b4' },\n { position: 1.0, color: '#313695' },\n];\n\n/**\n * Red-Yellow-Green diverging colormap.\n */\nexport const RdYlGn: ColorStop[] = [\n { position: 0.0, color: '#a50026' },\n { position: 0.1, color: '#d73027' },\n { position: 0.2, color: '#f46d43' },\n { position: 0.3, color: '#fdae61' },\n { position: 0.4, color: '#fee08b' },\n { position: 0.5, color: '#ffffbf' },\n { position: 0.6, color: '#d9ef8b' },\n { position: 0.7, color: '#a6d96a' },\n { position: 0.8, color: '#66bd63' },\n { position: 0.9, color: '#1a9850' },\n { position: 1.0, color: '#006837' },\n];\n\n/**\n * Spectral diverging colormap.\n */\nexport const spectral: ColorStop[] = [\n { position: 0.0, color: '#9e0142' },\n { position: 0.1, color: '#d53e4f' },\n { position: 0.2, color: '#f46d43' },\n { position: 0.3, color: '#fdae61' },\n { position: 0.4, color: '#fee08b' },\n { position: 0.5, color: '#ffffbf' },\n { position: 0.6, color: '#e6f598' },\n { position: 0.7, color: '#abdda4' },\n { position: 0.8, color: '#66c2a5' },\n { position: 0.9, color: '#3288bd' },\n { position: 1.0, color: '#5e4fa2' },\n];\n","import type { ColorStop } from '../core/types';\n\n/**\n * Jet colormap (classic rainbow-like).\n */\nexport const jet: ColorStop[] = [\n { position: 0.0, color: '#00007f' },\n { position: 0.125, color: '#0000ff' },\n { position: 0.25, color: '#007fff' },\n { position: 0.375, color: '#00ffff' },\n { position: 0.5, color: '#7fff7f' },\n { position: 0.625, color: '#ffff00' },\n { position: 0.75, color: '#ff7f00' },\n { position: 0.875, color: '#ff0000' },\n { position: 1.0, color: '#7f0000' },\n];\n\n/**\n * Rainbow colormap.\n */\nexport const rainbow: ColorStop[] = [\n { position: 0.0, color: '#ff0000' },\n { position: 0.17, color: '#ff8000' },\n { position: 0.33, color: '#ffff00' },\n { position: 0.5, color: '#00ff00' },\n { position: 0.67, color: '#00ffff' },\n { position: 0.83, color: '#0000ff' },\n { position: 1.0, color: '#8000ff' },\n];\n\n/**\n * Turbo colormap (improved rainbow).\n */\nexport const turbo: ColorStop[] = [\n { position: 0.0, color: '#30123b' },\n { position: 0.1, color: '#4662d7' },\n { position: 0.2, color: '#36aaf9' },\n { position: 0.3, color: '#1ae4b6' },\n { position: 0.4, color: '#72fe5e' },\n { position: 0.5, color: '#c8ef34' },\n { position: 0.6, color: '#faba39' },\n { position: 0.7, color: '#f66b19' },\n { position: 0.8, color: '#ca2a04' },\n { position: 0.9, color: '#7a0403' },\n { position: 1.0, color: '#7a0403' },\n];\n\n/**\n * Terrain colormap.\n */\nexport const terrain: ColorStop[] = [\n { position: 0.0, color: '#333399' },\n { position: 0.15, color: '#0099cc' },\n { position: 0.25, color: '#00cc99' },\n { position: 0.35, color: '#99cc00' },\n { position: 0.5, color: '#ffcc00' },\n { position: 0.65, color: '#cc6600' },\n { position: 0.75, color: '#993300' },\n { position: 0.85, color: '#996633' },\n { position: 1.0, color: '#ffffff' },\n];\n\n/**\n * Ocean colormap.\n */\nexport const ocean: ColorStop[] = [\n { position: 0.0, color: '#007f00' },\n { position: 0.25, color: '#00007f' },\n { position: 0.5, color: '#0000ff' },\n { position: 0.75, color: '#7fffff' },\n { position: 1.0, color: '#ffffff' },\n];\n\n/**\n * Hot colormap (black-red-yellow-white).\n */\nexport const hot: ColorStop[] = [\n { position: 0.0, color: '#000000' },\n { position: 0.33, color: '#ff0000' },\n { position: 0.67, color: '#ffff00' },\n { position: 1.0, color: '#ffffff' },\n];\n\n/**\n * Cool colormap (cyan-magenta).\n */\nexport const cool: ColorStop[] = [\n { position: 0.0, color: '#00ffff' },\n { position: 1.0, color: '#ff00ff' },\n];\n\n/**\n * Gray/Grayscale colormap.\n */\nexport const gray: ColorStop[] = [\n { position: 0.0, color: '#000000' },\n { position: 1.0, color: '#ffffff' },\n];\n\n/**\n * Bone colormap.\n */\nexport const bone: ColorStop[] = [\n { position: 0.0, color: '#000000' },\n { position: 0.375, color: '#545474' },\n { position: 0.75, color: '#a9c8c8' },\n { position: 1.0, color: '#ffffff' },\n];\n","import type { ColorStop, ColormapName } from '../core/types';\nimport { viridis, plasma, inferno, magma, cividis } from './sequential';\nimport { coolwarm, bwr, seismic, RdBu, RdYlBu, RdYlGn, spectral } from './diverging';\nimport { jet, rainbow, turbo, terrain, ocean, hot, cool, gray, bone } from './misc';\n\n/**\n * Map of all built-in colormaps.\n */\nexport const COLORMAPS: Record<ColormapName, ColorStop[]> = {\n // Sequential\n viridis,\n plasma,\n inferno,\n magma,\n cividis,\n // Diverging\n coolwarm,\n bwr,\n seismic,\n RdBu,\n RdYlBu,\n RdYlGn,\n spectral,\n // Miscellaneous\n jet,\n rainbow,\n turbo,\n terrain,\n ocean,\n hot,\n cool,\n gray,\n bone,\n};\n\n/**\n * Gets a colormap by name.\n *\n * @param name - The colormap name.\n * @returns Array of color stops.\n */\nexport function getColormap(name: ColormapName): ColorStop[] {\n return COLORMAPS[name] || COLORMAPS.viridis;\n}\n\n/**\n * Checks if a colormap name is valid.\n *\n * @param name - The name to check.\n * @returns True if the name is a valid colormap.\n */\nexport function isValidColormap(name: string): name is ColormapName {\n return name in COLORMAPS;\n}\n\n/**\n * Gets all available colormap names.\n *\n * @returns Array of colormap names.\n */\nexport function getColormapNames(): ColormapName[] {\n return Object.keys(COLORMAPS) as ColormapName[];\n}\n\n// Re-export individual colormaps\nexport { viridis, plasma, inferno, magma, cividis };\nexport { coolwarm, bwr, seismic, RdBu, RdYlBu, RdYlGn, spectral };\nexport { jet, rainbow, turbo, terrain, ocean, hot, cool, gray, bone };\n","/**\n * Clamps a value between min and max.\n *\n * @param value - The value to clamp.\n * @param min - The minimum value.\n * @param max - The maximum value.\n * @returns The clamped value.\n */\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\n/**\n * Formats a numeric value based on the range.\n *\n * @param value - The value to format.\n * @param range - The total range (max - min).\n * @returns Formatted string.\n */\nexport function formatNumericValue(value: number, range: number): string {\n if (range >= 100) {\n return Math.round(value).toString();\n } else if (range >= 1) {\n return value.toFixed(1);\n } else if (range >= 0.1) {\n return value.toFixed(2);\n } else {\n return value.toFixed(3);\n }\n}\n\n/**\n * Generates a unique ID with optional prefix.\n *\n * @param prefix - Optional prefix for the ID.\n * @returns A unique ID string.\n */\nexport function generateId(prefix = 'mlgl'): string {\n return `${prefix}-${Math.random().toString(36).substring(2, 9)}`;\n}\n\n/**\n * Debounces a function call.\n *\n * @param fn - The function to debounce.\n * @param delay - The delay in milliseconds.\n * @returns A debounced function.\n */\nexport function debounce<T extends (...args: unknown[]) => void>(\n fn: T,\n delay: number\n): (...args: Parameters<T>) => void {\n let timeoutId: ReturnType<typeof setTimeout>;\n return (...args: Parameters<T>) => {\n clearTimeout(timeoutId);\n timeoutId = setTimeout(() => fn(...args), delay);\n };\n}\n\n/**\n * Throttles a function call.\n *\n * @param fn - The function to throttle.\n * @param limit - The minimum time between calls in milliseconds.\n * @returns A throttled function.\n */\nexport function throttle<T extends (...args: unknown[]) => void>(\n fn: T,\n limit: number\n): (...args: Parameters<T>) => void {\n let inThrottle = false;\n return (...args: Parameters<T>) => {\n if (!inThrottle) {\n fn(...args);\n inThrottle = true;\n setTimeout(() => (inThrottle = false), limit);\n }\n };\n}\n\n/**\n * Joins class names, filtering out falsy values.\n *\n * @param classes - Class names to join.\n * @returns Joined class string.\n */\nexport function classNames(...classes: (string | undefined | null | false)[]): string {\n return classes.filter(Boolean).join(' ');\n}\n","import type { BasemapItem } from '../core/types';\n\n/**\n * Default URL for xyzservices providers.json.\n */\nexport const XYZSERVICES_URL =\n 'https://raw.githubusercontent.com/geopandas/xyzservices/main/xyzservices/data/providers.json';\n\n/**\n * XYZservices provider structure from providers.json.\n */\ninterface XYZProvider {\n url: string;\n name: string;\n max_zoom?: number;\n min_zoom?: number;\n attribution?: string;\n html_attribution?: string;\n bounds?: [[number, number], [number, number]];\n accessToken?: string;\n variant?: string;\n ext?: string;\n subdomains?: string;\n status?: string;\n}\n\n/**\n * Parsed provider group from xyzservices.\n */\ninterface ProviderGroup {\n [key: string]: XYZProvider | ProviderGroup;\n}\n\n/**\n * Options for parsing providers.\n */\ninterface ParseOptions {\n filterGroups?: string[];\n excludeGroups?: string[];\n excludeBroken?: boolean;\n}\n\n/**\n * Check if an object is an XYZ provider (has url field).\n */\nfunction isXYZProvider(obj: unknown): obj is XYZProvider {\n return typeof obj === 'object' && obj !== null && 'url' in obj && typeof (obj as XYZProvider).url === 'string';\n}\n\n/**\n * Build the tile URL from an XYZ provider.\n * Replaces placeholders like {s}, {r}, {variant}, {ext}.\n */\nexport function buildTileUrl(basemap: BasemapItem): string {\n let url = basemap.url || '';\n\n // Replace subdomains placeholder with 'a' (first subdomain)\n url = url.replace('{s}', 'a');\n\n // Replace retina placeholder\n url = url.replace('{r}', '');\n\n // Replace variant placeholder (e.g., CartoDB uses {variant} for 'light_all', 'dark_all', etc.)\n if (basemap.variant) {\n url = url.replace('{variant}', basemap.variant);\n }\n\n // Replace file extension placeholder (e.g., some providers use {ext} for 'png', 'jpg')\n if (basemap.ext) {\n url = url.replace('{ext}', basemap.ext);\n }\n\n // Handle API key placeholders\n if (basemap.apiKey) {\n url = url.replace('{apikey}', basemap.apiKey);\n url = url.replace('{accessToken}', basemap.apiKey);\n url = url.replace('<insert your api key here>', basemap.apiKey);\n url = url.replace('<insert your access token here>', basemap.apiKey);\n }\n\n return url;\n}\n\n/**\n * Generate a thumbnail URL from a basemap's tile URL.\n * Uses zoom level 3 for a reasonable world view.\n */\nexport function generateThumbnailUrl(basemap: BasemapItem): string {\n if (basemap.thumbnail) {\n return basemap.thumbnail;\n }\n\n if (basemap.url) {\n let url = buildTileUrl(basemap);\n // Generate thumbnail at zoom 3, tile 4/2 (roughly centered on Europe)\n url = url.replace('{z}', '3');\n url = url.replace('{x}', '4');\n url = url.replace('{y}', '2');\n return url;\n }\n\n return '';\n}\n\n/**\n * Parse xyzservices providers.json data into BasemapItem array.\n */\nexport function parseProviders(data: Record<string, unknown>, options: ParseOptions = {}): BasemapItem[] {\n const { filterGroups, excludeGroups, excludeBroken = true } = options;\n const basemaps: BasemapItem[] = [];\n\n function processProvider(provider: XYZProvider, groupName: string, providerName: string): void {\n // Skip broken providers\n if (excludeBroken && provider.status === 'broken') {\n return;\n }\n\n // Skip providers without URL\n if (!provider.url) {\n return;\n }\n\n // Check if requires API key\n const requiresApiKey =\n provider.accessToken?.includes('insert your') ||\n provider.url.includes('{apikey}') ||\n provider.url.includes('{accessToken}');\n\n basemaps.push({\n id: provider.name || `${groupName}.${providerName}`,\n name: providerName,\n group: groupName,\n url: provider.url,\n attribution: provider.html_attribution || provider.attribution,\n maxZoom: provider.max_zoom,\n minZoom: provider.min_zoom,\n requiresApiKey,\n variant: provider.variant,\n ext: provider.ext,\n });\n }\n\n function processGroup(group: ProviderGroup, groupName: string): void {\n for (const [key, value] of Object.entries(group)) {\n if (isXYZProvider(value)) {\n processProvider(value, groupName, key);\n }\n }\n }\n\n for (const [groupName, groupValue] of Object.entries(data)) {\n // Apply group filtering\n if (excludeGroups?.includes(groupName)) {\n continue;\n }\n if (filterGroups?.length && !filterGroups.includes(groupName)) {\n continue;\n }\n\n // Check if this is a direct provider or a group of providers\n if (isXYZProvider(groupValue)) {\n // Direct provider (like OpenSeaMap)\n processProvider(groupValue, groupName, groupName);\n } else if (typeof groupValue === 'object' && groupValue !== null) {\n // Group of providers (like OpenStreetMap with Mapnik, HOT, etc.)\n processGroup(groupValue as ProviderGroup, groupName);\n }\n }\n\n return basemaps;\n}\n\n/**\n * Fetch and parse providers from xyzservices URL.\n */\nexport async function fetchProviders(\n url: string = XYZSERVICES_URL,\n options: ParseOptions = {}\n): Promise<BasemapItem[]> {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`Failed to fetch providers: ${response.statusText}`);\n }\n const data = await response.json();\n return parseProviders(data, options);\n}\n\n/**\n * Group basemaps by their group property.\n */\nexport function groupBasemaps(basemaps: BasemapItem[]): Map<string, BasemapItem[]> {\n const groups = new Map<string, BasemapItem[]>();\n\n for (const basemap of basemaps) {\n const groupName = basemap.group || 'Other';\n const existing = groups.get(groupName) || [];\n existing.push(basemap);\n groups.set(groupName, existing);\n }\n\n return groups;\n}\n\n/**\n * Filter basemaps by search text.\n */\nexport function filterBasemaps(basemaps: BasemapItem[], searchText: string): BasemapItem[] {\n if (!searchText.trim()) {\n return basemaps;\n }\n\n const search = searchText.toLowerCase();\n return basemaps.filter(\n (b) =>\n b.name.toLowerCase().includes(search) ||\n b.id.toLowerCase().includes(search) ||\n b.group?.toLowerCase().includes(search)\n );\n}\n\n/**\n * Google basemap definitions.\n * These are not included in xyzservices but are commonly requested.\n */\nexport const GOOGLE_BASEMAPS: BasemapItem[] = [\n {\n id: 'Google.Roadmap',\n name: 'Roadmap',\n group: 'Google',\n url: 'https://mt1.google.com/vt/lyrs=m&x={x}&y={y}&z={z}',\n attribution: '© Google Maps',\n maxZoom: 22,\n },\n {\n id: 'Google.Satellite',\n name: 'Satellite',\n group: 'Google',\n url: 'https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}',\n attribution: '© Google Maps',\n maxZoom: 22,\n },\n {\n id: 'Google.Terrain',\n name: 'Terrain',\n group: 'Google',\n url: 'https://mt1.google.com/vt/lyrs=p&x={x}&y={y}&z={z}',\n attribution: '© Google Maps',\n maxZoom: 22,\n },\n {\n id: 'Google.Hybrid',\n name: 'Hybrid',\n group: 'Google',\n url: 'https://mt1.google.com/vt/lyrs=y&x={x}&y={y}&z={z}',\n attribution: '© Google Maps',\n maxZoom: 22,\n },\n];\n","import type { IControl, Map as MapLibreMap } from 'maplibre-gl';\nimport type {\n ColorbarOptions,\n ColorbarState,\n ComponentEvent,\n ComponentEventHandler,\n ColorStop,\n} from './types';\nimport { getColormap, isValidColormap } from '../colormaps';\nimport { formatNumericValue } from '../utils';\n\n/**\n * Default options for the Colorbar control.\n */\nconst DEFAULT_OPTIONS: Required<Omit<ColorbarOptions, 'colorStops'>> & { colorStops: ColorStop[] } = {\n colormap: 'viridis',\n colorStops: [],\n vmin: 0,\n vmax: 1,\n label: '',\n units: '',\n orientation: 'vertical',\n position: 'bottom-right',\n barThickness: 20,\n barLength: 200,\n ticks: { count: 5 },\n className: '',\n visible: true,\n opacity: 1,\n backgroundColor: 'rgba(255, 255, 255, 0.9)',\n fontSize: 11,\n fontColor: '#333',\n borderRadius: 4,\n padding: 8,\n minzoom: 0,\n maxzoom: 24,\n};\n\n/**\n * A continuous gradient colorbar control for MapLibre GL maps.\n *\n * Displays a color gradient legend with customizable colormaps,\n * tick marks, labels, and positioning.\n *\n * @example\n * ```typescript\n * const colorbar = new Colorbar({\n * colormap: 'viridis',\n * vmin: 0,\n * vmax: 100,\n * label: 'Temperature',\n * units: '°C',\n * orientation: 'vertical',\n * });\n * map.addControl(colorbar, 'bottom-right');\n * ```\n */\nexport class Colorbar implements IControl {\n private _container?: HTMLElement;\n private _options: Required<Omit<ColorbarOptions, 'colorStops'>> & { colorStops: ColorStop[] };\n private _state: ColorbarState;\n private _eventHandlers: Map<ComponentEvent, Set<ComponentEventHandler<ColorbarState>>> =\n new Map();\n private _map?: MapLibreMap;\n private _handleZoom?: () => void;\n private _zoomVisible: boolean = true;\n\n /**\n * Creates a new Colorbar instance.\n *\n * @param options - Configuration options for the colorbar.\n */\n constructor(options?: ColorbarOptions) {\n this._options = { ...DEFAULT_OPTIONS, ...options };\n this._state = {\n visible: this._options.visible,\n vmin: this._options.vmin,\n vmax: this._options.vmax,\n colormap: this._options.colormap,\n };\n }\n\n /**\n * Called when the control is added to the map.\n * Implements the IControl interface.\n *\n * @param map - The MapLibre GL map instance.\n * @returns The control's container element.\n */\n onAdd(map: MapLibreMap): HTMLElement {\n this._map = map;\n this._container = this._createContainer();\n this._render();\n\n // Set up zoom listener\n this._handleZoom = () => this._checkZoomVisibility();\n this._map.on('zoom', this._handleZoom);\n\n // Check initial zoom\n this._checkZoomVisibility();\n\n return this._container;\n }\n\n /**\n * Called when the control is removed from the map.\n * Implements the IControl interface.\n */\n onRemove(): void {\n if (this._map && this._handleZoom) {\n this._map.off('zoom', this._handleZoom);\n this._handleZoom = undefined;\n }\n this._map = undefined;\n this._container?.parentNode?.removeChild(this._container);\n this._container = undefined;\n this._eventHandlers.clear();\n }\n\n /**\n * Shows the colorbar.\n */\n show(): void {\n if (!this._state.visible) {\n this._state.visible = true;\n this._updateDisplayState();\n this._emit('show');\n }\n }\n\n /**\n * Hides the colorbar.\n */\n hide(): void {\n if (this._state.visible) {\n this._state.visible = false;\n this._updateDisplayState();\n this._emit('hide');\n }\n }\n\n /**\n * Updates the colorbar options and re-renders.\n *\n * @param options - Partial options to update.\n */\n update(options: Partial<ColorbarOptions>): void {\n this._options = { ...this._options, ...options };\n if (options.vmin !== undefined) this._state.vmin = options.vmin;\n if (options.vmax !== undefined) this._state.vmax = options.vmax;\n if (options.colormap !== undefined) this._state.colormap = options.colormap;\n if (options.visible !== undefined) this._state.visible = options.visible;\n this._render();\n this._emit('update');\n }\n\n /**\n * Gets the current state.\n *\n * @returns The current colorbar state.\n */\n getState(): ColorbarState {\n return { ...this._state };\n }\n\n /**\n * Registers an event handler.\n *\n * @param event - The event type to listen for.\n * @param handler - The callback function.\n */\n on(event: ComponentEvent, handler: ComponentEventHandler<ColorbarState>): void {\n if (!this._eventHandlers.has(event)) {\n this._eventHandlers.set(event, new Set());\n }\n this._eventHandlers.get(event)!.add(handler);\n }\n\n /**\n * Removes an event handler.\n *\n * @param event - The event type.\n * @param handler - The callback function to remove.\n */\n off(event: ComponentEvent, handler: ComponentEventHandler<ColorbarState>): void {\n this._eventHandlers.get(event)?.delete(handler);\n }\n\n /**\n * Gets the resolved color stops for the current colormap.\n *\n * @returns Array of color stops.\n */\n private _getColorStops(): ColorStop[] {\n // Custom color stops take priority\n if (this._options.colorStops && this._options.colorStops.length > 0) {\n return this._options.colorStops;\n }\n\n const colormap = this._options.colormap;\n\n // If colormap is a string array, convert to color stops\n if (Array.isArray(colormap)) {\n return colormap.map((color, i) => ({\n position: i / (colormap.length - 1),\n color,\n }));\n }\n\n // If colormap is a name, get the built-in colormap\n if (typeof colormap === 'string' && isValidColormap(colormap)) {\n return getColormap(colormap);\n }\n\n // Default to viridis\n return getColormap('viridis');\n }\n\n /**\n * Generates the CSS gradient string.\n *\n * @returns CSS linear-gradient string.\n */\n private _generateGradient(): string {\n const stops = this._getColorStops();\n const direction = this._options.orientation === 'horizontal' ? 'to right' : 'to top';\n const colorStops = stops.map((stop) => `${stop.color} ${stop.position * 100}%`).join(', ');\n return `linear-gradient(${direction}, ${colorStops})`;\n }\n\n /**\n * Generates tick values.\n *\n * @returns Array of tick values.\n */\n private _generateTicks(): number[] {\n const { ticks, vmin, vmax } = this._options;\n\n if (ticks.values && ticks.values.length > 0) {\n return ticks.values;\n }\n\n const count = ticks.count || 5;\n const step = (vmax - vmin) / (count - 1);\n return Array.from({ length: count }, (_, i) => vmin + i * step);\n }\n\n /**\n * Formats a tick value for display.\n *\n * @param value - The tick value.\n * @returns Formatted string.\n */\n private _formatTick(value: number): string {\n const { ticks, units } = this._options;\n\n if (ticks.format) {\n return ticks.format(value);\n }\n\n // Auto-format based on range\n const range = this._options.vmax - this._options.vmin;\n const formatted = formatNumericValue(value, range);\n\n return units ? `${formatted}${units}` : formatted;\n }\n\n /**\n * Emits an event to all registered handlers.\n *\n * @param event - The event type to emit.\n */\n private _emit(event: ComponentEvent): void {\n const handlers = this._eventHandlers.get(event);\n if (handlers) {\n const eventData = { type: event, state: this.getState() };\n handlers.forEach((handler) => handler(eventData));\n }\n }\n\n /**\n * Checks if the current zoom level is within the visibility range.\n */\n private _checkZoomVisibility(): void {\n if (!this._map) return;\n\n const zoom = this._map.getZoom();\n const { minzoom, maxzoom } = this._options;\n const inRange = zoom >= minzoom && zoom <= maxzoom;\n\n if (inRange !== this._zoomVisible) {\n this._zoomVisible = inRange;\n this._updateDisplayState();\n }\n }\n\n /**\n * Updates the display state based on visibility and zoom level.\n */\n private _updateDisplayState(): void {\n if (!this._container) return;\n const shouldShow = this._state.visible && this._zoomVisible;\n this._container.style.display = shouldShow ? 'flex' : 'none';\n }\n\n /**\n * Creates the main container element.\n *\n * @returns The container element.\n */\n private _createContainer(): HTMLElement {\n const container = document.createElement('div');\n container.className = `maplibregl-ctrl maplibre-gl-colorbar${\n this._options.className ? ` ${this._options.className}` : ''\n }`;\n\n const shouldShow = this._state.visible && this._zoomVisible;\n if (!shouldShow) {\n container.style.display = 'none';\n }\n\n return container;\n }\n\n /**\n * Renders the colorbar content.\n */\n private _render(): void {\n if (!this._container) return;\n\n const {\n orientation,\n barThickness,\n barLength,\n label,\n backgroundColor,\n opacity,\n fontSize,\n fontColor,\n borderRadius,\n padding,\n } = this._options;\n const isVertical = orientation === 'vertical';\n const ticks = this._generateTicks();\n\n // Clear existing content\n this._container.innerHTML = '';\n\n // Apply container styles\n const shouldShow = this._state.visible && this._zoomVisible;\n Object.assign(this._container.style, {\n backgroundColor,\n opacity: opacity.toString(),\n borderRadius: `${borderRadius}px`,\n padding: `${padding}px`,\n fontSize: `${fontSize}px`,\n color: fontColor,\n display: shouldShow ? 'flex' : 'none',\n flexDirection: isVertical ? 'row' : 'column',\n alignItems: 'stretch',\n gap: '6px',\n boxShadow: '0 0 0 2px rgba(0, 0, 0, 0.1)',\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n });\n\n // Add label if provided\n if (label) {\n const labelEl = document.createElement('div');\n labelEl.className = 'maplibre-gl-colorbar-label';\n labelEl.textContent = label;\n Object.assign(labelEl.style, {\n fontWeight: '600',\n textAlign: 'center',\n marginBottom: isVertical ? '0' : '4px',\n writingMode: isVertical ? 'vertical-rl' : 'horizontal-tb',\n transform: isVertical ? 'rotate(180deg)' : 'none',\n });\n this._container.appendChild(labelEl);\n }\n\n // Create gradient bar with ticks\n const barWrapper = document.createElement('div');\n barWrapper.className = 'maplibre-gl-colorbar-bar-wrapper';\n Object.assign(barWrapper.style, {\n display: 'flex',\n flexDirection: isVertical ? 'row' : 'column',\n alignItems: 'stretch',\n });\n\n // Gradient bar\n const bar = document.createElement('div');\n bar.className = 'maplibre-gl-colorbar-bar';\n Object.assign(bar.style, {\n background: this._generateGradient(),\n width: isVertical ? `${barThickness}px` : `${barLength}px`,\n height: isVertical ? `${barLength}px` : `${barThickness}px`,\n borderRadius: '2px',\n border: '1px solid rgba(0, 0, 0, 0.2)',\n });\n\n // Ticks container\n const ticksContainer = document.createElement('div');\n ticksContainer.className = 'maplibre-gl-colorbar-ticks';\n Object.assign(ticksContainer.style, {\n display: 'flex',\n flexDirection: isVertical ? 'column-reverse' : 'row',\n justifyContent: 'space-between',\n width: isVertical ? 'auto' : `${barLength}px`,\n height: isVertical ? `${barLength}px` : 'auto',\n marginLeft: isVertical ? '4px' : '0',\n marginTop: isVertical ? '0' : '4px',\n });\n\n ticks.forEach((value) => {\n const tick = document.createElement('span');\n tick.className = 'maplibre-gl-colorbar-tick';\n tick.textContent = this._formatTick(value);\n tick.style.fontSize = `${fontSize - 1}px`;\n ticksContainer.appendChild(tick);\n });\n\n barWrapper.appendChild(bar);\n barWrapper.appendChild(ticksContainer);\n this._container.appendChild(barWrapper);\n }\n}\n","import type { IControl, Map as MapLibreMap } from 'maplibre-gl';\nimport type {\n LegendOptions,\n LegendState,\n LegendItem,\n ComponentEvent,\n ComponentEventHandler,\n} from './types';\n\n/**\n * Default options for the Legend control.\n */\nconst DEFAULT_OPTIONS: Required<LegendOptions> = {\n title: '',\n items: [],\n position: 'bottom-left',\n className: '',\n visible: true,\n collapsible: false,\n collapsed: false,\n width: 200,\n maxHeight: 300,\n opacity: 1,\n backgroundColor: 'rgba(255, 255, 255, 0.9)',\n fontSize: 12,\n fontColor: '#333',\n swatchSize: 16,\n borderRadius: 4,\n padding: 10,\n minzoom: 0,\n maxzoom: 24,\n};\n\n/**\n * A categorical legend control for MapLibre GL maps.\n *\n * Displays discrete legend items with color swatches and labels.\n *\n * @example\n * ```typescript\n * const legend = new Legend({\n * title: 'Land Use',\n * items: [\n * { label: 'Residential', color: '#ff6b6b' },\n * { label: 'Commercial', color: '#4ecdc4' },\n * { label: 'Industrial', color: '#95a5a6' },\n * ],\n * });\n * map.addControl(legend, 'bottom-left');\n * ```\n */\nexport class Legend implements IControl {\n private _container?: HTMLElement;\n private _options: Required<LegendOptions>;\n private _state: LegendState;\n private _eventHandlers: Map<ComponentEvent, Set<ComponentEventHandler<LegendState>>> = new Map();\n private _map?: MapLibreMap;\n private _handleZoom?: () => void;\n private _zoomVisible: boolean = true;\n\n /**\n * Creates a new Legend instance.\n *\n * @param options - Configuration options for the legend.\n */\n constructor(options?: LegendOptions) {\n this._options = { ...DEFAULT_OPTIONS, ...options };\n this._state = {\n visible: this._options.visible,\n collapsed: this._options.collapsed,\n items: [...this._options.items],\n };\n }\n\n /**\n * Called when the control is added to the map.\n *\n * @param map - The MapLibre GL map instance.\n * @returns The control's container element.\n */\n onAdd(map: MapLibreMap): HTMLElement {\n this._map = map;\n this._container = this._createContainer();\n this._render();\n\n // Set up zoom listener\n this._handleZoom = () => this._checkZoomVisibility();\n this._map.on('zoom', this._handleZoom);\n\n // Check initial zoom\n this._checkZoomVisibility();\n\n return this._container;\n }\n\n /**\n * Called when the control is removed from the map.\n */\n onRemove(): void {\n if (this._map && this._handleZoom) {\n this._map.off('zoom', this._handleZoom);\n this._handleZoom = undefined;\n }\n this._map = undefined;\n this._container?.parentNode?.removeChild(this._container);\n this._container = undefined;\n this._eventHandlers.clear();\n }\n\n /**\n * Shows the legend.\n */\n show(): void {\n if (!this._state.visible) {\n this._state.visible = true;\n this._updateDisplayState();\n this._emit('show');\n }\n }\n\n /**\n * Hides the legend.\n */\n hide(): void {\n if (this._state.visible) {\n this._state.visible = false;\n this._updateDisplayState();\n this._emit('hide');\n }\n }\n\n /**\n * Expands the legend (if collapsible).\n */\n expand(): void {\n if (this._state.collapsed) {\n this._state.collapsed = false;\n this._render();\n this._emit('expand');\n }\n }\n\n /**\n * Collapses the legend (if collapsible).\n */\n collapse(): void {\n if (!this._state.collapsed) {\n this._state.collapsed = true;\n this._render();\n this._emit('collapse');\n }\n }\n\n /**\n * Toggles the collapsed state.\n */\n toggle(): void {\n if (this._state.collapsed) {\n this.expand();\n } else {\n this.collapse();\n }\n }\n\n /**\n * Updates the legend items.\n *\n * @param items - New legend items.\n */\n setItems(items: LegendItem[]): void {\n this._state.items = [...items];\n this._options.items = [...items];\n this._render();\n this._emit('update');\n }\n\n /**\n * Adds a legend item.\n *\n * @param item - Legend item to add.\n */\n addItem(item: LegendItem): void {\n this._state.items.push(item);\n this._options.items.push(item);\n this._render();\n this._emit('update');\n }\n\n /**\n * Removes a legend item by label.\n *\n * @param label - Label of the item to remove.\n */\n removeItem(label: string): void {\n this._state.items = this._state.items.filter((item) => item.label !== label);\n this._options.items = [...this._state.items];\n this._render();\n this._emit('update');\n }\n\n /**\n * Updates legend options and re-renders.\n *\n * @param options - Partial options to update.\n */\n update(options: Partial<LegendOptions>): void {\n this._options = { ...this._options, ...options };\n if (options.items) this._state.items = [...options.items];\n if (options.visible !== undefined) this._state.visible = options.visible;\n if (options.collapsed !== undefined) this._state.collapsed = options.collapsed;\n this._render();\n this._emit('update');\n }\n\n /**\n * Gets the current state.\n *\n * @returns The current legend state.\n */\n getState(): LegendState {\n return { ...this._state, items: [...this._state.items] };\n }\n\n /**\n * Registers an event handler.\n *\n * @param event - The event type to listen for.\n * @param handler - The callback function.\n */\n on(event: ComponentEvent, handler: ComponentEventHandler<LegendState>): void {\n if (!this._eventHandlers.has(event)) {\n this._eventHandlers.set(event, new Set());\n }\n this._eventHandlers.get(event)!.add(handler);\n }\n\n /**\n * Removes an event handler.\n *\n * @param event - The event type.\n * @param handler - The callback function to remove.\n */\n off(event: ComponentEvent, handler: ComponentEventHandler<LegendState>): void {\n this._eventHandlers.get(event)?.delete(handler);\n }\n\n /**\n * Emits an event to all registered handlers.\n *\n * @param event - The event type to emit.\n */\n private _emit(event: ComponentEvent): void {\n const handlers = this._eventHandlers.get(event);\n if (handlers) {\n const eventData = { type: event, state: this.getState() };\n handlers.forEach((handler) => handler(eventData));\n }\n }\n\n /**\n * Checks if the current zoom level is within the visibility range.\n */\n private _checkZoomVisibility(): void {\n if (!this._map) return;\n\n const zoom = this._map.getZoom();\n const { minzoom, maxzoom } = this._options;\n const inRange = zoom >= minzoom && zoom <= maxzoom;\n\n if (inRange !== this._zoomVisible) {\n this._zoomVisible = inRange;\n this._updateDisplayState();\n }\n }\n\n /**\n * Updates the display state based on visibility and zoom level.\n */\n private _updateDisplayState(): void {\n if (!this._container) return;\n const shouldShow = this._state.visible && this._zoomVisible;\n this._container.style.display = shouldShow ? 'block' : 'none';\n }\n\n /**\n * Creates the main container element.\n *\n * @returns The container element.\n */\n private _createContainer(): HTMLElement {\n const container = document.createElement('div');\n container.className = `maplibregl-ctrl maplibre-gl-legend${\n this._options.className ? ` ${this._options.className}` : ''\n }`;\n\n const shouldShow = this._state.visible && this._zoomVisible;\n if (!shouldShow) {\n container.style.display = 'none';\n }\n\n return container;\n }\n\n /**\n * Creates a color swatch element.\n *\n * @param item - Legend item configuration.\n * @returns The swatch element.\n */\n private _createSwatch(item: LegendItem): HTMLElement {\n const { swatchSize = 16 } = this._options;\n const shape = item.shape || 'square';\n const swatch = document.createElement('span');\n swatch.className = `maplibre-gl-legend-swatch maplibre-gl-legend-swatch-${shape}`;\n\n // Base styles\n const baseStyles: Record<string, string> = {\n flexShrink: '0',\n display: 'inline-block',\n };\n\n if (shape === 'line') {\n // Line shape: horizontal line with rounded ends\n Object.assign(swatch.style, {\n ...baseStyles,\n width: `${swatchSize}px`,\n height: '4px',\n backgroundColor: item.color,\n borderRadius: '2px',\n border: 'none',\n alignSelf: 'center',\n });\n } else if (shape === 'circle') {\n // Circle shape\n Object.assign(swatch.style, {\n ...baseStyles,\n width: `${swatchSize}px`,\n height: `${swatchSize}px`,\n backgroundColor: item.color,\n borderRadius: '50%',\n border: item.strokeColor ? `2px solid ${item.strokeColor}` : '1px solid rgba(0,0,0,0.1)',\n });\n } else {\n // Square shape (default)\n Object.assign(swatch.style, {\n ...baseStyles,\n width: `${swatchSize}px`,\n height: `${swatchSize}px`,\n backgroundColor: item.color,\n borderRadius: '2px',\n border: item.strokeColor ? `2px solid ${item.strokeColor}` : '1px solid rgba(0,0,0,0.1)',\n });\n }\n\n // If icon is provided, use background image\n if (item.icon) {\n Object.assign(swatch.style, {\n backgroundImage: `url(${item.icon})`,\n backgroundSize: 'contain',\n backgroundRepeat: 'no-repeat',\n backgroundPosition: 'center',\n backgroundColor: 'transparent',\n border: 'none',\n width: `${swatchSize}px`,\n height: `${swatchSize}px`,\n });\n }\n\n return swatch;\n }\n\n /**\n * Renders the legend content.\n */\n private _render(): void {\n if (!this._container) return;\n\n const {\n title,\n backgroundColor,\n opacity,\n fontSize,\n fontColor,\n borderRadius,\n padding,\n width,\n maxHeight,\n collapsible,\n } = this._options;\n\n // Clear existing content\n this._container.innerHTML = '';\n\n // Apply container styles\n // When collapsed with header, use minimal vertical padding to match HtmlControl\n const isCollapsedWithHeader = this._state.collapsed && (title || collapsible);\n const vertPadding = isCollapsedWithHeader ? 4 : padding;\n const shouldShow = this._state.visible && this._zoomVisible;\n Object.assign(this._container.style, {\n backgroundColor,\n opacity: opacity.toString(),\n borderRadius: `${borderRadius}px`,\n padding: `${vertPadding}px ${padding}px`,\n fontSize: `${fontSize}px`,\n color: fontColor,\n width: isCollapsedWithHeader ? 'auto' : `${width}px`,\n maxWidth: `${width}px`,\n boxShadow: '0 0 0 2px rgba(0, 0, 0, 0.1)',\n display: shouldShow ? 'block' : 'none',\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n });\n\n // Add title/header\n if (title || collapsible) {\n const header = document.createElement('div');\n header.className = 'maplibre-gl-legend-header';\n Object.assign(header.style, {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n paddingBottom: this._state.collapsed ? '0' : '4px',\n cursor: collapsible ? 'pointer' : 'default',\n });\n\n if (title) {\n const titleEl = document.createElement('span');\n titleEl.className = 'maplibre-gl-legend-title';\n titleEl.textContent = title;\n titleEl.style.fontWeight = '600';\n header.appendChild(titleEl);\n }\n\n if (collapsible) {\n const toggleBtn = document.createElement('span');\n toggleBtn.className = 'maplibre-gl-legend-toggle';\n toggleBtn.innerHTML = this._state.collapsed ? '▶' : '▼';\n toggleBtn.style.marginLeft = '8px';\n header.appendChild(toggleBtn);\n header.addEventListener('click', () => this.toggle());\n }\n\n this._container.appendChild(header);\n }\n\n // Content area\n const content = document.createElement('div');\n content.className = 'maplibre-gl-legend-content';\n Object.assign(content.style, {\n maxHeight: `${maxHeight}px`,\n overflowY: 'auto',\n display: this._state.collapsed ? 'none' : 'block',\n });\n\n // Render legend items\n this._state.items.forEach((item) => {\n const row = document.createElement('div');\n row.className = 'maplibre-gl-legend-item';\n Object.assign(row.style, {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n padding: '4px 0',\n });\n\n const swatch = this._createSwatch(item);\n const label = document.createElement('span');\n label.className = 'maplibre-gl-legend-label';\n label.textContent = item.label;\n\n row.appendChild(swatch);\n row.appendChild(label);\n content.appendChild(row);\n });\n\n this._container.appendChild(content);\n }\n}\n","import type { IControl, Map as MapLibreMap } from 'maplibre-gl';\nimport type {\n HtmlControlOptions,\n HtmlControlState,\n ComponentEvent,\n ComponentEventHandler,\n} from './types';\n\n/**\n * Default options for the HtmlControl.\n */\nconst DEFAULT_OPTIONS: Required<Omit<HtmlControlOptions, 'element'>> & { element?: HTMLElement } = {\n html: '',\n element: undefined,\n title: '',\n position: 'top-left',\n className: '',\n visible: true,\n collapsible: false,\n collapsed: false,\n backgroundColor: 'rgba(255, 255, 255, 0.9)',\n padding: 10,\n borderRadius: 4,\n opacity: 1,\n maxWidth: 300,\n maxHeight: 400,\n fontSize: 12,\n fontColor: '#333',\n minzoom: 0,\n maxzoom: 24,\n};\n\n/**\n * A flexible HTML content control for MapLibre GL maps.\n *\n * Allows displaying arbitrary HTML content that can be dynamically updated.\n * Supports collapsible mode with a toggle button.\n *\n * @example\n * ```typescript\n * const htmlControl = new HtmlControl({\n * html: '<div><strong>Stats:</strong> 1,234 features</div>',\n * position: 'top-left',\n * collapsible: true,\n * title: 'Statistics',\n * });\n * map.addControl(htmlControl, 'top-left');\n *\n * // Update content dynamically\n * htmlControl.setHtml('<div><strong>Stats:</strong> 5,678 features</div>');\n * ```\n */\nexport class HtmlControl implements IControl {\n private _container?: HTMLElement;\n private _contentEl?: HTMLElement;\n private _options: Required<Omit<HtmlControlOptions, 'element'>> & { element?: HTMLElement };\n private _state: HtmlControlState;\n private _eventHandlers: Map<ComponentEvent, Set<ComponentEventHandler<HtmlControlState>>> =\n new Map();\n private _map?: MapLibreMap;\n private _handleZoom?: () => void;\n private _zoomVisible: boolean = true;\n\n /**\n * Creates a new HtmlControl instance.\n *\n * @param options - Configuration options for the control.\n */\n constructor(options?: HtmlControlOptions) {\n this._options = { ...DEFAULT_OPTIONS, ...options };\n this._state = {\n visible: this._options.visible,\n collapsed: this._options.collapsed,\n html: this._options.html,\n };\n }\n\n /**\n * Called when the control is added to the map.\n * Implements the IControl interface.\n *\n * @param map - The MapLibre GL map instance.\n * @returns The control's container element.\n */\n onAdd(map: MapLibreMap): HTMLElement {\n this._map = map;\n this._container = this._createContainer();\n this._render();\n\n // Set up zoom listener\n this._handleZoom = () => this._checkZoomVisibility();\n this._map.on('zoom', this._handleZoom);\n\n // Check initial zoom\n this._checkZoomVisibility();\n\n return this._container;\n }\n\n /**\n * Called when the control is removed from the map.\n * Implements the IControl interface.\n */\n onRemove(): void {\n if (this._map && this._handleZoom) {\n this._map.off('zoom', this._handleZoom);\n this._handleZoom = undefined;\n }\n this._map = undefined;\n this._container?.parentNode?.removeChild(this._container);\n this._container = undefined;\n this._contentEl = undefined;\n this._eventHandlers.clear();\n }\n\n /**\n * Shows the control.\n */\n show(): void {\n if (!this._state.visible) {\n this._state.visible = true;\n this._updateDisplayState();\n this._emit('show');\n }\n }\n\n /**\n * Hides the control.\n */\n hide(): void {\n if (this._state.visible) {\n this._state.visible = false;\n this._updateDisplayState();\n this._emit('hide');\n }\n }\n\n /**\n * Expands the control (if collapsible).\n */\n expand(): void {\n if (this._state.collapsed) {\n this._state.collapsed = false;\n this._render();\n this._emit('expand');\n }\n }\n\n /**\n * Collapses the control (if collapsible).\n */\n collapse(): void {\n if (!this._state.collapsed) {\n this._state.collapsed = true;\n this._render();\n this._emit('collapse');\n }\n }\n\n /**\n * Toggles the collapsed state.\n */\n toggle(): void {\n if (this._state.collapsed) {\n this.expand();\n } else {\n this.collapse();\n }\n }\n\n /**\n * Sets the HTML content.\n *\n * @param html - The HTML string to display.\n */\n setHtml(html: string): void {\n this._state.html = html;\n this._options.html = html;\n this._options.element = undefined; // Clear element when setting HTML\n if (this._contentEl) {\n this._contentEl.innerHTML = html;\n }\n this._emit('update');\n }\n\n /**\n * Sets a DOM element as content.\n *\n * @param element - The DOM element to display.\n */\n setElement(element: HTMLElement): void {\n this._options.element = element;\n this._options.html = '';\n this._state.html = '';\n if (this._contentEl) {\n this._contentEl.innerHTML = '';\n this._contentEl.appendChild(element);\n }\n this._emit('update');\n }\n\n /**\n * Gets the content container element.\n *\n * @returns The content container element, or undefined if not yet added to map.\n */\n getElement(): HTMLElement | undefined {\n return this._contentEl;\n }\n\n /**\n * Updates control options and re-renders.\n *\n * @param options - Partial options to update.\n */\n update(options: Partial<HtmlControlOptions>): void {\n this._options = { ...this._options, ...options };\n if (options.html !== undefined) this._state.html = options.html;\n if (options.visible !== undefined) this._state.visible = options.visible;\n if (options.collapsed !== undefined) this._state.collapsed = options.collapsed;\n this._render();\n this._emit('update');\n }\n\n /**\n * Gets the current state.\n *\n * @returns The current control state.\n */\n getState(): HtmlControlState {\n return { ...this._state };\n }\n\n /**\n * Registers an event handler.\n *\n * @param event - The event type to listen for.\n * @param handler - The callback function.\n */\n on(event: ComponentEvent, handler: ComponentEventHandler<HtmlControlState>): void {\n if (!this._eventHandlers.has(event)) {\n this._eventHandlers.set(event, new Set());\n }\n this._eventHandlers.get(event)!.add(handler);\n }\n\n /**\n * Removes an event handler.\n *\n * @param event - The event type.\n * @param handler - The callback function to remove.\n */\n off(event: ComponentEvent, handler: ComponentEventHandler<HtmlControlState>): void {\n this._eventHandlers.get(event)?.delete(handler);\n }\n\n /**\n * Emits an event to all registered handlers.\n *\n * @param event - The event type to emit.\n */\n private _emit(event: ComponentEvent): void {\n const handlers = this._eventHandlers.get(event);\n if (handlers) {\n const eventData = { type: event, state: this.getState() };\n handlers.forEach((handler) => handler(eventData));\n }\n }\n\n /**\n * Checks if the current zoom level is within the visibility range.\n */\n private _checkZoomVisibility(): void {\n if (!this._map) return;\n\n const zoom = this._map.getZoom();\n const { minzoom, maxzoom } = this._options;\n const inRange = zoom >= minzoom && zoom <= maxzoom;\n\n if (inRange !== this._zoomVisible) {\n this._zoomVisible = inRange;\n this._updateDisplayState();\n }\n }\n\n /**\n * Updates the display state based on visibility and zoom level.\n */\n private _updateDisplayState(): void {\n if (!this._container) return;\n const shouldShow = this._state.visible && this._zoomVisible;\n this._container.style.display = shouldShow ? 'block' : 'none';\n }\n\n /**\n * Creates the main container element.\n *\n * @returns The container element.\n */\n private _createContainer(): HTMLElement {\n const container = document.createElement('div');\n container.className = `maplibregl-ctrl maplibre-gl-html-control${\n this._options.className ? ` ${this._options.className}` : ''\n }`;\n\n const shouldShow = this._state.visible && this._zoomVisible;\n if (!shouldShow) {\n container.style.display = 'none';\n }\n\n return container;\n }\n\n /**\n * Renders the control content.\n */\n private _render(): void {\n if (!this._container) return;\n\n const {\n title = '',\n collapsible = false,\n backgroundColor = 'rgba(255, 255, 255, 0.9)',\n opacity = 1,\n borderRadius = 4,\n padding = 10,\n maxWidth = 300,\n maxHeight = 400,\n fontSize = 12,\n fontColor = '#333',\n } = this._options;\n\n // Clear existing content\n this._container.innerHTML = '';\n\n // Apply container styles\n // When collapsed with header, use minimal vertical padding\n const isCollapsedWithHeader = this._state.collapsed && (title || collapsible);\n const vertPadding = isCollapsedWithHeader ? 4 : padding;\n const shouldShow = this._state.visible && this._zoomVisible;\n Object.assign(this._container.style, {\n backgroundColor,\n opacity: String(opacity),\n borderRadius: `${borderRadius}px`,\n padding: `${vertPadding}px ${padding}px`,\n maxWidth: `${maxWidth}px`,\n fontSize: `${fontSize}px`,\n color: fontColor,\n boxShadow: '0 0 0 2px rgba(0, 0, 0, 0.1)',\n display: shouldShow ? 'block' : 'none',\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n });\n\n // Add header with toggle if collapsible\n if (collapsible || title) {\n const header = document.createElement('div');\n header.className = 'maplibre-gl-html-control-header';\n Object.assign(header.style, {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n paddingBottom: this._state.collapsed ? '0' : '8px',\n cursor: collapsible ? 'pointer' : 'default',\n });\n\n if (title) {\n const titleEl = document.createElement('span');\n titleEl.className = 'maplibre-gl-html-control-title';\n titleEl.textContent = title;\n titleEl.style.fontWeight = '600';\n header.appendChild(titleEl);\n }\n\n if (collapsible) {\n const toggleBtn = document.createElement('span');\n toggleBtn.className = 'maplibre-gl-html-control-toggle';\n toggleBtn.innerHTML = this._state.collapsed ? '▶' : '▼';\n Object.assign(toggleBtn.style, {\n marginLeft: '8px',\n fontSize: '10px',\n userSelect: 'none',\n });\n header.appendChild(toggleBtn);\n header.addEventListener('click', () => this.toggle());\n }\n\n this._container.appendChild(header);\n }\n\n // Create content element\n const content = document.createElement('div');\n content.className = 'maplibre-gl-html-control-content';\n Object.assign(content.style, {\n maxHeight: `${maxHeight}px`,\n overflowY: 'auto',\n display: this._state.collapsed ? 'none' : 'block',\n });\n this._contentEl = content;\n\n // Set content\n if (this._options.element) {\n content.appendChild(this._options.element);\n } else if (this._options.html) {\n content.innerHTML = this._options.html;\n }\n\n this._container.appendChild(content);\n }\n}\n","import type { IControl, Map as MapLibreMap } from 'maplibre-gl';\nimport type {\n BasemapControlOptions,\n BasemapControlState,\n BasemapItem,\n BasemapEvent,\n ComponentEvent,\n} from './types';\nimport {\n XYZSERVICES_URL,\n parseProviders,\n buildTileUrl,\n groupBasemaps,\n filterBasemaps,\n GOOGLE_BASEMAPS,\n} from '../utils/providers';\n\n/**\n * Event handler type for basemap events.\n */\ntype BasemapEventHandler = (event: { type: BasemapEvent; state: BasemapControlState; basemap?: BasemapItem }) => void;\n\n/**\n * Default options for the BasemapControl.\n */\nconst DEFAULT_OPTIONS: Required<Omit<BasemapControlOptions, 'basemaps' | 'filterGroups' | 'excludeGroups' | 'beforeId'>> & {\n basemaps: BasemapItem[];\n filterGroups: string[] | undefined;\n excludeGroups: string[] | undefined;\n beforeId: string | undefined;\n} = {\n basemaps: [],\n providersUrl: XYZSERVICES_URL,\n defaultBasemap: '',\n position: 'top-right',\n className: '',\n visible: true,\n collapsible: true,\n collapsed: true,\n displayMode: 'dropdown',\n showSearch: true,\n filterGroups: undefined,\n excludeGroups: undefined,\n excludeBroken: true,\n backgroundColor: 'rgba(255, 255, 255, 0.9)',\n padding: 10,\n borderRadius: 4,\n opacity: 1,\n maxWidth: 250,\n maxHeight: 300,\n fontSize: 12,\n fontColor: '#333',\n minzoom: 0,\n maxzoom: 24,\n beforeId: undefined,\n belowLabels: false,\n};\n\n/**\n * Source and layer IDs for the basemap raster layer.\n */\nconst BASEMAP_SOURCE_ID = 'basemap-raster-source';\nconst BASEMAP_LAYER_ID = 'basemap-raster-layer';\n\n/**\n * A basemap switcher control for MapLibre GL maps.\n *\n * Allows users to interactively switch between different basemap tile sources.\n * Supports loading basemaps from xyzservices or custom basemap arrays.\n *\n * @example\n * ```typescript\n * const basemapControl = new BasemapControl({\n * defaultBasemap: 'OpenStreetMap.Mapnik',\n * showSearch: true,\n * filterGroups: ['OpenStreetMap', 'CartoDB', 'Stadia'],\n * });\n * map.addControl(basemapControl, 'top-right');\n * ```\n */\nexport class BasemapControl implements IControl {\n private _container?: HTMLElement;\n private _options: typeof DEFAULT_OPTIONS;\n private _state: BasemapControlState;\n private _basemaps: BasemapItem[] = [];\n private _eventHandlers: Map<BasemapEvent, Set<BasemapEventHandler>> = new Map();\n private _map?: MapLibreMap;\n private _handleZoom?: () => void;\n private _zoomVisible: boolean = true;\n\n /**\n * Creates a new BasemapControl instance.\n *\n * @param options - Configuration options for the control.\n */\n constructor(options?: BasemapControlOptions) {\n this._options = { ...DEFAULT_OPTIONS, ...options };\n this._state = {\n visible: this._options.visible,\n collapsed: this._options.collapsed,\n selectedBasemap: this._options.defaultBasemap || null,\n searchText: '',\n loading: false,\n error: null,\n belowLabels: this._options.belowLabels,\n };\n\n // Use provided basemaps if any\n if (this._options.basemaps.length > 0) {\n this._basemaps = [...this._options.basemaps];\n }\n }\n\n /**\n * Called when the control is added to the map.\n *\n * @param map - The MapLibre GL map instance.\n * @returns The control's container element.\n */\n onAdd(map: MapLibreMap): HTMLElement {\n this._map = map;\n this._container = this._createContainer();\n\n // Fetch providers if no basemaps provided\n if (this._basemaps.length === 0 && this._options.providersUrl) {\n this._fetchProviders();\n } else {\n this._render();\n // Apply initial basemap if specified\n if (this._state.selectedBasemap) {\n const basemap = this._basemaps.find((b) => b.id === this._state.selectedBasemap);\n if (basemap) {\n this._applyBasemap(basemap);\n }\n }\n }\n\n // Set up zoom listener\n this._handleZoom = () => this._checkZoomVisibility();\n this._map.on('zoom', this._handleZoom);\n this._checkZoomVisibility();\n\n return this._container;\n }\n\n /**\n * Called when the control is removed from the map.\n */\n onRemove(): void {\n if (this._map && this._handleZoom) {\n this._map.off('zoom', this._handleZoom);\n this._handleZoom = undefined;\n }\n\n // Remove basemap layer and source\n this._removeBasemapLayer();\n\n this._map = undefined;\n this._container?.parentNode?.removeChild(this._container);\n this._container = undefined;\n this._eventHandlers.clear();\n }\n\n /**\n * Shows the control.\n */\n show(): void {\n if (!this._state.visible) {\n this._state.visible = true;\n this._updateDisplayState();\n this._emit('show');\n }\n }\n\n /**\n * Hides the control.\n */\n hide(): void {\n if (this._state.visible) {\n this._state.visible = false;\n this._updateDisplayState();\n this._emit('hide');\n }\n }\n\n /**\n * Expands the control (if collapsible).\n */\n expand(): void {\n if (this._state.collapsed) {\n this._state.collapsed = false;\n this._render();\n this._emit('expand');\n }\n }\n\n /**\n * Collapses the control (if collapsible).\n */\n collapse(): void {\n if (!this._state.collapsed) {\n this._state.collapsed = true;\n this._render();\n this._emit('collapse');\n }\n }\n\n /**\n * Toggles the collapsed state.\n */\n toggle(): void {\n if (this._state.collapsed) {\n this.expand();\n } else {\n this.collapse();\n }\n }\n\n /**\n * Sets the active basemap by ID.\n *\n * @param basemapId - The ID of the basemap to activate.\n */\n setBasemap(basemapId: string): void {\n const basemap = this._basemaps.find((b) => b.id === basemapId);\n if (basemap) {\n this._state.selectedBasemap = basemapId;\n this._applyBasemap(basemap);\n this._render();\n this._emit('basemapchange', basemap);\n this._emit('update');\n }\n }\n\n /**\n * Gets the list of available basemaps.\n *\n * @returns Array of basemap items.\n */\n getBasemaps(): BasemapItem[] {\n return [...this._basemaps];\n }\n\n /**\n * Adds a custom basemap.\n *\n * @param basemap - The basemap item to add.\n */\n addBasemap(basemap: BasemapItem): void {\n this._basemaps.push(basemap);\n this._render();\n }\n\n /**\n * Removes a basemap by ID.\n *\n * @param basemapId - The ID of the basemap to remove.\n */\n removeBasemap(basemapId: string): void {\n this._basemaps = this._basemaps.filter((b) => b.id !== basemapId);\n this._render();\n }\n\n /**\n * Sets an API key for a basemap.\n *\n * @param basemapId - The ID of the basemap.\n * @param apiKey - The API key to set.\n */\n setApiKey(basemapId: string, apiKey: string): void {\n const basemap = this._basemaps.find((b) => b.id === basemapId);\n if (basemap) {\n basemap.apiKey = apiKey;\n basemap.requiresApiKey = false;\n }\n }\n\n /**\n * Updates control options and re-renders.\n *\n * @param options - Partial options to update.\n */\n update(options: Partial<BasemapControlOptions>): void {\n this._options = { ...this._options, ...options };\n if (options.basemaps) {\n this._basemaps = [...options.basemaps];\n }\n if (options.visible !== undefined) this._state.visible = options.visible;\n if (options.collapsed !== undefined) this._state.collapsed = options.collapsed;\n this._render();\n this._emit('update');\n }\n\n /**\n * Gets the current state.\n *\n * @returns The current control state.\n */\n getState(): BasemapControlState {\n return { ...this._state };\n }\n\n /**\n * Gets the currently selected basemap.\n *\n * @returns The selected basemap item, or null if none selected.\n */\n getSelectedBasemap(): BasemapItem | null {\n if (!this._state.selectedBasemap) return null;\n return this._basemaps.find((b) => b.id === this._state.selectedBasemap) || null;\n }\n\n /**\n * Registers an event handler.\n *\n * @param event - The event type to listen for.\n * @param handler - The callback function.\n */\n on(event: BasemapEvent, handler: BasemapEventHandler): void {\n if (!this._eventHandlers.has(event)) {\n this._eventHandlers.set(event, new Set());\n }\n this._eventHandlers.get(event)!.add(handler);\n }\n\n /**\n * Removes an event handler.\n *\n * @param event - The event type.\n * @param handler - The callback function to remove.\n */\n off(event: BasemapEvent, handler: BasemapEventHandler): void {\n this._eventHandlers.get(event)?.delete(handler);\n }\n\n /**\n * Emits an event to all registered handlers.\n */\n private _emit(event: ComponentEvent | 'basemapchange', basemap?: BasemapItem): void {\n const handlers = this._eventHandlers.get(event);\n if (handlers) {\n const eventData = { type: event, state: this.getState(), basemap };\n handlers.forEach((handler) => handler(eventData));\n }\n }\n\n /**\n * Fetches providers from the xyzservices URL.\n */\n private async _fetchProviders(): Promise<void> {\n this._state.loading = true;\n this._state.error = null;\n this._render();\n\n try {\n const response = await fetch(this._options.providersUrl);\n if (!response.ok) {\n throw new Error(`Failed to fetch: ${response.statusText}`);\n }\n const data = await response.json();\n\n this._basemaps = parseProviders(data, {\n filterGroups: this._options.filterGroups,\n excludeGroups: this._options.excludeGroups,\n excludeBroken: this._options.excludeBroken,\n });\n\n // Add Google basemaps if not excluded\n const shouldIncludeGoogle =\n !this._options.excludeGroups?.includes('Google') &&\n (!this._options.filterGroups?.length || this._options.filterGroups.includes('Google'));\n\n if (shouldIncludeGoogle) {\n this._basemaps = [...this._basemaps, ...GOOGLE_BASEMAPS];\n }\n\n this._state.loading = false;\n this._state.error = null;\n\n // Apply initial basemap if specified\n if (this._state.selectedBasemap) {\n const basemap = this._basemaps.find((b) => b.id === this._state.selectedBasemap);\n if (basemap) {\n this._applyBasemap(basemap);\n }\n }\n } catch (error) {\n this._state.loading = false;\n this._state.error = error instanceof Error ? error.message : 'Failed to load providers';\n console.error('BasemapControl: Failed to fetch providers', error);\n }\n\n this._render();\n }\n\n /**\n * Applies a basemap to the map.\n */\n private _applyBasemap(basemap: BasemapItem): void {\n if (!this._map) return;\n\n // Check if basemap requires API key\n if (basemap.requiresApiKey && !basemap.apiKey) {\n console.warn(`BasemapControl: Basemap \"${basemap.name}\" requires an API key`);\n return;\n }\n\n if (basemap.style) {\n // Vector style - use setStyle\n this._applyStyleBasemap(basemap);\n } else if (basemap.url) {\n // XYZ tiles - add as raster source/layer\n this._applyXYZBasemap(basemap);\n }\n }\n\n /**\n * Applies an XYZ tile basemap.\n */\n private _applyXYZBasemap(basemap: BasemapItem): void {\n if (!this._map) return;\n\n // Remove existing basemap layer\n this._removeBasemapLayer();\n\n // Build the tile URL\n const tileUrl = buildTileUrl(basemap);\n\n // Add raster source\n this._map.addSource(BASEMAP_SOURCE_ID, {\n type: 'raster',\n tiles: [tileUrl],\n tileSize: 256,\n attribution: basemap.attribution,\n maxzoom: basemap.maxZoom || 19,\n minzoom: basemap.minZoom || 0,\n });\n\n // Find the layer to insert before\n let beforeLayerId: string | undefined;\n if (this._state.belowLabels) {\n // Find the first symbol layer to insert basemap below labels\n const layers = this._map.getStyle()?.layers;\n if (layers) {\n for (const layer of layers) {\n if (layer.type === 'symbol') {\n beforeLayerId = layer.id;\n break;\n }\n }\n }\n }\n\n // Add raster layer\n this._map.addLayer(\n {\n id: BASEMAP_LAYER_ID,\n type: 'raster',\n source: BASEMAP_SOURCE_ID,\n },\n beforeLayerId\n );\n }\n\n /**\n * Applies a vector style basemap.\n */\n private _applyStyleBasemap(basemap: BasemapItem): void {\n if (!this._map || !basemap.style) return;\n\n // Remove existing basemap layer first\n this._removeBasemapLayer();\n\n // For style-based basemaps, we need to be careful about preserving user layers\n // This is a simplified approach - for full layer preservation, more complex logic is needed\n this._map.setStyle(basemap.style);\n }\n\n /**\n * Removes the basemap layer and source.\n */\n private _removeBasemapLayer(): void {\n if (!this._map) return;\n\n if (this._map.getLayer(BASEMAP_LAYER_ID)) {\n this._map.removeLayer(BASEMAP_LAYER_ID);\n }\n if (this._map.getSource(BASEMAP_SOURCE_ID)) {\n this._map.removeSource(BASEMAP_SOURCE_ID);\n }\n }\n\n /**\n * Checks if the current zoom level is within the visibility range.\n */\n private _checkZoomVisibility(): void {\n if (!this._map) return;\n\n const zoom = this._map.getZoom();\n const { minzoom, maxzoom } = this._options;\n const inRange = zoom >= minzoom && zoom <= maxzoom;\n\n if (inRange !== this._zoomVisible) {\n this._zoomVisible = inRange;\n this._updateDisplayState();\n }\n }\n\n /**\n * Updates the display state based on visibility and zoom level.\n */\n private _updateDisplayState(): void {\n if (!this._container) return;\n const shouldShow = this._state.visible && this._zoomVisible;\n this._container.style.display = shouldShow ? 'block' : 'none';\n }\n\n /**\n * Creates the main container element.\n */\n private _createContainer(): HTMLElement {\n const container = document.createElement('div');\n container.className = `maplibregl-ctrl maplibre-gl-basemap${\n this._options.className ? ` ${this._options.className}` : ''\n }`;\n\n const shouldShow = this._state.visible && this._zoomVisible;\n if (!shouldShow) {\n container.style.display = 'none';\n }\n\n return container;\n }\n\n /**\n * Renders the control content.\n */\n private _render(): void {\n if (!this._container) return;\n\n const {\n backgroundColor,\n opacity,\n fontSize,\n fontColor,\n borderRadius,\n padding,\n maxWidth,\n maxHeight,\n collapsible,\n displayMode,\n showSearch,\n } = this._options;\n\n // Save scroll position before clearing content\n const contentEl = this._container.querySelector('.maplibre-gl-basemap-content');\n const scrollTop = contentEl ? contentEl.scrollTop : 0;\n\n // Clear existing content\n this._container.innerHTML = '';\n\n const shouldShow = this._state.visible && this._zoomVisible;\n\n // When collapsed and collapsible, show only icon button\n if (collapsible && this._state.collapsed) {\n Object.assign(this._container.style, {\n backgroundColor,\n opacity: opacity.toString(),\n borderRadius: `${borderRadius}px`,\n boxShadow: '0 0 0 2px rgba(0, 0, 0, 0.1)',\n display: shouldShow ? 'block' : 'none',\n padding: '0',\n maxWidth: 'none',\n });\n\n const iconButton = this._createIconButton();\n this._container.appendChild(iconButton);\n return;\n }\n\n // Apply container styles for expanded state\n Object.assign(this._container.style, {\n backgroundColor,\n opacity: opacity.toString(),\n borderRadius: `${borderRadius}px`,\n fontSize: `${fontSize}px`,\n color: fontColor,\n maxWidth: `${maxWidth}px`,\n boxShadow: '0 0 0 2px rgba(0, 0, 0, 0.1)',\n display: shouldShow ? 'block' : 'none',\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n position: 'relative',\n padding: '0',\n });\n\n // Header with close button\n if (collapsible) {\n const header = this._createHeader();\n this._container.appendChild(header);\n }\n\n // Content\n const content = document.createElement('div');\n content.className = 'maplibre-gl-basemap-content';\n Object.assign(content.style, {\n padding: `0 ${padding}px ${padding}px ${padding}px`,\n maxHeight: `${maxHeight}px`,\n overflowY: 'auto',\n });\n\n // Loading state\n if (this._state.loading) {\n const loading = document.createElement('div');\n loading.className = 'maplibre-gl-basemap-loading';\n loading.textContent = 'Loading basemaps...';\n Object.assign(loading.style, {\n padding: '20px',\n textAlign: 'center',\n color: '#666',\n });\n content.appendChild(loading);\n }\n // Error state\n else if (this._state.error) {\n const error = document.createElement('div');\n error.className = 'maplibre-gl-basemap-error';\n error.textContent = this._state.error;\n Object.assign(error.style, {\n padding: '10px',\n color: '#d32f2f',\n fontSize: '0.9em',\n });\n content.appendChild(error);\n }\n // Normal content\n else {\n // Search input\n if (showSearch && this._basemaps.length > 5) {\n const searchInput = this._createSearchInput();\n content.appendChild(searchInput);\n }\n\n // Below labels checkbox\n const checkboxContainer = this._createBelowLabelsCheckbox();\n content.appendChild(checkboxContainer);\n\n // Basemap list - always use list mode when panel is expanded\n // (dropdown mode only affects collapsed icon behavior)\n const filteredBasemaps = filterBasemaps(this._basemaps, this._state.searchText);\n\n if (displayMode === 'gallery') {\n const gallery = this._renderGallery(filteredBasemaps);\n content.appendChild(gallery);\n } else {\n // Both 'dropdown' and 'list' modes show a scrollable list when expanded\n const list = this._renderList(filteredBasemaps);\n content.appendChild(list);\n }\n }\n\n this._container.appendChild(content);\n\n // Restore scroll position\n if (scrollTop > 0) {\n content.scrollTop = scrollTop;\n }\n }\n\n /**\n * Creates the icon button for collapsed state.\n */\n private _createIconButton(): HTMLElement {\n const button = document.createElement('button');\n button.className = 'maplibre-gl-basemap-icon-button';\n button.title = 'Basemaps';\n\n // Map icon SVG (folded map with pin)\n button.innerHTML = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polygon points=\"1 6 1 22 8 18 16 22 23 18 23 2 16 6 8 2 1 6\"></polygon>\n <line x1=\"8\" y1=\"2\" x2=\"8\" y2=\"18\"></line>\n <line x1=\"16\" y1=\"6\" x2=\"16\" y2=\"22\"></line>\n </svg>\n `;\n\n Object.assign(button.style, {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '29px',\n height: '29px',\n padding: '0',\n border: 'none',\n background: 'transparent',\n cursor: 'pointer',\n color: '#333',\n });\n\n button.addEventListener('click', (e) => {\n e.stopPropagation();\n this.expand();\n });\n\n button.addEventListener('mouseenter', () => {\n button.style.color = '#0078d7';\n });\n\n button.addEventListener('mouseleave', () => {\n button.style.color = '#333';\n });\n\n return button;\n }\n\n /**\n * Creates the header element.\n */\n private _createHeader(): HTMLElement {\n const { padding } = this._options;\n\n const header = document.createElement('div');\n header.className = 'maplibre-gl-basemap-header';\n Object.assign(header.style, {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: `${padding}px`,\n borderBottom: '1px solid rgba(0,0,0,0.1)',\n });\n\n const title = document.createElement('span');\n title.className = 'maplibre-gl-basemap-title';\n title.textContent = 'Basemaps';\n title.style.fontWeight = '600';\n header.appendChild(title);\n\n // Close button\n const closeBtn = document.createElement('button');\n closeBtn.className = 'maplibre-gl-basemap-close';\n closeBtn.title = 'Close';\n closeBtn.innerHTML = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n </svg>\n `;\n Object.assign(closeBtn.style, {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '24px',\n height: '24px',\n padding: '0',\n border: 'none',\n background: 'transparent',\n cursor: 'pointer',\n color: '#666',\n borderRadius: '4px',\n });\n\n closeBtn.addEventListener('click', (e) => {\n e.stopPropagation();\n this.collapse();\n });\n\n closeBtn.addEventListener('mouseenter', () => {\n closeBtn.style.background = 'rgba(0,0,0,0.1)';\n closeBtn.style.color = '#333';\n });\n\n closeBtn.addEventListener('mouseleave', () => {\n closeBtn.style.background = 'transparent';\n closeBtn.style.color = '#666';\n });\n\n header.appendChild(closeBtn);\n\n return header;\n }\n\n /**\n * Creates the search input element.\n */\n private _createSearchInput(): HTMLElement {\n const container = document.createElement('div');\n container.style.marginBottom = '8px';\n\n const input = document.createElement('input');\n input.type = 'text';\n input.placeholder = 'Search basemaps...';\n input.className = 'maplibre-gl-basemap-search';\n input.value = this._state.searchText;\n Object.assign(input.style, {\n width: '100%',\n padding: '6px 10px',\n border: '1px solid #ddd',\n borderRadius: '4px',\n fontSize: 'inherit',\n boxSizing: 'border-box',\n });\n\n input.addEventListener('input', (e) => {\n this._state.searchText = (e.target as HTMLInputElement).value;\n this._render();\n });\n\n input.addEventListener('click', (e) => {\n e.stopPropagation();\n });\n\n container.appendChild(input);\n return container;\n }\n\n /**\n * Creates the below labels checkbox element.\n */\n private _createBelowLabelsCheckbox(): HTMLElement {\n const container = document.createElement('div');\n container.className = 'maplibre-gl-basemap-checkbox';\n Object.assign(container.style, {\n display: 'flex',\n alignItems: 'center',\n marginBottom: '8px',\n padding: '4px 0',\n borderBottom: '1px solid #eee',\n });\n\n const checkbox = document.createElement('input');\n checkbox.type = 'checkbox';\n checkbox.id = 'basemap-below-labels';\n checkbox.checked = this._state.belowLabels;\n Object.assign(checkbox.style, {\n marginRight: '8px',\n cursor: 'pointer',\n });\n\n checkbox.addEventListener('change', (e) => {\n e.stopPropagation();\n this._state.belowLabels = (e.target as HTMLInputElement).checked;\n // Re-apply current basemap with new layer ordering\n if (this._state.selectedBasemap) {\n const basemap = this._basemaps.find((b) => b.id === this._state.selectedBasemap);\n if (basemap) {\n this._applyBasemap(basemap);\n }\n }\n });\n\n const label = document.createElement('label');\n label.htmlFor = 'basemap-below-labels';\n label.textContent = 'Below labels';\n Object.assign(label.style, {\n cursor: 'pointer',\n fontSize: '0.9em',\n color: '#666',\n });\n\n container.appendChild(checkbox);\n container.appendChild(label);\n return container;\n }\n\n /**\n * Renders the list mode.\n */\n private _renderList(basemaps: BasemapItem[]): HTMLElement {\n const container = document.createElement('div');\n container.className = 'maplibre-gl-basemap-list';\n\n // Group basemaps\n const groups = groupBasemaps(basemaps);\n\n groups.forEach((items, groupName) => {\n // Group header\n const groupHeader = document.createElement('div');\n groupHeader.className = 'maplibre-gl-basemap-group';\n groupHeader.textContent = groupName;\n Object.assign(groupHeader.style, {\n fontWeight: '600',\n padding: '8px 0 4px',\n color: '#666',\n fontSize: '0.9em',\n });\n container.appendChild(groupHeader);\n\n // Group items\n items.forEach((basemap) => {\n const item = this._createBasemapItem(basemap, true);\n container.appendChild(item);\n });\n });\n\n return container;\n }\n\n /**\n * Renders the gallery mode.\n */\n private _renderGallery(basemaps: BasemapItem[]): HTMLElement {\n const container = document.createElement('div');\n container.className = 'maplibre-gl-basemap-gallery';\n Object.assign(container.style, {\n display: 'grid',\n gridTemplateColumns: 'repeat(auto-fill, minmax(70px, 1fr))',\n gap: '8px',\n maxHeight: `${this._options.maxHeight}px`,\n overflowY: 'auto',\n });\n\n basemaps.forEach((basemap) => {\n const item = document.createElement('div');\n item.className = `maplibre-gl-basemap-gallery-item${\n basemap.id === this._state.selectedBasemap ? ' maplibre-gl-basemap-gallery-item--selected' : ''\n }`;\n Object.assign(item.style, {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n cursor: 'pointer',\n padding: '4px',\n borderRadius: '4px',\n transition: 'background-color 0.15s',\n outline: basemap.id === this._state.selectedBasemap ? '2px solid #0078d7' : 'none',\n });\n\n // Thumbnail\n const thumbnail = document.createElement('div');\n thumbnail.className = 'maplibre-gl-basemap-thumbnail';\n Object.assign(thumbnail.style, {\n width: '60px',\n height: '60px',\n borderRadius: '4px',\n border: '1px solid rgba(0, 0, 0, 0.1)',\n backgroundColor: '#f0f0f0',\n backgroundSize: 'cover',\n backgroundPosition: 'center',\n });\n\n // Generate thumbnail URL\n if (basemap.thumbnail || basemap.url) {\n let thumbUrl = basemap.thumbnail;\n if (!thumbUrl && basemap.url) {\n thumbUrl = buildTileUrl(basemap)\n .replace('{z}', '3')\n .replace('{x}', '4')\n .replace('{y}', '2');\n }\n if (thumbUrl) {\n thumbnail.style.backgroundImage = `url(${thumbUrl})`;\n }\n }\n\n // Name\n const name = document.createElement('div');\n name.className = 'maplibre-gl-basemap-name';\n name.textContent = basemap.name;\n Object.assign(name.style, {\n marginTop: '4px',\n fontSize: '0.75em',\n textAlign: 'center',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n maxWidth: '70px',\n });\n\n item.appendChild(thumbnail);\n item.appendChild(name);\n\n item.addEventListener('click', (e) => {\n e.stopPropagation();\n this.setBasemap(basemap.id);\n });\n\n item.addEventListener('mouseenter', () => {\n if (basemap.id !== this._state.selectedBasemap) {\n item.style.backgroundColor = 'rgba(0, 0, 0, 0.05)';\n }\n });\n\n item.addEventListener('mouseleave', () => {\n item.style.backgroundColor = '';\n });\n\n container.appendChild(item);\n });\n\n return container;\n }\n\n /**\n * Creates a basemap item element.\n */\n private _createBasemapItem(basemap: BasemapItem, showRadio = false): HTMLElement {\n const item = document.createElement('div');\n item.className = `maplibre-gl-basemap-item${\n basemap.id === this._state.selectedBasemap ? ' maplibre-gl-basemap-item--selected' : ''\n }`;\n Object.assign(item.style, {\n display: 'flex',\n alignItems: 'center',\n padding: '6px 12px',\n cursor: 'pointer',\n borderRadius: '4px',\n transition: 'background-color 0.15s',\n backgroundColor: basemap.id === this._state.selectedBasemap ? 'rgba(0, 120, 215, 0.1)' : '',\n });\n\n if (showRadio) {\n const radio = document.createElement('input');\n radio.type = 'radio';\n radio.name = 'basemap';\n radio.checked = basemap.id === this._state.selectedBasemap;\n radio.className = 'maplibre-gl-basemap-item-radio';\n radio.style.marginRight = '8px';\n item.appendChild(radio);\n }\n\n const label = document.createElement('span');\n label.textContent = basemap.name;\n label.style.flex = '1';\n label.style.overflow = 'hidden';\n label.style.textOverflow = 'ellipsis';\n label.style.whiteSpace = 'nowrap';\n item.appendChild(label);\n\n // API key badge\n if (basemap.requiresApiKey && !basemap.apiKey) {\n const badge = document.createElement('span');\n badge.className = 'maplibre-gl-basemap-apikey-badge';\n badge.textContent = 'API';\n Object.assign(badge.style, {\n fontSize: '0.7em',\n background: '#ff9800',\n color: 'white',\n padding: '2px 6px',\n borderRadius: '3px',\n marginLeft: '4px',\n flexShrink: '0',\n });\n item.appendChild(badge);\n }\n\n item.addEventListener('click', (e) => {\n e.stopPropagation();\n if (!basemap.requiresApiKey || basemap.apiKey) {\n this.setBasemap(basemap.id);\n }\n });\n\n item.addEventListener('mouseenter', () => {\n if (basemap.id !== this._state.selectedBasemap) {\n item.style.backgroundColor = 'rgba(0, 0, 0, 0.05)';\n }\n });\n\n item.addEventListener('mouseleave', () => {\n item.style.backgroundColor =\n basemap.id === this._state.selectedBasemap ? 'rgba(0, 120, 215, 0.1)' : '';\n });\n\n return item;\n }\n}\n","import type { IControl, Map as MapLibreMap } from 'maplibre-gl';\nimport type {\n TerrainControlOptions,\n TerrainControlState,\n TerrainEvent,\n TerrainEventHandler,\n} from './types';\n\n/**\n * AWS Terrarium terrain tiles URL.\n */\nconst DEFAULT_TERRAIN_URL =\n 'https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png';\n\n/**\n * Unique source ID for terrain DEM.\n */\nconst TERRAIN_SOURCE_ID = 'maplibre-gl-terrain-dem';\n\n/**\n * Unique layer ID for hillshade.\n */\nconst HILLSHADE_LAYER_ID = 'maplibre-gl-terrain-hillshade';\n\n/**\n * Default options for the TerrainControl.\n */\nconst DEFAULT_OPTIONS: Required<TerrainControlOptions> = {\n sourceUrl: DEFAULT_TERRAIN_URL,\n encoding: 'terrarium',\n exaggeration: 1.0,\n enabled: false,\n hillshade: true,\n hillshadeExaggeration: 0.5,\n sourceMinzoom: 0,\n sourceMaxzoom: 15,\n tileSize: 256,\n position: 'top-right',\n className: '',\n visible: true,\n backgroundColor: 'rgba(255, 255, 255, 0.9)',\n borderRadius: 4,\n opacity: 1,\n minzoom: 0,\n maxzoom: 24,\n};\n\n/**\n * Mountain icon SVG for the terrain toggle button.\n */\nconst TERRAIN_ICON = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"m8 3 4 8 5-5 5 15H2L8 3z\"/></svg>`;\n\n/**\n * A terrain toggle control for MapLibre GL maps.\n *\n * Enables/disables 3D terrain rendering using AWS Terrarium elevation tiles.\n *\n * @example\n * ```typescript\n * const terrain = new TerrainControl({\n * exaggeration: 1.5,\n * hillshade: true,\n * });\n * map.addControl(terrain, 'top-right');\n *\n * terrain.on('terrainchange', (event) => {\n * console.log('Terrain enabled:', event.state.enabled);\n * });\n * ```\n */\nexport class TerrainControl implements IControl {\n private _container?: HTMLElement;\n private _button?: HTMLButtonElement;\n private _options: Required<TerrainControlOptions>;\n private _state: TerrainControlState;\n private _eventHandlers: Map<TerrainEvent, Set<TerrainEventHandler>> = new Map();\n private _map?: MapLibreMap;\n private _handleZoom?: () => void;\n private _handleStyleLoad?: () => void;\n private _zoomVisible: boolean = true;\n\n /**\n * Creates a new TerrainControl instance.\n *\n * @param options - Configuration options for the terrain control.\n */\n constructor(options?: TerrainControlOptions) {\n this._options = { ...DEFAULT_OPTIONS, ...options };\n this._state = {\n visible: this._options.visible,\n enabled: this._options.enabled,\n exaggeration: this._options.exaggeration,\n hillshade: this._options.hillshade,\n };\n }\n\n /**\n * Called when the control is added to the map.\n *\n * @param map - The MapLibre GL map instance.\n * @returns The control's container element.\n */\n onAdd(map: MapLibreMap): HTMLElement {\n this._map = map;\n this._container = this._createContainer();\n this._render();\n\n // Set up zoom listener\n this._handleZoom = () => this._checkZoomVisibility();\n this._map.on('zoom', this._handleZoom);\n\n // Handle style changes (e.g., when basemap changes)\n this._handleStyleLoad = () => {\n if (this._state.enabled) {\n // Re-apply terrain after style change\n this._setupTerrain();\n }\n };\n this._map.on('style.load', this._handleStyleLoad);\n\n // Check initial zoom\n this._checkZoomVisibility();\n\n // Enable terrain if default enabled\n if (this._options.enabled) {\n // Wait for map to be ready\n if (this._map.isStyleLoaded()) {\n this._setupTerrain();\n } else {\n this._map.once('load', () => this._setupTerrain());\n }\n }\n\n return this._container;\n }\n\n /**\n * Called when the control is removed from the map.\n */\n onRemove(): void {\n // Remove terrain and hillshade\n this._removeTerrain();\n\n // Remove event listeners\n if (this._map && this._handleZoom) {\n this._map.off('zoom', this._handleZoom);\n this._handleZoom = undefined;\n }\n if (this._map && this._handleStyleLoad) {\n this._map.off('style.load', this._handleStyleLoad);\n this._handleStyleLoad = undefined;\n }\n\n this._map = undefined;\n this._container?.parentNode?.removeChild(this._container);\n this._container = undefined;\n this._button = undefined;\n this._eventHandlers.clear();\n }\n\n /**\n * Shows the control.\n */\n show(): void {\n if (!this._state.visible) {\n this._state.visible = true;\n this._updateDisplayState();\n this._emit('show');\n }\n }\n\n /**\n * Hides the control.\n */\n hide(): void {\n if (this._state.visible) {\n this._state.visible = false;\n this._updateDisplayState();\n this._emit('hide');\n }\n }\n\n /**\n * Enables terrain rendering.\n */\n enable(): void {\n if (!this._state.enabled) {\n this._setupTerrain();\n this._render();\n this._emit('terrainchange');\n this._emit('update');\n }\n }\n\n /**\n * Disables terrain rendering.\n */\n disable(): void {\n if (this._state.enabled) {\n this._removeTerrain();\n this._render();\n this._emit('terrainchange');\n this._emit('update');\n }\n }\n\n /**\n * Toggles terrain on/off.\n */\n toggle(): void {\n if (this._state.enabled) {\n this.disable();\n } else {\n this.enable();\n }\n }\n\n /**\n * Checks if terrain is currently enabled.\n *\n * @returns True if terrain is enabled.\n */\n isEnabled(): boolean {\n return this._state.enabled;\n }\n\n /**\n * Sets the terrain exaggeration factor.\n *\n * @param value - Exaggeration value (typically 0.1 to 10.0).\n */\n setExaggeration(value: number): void {\n const clampedValue = Math.max(0.1, Math.min(10, value));\n this._state.exaggeration = clampedValue;\n this._options.exaggeration = clampedValue;\n\n if (this._map && this._state.enabled) {\n this._map.setTerrain({\n source: TERRAIN_SOURCE_ID,\n exaggeration: clampedValue,\n });\n }\n\n this._emit('update');\n }\n\n /**\n * Gets the current exaggeration value.\n *\n * @returns The current exaggeration factor.\n */\n getExaggeration(): number {\n return this._state.exaggeration;\n }\n\n /**\n * Enables the hillshade layer.\n */\n enableHillshade(): void {\n if (!this._state.hillshade) {\n this._state.hillshade = true;\n this._options.hillshade = true;\n if (this._state.enabled) {\n this._addHillshadeLayer();\n }\n this._emit('update');\n }\n }\n\n /**\n * Disables the hillshade layer.\n */\n disableHillshade(): void {\n if (this._state.hillshade) {\n this._state.hillshade = false;\n this._options.hillshade = false;\n this._removeHillshadeLayer();\n this._emit('update');\n }\n }\n\n /**\n * Toggles the hillshade layer.\n */\n toggleHillshade(): void {\n if (this._state.hillshade) {\n this.disableHillshade();\n } else {\n this.enableHillshade();\n }\n }\n\n /**\n * Updates control options and re-renders.\n *\n * @param options - Partial options to update.\n */\n update(options: Partial<TerrainControlOptions>): void {\n const prevEnabled = this._state.enabled;\n\n this._options = { ...this._options, ...options };\n\n if (options.visible !== undefined) this._state.visible = options.visible;\n if (options.enabled !== undefined) this._state.enabled = options.enabled;\n if (options.exaggeration !== undefined) {\n this._state.exaggeration = options.exaggeration;\n }\n if (options.hillshade !== undefined) this._state.hillshade = options.hillshade;\n\n // Handle terrain enable/disable\n if (options.enabled !== undefined && options.enabled !== prevEnabled) {\n if (options.enabled) {\n this._setupTerrain();\n } else {\n this._removeTerrain();\n }\n } else if (this._state.enabled && options.exaggeration !== undefined) {\n // Update exaggeration if terrain is already enabled\n this.setExaggeration(options.exaggeration);\n }\n\n this._render();\n this._emit('update');\n }\n\n /**\n * Gets the current state.\n *\n * @returns The current terrain control state.\n */\n getState(): TerrainControlState {\n return { ...this._state };\n }\n\n /**\n * Registers an event handler.\n *\n * @param event - The event type to listen for.\n * @param handler - The callback function.\n */\n on(event: TerrainEvent, handler: TerrainEventHandler): void {\n if (!this._eventHandlers.has(event)) {\n this._eventHandlers.set(event, new Set());\n }\n this._eventHandlers.get(event)!.add(handler);\n }\n\n /**\n * Removes an event handler.\n *\n * @param event - The event type.\n * @param handler - The callback function to remove.\n */\n off(event: TerrainEvent, handler: TerrainEventHandler): void {\n this._eventHandlers.get(event)?.delete(handler);\n }\n\n /**\n * Emits an event to all registered handlers.\n *\n * @param event - The event type to emit.\n */\n private _emit(event: TerrainEvent): void {\n const handlers = this._eventHandlers.get(event);\n if (handlers) {\n const eventData = { type: event, state: this.getState() };\n handlers.forEach((handler) => handler(eventData));\n }\n }\n\n /**\n * Sets up the terrain source and enables terrain rendering.\n */\n private _setupTerrain(): void {\n if (!this._map) return;\n\n try {\n // Add raster-dem source if not already present\n if (!this._map.getSource(TERRAIN_SOURCE_ID)) {\n this._map.addSource(TERRAIN_SOURCE_ID, {\n type: 'raster-dem',\n tiles: [this._options.sourceUrl],\n encoding: this._options.encoding,\n tileSize: this._options.tileSize,\n minzoom: this._options.sourceMinzoom,\n maxzoom: this._options.sourceMaxzoom,\n });\n }\n\n // Enable terrain on the map\n this._map.setTerrain({\n source: TERRAIN_SOURCE_ID,\n exaggeration: this._state.exaggeration,\n });\n\n // Add hillshade if enabled\n if (this._state.hillshade) {\n this._addHillshadeLayer();\n }\n\n this._state.enabled = true;\n } catch (error) {\n console.error('Failed to setup terrain:', error);\n }\n }\n\n /**\n * Removes terrain and cleans up sources/layers.\n */\n private _removeTerrain(): void {\n if (!this._map) return;\n\n try {\n // Disable terrain\n this._map.setTerrain(null);\n\n // Remove hillshade layer\n this._removeHillshadeLayer();\n\n // Remove source\n if (this._map.getSource(TERRAIN_SOURCE_ID)) {\n this._map.removeSource(TERRAIN_SOURCE_ID);\n }\n\n this._state.enabled = false;\n } catch (error) {\n console.error('Failed to remove terrain:', error);\n }\n }\n\n /**\n * Adds the hillshade layer for better terrain visualization.\n */\n private _addHillshadeLayer(): void {\n if (!this._map || this._map.getLayer(HILLSHADE_LAYER_ID)) return;\n\n try {\n // Find the first symbol layer to insert hillshade below labels\n const layers = this._map.getStyle().layers || [];\n let firstSymbolId: string | undefined;\n for (const layer of layers) {\n if (layer.type === 'symbol') {\n firstSymbolId = layer.id;\n break;\n }\n }\n\n this._map.addLayer(\n {\n id: HILLSHADE_LAYER_ID,\n type: 'hillshade',\n source: TERRAIN_SOURCE_ID,\n paint: {\n 'hillshade-exaggeration': this._options.hillshadeExaggeration,\n },\n },\n firstSymbolId\n );\n } catch (error) {\n console.error('Failed to add hillshade layer:', error);\n }\n }\n\n /**\n * Removes the hillshade layer.\n */\n private _removeHillshadeLayer(): void {\n if (!this._map) return;\n\n try {\n if (this._map.getLayer(HILLSHADE_LAYER_ID)) {\n this._map.removeLayer(HILLSHADE_LAYER_ID);\n }\n } catch (error) {\n console.error('Failed to remove hillshade layer:', error);\n }\n }\n\n /**\n * Checks if the current zoom level is within the visibility range.\n */\n private _checkZoomVisibility(): void {\n if (!this._map) return;\n\n const zoom = this._map.getZoom();\n const { minzoom, maxzoom } = this._options;\n const inRange = zoom >= minzoom && zoom <= maxzoom;\n\n if (inRange !== this._zoomVisible) {\n this._zoomVisible = inRange;\n this._updateDisplayState();\n }\n }\n\n /**\n * Updates the display state based on visibility and zoom level.\n */\n private _updateDisplayState(): void {\n if (!this._container) return;\n const shouldShow = this._state.visible && this._zoomVisible;\n this._container.style.display = shouldShow ? 'flex' : 'none';\n }\n\n /**\n * Creates the main container element.\n *\n * @returns The container element.\n */\n private _createContainer(): HTMLElement {\n const container = document.createElement('div');\n container.className = `maplibregl-ctrl maplibregl-ctrl-group maplibre-gl-terrain${\n this._options.className ? ` ${this._options.className}` : ''\n }`;\n\n const shouldShow = this._state.visible && this._zoomVisible;\n if (!shouldShow) {\n container.style.display = 'none';\n }\n\n // Apply custom styles\n if (this._options.backgroundColor) {\n container.style.backgroundColor = this._options.backgroundColor;\n }\n if (this._options.borderRadius) {\n container.style.borderRadius = `${this._options.borderRadius}px`;\n }\n if (this._options.opacity !== 1) {\n container.style.opacity = String(this._options.opacity);\n }\n\n // Create button\n this._button = document.createElement('button');\n this._button.type = 'button';\n this._button.className = 'maplibre-gl-terrain-button';\n this._button.title = 'Toggle terrain';\n this._button.setAttribute('aria-label', 'Toggle terrain');\n this._button.innerHTML = TERRAIN_ICON;\n\n this._button.addEventListener('click', () => this.toggle());\n\n container.appendChild(this._button);\n\n return container;\n }\n\n /**\n * Renders/updates the control appearance based on current state.\n */\n private _render(): void {\n if (!this._button) return;\n\n // Update button active state\n if (this._state.enabled) {\n this._button.classList.add('maplibre-gl-terrain-button--active');\n this._button.title = 'Disable terrain';\n this._button.setAttribute('aria-label', 'Disable terrain');\n } else {\n this._button.classList.remove('maplibre-gl-terrain-button--active');\n this._button.title = 'Enable terrain';\n this._button.setAttribute('aria-label', 'Enable terrain');\n }\n\n this._updateDisplayState();\n }\n}\n","import type { IControl, Map as MapLibreMap, Marker } from 'maplibre-gl';\nimport type {\n SearchControlOptions,\n SearchControlState,\n SearchResult,\n SearchEvent,\n SearchEventHandler,\n} from './types';\n\n/**\n * Default Nominatim geocoding URL (OpenStreetMap).\n */\nconst NOMINATIM_URL = 'https://nominatim.openstreetmap.org/search';\n\n/**\n * Default options for the SearchControl.\n */\nconst DEFAULT_OPTIONS: Required<Omit<SearchControlOptions, 'geocoder'>> & { geocoder?: SearchControlOptions['geocoder'] } = {\n position: 'top-right',\n className: '',\n visible: true,\n collapsed: true,\n placeholder: 'Search places...',\n geocoderUrl: NOMINATIM_URL,\n maxResults: 5,\n debounceMs: 300,\n flyToZoom: 14,\n showMarker: true,\n markerColor: '#4264fb',\n collapseOnSelect: true,\n clearOnSelect: true,\n geocoder: undefined,\n backgroundColor: 'rgba(255, 255, 255, 0.95)',\n borderRadius: 4,\n opacity: 1,\n width: 280,\n fontSize: 13,\n fontColor: '#333',\n minzoom: 0,\n maxzoom: 24,\n};\n\n/**\n * A collapsible search control for MapLibre GL maps.\n *\n * Provides place search functionality using Nominatim (or custom geocoder).\n * Shows a search icon that expands to reveal a search input with autocomplete results.\n *\n * @example\n * ```typescript\n * const searchControl = new SearchControl({\n * placeholder: 'Search for a place...',\n * flyToZoom: 12,\n * showMarker: true,\n * });\n * map.addControl(searchControl, 'top-right');\n *\n * // Listen for result selection\n * searchControl.on('resultselect', (event) => {\n * console.log('Selected:', event.result);\n * });\n * ```\n */\nexport class SearchControl implements IControl {\n private _container?: HTMLElement;\n private _inputEl?: HTMLInputElement;\n private _inputWrapper?: HTMLElement;\n private _resultsContainer?: HTMLElement;\n private _loadingEl?: HTMLElement;\n private _clearBtn?: HTMLButtonElement;\n private _options: Required<Omit<SearchControlOptions, 'geocoder'>> & { geocoder?: SearchControlOptions['geocoder'] };\n private _state: SearchControlState;\n private _eventHandlers: Map<SearchEvent, Set<SearchEventHandler>> = new Map();\n private _map?: MapLibreMap;\n private _handleZoom?: () => void;\n private _zoomVisible: boolean = true;\n private _marker?: Marker;\n private _debounceTimer?: ReturnType<typeof setTimeout>;\n\n /**\n * Creates a new SearchControl instance.\n *\n * @param options - Configuration options for the control.\n */\n constructor(options?: SearchControlOptions) {\n this._options = { ...DEFAULT_OPTIONS, ...options };\n this._state = {\n visible: this._options.visible,\n collapsed: this._options.collapsed,\n query: '',\n results: [],\n loading: false,\n selectedResult: null,\n error: null,\n };\n }\n\n /**\n * Called when the control is added to the map.\n *\n * @param map - The MapLibre GL map instance.\n * @returns The control's container element.\n */\n onAdd(map: MapLibreMap): HTMLElement {\n this._map = map;\n this._container = this._createContainer();\n this._render();\n\n // Set up zoom listener\n this._handleZoom = () => this._checkZoomVisibility();\n this._map.on('zoom', this._handleZoom);\n\n // Check initial zoom\n this._checkZoomVisibility();\n\n return this._container;\n }\n\n /**\n * Called when the control is removed from the map.\n */\n onRemove(): void {\n if (this._map && this._handleZoom) {\n this._map.off('zoom', this._handleZoom);\n this._handleZoom = undefined;\n }\n this._removeMarker();\n this._map = undefined;\n this._container?.parentNode?.removeChild(this._container);\n this._container = undefined;\n this._inputEl = undefined;\n this._inputWrapper = undefined;\n this._resultsContainer = undefined;\n this._loadingEl = undefined;\n this._clearBtn = undefined;\n this._eventHandlers.clear();\n if (this._debounceTimer) {\n clearTimeout(this._debounceTimer);\n }\n }\n\n /**\n * Shows the control.\n */\n show(): void {\n if (!this._state.visible) {\n this._state.visible = true;\n this._updateDisplayState();\n this._emit('show');\n }\n }\n\n /**\n * Hides the control.\n */\n hide(): void {\n if (this._state.visible) {\n this._state.visible = false;\n this._updateDisplayState();\n this._emit('hide');\n }\n }\n\n /**\n * Expands the search control to show the input.\n */\n expand(): void {\n if (this._state.collapsed) {\n this._state.collapsed = false;\n this._render();\n this._emit('expand');\n // Focus the input when expanded\n setTimeout(() => this._inputEl?.focus(), 50);\n }\n }\n\n /**\n * Collapses the search control to icon only.\n */\n collapse(): void {\n if (!this._state.collapsed) {\n this._state.collapsed = true;\n this._state.results = [];\n this._render();\n this._emit('collapse');\n }\n }\n\n /**\n * Toggles the collapsed state.\n */\n toggle(): void {\n if (this._state.collapsed) {\n this.expand();\n } else {\n this.collapse();\n }\n }\n\n /**\n * Performs a search with the given query.\n *\n * @param query - The search query string.\n */\n async search(query: string): Promise<void> {\n this._state.query = query;\n\n if (!query.trim()) {\n this._state.results = [];\n this._state.error = null;\n this._updateLoadingState();\n this._renderResultsOnly();\n return;\n }\n\n this._state.loading = true;\n this._state.error = null;\n this._updateLoadingState();\n this._renderResultsOnly();\n\n try {\n let results: SearchResult[];\n\n if (this._options.geocoder) {\n // Use custom geocoder\n results = await this._options.geocoder(query);\n } else {\n // Use Nominatim\n results = await this._nominatimSearch(query);\n }\n\n // Check if query has changed while we were waiting (user typed something new)\n if (this._state.query !== query) {\n return; // Discard stale results\n }\n\n this._state.results = results.slice(0, this._options.maxResults);\n this._state.loading = false;\n this._updateLoadingState();\n this._renderResultsOnly();\n this._emit('search');\n } catch (error) {\n // Check if query has changed while we were waiting\n if (this._state.query !== query) {\n return; // Discard stale error\n }\n\n this._state.loading = false;\n this._state.error = error instanceof Error ? error.message : 'Search failed';\n this._state.results = [];\n this._updateLoadingState();\n this._renderResultsOnly();\n }\n }\n\n /**\n * Selects a search result and flies to its location.\n *\n * @param result - The search result to select.\n */\n selectResult(result: SearchResult): void {\n this._state.selectedResult = result;\n\n if (this._map) {\n // Fly to the result location\n if (result.bbox) {\n this._map.fitBounds(\n [[result.bbox[0], result.bbox[1]], [result.bbox[2], result.bbox[3]]],\n { padding: 50, maxZoom: this._options.flyToZoom }\n );\n } else {\n this._map.flyTo({\n center: [result.lng, result.lat],\n zoom: this._options.flyToZoom,\n });\n }\n\n // Add marker if enabled\n if (this._options.showMarker) {\n this._addMarker(result);\n }\n }\n\n if (this._options.clearOnSelect) {\n this._state.query = '';\n this._state.results = [];\n }\n\n if (this._options.collapseOnSelect) {\n this._state.collapsed = true;\n }\n\n this._render();\n this._emit('resultselect', result);\n }\n\n /**\n * Clears the search query and results.\n */\n clear(): void {\n this._state.query = '';\n this._state.results = [];\n this._state.selectedResult = null;\n this._state.error = null;\n this._state.loading = false;\n this._removeMarker();\n\n // Update input value directly if it exists\n if (this._inputEl) {\n this._inputEl.value = '';\n }\n\n // Use partial rendering to avoid losing focus\n this._updateLoadingState();\n this._renderResultsOnly();\n this._emit('clear');\n }\n\n /**\n * Gets the current state.\n *\n * @returns The current control state.\n */\n getState(): SearchControlState {\n return { ...this._state, results: [...this._state.results] };\n }\n\n /**\n * Updates control options.\n *\n * @param options - Partial options to update.\n */\n update(options: Partial<SearchControlOptions>): void {\n this._options = { ...this._options, ...options };\n if (options.visible !== undefined) this._state.visible = options.visible;\n if (options.collapsed !== undefined) this._state.collapsed = options.collapsed;\n this._render();\n this._emit('update');\n }\n\n /**\n * Registers an event handler.\n *\n * @param event - The event type to listen for.\n * @param handler - The callback function.\n */\n on(event: SearchEvent, handler: SearchEventHandler): void {\n if (!this._eventHandlers.has(event)) {\n this._eventHandlers.set(event, new Set());\n }\n this._eventHandlers.get(event)!.add(handler);\n }\n\n /**\n * Removes an event handler.\n *\n * @param event - The event type.\n * @param handler - The callback function to remove.\n */\n off(event: SearchEvent, handler: SearchEventHandler): void {\n this._eventHandlers.get(event)?.delete(handler);\n }\n\n /**\n * Emits an event to all registered handlers.\n */\n private _emit(event: SearchEvent, result?: SearchResult): void {\n const handlers = this._eventHandlers.get(event);\n if (handlers) {\n const eventData = { type: event, state: this.getState(), result };\n handlers.forEach((handler) => handler(eventData));\n }\n }\n\n /**\n * Performs a search using Nominatim geocoding service.\n */\n private async _nominatimSearch(query: string): Promise<SearchResult[]> {\n const params = new URLSearchParams({\n q: query,\n format: 'json',\n limit: String(this._options.maxResults),\n addressdetails: '1',\n });\n\n const response = await fetch(`${this._options.geocoderUrl}?${params}`, {\n headers: {\n 'Accept': 'application/json',\n },\n });\n\n if (!response.ok) {\n throw new Error(`Geocoding failed: ${response.statusText}`);\n }\n\n const data = await response.json();\n\n return data.map((item: {\n place_id: number;\n display_name: string;\n name?: string;\n lon: string;\n lat: string;\n boundingbox?: string[];\n type?: string;\n importance?: number;\n }) => ({\n id: String(item.place_id),\n name: item.name || item.display_name.split(',')[0],\n displayName: item.display_name,\n lng: parseFloat(item.lon),\n lat: parseFloat(item.lat),\n bbox: item.boundingbox\n ? [\n parseFloat(item.boundingbox[2]),\n parseFloat(item.boundingbox[0]),\n parseFloat(item.boundingbox[3]),\n parseFloat(item.boundingbox[1]),\n ] as [number, number, number, number]\n : undefined,\n type: item.type,\n importance: item.importance,\n }));\n }\n\n /**\n * Checks if the current zoom level is within the visibility range.\n */\n private _checkZoomVisibility(): void {\n if (!this._map) return;\n\n const zoom = this._map.getZoom();\n const { minzoom, maxzoom } = this._options;\n const inRange = zoom >= minzoom && zoom <= maxzoom;\n\n if (inRange !== this._zoomVisible) {\n this._zoomVisible = inRange;\n this._updateDisplayState();\n }\n }\n\n /**\n * Updates the display state based on visibility and zoom level.\n */\n private _updateDisplayState(): void {\n if (!this._container) return;\n const shouldShow = this._state.visible && this._zoomVisible;\n this._container.style.display = shouldShow ? 'block' : 'none';\n }\n\n /**\n * Adds a marker at the result location.\n */\n private _addMarker(result: SearchResult): void {\n this._removeMarker();\n\n if (!this._map) return;\n\n // Import maplibre-gl dynamically to avoid circular dependencies\n import('maplibre-gl').then(({ Marker }) => {\n // Create custom marker element\n const el = document.createElement('div');\n el.className = 'maplibre-gl-search-marker';\n el.innerHTML = `\n <svg width=\"28\" height=\"36\" viewBox=\"0 0 28 36\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M14 0C6.268 0 0 6.268 0 14C0 24.5 14 36 14 36C14 36 28 24.5 28 14C28 6.268 21.732 0 14 0Z\" fill=\"${this._options.markerColor}\"/>\n <circle cx=\"14\" cy=\"14\" r=\"6\" fill=\"white\"/>\n </svg>\n `;\n el.style.cursor = 'pointer';\n\n this._marker = new Marker({ element: el })\n .setLngLat([result.lng, result.lat])\n .addTo(this._map!);\n });\n }\n\n /**\n * Removes the current marker.\n */\n private _removeMarker(): void {\n if (this._marker) {\n this._marker.remove();\n this._marker = undefined;\n }\n }\n\n /**\n * Updates only the results section without rebuilding the entire DOM.\n * This prevents input focus loss during search.\n */\n private _renderResultsOnly(): void {\n if (!this._container || this._state.collapsed) return;\n\n // Remove existing results container if present\n if (this._resultsContainer) {\n this._resultsContainer.remove();\n this._resultsContainer = undefined;\n }\n\n // Remove existing error element if present\n const existingError = this._container.querySelector('.maplibre-gl-search-error');\n if (existingError) {\n existingError.remove();\n }\n\n // Render error if present\n if (this._state.error) {\n const errorEl = document.createElement('div');\n errorEl.className = 'maplibre-gl-search-error';\n errorEl.textContent = this._state.error;\n Object.assign(errorEl.style, {\n padding: '8px 10px',\n color: '#d32f2f',\n fontSize: '12px',\n borderTop: '1px solid rgba(0, 0, 0, 0.08)',\n });\n this._container.appendChild(errorEl);\n }\n\n // Render results if present\n if (this._state.results.length > 0) {\n this._resultsContainer = document.createElement('div');\n this._resultsContainer.className = 'maplibre-gl-search-results';\n Object.assign(this._resultsContainer.style, {\n borderTop: '1px solid rgba(0, 0, 0, 0.08)',\n maxHeight: '250px',\n overflowY: 'auto',\n });\n\n this._state.results.forEach((result) => {\n const resultEl = document.createElement('div');\n resultEl.className = 'maplibre-gl-search-result';\n Object.assign(resultEl.style, {\n padding: '10px 12px',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'flex-start',\n gap: '10px',\n transition: 'background-color 0.15s ease',\n });\n\n // Location icon\n const icon = document.createElement('span');\n icon.innerHTML = `\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" style=\"flex-shrink: 0; margin-top: 2px;\">\n <path d=\"M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z\"/>\n <circle cx=\"12\" cy=\"10\" r=\"3\"/>\n </svg>\n `;\n icon.style.color = '#888';\n resultEl.appendChild(icon);\n\n // Text content\n const textWrapper = document.createElement('div');\n textWrapper.style.flex = '1';\n textWrapper.style.minWidth = '0';\n\n const nameEl = document.createElement('div');\n nameEl.className = 'maplibre-gl-search-result-name';\n nameEl.textContent = result.name;\n Object.assign(nameEl.style, {\n fontWeight: '500',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n });\n textWrapper.appendChild(nameEl);\n\n const detailEl = document.createElement('div');\n detailEl.className = 'maplibre-gl-search-result-detail';\n detailEl.textContent = result.displayName;\n Object.assign(detailEl.style, {\n fontSize: '11px',\n color: '#666',\n marginTop: '2px',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n });\n textWrapper.appendChild(detailEl);\n\n resultEl.appendChild(textWrapper);\n\n resultEl.addEventListener('mouseenter', () => {\n resultEl.style.backgroundColor = 'rgba(0, 0, 0, 0.04)';\n });\n resultEl.addEventListener('mouseleave', () => {\n resultEl.style.backgroundColor = 'transparent';\n });\n resultEl.addEventListener('click', () => this.selectResult(result));\n\n this._resultsContainer!.appendChild(resultEl);\n });\n\n this._container.appendChild(this._resultsContainer);\n }\n }\n\n /**\n * Updates only the loading/clear button state without full DOM rebuild.\n */\n private _updateLoadingState(): void {\n if (!this._inputWrapper) return;\n\n // Remove existing loading element\n if (this._loadingEl) {\n this._loadingEl.remove();\n this._loadingEl = undefined;\n }\n\n // Remove existing clear button\n if (this._clearBtn) {\n this._clearBtn.remove();\n this._clearBtn = undefined;\n }\n\n // Find the collapse button to insert before it\n const collapseBtn = this._inputWrapper.querySelector('.maplibre-gl-search-collapse');\n\n if (this._state.loading) {\n this._loadingEl = document.createElement('span');\n this._loadingEl.className = 'maplibre-gl-search-loader';\n this._loadingEl.innerHTML = `\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke-opacity=\"0.25\"/>\n <path d=\"M12 2a10 10 0 0 1 10 10\" stroke-linecap=\"round\">\n <animateTransform attributeName=\"transform\" type=\"rotate\" from=\"0 12 12\" to=\"360 12 12\" dur=\"1s\" repeatCount=\"indefinite\"/>\n </path>\n </svg>\n `;\n Object.assign(this._loadingEl.style, {\n display: 'flex',\n alignItems: 'center',\n color: '#888',\n flexShrink: '0',\n });\n if (collapseBtn) {\n this._inputWrapper.insertBefore(this._loadingEl, collapseBtn);\n } else {\n this._inputWrapper.appendChild(this._loadingEl);\n }\n } else if (this._state.query) {\n this._clearBtn = document.createElement('button');\n this._clearBtn.className = 'maplibre-gl-search-clear';\n this._clearBtn.type = 'button';\n this._clearBtn.title = 'Clear';\n this._clearBtn.innerHTML = `\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M18 6L6 18M6 6l12 12\"/>\n </svg>\n `;\n Object.assign(this._clearBtn.style, {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '24px',\n height: '24px',\n padding: '4px',\n border: 'none',\n background: 'transparent',\n cursor: 'pointer',\n color: '#888',\n flexShrink: '0',\n });\n this._clearBtn.addEventListener('click', (e) => {\n e.stopPropagation();\n this.clear();\n });\n if (collapseBtn) {\n this._inputWrapper.insertBefore(this._clearBtn, collapseBtn);\n } else {\n this._inputWrapper.appendChild(this._clearBtn);\n }\n }\n }\n\n /**\n * Creates the main container element.\n */\n private _createContainer(): HTMLElement {\n const container = document.createElement('div');\n container.className = `maplibregl-ctrl maplibre-gl-search${\n this._options.className ? ` ${this._options.className}` : ''\n }`;\n\n const shouldShow = this._state.visible && this._zoomVisible;\n if (!shouldShow) {\n container.style.display = 'none';\n }\n\n return container;\n }\n\n /**\n * Handles input change with debouncing.\n */\n private _handleInput = (e: Event): void => {\n const value = (e.target as HTMLInputElement).value;\n this._state.query = value;\n\n if (this._debounceTimer) {\n clearTimeout(this._debounceTimer);\n }\n\n this._debounceTimer = setTimeout(() => {\n this.search(value);\n }, this._options.debounceMs);\n };\n\n /**\n * Renders the control content.\n */\n private _render(): void {\n if (!this._container) return;\n\n const {\n backgroundColor,\n borderRadius,\n opacity,\n width,\n fontSize,\n fontColor,\n placeholder,\n } = this._options;\n\n // Clear existing content and DOM references\n this._container.innerHTML = '';\n this._inputEl = undefined;\n this._inputWrapper = undefined;\n this._resultsContainer = undefined;\n this._loadingEl = undefined;\n this._clearBtn = undefined;\n\n // Apply base container styles\n Object.assign(this._container.style, {\n backgroundColor,\n borderRadius: `${borderRadius}px`,\n opacity: String(opacity),\n boxShadow: '0 0 0 2px rgba(0, 0, 0, 0.1)',\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n fontSize: `${fontSize}px`,\n color: fontColor,\n overflow: 'hidden',\n });\n\n if (this._state.collapsed) {\n // Collapsed state - just show the search icon\n this._container.style.width = 'auto';\n this._renderCollapsedState();\n } else {\n // Expanded state - show search input and results\n Object.assign(this._container.style, {\n width: `${width}px`,\n });\n this._renderExpandedState(placeholder, fontColor);\n }\n }\n\n /**\n * Renders the collapsed state (search icon only).\n */\n private _renderCollapsedState(): void {\n const button = document.createElement('button');\n button.className = 'maplibre-gl-search-toggle';\n button.type = 'button';\n button.title = 'Search places';\n button.innerHTML = `\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"11\" cy=\"11\" r=\"8\"/>\n <path d=\"M21 21l-4.35-4.35\"/>\n </svg>\n `;\n Object.assign(button.style, {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '30px',\n height: '30px',\n padding: '0',\n border: 'none',\n background: 'transparent',\n cursor: 'pointer',\n color: this._options.fontColor,\n });\n button.addEventListener('click', (e) => {\n e.stopPropagation();\n this.expand();\n });\n this._container!.appendChild(button);\n }\n\n /**\n * Renders the expanded state (search input and results).\n */\n private _renderExpandedState(placeholder: string, fontColor: string): void {\n // Search input wrapper\n const inputWrapper = document.createElement('div');\n inputWrapper.className = 'maplibre-gl-search-input-wrapper';\n Object.assign(inputWrapper.style, {\n display: 'flex',\n alignItems: 'center',\n padding: '0 10px',\n gap: '8px',\n height: '30px',\n boxSizing: 'border-box',\n });\n\n // Search icon\n const searchIcon = document.createElement('span');\n searchIcon.className = 'maplibre-gl-search-icon';\n searchIcon.innerHTML = `\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"11\" cy=\"11\" r=\"8\"/>\n <path d=\"M21 21l-4.35-4.35\"/>\n </svg>\n `;\n Object.assign(searchIcon.style, {\n display: 'flex',\n alignItems: 'center',\n color: '#888',\n flexShrink: '0',\n });\n inputWrapper.appendChild(searchIcon);\n\n // Input element\n const input = document.createElement('input');\n input.type = 'text';\n input.className = 'maplibre-gl-search-input';\n input.placeholder = placeholder;\n input.value = this._state.query;\n Object.assign(input.style, {\n flex: '1',\n border: 'none',\n outline: 'none',\n background: 'transparent',\n fontSize: 'inherit',\n color: fontColor,\n minWidth: '0',\n });\n input.addEventListener('input', this._handleInput);\n input.addEventListener('keydown', (e) => {\n if (e.key === 'Escape') {\n this.collapse();\n }\n });\n this._inputEl = input;\n inputWrapper.appendChild(input);\n\n // Loading indicator or clear button\n if (this._state.loading) {\n const loader = document.createElement('span');\n loader.className = 'maplibre-gl-search-loader';\n loader.innerHTML = `\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke-opacity=\"0.25\"/>\n <path d=\"M12 2a10 10 0 0 1 10 10\" stroke-linecap=\"round\">\n <animateTransform attributeName=\"transform\" type=\"rotate\" from=\"0 12 12\" to=\"360 12 12\" dur=\"1s\" repeatCount=\"indefinite\"/>\n </path>\n </svg>\n `;\n Object.assign(loader.style, {\n display: 'flex',\n alignItems: 'center',\n color: '#888',\n flexShrink: '0',\n });\n inputWrapper.appendChild(loader);\n } else if (this._state.query) {\n const clearBtn = document.createElement('button');\n clearBtn.className = 'maplibre-gl-search-clear';\n clearBtn.type = 'button';\n clearBtn.title = 'Clear';\n clearBtn.innerHTML = `\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M18 6L6 18M6 6l12 12\"/>\n </svg>\n `;\n Object.assign(clearBtn.style, {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '24px',\n height: '24px',\n padding: '4px',\n border: 'none',\n background: 'transparent',\n cursor: 'pointer',\n color: '#888',\n flexShrink: '0',\n });\n clearBtn.addEventListener('click', (e) => {\n e.stopPropagation();\n this.clear();\n });\n inputWrapper.appendChild(clearBtn);\n }\n\n // Collapse button\n const collapseBtn = document.createElement('button');\n collapseBtn.className = 'maplibre-gl-search-collapse';\n collapseBtn.type = 'button';\n collapseBtn.title = 'Close';\n collapseBtn.innerHTML = `\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M19 12H5M12 19l-7-7 7-7\"/>\n </svg>\n `;\n Object.assign(collapseBtn.style, {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '24px',\n height: '24px',\n padding: '4px',\n border: 'none',\n background: 'transparent',\n cursor: 'pointer',\n color: '#888',\n flexShrink: '0',\n });\n collapseBtn.addEventListener('click', (e) => {\n e.stopPropagation();\n this.collapse();\n });\n inputWrapper.appendChild(collapseBtn);\n\n // Store reference for partial rendering\n this._inputWrapper = inputWrapper;\n this._container!.appendChild(inputWrapper);\n\n // Error message\n if (this._state.error) {\n const errorEl = document.createElement('div');\n errorEl.className = 'maplibre-gl-search-error';\n errorEl.textContent = this._state.error;\n Object.assign(errorEl.style, {\n padding: '8px 10px',\n color: '#d32f2f',\n fontSize: '12px',\n borderTop: '1px solid rgba(0, 0, 0, 0.08)',\n });\n this._container!.appendChild(errorEl);\n }\n\n // Results list\n if (this._state.results.length > 0) {\n const resultsEl = document.createElement('div');\n resultsEl.className = 'maplibre-gl-search-results';\n Object.assign(resultsEl.style, {\n borderTop: '1px solid rgba(0, 0, 0, 0.08)',\n maxHeight: '250px',\n overflowY: 'auto',\n });\n\n this._state.results.forEach((result) => {\n const resultEl = document.createElement('div');\n resultEl.className = 'maplibre-gl-search-result';\n Object.assign(resultEl.style, {\n padding: '10px 12px',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'flex-start',\n gap: '10px',\n transition: 'background-color 0.15s ease',\n });\n\n // Location icon\n const icon = document.createElement('span');\n icon.innerHTML = `\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" style=\"flex-shrink: 0; margin-top: 2px;\">\n <path d=\"M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z\"/>\n <circle cx=\"12\" cy=\"10\" r=\"3\"/>\n </svg>\n `;\n icon.style.color = '#888';\n resultEl.appendChild(icon);\n\n // Text content\n const textWrapper = document.createElement('div');\n textWrapper.style.flex = '1';\n textWrapper.style.minWidth = '0';\n\n const nameEl = document.createElement('div');\n nameEl.className = 'maplibre-gl-search-result-name';\n nameEl.textContent = result.name;\n Object.assign(nameEl.style, {\n fontWeight: '500',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n });\n textWrapper.appendChild(nameEl);\n\n const detailEl = document.createElement('div');\n detailEl.className = 'maplibre-gl-search-result-detail';\n detailEl.textContent = result.displayName;\n Object.assign(detailEl.style, {\n fontSize: '11px',\n color: '#666',\n marginTop: '2px',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n });\n textWrapper.appendChild(detailEl);\n\n resultEl.appendChild(textWrapper);\n\n resultEl.addEventListener('mouseenter', () => {\n resultEl.style.backgroundColor = 'rgba(0, 0, 0, 0.04)';\n });\n resultEl.addEventListener('mouseleave', () => {\n resultEl.style.backgroundColor = 'transparent';\n });\n resultEl.addEventListener('click', () => this.selectResult(result));\n\n resultsEl.appendChild(resultEl);\n });\n\n this._container!.appendChild(resultsEl);\n }\n }\n}\n","/**\n * Supported vector file formats.\n *\n * DuckDB's spatial extension uses GDAL under the hood, enabling support\n * for many common geospatial formats via ST_Read().\n */\nexport type VectorFormat =\n | 'geojson'\n | 'shapefile'\n | 'geopackage'\n | 'geoparquet'\n | 'kml'\n | 'kmz'\n | 'gpx'\n | 'flatgeobuf'\n | 'gml'\n | 'topojson'\n | 'csv'\n | 'xlsx'\n | 'dxf'\n | 'unknown';\n\n/**\n * File extensions for GeoJSON files.\n */\nexport const GEOJSON_EXTENSIONS = ['.geojson', '.json'];\n\n/**\n * File extensions for Shapefile files.\n * Includes .zip for zipped shapefiles (most common distribution).\n */\nexport const SHAPEFILE_EXTENSIONS = ['.shp', '.zip'];\n\n/**\n * File extensions for GeoPackage files.\n */\nexport const GEOPACKAGE_EXTENSIONS = ['.gpkg'];\n\n/**\n * File extensions for GeoParquet files.\n */\nexport const GEOPARQUET_EXTENSIONS = ['.parquet', '.geoparquet'];\n\n/**\n * File extensions for KML (Keyhole Markup Language) files.\n * Used by Google Earth.\n */\nexport const KML_EXTENSIONS = ['.kml'];\n\n/**\n * File extensions for KMZ (compressed KML) files.\n * KMZ is a zipped KML file used by Google Earth.\n */\nexport const KMZ_EXTENSIONS = ['.kmz'];\n\n/**\n * File extensions for GPX (GPS Exchange Format) files.\n * Common format for GPS tracks, waypoints, and routes.\n */\nexport const GPX_EXTENSIONS = ['.gpx'];\n\n/**\n * File extensions for FlatGeobuf files.\n * A performant binary encoding for geographic data.\n */\nexport const FLATGEOBUF_EXTENSIONS = ['.fgb'];\n\n/**\n * File extensions for GML (Geography Markup Language) files.\n * OGC standard XML-based format.\n */\nexport const GML_EXTENSIONS = ['.gml'];\n\n/**\n * File extensions for TopoJSON files.\n * An extension of GeoJSON that encodes topology.\n */\nexport const TOPOJSON_EXTENSIONS = ['.topojson'];\n\n/**\n * File extensions for CSV files with geometry.\n * Can contain WKT geometry or lat/lon columns.\n */\nexport const CSV_EXTENSIONS = ['.csv'];\n\n/**\n * File extensions for Excel files with geometry.\n * Can contain WKT geometry or lat/lon columns.\n */\nexport const XLSX_EXTENSIONS = ['.xlsx', '.xls'];\n\n/**\n * File extensions for DXF (AutoCAD Drawing Exchange Format) files.\n */\nexport const DXF_EXTENSIONS = ['.dxf'];\n\n/**\n * Extensions processed via shpjs (Shapefile library).\n */\nexport const SHPJS_EXTENSIONS = [...SHAPEFILE_EXTENSIONS];\n\n/**\n * Extensions processed via DuckDB spatial (GDAL-powered).\n */\nexport const DUCKDB_EXTENSIONS = [\n ...GEOPACKAGE_EXTENSIONS,\n ...GEOPARQUET_EXTENSIONS,\n ...KML_EXTENSIONS,\n ...KMZ_EXTENSIONS,\n ...GPX_EXTENSIONS,\n ...FLATGEOBUF_EXTENSIONS,\n ...GML_EXTENSIONS,\n ...TOPOJSON_EXTENSIONS,\n ...CSV_EXTENSIONS,\n ...XLSX_EXTENSIONS,\n ...DXF_EXTENSIONS,\n];\n\n/**\n * All supported extensions for advanced formats (require DuckDB or shpjs).\n */\nexport const ADVANCED_EXTENSIONS = [...SHPJS_EXTENSIONS, ...DUCKDB_EXTENSIONS];\n\n/**\n * All supported vector file extensions.\n */\nexport const ALL_EXTENSIONS = [...GEOJSON_EXTENSIONS, ...ADVANCED_EXTENSIONS];\n\n/**\n * Detects the vector format from a filename.\n *\n * @param filename - The filename to check.\n * @returns The detected vector format.\n *\n * @example\n * ```typescript\n * detectFormat('data.geojson'); // 'geojson'\n * detectFormat('counties.shp'); // 'shapefile'\n * detectFormat('data.gpkg'); // 'geopackage'\n * detectFormat('track.gpx'); // 'gpx'\n * detectFormat('places.kml'); // 'kml'\n * detectFormat('data.zip'); // 'shapefile'\n * detectFormat('data.txt'); // 'unknown'\n * ```\n */\nexport function detectFormat(filename: string): VectorFormat {\n const ext = getFileExtension(filename);\n\n if (GEOJSON_EXTENSIONS.includes(ext)) {\n return 'geojson';\n }\n\n if (SHAPEFILE_EXTENSIONS.includes(ext)) {\n return 'shapefile';\n }\n\n if (GEOPACKAGE_EXTENSIONS.includes(ext)) {\n return 'geopackage';\n }\n\n if (GEOPARQUET_EXTENSIONS.includes(ext)) {\n return 'geoparquet';\n }\n\n if (KML_EXTENSIONS.includes(ext)) {\n return 'kml';\n }\n\n if (KMZ_EXTENSIONS.includes(ext)) {\n return 'kmz';\n }\n\n if (GPX_EXTENSIONS.includes(ext)) {\n return 'gpx';\n }\n\n if (FLATGEOBUF_EXTENSIONS.includes(ext)) {\n return 'flatgeobuf';\n }\n\n if (GML_EXTENSIONS.includes(ext)) {\n return 'gml';\n }\n\n if (TOPOJSON_EXTENSIONS.includes(ext)) {\n return 'topojson';\n }\n\n if (CSV_EXTENSIONS.includes(ext)) {\n return 'csv';\n }\n\n if (XLSX_EXTENSIONS.includes(ext)) {\n return 'xlsx';\n }\n\n if (DXF_EXTENSIONS.includes(ext)) {\n return 'dxf';\n }\n\n return 'unknown';\n}\n\n/**\n * Checks if a format requires DuckDB for processing.\n * Note: Shapefiles use shpjs, not DuckDB.\n *\n * @param format - The vector format to check.\n * @returns True if the format requires DuckDB.\n *\n * @example\n * ```typescript\n * requiresDuckDB('geojson'); // false\n * requiresDuckDB('shapefile'); // false (uses shpjs)\n * requiresDuckDB('geopackage'); // true\n * requiresDuckDB('geoparquet'); // true\n * requiresDuckDB('kml'); // true\n * requiresDuckDB('gpx'); // true\n * ```\n */\nexport function requiresDuckDB(format: VectorFormat): boolean {\n return (\n format === 'geopackage' ||\n format === 'geoparquet' ||\n format === 'kml' ||\n format === 'kmz' ||\n format === 'gpx' ||\n format === 'flatgeobuf' ||\n format === 'gml' ||\n format === 'topojson' ||\n format === 'csv' ||\n format === 'xlsx' ||\n format === 'dxf'\n );\n}\n\n/**\n * Checks if a format requires a special converter (not native GeoJSON).\n *\n * @param format - The vector format to check.\n * @returns True if the format requires conversion.\n */\nexport function requiresConversion(format: VectorFormat): boolean {\n return format !== 'geojson' && format !== 'unknown';\n}\n\n/**\n * Gets the file extension from a filename (lowercase, with leading dot).\n *\n * @param filename - The filename to extract extension from.\n * @returns The file extension (e.g., '.geojson') or empty string.\n *\n * @example\n * ```typescript\n * getFileExtension('data.GeoJSON'); // '.geojson'\n * getFileExtension('file.tar.gz'); // '.gz'\n * getFileExtension('noextension'); // ''\n * ```\n */\nexport function getFileExtension(filename: string): string {\n const lastDot = filename.lastIndexOf('.');\n if (lastDot === -1 || lastDot === filename.length - 1) {\n return '';\n }\n return filename.slice(lastDot).toLowerCase();\n}\n\n/**\n * Reads a File object as an ArrayBuffer.\n *\n * @param file - The file to read.\n * @returns Promise resolving to the file contents as ArrayBuffer.\n *\n * @example\n * ```typescript\n * const input = document.querySelector('input[type=\"file\"]');\n * const file = input.files[0];\n * const buffer = await readFileAsBuffer(file);\n * ```\n */\nexport function readFileAsBuffer(file: File): Promise<ArrayBuffer> {\n return file.arrayBuffer();\n}\n\n/**\n * Gets the list of accepted file extensions based on options.\n *\n * @param enableAdvanced - Whether to include advanced format extensions.\n * @returns Array of accepted file extensions.\n *\n * @example\n * ```typescript\n * getAcceptedExtensions(false); // ['.geojson', '.json']\n * getAcceptedExtensions(true); // ['.geojson', '.json', '.shp', '.zip', '.gpkg', '.kml', ...]\n * ```\n */\nexport function getAcceptedExtensions(enableAdvanced: boolean): string[] {\n if (enableAdvanced) {\n return ALL_EXTENSIONS;\n }\n return GEOJSON_EXTENSIONS;\n}\n\n/**\n * Checks if a file extension is valid for the given options.\n *\n * @param filename - The filename to check.\n * @param enableAdvanced - Whether advanced formats are enabled.\n * @returns True if the extension is accepted.\n *\n * @example\n * ```typescript\n * isValidExtension('data.geojson', false); // true\n * isValidExtension('data.gpkg', false); // false\n * isValidExtension('data.gpkg', true); // true\n * isValidExtension('track.gpx', true); // true\n * ```\n */\nexport function isValidExtension(filename: string, enableAdvanced: boolean): boolean {\n const ext = getFileExtension(filename);\n const accepted = getAcceptedExtensions(enableAdvanced);\n return accepted.includes(ext);\n}\n\n/**\n * Gets a human-readable format name for display.\n *\n * @param format - The vector format.\n * @returns Human-readable format name.\n *\n * @example\n * ```typescript\n * getFormatDisplayName('geojson'); // 'GeoJSON'\n * getFormatDisplayName('shapefile'); // 'Shapefile'\n * getFormatDisplayName('kml'); // 'KML'\n * getFormatDisplayName('gpx'); // 'GPX'\n * ```\n */\nexport function getFormatDisplayName(format: VectorFormat): string {\n switch (format) {\n case 'geojson':\n return 'GeoJSON';\n case 'shapefile':\n return 'Shapefile';\n case 'geopackage':\n return 'GeoPackage';\n case 'geoparquet':\n return 'GeoParquet';\n case 'kml':\n return 'KML';\n case 'kmz':\n return 'KMZ';\n case 'gpx':\n return 'GPX';\n case 'flatgeobuf':\n return 'FlatGeobuf';\n case 'gml':\n return 'GML';\n case 'topojson':\n return 'TopoJSON';\n case 'csv':\n return 'CSV';\n case 'xlsx':\n return 'Excel';\n case 'dxf':\n return 'DXF';\n default:\n return 'Unknown';\n }\n}\n\n/**\n * Gets a description of the format for tooltips/help text.\n *\n * @param format - The vector format.\n * @returns Description of the format.\n */\nexport function getFormatDescription(format: VectorFormat): string {\n switch (format) {\n case 'geojson':\n return 'GeoJSON - Open standard format for geographic data';\n case 'shapefile':\n return 'Shapefile - Esri vector data format (.shp or .zip)';\n case 'geopackage':\n return 'GeoPackage - OGC standard SQLite-based format';\n case 'geoparquet':\n return 'GeoParquet - Columnar format for geospatial data';\n case 'kml':\n return 'KML - Keyhole Markup Language (Google Earth)';\n case 'kmz':\n return 'KMZ - Compressed KML (Google Earth)';\n case 'gpx':\n return 'GPX - GPS Exchange Format for tracks and waypoints';\n case 'flatgeobuf':\n return 'FlatGeobuf - Fast binary encoding for geographic data';\n case 'gml':\n return 'GML - Geography Markup Language (OGC standard)';\n case 'topojson':\n return 'TopoJSON - Topology-encoded GeoJSON extension';\n case 'csv':\n return 'CSV - Comma-separated values with geometry (WKT or lat/lon)';\n case 'xlsx':\n return 'Excel - Spreadsheet with geometry (WKT or lat/lon)';\n case 'dxf':\n return 'DXF - AutoCAD Drawing Exchange Format';\n default:\n return 'Unknown format';\n }\n}\n","import type { IControl, Map as MapLibreMap } from 'maplibre-gl';\nimport type {\n VectorDatasetControlOptions,\n VectorDatasetControlState,\n VectorDatasetEvent,\n VectorDatasetEventHandler,\n LoadedDataset,\n VectorLayerStyle,\n VectorFormat,\n} from './types';\nimport { generateId } from '../utils/helpers';\nimport {\n detectFormat,\n requiresConversion,\n requiresDuckDB,\n getAcceptedExtensions,\n isValidExtension,\n getFormatDisplayName,\n readFileAsBuffer,\n} from '../utils/fileHelpers';\nimport type { DuckDBConverter } from '../converters/DuckDBConverter';\nimport type { ShapefileConverter } from '../converters/ShapefileConverter';\n\n/**\n * Default style for vector layers.\n */\nconst DEFAULT_STYLE: Required<VectorLayerStyle> = {\n fillColor: '#3388ff',\n fillOpacity: 0.3,\n strokeColor: '#3388ff',\n strokeWidth: 2,\n strokeOpacity: 1,\n circleRadius: 6,\n circleColor: '#3388ff',\n circleStrokeColor: '#ffffff',\n circleStrokeWidth: 2,\n};\n\n/**\n * Default options for the VectorDatasetControl.\n */\nconst DEFAULT_OPTIONS: Required<Omit<VectorDatasetControlOptions, 'onConversionProgress' | 'duckdbBundleUrl'>> & {\n onConversionProgress: VectorDatasetControlOptions['onConversionProgress'];\n duckdbBundleUrl: VectorDatasetControlOptions['duckdbBundleUrl'];\n} = {\n position: 'top-right',\n className: '',\n visible: true,\n showDropZone: true,\n acceptedExtensions: ['.geojson', '.json'],\n multiple: true,\n defaultStyle: DEFAULT_STYLE,\n fitBounds: true,\n fitBoundsPadding: 50,\n maxFileSize: 52428800, // 50MB\n backgroundColor: 'rgba(255, 255, 255, 0.9)',\n borderRadius: 4,\n opacity: 1,\n minzoom: 0,\n maxzoom: 24,\n enableAdvancedFormats: false,\n duckdbBundleUrl: undefined,\n onConversionProgress: undefined,\n};\n\n/**\n * Upload icon SVG for the button.\n */\nconst UPLOAD_ICON = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"/><polyline points=\"17 8 12 3 7 8\"/><line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"15\"/></svg>`;\n\n/**\n * A vector dataset upload control for MapLibre GL maps.\n *\n * Enables loading GeoJSON files via file upload button or drag-and-drop.\n *\n * @example\n * ```typescript\n * const vectorControl = new VectorDatasetControl({\n * fitBounds: true,\n * defaultStyle: {\n * fillColor: '#ff0000',\n * fillOpacity: 0.5,\n * },\n * });\n * map.addControl(vectorControl, 'top-right');\n *\n * vectorControl.on('load', (event) => {\n * console.log('Loaded dataset:', event.dataset?.filename);\n * });\n * ```\n */\nexport class VectorDatasetControl implements IControl {\n private _container?: HTMLElement;\n private _button?: HTMLButtonElement;\n private _fileInput?: HTMLInputElement;\n private _dropZone?: HTMLElement;\n private _options: Required<Omit<VectorDatasetControlOptions, 'onConversionProgress' | 'duckdbBundleUrl'>> & {\n onConversionProgress: VectorDatasetControlOptions['onConversionProgress'];\n duckdbBundleUrl: VectorDatasetControlOptions['duckdbBundleUrl'];\n };\n private _state: VectorDatasetControlState;\n private _eventHandlers: Map<VectorDatasetEvent, Set<VectorDatasetEventHandler>> = new Map();\n private _map?: MapLibreMap;\n private _handleZoom?: () => void;\n private _zoomVisible: boolean = true;\n private _boundDragOver?: (e: DragEvent) => void;\n private _boundDragLeave?: (e: DragEvent) => void;\n private _boundDrop?: (e: DragEvent) => void;\n private _duckdbConverter?: DuckDBConverter;\n private _shapefileConverter?: ShapefileConverter;\n private _loadingOverlay?: HTMLElement;\n private _loadingText?: HTMLElement;\n private _loadingProgress?: HTMLElement;\n\n /**\n * Creates a new VectorDatasetControl instance.\n *\n * @param options - Configuration options for the vector dataset control.\n */\n constructor(options?: VectorDatasetControlOptions) {\n // Determine accepted extensions based on enableAdvancedFormats\n const enableAdvanced = options?.enableAdvancedFormats ?? DEFAULT_OPTIONS.enableAdvancedFormats;\n const acceptedExtensions =\n options?.acceptedExtensions ?? getAcceptedExtensions(enableAdvanced);\n\n this._options = {\n ...DEFAULT_OPTIONS,\n ...options,\n acceptedExtensions,\n defaultStyle: { ...DEFAULT_STYLE, ...options?.defaultStyle },\n };\n this._state = {\n visible: this._options.visible,\n isDragging: false,\n isLoading: false,\n loadedDatasets: [],\n error: null,\n };\n }\n\n /**\n * Called when the control is added to the map.\n *\n * @param map - The MapLibre GL map instance.\n * @returns The control's container element.\n */\n onAdd(map: MapLibreMap): HTMLElement {\n this._map = map;\n this._container = this._createContainer();\n\n // Set up zoom listener\n this._handleZoom = () => this._checkZoomVisibility();\n this._map.on('zoom', this._handleZoom);\n\n // Set up drag-and-drop on the map container\n if (this._options.showDropZone) {\n this._setupDragAndDrop();\n }\n\n this._checkZoomVisibility();\n\n return this._container;\n }\n\n /**\n * Called when the control is removed from the map.\n */\n onRemove(): void {\n // Remove drag-and-drop listeners\n this._removeDragAndDrop();\n\n // Remove all loaded sources and layers\n this._removeAllDatasets();\n\n // Dispose converters if present\n if (this._duckdbConverter) {\n this._duckdbConverter.dispose();\n this._duckdbConverter = undefined;\n }\n if (this._shapefileConverter) {\n this._shapefileConverter.dispose();\n this._shapefileConverter = undefined;\n }\n\n // Remove zoom listener\n if (this._map && this._handleZoom) {\n this._map.off('zoom', this._handleZoom);\n this._handleZoom = undefined;\n }\n\n this._map = undefined;\n this._container?.parentNode?.removeChild(this._container);\n this._container = undefined;\n this._button = undefined;\n this._fileInput = undefined;\n this._dropZone = undefined;\n this._eventHandlers.clear();\n }\n\n /**\n * Shows the control.\n */\n show(): void {\n if (!this._state.visible) {\n this._state.visible = true;\n this._updateDisplayState();\n this._emit('show');\n }\n }\n\n /**\n * Hides the control.\n */\n hide(): void {\n if (this._state.visible) {\n this._state.visible = false;\n this._updateDisplayState();\n this._emit('hide');\n }\n }\n\n /**\n * Gets the current state.\n *\n * @returns The current vector dataset control state.\n */\n getState(): VectorDatasetControlState {\n return { ...this._state, loadedDatasets: [...this._state.loadedDatasets] };\n }\n\n /**\n * Gets all loaded datasets.\n *\n * @returns Array of loaded datasets.\n */\n getLoadedDatasets(): LoadedDataset[] {\n return [...this._state.loadedDatasets];\n }\n\n /**\n * Removes a dataset by ID.\n *\n * @param datasetId - The ID of the dataset to remove.\n */\n removeDataset(datasetId: string): void {\n const dataset = this._state.loadedDatasets.find((d) => d.id === datasetId);\n if (!dataset || !this._map) return;\n\n try {\n // Remove layers first\n for (const layerId of dataset.layerIds) {\n if (this._map.getLayer(layerId)) {\n this._map.removeLayer(layerId);\n }\n }\n\n // Remove source\n if (this._map.getSource(dataset.sourceId)) {\n this._map.removeSource(dataset.sourceId);\n }\n\n // Update state\n this._state.loadedDatasets = this._state.loadedDatasets.filter((d) => d.id !== datasetId);\n this._emit('update');\n } catch (error) {\n console.error('Failed to remove dataset:', error);\n }\n }\n\n /**\n * Removes all loaded datasets.\n */\n removeAllDatasets(): void {\n this._removeAllDatasets();\n this._emit('update');\n }\n\n /**\n * Programmatically loads a GeoJSON object.\n *\n * @param geojson - The GeoJSON object to load.\n * @param filename - Optional filename for the dataset.\n * @returns The loaded dataset or null if failed.\n */\n async loadGeoJSON(\n geojson: GeoJSON.GeoJSON,\n filename: string = 'data.geojson'\n ): Promise<LoadedDataset | null> {\n return this._processGeoJSON(geojson, filename, 'geojson');\n }\n\n /**\n * Registers an event handler.\n *\n * @param event - The event type to listen for.\n * @param handler - The callback function.\n */\n on(event: VectorDatasetEvent, handler: VectorDatasetEventHandler): void {\n if (!this._eventHandlers.has(event)) {\n this._eventHandlers.set(event, new Set());\n }\n this._eventHandlers.get(event)!.add(handler);\n }\n\n /**\n * Removes an event handler.\n *\n * @param event - The event type.\n * @param handler - The callback function to remove.\n */\n off(event: VectorDatasetEvent, handler: VectorDatasetEventHandler): void {\n this._eventHandlers.get(event)?.delete(handler);\n }\n\n /**\n * Updates control options and re-renders.\n *\n * @param options - Partial options to update.\n */\n update(options: Partial<VectorDatasetControlOptions>): void {\n this._options = {\n ...this._options,\n ...options,\n defaultStyle: { ...this._options.defaultStyle, ...options?.defaultStyle },\n };\n\n if (options.visible !== undefined) {\n this._state.visible = options.visible;\n }\n\n this._updateDisplayState();\n this._emit('update');\n }\n\n /**\n * Emits an event to all registered handlers.\n *\n * @param event - The event type to emit.\n * @param dataset - Optional dataset for load events.\n * @param error - Optional error message for error events.\n * @param filename - Optional filename for error events.\n */\n private _emit(\n event: VectorDatasetEvent,\n dataset?: LoadedDataset,\n error?: string,\n filename?: string\n ): void {\n const handlers = this._eventHandlers.get(event);\n if (handlers) {\n const eventData = {\n type: event,\n state: this.getState(),\n dataset,\n error,\n filename,\n };\n handlers.forEach((handler) => handler(eventData));\n }\n }\n\n /**\n * Creates the main container element.\n *\n * @returns The container element.\n */\n private _createContainer(): HTMLElement {\n const container = document.createElement('div');\n container.className = `maplibregl-ctrl maplibregl-ctrl-group maplibre-gl-vector-dataset${\n this._options.className ? ` ${this._options.className}` : ''\n }`;\n\n const shouldShow = this._state.visible && this._zoomVisible;\n if (!shouldShow) {\n container.style.display = 'none';\n }\n\n // Apply custom styles\n if (this._options.backgroundColor) {\n container.style.backgroundColor = this._options.backgroundColor;\n }\n if (this._options.borderRadius) {\n container.style.borderRadius = `${this._options.borderRadius}px`;\n }\n if (this._options.opacity !== 1) {\n container.style.opacity = String(this._options.opacity);\n }\n\n // Create hidden file input\n this._fileInput = document.createElement('input');\n this._fileInput.type = 'file';\n this._fileInput.accept = this._options.acceptedExtensions.join(',');\n this._fileInput.multiple = this._options.multiple;\n this._fileInput.style.display = 'none';\n this._fileInput.addEventListener('change', (e) => this._handleFileSelect(e));\n container.appendChild(this._fileInput);\n\n // Create button\n this._button = document.createElement('button');\n this._button.type = 'button';\n this._button.className = 'maplibre-gl-vector-dataset-button';\n const buttonLabel = this._options.enableAdvancedFormats\n ? 'Load vector file (GeoJSON, Shapefile, GeoPackage, KML, GPX, and more)'\n : 'Load GeoJSON file';\n this._button.title = buttonLabel;\n this._button.setAttribute('aria-label', buttonLabel);\n this._button.innerHTML = UPLOAD_ICON;\n this._button.addEventListener('click', () => this._fileInput?.click());\n container.appendChild(this._button);\n\n return container;\n }\n\n /**\n * Sets up drag-and-drop event listeners on the map container.\n */\n private _setupDragAndDrop(): void {\n if (!this._map) return;\n\n const mapContainer = this._map.getContainer();\n\n // Create drop zone overlay\n this._dropZone = document.createElement('div');\n this._dropZone.className = 'maplibre-gl-vector-dataset-dropzone';\n const dropzoneText = this._options.enableAdvancedFormats\n ? 'Drop vector files here (GeoJSON, Shapefile, GeoPackage, KML, GPX, CSV, and more)'\n : 'Drop GeoJSON files here';\n this._dropZone.innerHTML = `\n <div class=\"maplibre-gl-vector-dataset-dropzone-content\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"48\" height=\"48\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"/>\n <polyline points=\"17 8 12 3 7 8\"/>\n <line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"15\"/>\n </svg>\n <p>${dropzoneText}</p>\n </div>\n `;\n this._dropZone.style.display = 'none';\n mapContainer.appendChild(this._dropZone);\n\n // Create loading overlay\n this._loadingOverlay = document.createElement('div');\n this._loadingOverlay.className = 'maplibre-gl-vector-dataset-loading';\n this._loadingOverlay.innerHTML = `\n <div class=\"maplibre-gl-vector-dataset-loading-content\">\n <div class=\"maplibre-gl-vector-dataset-spinner\"></div>\n <p class=\"maplibre-gl-vector-dataset-loading-text\">Loading...</p>\n <p class=\"maplibre-gl-vector-dataset-loading-progress\"></p>\n </div>\n `;\n this._loadingOverlay.style.display = 'none';\n this._loadingText = this._loadingOverlay.querySelector('.maplibre-gl-vector-dataset-loading-text') as HTMLElement;\n this._loadingProgress = this._loadingOverlay.querySelector('.maplibre-gl-vector-dataset-loading-progress') as HTMLElement;\n mapContainer.appendChild(this._loadingOverlay);\n\n // Bind event handlers\n this._boundDragOver = (e: DragEvent) => this._handleDragOver(e);\n this._boundDragLeave = (e: DragEvent) => this._handleDragLeave(e);\n this._boundDrop = (e: DragEvent) => this._handleDrop(e);\n\n mapContainer.addEventListener('dragover', this._boundDragOver);\n mapContainer.addEventListener('dragleave', this._boundDragLeave);\n mapContainer.addEventListener('drop', this._boundDrop);\n }\n\n /**\n * Removes drag-and-drop event listeners.\n */\n private _removeDragAndDrop(): void {\n if (!this._map) return;\n\n const mapContainer = this._map.getContainer();\n\n if (this._boundDragOver) {\n mapContainer.removeEventListener('dragover', this._boundDragOver);\n }\n if (this._boundDragLeave) {\n mapContainer.removeEventListener('dragleave', this._boundDragLeave);\n }\n if (this._boundDrop) {\n mapContainer.removeEventListener('drop', this._boundDrop);\n }\n\n if (this._dropZone && this._dropZone.parentNode) {\n this._dropZone.parentNode.removeChild(this._dropZone);\n }\n\n if (this._loadingOverlay && this._loadingOverlay.parentNode) {\n this._loadingOverlay.parentNode.removeChild(this._loadingOverlay);\n }\n }\n\n /**\n * Handles dragover event.\n *\n * @param e - The drag event.\n */\n private _handleDragOver(e: DragEvent): void {\n e.preventDefault();\n e.stopPropagation();\n\n if (!this._state.isDragging) {\n this._state.isDragging = true;\n if (this._dropZone) {\n this._dropZone.style.display = 'flex';\n }\n this._emit('dragenter');\n }\n }\n\n /**\n * Handles dragleave event.\n *\n * @param e - The drag event.\n */\n private _handleDragLeave(e: DragEvent): void {\n e.preventDefault();\n e.stopPropagation();\n\n // Check if we're leaving the map container entirely\n const mapContainer = this._map?.getContainer();\n if (mapContainer && !mapContainer.contains(e.relatedTarget as Node)) {\n this._state.isDragging = false;\n if (this._dropZone) {\n this._dropZone.style.display = 'none';\n }\n this._emit('dragleave');\n }\n }\n\n /**\n * Handles drop event.\n *\n * @param e - The drag event.\n */\n private _handleDrop(e: DragEvent): void {\n e.preventDefault();\n e.stopPropagation();\n\n this._state.isDragging = false;\n if (this._dropZone) {\n this._dropZone.style.display = 'none';\n }\n\n const files = e.dataTransfer?.files;\n if (files && files.length > 0) {\n this._processFiles(Array.from(files));\n }\n }\n\n /**\n * Handles file input change event.\n *\n * @param e - The change event.\n */\n private _handleFileSelect(e: Event): void {\n const input = e.target as HTMLInputElement;\n const files = input.files;\n if (files && files.length > 0) {\n this._processFiles(Array.from(files));\n }\n // Reset input to allow selecting the same file again\n input.value = '';\n }\n\n /**\n * Processes uploaded files.\n *\n * @param files - Array of files to process.\n */\n private async _processFiles(files: File[]): Promise<void> {\n this._state.isLoading = true;\n this._state.error = null;\n this._updateButtonState();\n\n for (const file of files) {\n // Validate file extension\n if (!isValidExtension(file.name, this._options.enableAdvancedFormats)) {\n this._state.error = `Invalid file type: ${file.name}. Accepted: ${this._options.acceptedExtensions.join(', ')}`;\n this._emit('error', undefined, this._state.error, file.name);\n continue;\n }\n\n // Validate file size\n if (file.size > this._options.maxFileSize) {\n const maxSizeMB = (this._options.maxFileSize / (1024 * 1024)).toFixed(1);\n this._state.error = `File too large: ${file.name}. Maximum size: ${maxSizeMB}MB`;\n this._emit('error', undefined, this._state.error, file.name);\n continue;\n }\n\n // Detect format and route to appropriate handler\n const format = detectFormat(file.name);\n\n try {\n if (requiresConversion(format)) {\n // Process with appropriate converter (shpjs for Shapefile, DuckDB for GeoPackage/GeoParquet)\n if (!this._options.enableAdvancedFormats) {\n this._state.error = `${getFormatDisplayName(format)} files require enableAdvancedFormats: true`;\n this._emit('error', undefined, this._state.error, file.name);\n continue;\n }\n // Show loading indicator for advanced formats\n this._showLoading(`Loading ${file.name}...`);\n await this._processAdvancedFormat(file, format);\n this._hideLoading();\n } else {\n // Process as GeoJSON\n this._showLoading(`Loading ${file.name}...`);\n const text = await file.text();\n const geojson = JSON.parse(text) as GeoJSON.GeoJSON;\n await this._processGeoJSON(geojson, file.name, 'geojson');\n this._hideLoading();\n }\n } catch (error) {\n this._hideLoading();\n this._state.error = `Failed to process ${file.name}: ${error instanceof Error ? error.message : 'Unknown error'}`;\n this._emit('error', undefined, this._state.error, file.name);\n }\n }\n\n this._state.isLoading = false;\n this._updateButtonState();\n }\n\n /**\n * Processes a file using the appropriate converter.\n *\n * @param file - The file to process.\n * @param format - The detected vector format.\n */\n private async _processAdvancedFormat(file: File, format: VectorFormat): Promise<void> {\n // Create a progress callback that updates both the loading indicator and user's callback\n const progressCallback = (progress: { stage: string; percent?: number; message?: string }) => {\n // Update loading indicator\n const message = progress.message || `Processing ${file.name}...`;\n const progressText = progress.percent !== undefined ? `${progress.percent}%` : '';\n this._updateLoading(message, progressText);\n\n // Call user's callback if provided\n this._options.onConversionProgress?.(progress as Parameters<NonNullable<typeof this._options.onConversionProgress>>[0]);\n };\n\n // Read file as buffer\n this._updateLoading(`Reading ${file.name}...`);\n const buffer = await readFileAsBuffer(file);\n\n if (format === 'shapefile') {\n // Use shpjs for Shapefiles\n if (!this._shapefileConverter) {\n this._updateLoading('Loading Shapefile converter...');\n const { getShapefileConverter } = await import('../converters/ShapefileConverter');\n this._shapefileConverter = getShapefileConverter();\n }\n\n const result = await this._shapefileConverter.convert(\n buffer,\n file.name,\n progressCallback\n );\n\n if (result.geojson) {\n this._updateLoading('Adding to map...');\n await this._processGeoJSON(result.geojson, file.name, format);\n }\n } else if (requiresDuckDB(format)) {\n // Use DuckDB for GeoPackage, GeoParquet, KML, GPX, FlatGeobuf, GML, TopoJSON, CSV, Excel, DXF\n if (!this._duckdbConverter) {\n this._updateLoading('Loading DuckDB converter...');\n const { getDuckDBConverter } = await import('../converters/DuckDBConverter');\n this._duckdbConverter = getDuckDBConverter();\n\n // Configure custom bundle URL if provided\n if (this._options.duckdbBundleUrl) {\n const { DuckDBConverter } = await import('../converters/DuckDBConverter');\n this._duckdbConverter = new DuckDBConverter(this._options.duckdbBundleUrl);\n }\n }\n\n const result = await this._duckdbConverter.convert(\n buffer,\n file.name,\n progressCallback\n );\n\n if (result.geojson) {\n this._updateLoading('Adding to map...');\n await this._processGeoJSON(result.geojson, file.name, format);\n }\n }\n }\n\n /**\n * Processes a GeoJSON object and adds it to the map.\n *\n * @param geojson - The GeoJSON object to process.\n * @param filename - The filename of the dataset.\n * @param originalFormat - The original file format.\n * @returns The loaded dataset or null if failed.\n */\n private async _processGeoJSON(\n geojson: GeoJSON.GeoJSON,\n filename: string,\n originalFormat: VectorFormat = 'geojson'\n ): Promise<LoadedDataset | null> {\n if (!this._map) return null;\n\n // Validate GeoJSON structure\n if (!geojson.type) {\n this._state.error = `Invalid GeoJSON: missing type property in ${filename}`;\n this._emit('error', undefined, this._state.error, filename);\n return null;\n }\n\n // Normalize to FeatureCollection\n let featureCollection: GeoJSON.FeatureCollection;\n if (geojson.type === 'FeatureCollection') {\n featureCollection = geojson as GeoJSON.FeatureCollection;\n } else if (geojson.type === 'Feature') {\n featureCollection = {\n type: 'FeatureCollection',\n features: [geojson as GeoJSON.Feature],\n };\n } else {\n // It's a geometry object\n featureCollection = {\n type: 'FeatureCollection',\n features: [\n {\n type: 'Feature',\n properties: {},\n geometry: geojson as GeoJSON.Geometry,\n },\n ],\n };\n }\n\n // Generate unique IDs\n const datasetId = generateId('vds');\n const sourceId = `${datasetId}-source`;\n\n // Analyze geometry types\n const geometryTypes = new Set<string>();\n for (const feature of featureCollection.features) {\n if (feature.geometry) {\n geometryTypes.add(feature.geometry.type);\n }\n }\n\n try {\n // Add source\n this._map.addSource(sourceId, {\n type: 'geojson',\n data: featureCollection,\n generateId: true,\n });\n\n // Add layers based on geometry types\n const layerIds: string[] = [];\n const style = this._options.defaultStyle;\n\n // Add polygon fill layer\n if (geometryTypes.has('Polygon') || geometryTypes.has('MultiPolygon')) {\n const fillLayerId = `${datasetId}-fill`;\n this._map.addLayer({\n id: fillLayerId,\n type: 'fill',\n source: sourceId,\n filter: [\n 'any',\n ['==', ['geometry-type'], 'Polygon'],\n ['==', ['geometry-type'], 'MultiPolygon'],\n ],\n paint: {\n 'fill-color': style.fillColor,\n 'fill-opacity': style.fillOpacity,\n },\n });\n layerIds.push(fillLayerId);\n\n // Add polygon outline\n const outlineLayerId = `${datasetId}-outline`;\n this._map.addLayer({\n id: outlineLayerId,\n type: 'line',\n source: sourceId,\n filter: [\n 'any',\n ['==', ['geometry-type'], 'Polygon'],\n ['==', ['geometry-type'], 'MultiPolygon'],\n ],\n paint: {\n 'line-color': style.strokeColor,\n 'line-width': style.strokeWidth,\n 'line-opacity': style.strokeOpacity,\n },\n });\n layerIds.push(outlineLayerId);\n }\n\n // Add line layer\n if (geometryTypes.has('LineString') || geometryTypes.has('MultiLineString')) {\n const lineLayerId = `${datasetId}-line`;\n this._map.addLayer({\n id: lineLayerId,\n type: 'line',\n source: sourceId,\n filter: [\n 'any',\n ['==', ['geometry-type'], 'LineString'],\n ['==', ['geometry-type'], 'MultiLineString'],\n ],\n paint: {\n 'line-color': style.strokeColor,\n 'line-width': style.strokeWidth,\n 'line-opacity': style.strokeOpacity,\n },\n });\n layerIds.push(lineLayerId);\n }\n\n // Add point layer\n if (geometryTypes.has('Point') || geometryTypes.has('MultiPoint')) {\n const pointLayerId = `${datasetId}-point`;\n this._map.addLayer({\n id: pointLayerId,\n type: 'circle',\n source: sourceId,\n filter: [\n 'any',\n ['==', ['geometry-type'], 'Point'],\n ['==', ['geometry-type'], 'MultiPoint'],\n ],\n paint: {\n 'circle-radius': style.circleRadius,\n 'circle-color': style.circleColor,\n 'circle-stroke-color': style.circleStrokeColor,\n 'circle-stroke-width': style.circleStrokeWidth,\n },\n });\n layerIds.push(pointLayerId);\n }\n\n // Create dataset record\n const dataset: LoadedDataset = {\n id: datasetId,\n filename,\n sourceId,\n layerIds,\n featureCount: featureCollection.features.length,\n geometryTypes: Array.from(geometryTypes) as LoadedDataset['geometryTypes'],\n loadedAt: new Date(),\n originalFormat,\n };\n\n this._state.loadedDatasets.push(dataset);\n\n // Fit bounds if enabled\n if (this._options.fitBounds && featureCollection.features.length > 0) {\n this._fitToData(featureCollection);\n }\n\n this._emit('load', dataset);\n this._emit('update');\n\n return dataset;\n } catch (error) {\n this._state.error = `Failed to add ${filename} to map: ${error instanceof Error ? error.message : 'Unknown error'}`;\n this._emit('error', undefined, this._state.error, filename);\n return null;\n }\n }\n\n /**\n * Fits the map view to the loaded data bounds.\n *\n * @param geojson - The GeoJSON FeatureCollection to fit to.\n */\n private _fitToData(geojson: GeoJSON.FeatureCollection): void {\n if (!this._map) return;\n\n // Calculate bounds from all features\n let minLng = Infinity,\n minLat = Infinity,\n maxLng = -Infinity,\n maxLat = -Infinity;\n\n const processCoords = (coords: number[]) => {\n minLng = Math.min(minLng, coords[0]);\n maxLng = Math.max(maxLng, coords[0]);\n minLat = Math.min(minLat, coords[1]);\n maxLat = Math.max(maxLat, coords[1]);\n };\n\n const processCoordArray = (coords: number[][] | number[][][] | number[][][][]) => {\n for (const item of coords) {\n if (typeof item[0] === 'number') {\n processCoords(item as number[]);\n } else {\n processCoordArray(item as number[][] | number[][][]);\n }\n }\n };\n\n for (const feature of geojson.features) {\n if (!feature.geometry) continue;\n\n const geom = feature.geometry;\n if (geom.type === 'Point') {\n processCoords(geom.coordinates);\n } else if (geom.type === 'MultiPoint' || geom.type === 'LineString') {\n processCoordArray(geom.coordinates);\n } else if (geom.type === 'MultiLineString' || geom.type === 'Polygon') {\n processCoordArray(geom.coordinates);\n } else if (geom.type === 'MultiPolygon') {\n processCoordArray(geom.coordinates);\n }\n }\n\n if (minLng !== Infinity) {\n this._map.fitBounds(\n [\n [minLng, minLat],\n [maxLng, maxLat],\n ],\n { padding: this._options.fitBoundsPadding }\n );\n }\n }\n\n /**\n * Removes all loaded datasets from the map.\n */\n private _removeAllDatasets(): void {\n for (const dataset of this._state.loadedDatasets) {\n if (this._map) {\n for (const layerId of dataset.layerIds) {\n if (this._map.getLayer(layerId)) {\n this._map.removeLayer(layerId);\n }\n }\n if (this._map.getSource(dataset.sourceId)) {\n this._map.removeSource(dataset.sourceId);\n }\n }\n }\n this._state.loadedDatasets = [];\n }\n\n /**\n * Checks if the current zoom level is within the visibility range.\n */\n private _checkZoomVisibility(): void {\n if (!this._map) return;\n\n const zoom = this._map.getZoom();\n const { minzoom, maxzoom } = this._options;\n const inRange = zoom >= minzoom && zoom <= maxzoom;\n\n if (inRange !== this._zoomVisible) {\n this._zoomVisible = inRange;\n this._updateDisplayState();\n }\n }\n\n /**\n * Updates the display state based on visibility and zoom level.\n */\n private _updateDisplayState(): void {\n if (!this._container) return;\n const shouldShow = this._state.visible && this._zoomVisible;\n this._container.style.display = shouldShow ? 'flex' : 'none';\n }\n\n /**\n * Updates the button state to reflect loading status.\n */\n private _updateButtonState(): void {\n if (!this._button) return;\n\n if (this._state.isLoading) {\n this._button.classList.add('maplibre-gl-vector-dataset-button--loading');\n this._button.disabled = true;\n } else {\n this._button.classList.remove('maplibre-gl-vector-dataset-button--loading');\n this._button.disabled = false;\n }\n }\n\n /**\n * Shows the loading overlay with an optional message.\n *\n * @param message - The loading message to display.\n * @param progress - Optional progress percentage or status.\n */\n private _showLoading(message: string, progress?: string): void {\n if (!this._loadingOverlay) return;\n this._loadingOverlay.style.display = 'flex';\n if (this._loadingText) {\n this._loadingText.textContent = message;\n }\n if (this._loadingProgress) {\n this._loadingProgress.textContent = progress || '';\n }\n }\n\n /**\n * Updates the loading overlay message.\n *\n * @param message - The loading message to display.\n * @param progress - Optional progress percentage or status.\n */\n private _updateLoading(message: string, progress?: string): void {\n if (this._loadingText) {\n this._loadingText.textContent = message;\n }\n if (this._loadingProgress) {\n this._loadingProgress.textContent = progress || '';\n }\n }\n\n /**\n * Hides the loading overlay.\n */\n private _hideLoading(): void {\n if (!this._loadingOverlay) return;\n this._loadingOverlay.style.display = 'none';\n }\n}\n","import maplibregl, { type IControl, type Map as MapLibreMap, type MapMouseEvent, Popup } from 'maplibre-gl';\nimport type {\n InspectControlOptions,\n InspectControlState,\n InspectedFeature,\n InspectHighlightStyle,\n InspectEvent,\n InspectEventHandler,\n} from './types';\nimport { generateId } from '../utils/helpers';\n\n/**\n * Default highlight style for selected features.\n */\nconst DEFAULT_HIGHLIGHT_STYLE: Required<InspectHighlightStyle> = {\n fillColor: '#ffff00',\n fillOpacity: 0.3,\n strokeColor: '#ffff00',\n strokeWidth: 3,\n circleRadius: 10,\n circleStrokeWidth: 3,\n};\n\n/**\n * Default options for the InspectControl.\n */\nconst DEFAULT_OPTIONS: Required<InspectControlOptions> = {\n position: 'top-right',\n className: '',\n visible: true,\n enabled: false,\n maxFeatures: 10,\n includeLayers: [],\n excludeLayers: [],\n highlightStyle: DEFAULT_HIGHLIGHT_STYLE,\n excludeProperties: [],\n showGeometryType: true,\n showLayerName: true,\n maxWidth: 320,\n maxHeight: 300,\n backgroundColor: 'rgba(255, 255, 255, 0.95)',\n borderRadius: 4,\n opacity: 1,\n fontSize: 13,\n fontColor: '#333',\n minzoom: 0,\n maxzoom: 24,\n};\n\n/**\n * SVG icon for the inspect button (info circle).\n */\nconst INSPECT_ICON = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"M12 16v-4\"/><path d=\"M12 8h.01\"/></svg>`;\n\n/**\n * A control for inspecting vector features on the map.\n *\n * Provides click-to-inspect functionality that shows feature properties/attributes\n * in a popup. Supports multiple features at the same location with navigation.\n *\n * @example\n * ```typescript\n * const inspectControl = new InspectControl({\n * excludeLayers: ['background'],\n * highlightStyle: { strokeColor: '#00ff00', strokeWidth: 4 },\n * });\n * map.addControl(inspectControl, 'top-right');\n *\n * // Listen for feature selection\n * inspectControl.on('featureselect', (event) => {\n * console.log('Selected:', event.feature);\n * });\n * ```\n */\nexport class InspectControl implements IControl {\n private _container?: HTMLElement;\n private _button?: HTMLButtonElement;\n private _options: Required<InspectControlOptions>;\n private _state: InspectControlState;\n private _eventHandlers: Map<InspectEvent, Set<InspectEventHandler>> = new Map();\n private _map?: MapLibreMap;\n private _handleZoom?: () => void;\n private _zoomVisible: boolean = true;\n private _popup?: Popup;\n private _highlightSourceId: string = '';\n private _highlightLayerIds: string[] = [];\n\n // Bound event handlers for proper cleanup\n private _boundClickHandler?: (e: MapMouseEvent) => void;\n\n /**\n * Creates a new InspectControl instance.\n *\n * @param options - Configuration options for the control.\n */\n constructor(options?: InspectControlOptions) {\n this._options = {\n ...DEFAULT_OPTIONS,\n ...options,\n highlightStyle: { ...DEFAULT_HIGHLIGHT_STYLE, ...options?.highlightStyle },\n };\n this._state = {\n visible: this._options.visible,\n enabled: this._options.enabled,\n inspectedFeatures: [],\n selectedIndex: 0,\n error: null,\n };\n this._highlightSourceId = `inspect-highlight-${generateId()}`;\n }\n\n /**\n * Called when the control is added to the map.\n *\n * @param map - The MapLibre GL map instance.\n * @returns The control's container element.\n */\n onAdd(map: MapLibreMap): HTMLElement {\n this._map = map;\n this._container = this._createContainer();\n\n // Set up zoom listener\n this._handleZoom = () => this._checkZoomVisibility();\n this._map.on('zoom', this._handleZoom);\n\n // Check initial zoom\n this._checkZoomVisibility();\n\n // If enabled by default, set up click handler\n if (this._state.enabled) {\n this._setupMapListeners();\n }\n\n return this._container;\n }\n\n /**\n * Called when the control is removed from the map.\n */\n onRemove(): void {\n if (this._map && this._handleZoom) {\n this._map.off('zoom', this._handleZoom);\n this._handleZoom = undefined;\n }\n this._removeMapListeners();\n this._removeHighlight();\n this._hidePopup();\n this._map = undefined;\n this._container?.parentNode?.removeChild(this._container);\n this._container = undefined;\n this._button = undefined;\n this._eventHandlers.clear();\n }\n\n /**\n * Enables inspect mode.\n */\n enable(): void {\n if (!this._state.enabled) {\n this._state.enabled = true;\n this._updateButtonState();\n this._setupMapListeners();\n this._updateCursor(true);\n this._emit('enable');\n }\n }\n\n /**\n * Disables inspect mode.\n */\n disable(): void {\n if (this._state.enabled) {\n this._state.enabled = false;\n this._updateButtonState();\n this._removeMapListeners();\n this._updateCursor(false);\n this.clear();\n this._emit('disable');\n }\n }\n\n /**\n * Toggles inspect mode on/off.\n */\n toggle(): void {\n if (this._state.enabled) {\n this.disable();\n } else {\n this.enable();\n }\n }\n\n /**\n * Returns whether inspect mode is enabled.\n */\n isEnabled(): boolean {\n return this._state.enabled;\n }\n\n /**\n * Shows the control.\n */\n show(): void {\n if (!this._state.visible) {\n this._state.visible = true;\n this._updateDisplayState();\n this._emit('show');\n }\n }\n\n /**\n * Hides the control.\n */\n hide(): void {\n if (this._state.visible) {\n this._state.visible = true;\n this._updateDisplayState();\n this._emit('hide');\n }\n }\n\n /**\n * Clears the current inspection.\n */\n clear(): void {\n this._state.inspectedFeatures = [];\n this._state.selectedIndex = 0;\n this._removeHighlight();\n this._hidePopup();\n this._emit('clear');\n }\n\n /**\n * Returns a copy of the current state.\n */\n getState(): InspectControlState {\n return { ...this._state };\n }\n\n /**\n * Returns the currently inspected features.\n */\n getInspectedFeatures(): InspectedFeature[] {\n return [...this._state.inspectedFeatures];\n }\n\n /**\n * Returns the currently selected feature.\n */\n getSelectedFeature(): InspectedFeature | null {\n return this._state.inspectedFeatures[this._state.selectedIndex] || null;\n }\n\n /**\n * Selects a feature by index.\n */\n selectFeature(index: number): void {\n if (index >= 0 && index < this._state.inspectedFeatures.length) {\n this._state.selectedIndex = index;\n const feature = this._state.inspectedFeatures[index];\n this._addHighlight(feature);\n this._updatePopupContent();\n this._emit('featureselect', feature);\n }\n }\n\n /**\n * Selects the next feature.\n */\n nextFeature(): void {\n if (this._state.inspectedFeatures.length > 1) {\n const nextIndex = (this._state.selectedIndex + 1) % this._state.inspectedFeatures.length;\n this.selectFeature(nextIndex);\n }\n }\n\n /**\n * Selects the previous feature.\n */\n previousFeature(): void {\n if (this._state.inspectedFeatures.length > 1) {\n const prevIndex = this._state.selectedIndex === 0\n ? this._state.inspectedFeatures.length - 1\n : this._state.selectedIndex - 1;\n this.selectFeature(prevIndex);\n }\n }\n\n /**\n * Updates the control options.\n */\n update(options: Partial<InspectControlOptions>): void {\n Object.assign(this._options, options);\n if (options.highlightStyle) {\n this._options.highlightStyle = { ...DEFAULT_HIGHLIGHT_STYLE, ...options.highlightStyle };\n }\n if (options.visible !== undefined) {\n this._state.visible = options.visible;\n this._updateDisplayState();\n }\n if (options.enabled !== undefined) {\n if (options.enabled) {\n this.enable();\n } else {\n this.disable();\n }\n }\n this._emit('update');\n }\n\n /**\n * Registers an event handler.\n */\n on(event: InspectEvent, handler: InspectEventHandler): void {\n if (!this._eventHandlers.has(event)) {\n this._eventHandlers.set(event, new Set());\n }\n this._eventHandlers.get(event)!.add(handler);\n }\n\n /**\n * Removes an event handler.\n */\n off(event: InspectEvent, handler: InspectEventHandler): void {\n this._eventHandlers.get(event)?.delete(handler);\n }\n\n /**\n * Emits an event to all registered handlers.\n */\n private _emit(event: InspectEvent, feature?: InspectedFeature): void {\n const handlers = this._eventHandlers.get(event);\n if (handlers) {\n handlers.forEach((handler) =>\n handler({\n type: event,\n state: this.getState(),\n feature,\n features: this._state.inspectedFeatures,\n })\n );\n }\n }\n\n /**\n * Creates the control container.\n */\n private _createContainer(): HTMLElement {\n const container = document.createElement('div');\n container.className = `maplibregl-ctrl maplibregl-ctrl-group maplibre-gl-inspect ${this._options.className}`.trim();\n\n // Apply custom styling\n if (this._options.backgroundColor) {\n container.style.backgroundColor = this._options.backgroundColor;\n }\n if (this._options.borderRadius) {\n container.style.borderRadius = `${this._options.borderRadius}px`;\n }\n if (this._options.opacity !== undefined && this._options.opacity !== 1) {\n container.style.opacity = String(this._options.opacity);\n }\n\n // Create button\n this._button = document.createElement('button');\n this._button.type = 'button';\n this._button.className = 'maplibre-gl-inspect-button';\n this._button.title = 'Inspect features';\n this._button.innerHTML = INSPECT_ICON;\n this._button.addEventListener('click', () => this.toggle());\n\n container.appendChild(this._button);\n\n // Set initial display state\n container.style.display = this._state.visible ? 'block' : 'none';\n\n return container;\n }\n\n /**\n * Updates the button's active state appearance.\n */\n private _updateButtonState(): void {\n if (this._button) {\n if (this._state.enabled) {\n this._button.classList.add('maplibre-gl-inspect-button--active');\n this._button.title = 'Disable inspect mode';\n } else {\n this._button.classList.remove('maplibre-gl-inspect-button--active');\n this._button.title = 'Inspect features';\n }\n }\n }\n\n /**\n * Updates the cursor style when inspect mode is active.\n */\n private _updateCursor(inspectMode: boolean): void {\n if (this._map) {\n const canvas = this._map.getCanvas();\n if (inspectMode) {\n canvas.style.cursor = 'crosshair';\n } else {\n canvas.style.cursor = '';\n }\n }\n }\n\n /**\n * Sets up map click listener for inspect mode.\n */\n private _setupMapListeners(): void {\n if (!this._map || this._boundClickHandler) return;\n\n this._boundClickHandler = (e: MapMouseEvent) => this._handleMapClick(e);\n this._map.on('click', this._boundClickHandler);\n }\n\n /**\n * Removes map click listener.\n */\n private _removeMapListeners(): void {\n if (this._map && this._boundClickHandler) {\n this._map.off('click', this._boundClickHandler);\n this._boundClickHandler = undefined;\n }\n }\n\n /**\n * Handles map click events to inspect features.\n */\n private _handleMapClick(e: MapMouseEvent): void {\n if (!this._map) return;\n\n const point = e.point;\n const lngLat: [number, number] = [e.lngLat.lng, e.lngLat.lat];\n\n // Query features at click point\n const features = this._queryFeatures(point);\n\n if (features.length === 0) {\n this.clear();\n return;\n }\n\n // Convert to InspectedFeature format\n const inspectedFeatures: InspectedFeature[] = features\n .slice(0, this._options.maxFeatures)\n .map((f) => {\n const featureId = f.id;\n const feature: GeoJSON.Feature = {\n type: 'Feature' as const,\n geometry: f.geometry,\n properties: f.properties || {},\n };\n if (featureId !== undefined) {\n feature.id = featureId;\n }\n\n return {\n id: generateId('inspect'),\n feature,\n layerId: f.layer?.id || 'unknown',\n sourceId: f.source || 'unknown',\n sourceLayer: f.sourceLayer,\n featureId: featureId === undefined ? undefined : featureId,\n lngLat,\n };\n });\n\n this._state.inspectedFeatures = inspectedFeatures;\n this._state.selectedIndex = 0;\n\n const selectedFeature = inspectedFeatures[0];\n this._addHighlight(selectedFeature);\n this._showPopup(selectedFeature, lngLat);\n this._emit('featureselect', selectedFeature);\n }\n\n /**\n * Queries features at a point.\n */\n private _queryFeatures(point: maplibregl.PointLike): maplibregl.MapGeoJSONFeature[] {\n if (!this._map) return [];\n\n const queryOptions: { layers?: string[] } = {};\n\n // If includeLayers is specified, only query those layers\n if (this._options.includeLayers.length > 0) {\n queryOptions.layers = this._options.includeLayers;\n }\n\n let features = this._map.queryRenderedFeatures(point, queryOptions);\n\n // Filter out excluded layers\n if (this._options.excludeLayers.length > 0) {\n features = features.filter(\n (f) => f.layer && !this._options.excludeLayers.includes(f.layer.id)\n );\n }\n\n // Filter out highlight layers\n features = features.filter(\n (f) => f.layer && !f.layer.id.startsWith('inspect-highlight-')\n );\n\n return features;\n }\n\n /**\n * Adds highlight layer for the selected feature.\n */\n private _addHighlight(inspectedFeature: InspectedFeature): void {\n if (!this._map) return;\n\n // Remove existing highlight\n this._removeHighlight();\n\n const feature = inspectedFeature.feature;\n const geometryType = feature.geometry.type;\n const style = this._options.highlightStyle;\n\n const highlightTarget = this._getHighlightTarget(inspectedFeature);\n const highlightSourceId = highlightTarget?.sourceId ?? this._highlightSourceId;\n const highlightSourceLayer = highlightTarget?.sourceLayer;\n const highlightFilter = highlightTarget?.filter;\n\n if (!highlightTarget) {\n // Add source only when we can't use the original source for highlighting.\n this._map.addSource(this._highlightSourceId, {\n type: 'geojson',\n data: feature,\n });\n }\n\n const layerBase: {\n source: string;\n 'source-layer'?: string;\n filter?: maplibregl.FilterSpecification;\n } = { source: highlightSourceId };\n\n if (highlightSourceLayer) {\n layerBase['source-layer'] = highlightSourceLayer;\n }\n\n if (highlightFilter) {\n layerBase.filter = highlightFilter;\n }\n\n // Add appropriate layer(s) based on geometry type\n if (geometryType === 'Point' || geometryType === 'MultiPoint') {\n const layerId = `${this._highlightSourceId}-circle`;\n this._map.addLayer({\n id: layerId,\n type: 'circle',\n ...layerBase,\n paint: {\n 'circle-radius': style.circleRadius,\n 'circle-color': style.fillColor,\n 'circle-opacity': style.fillOpacity,\n 'circle-stroke-color': style.strokeColor,\n 'circle-stroke-width': style.circleStrokeWidth,\n },\n });\n this._highlightLayerIds.push(layerId);\n } else if (geometryType === 'LineString' || geometryType === 'MultiLineString') {\n const layerId = `${this._highlightSourceId}-line`;\n this._map.addLayer({\n id: layerId,\n type: 'line',\n ...layerBase,\n paint: {\n 'line-color': style.strokeColor,\n 'line-width': style.strokeWidth,\n 'line-opacity': 1,\n },\n });\n this._highlightLayerIds.push(layerId);\n } else if (geometryType === 'Polygon' || geometryType === 'MultiPolygon') {\n // Fill layer\n const fillLayerId = `${this._highlightSourceId}-fill`;\n this._map.addLayer({\n id: fillLayerId,\n type: 'fill',\n ...layerBase,\n paint: {\n 'fill-color': style.fillColor,\n 'fill-opacity': style.fillOpacity,\n },\n });\n this._highlightLayerIds.push(fillLayerId);\n\n // Outline layer\n const lineLayerId = `${this._highlightSourceId}-outline`;\n this._map.addLayer({\n id: lineLayerId,\n type: 'line',\n ...layerBase,\n paint: {\n 'line-color': style.strokeColor,\n 'line-width': style.strokeWidth,\n },\n });\n this._highlightLayerIds.push(lineLayerId);\n }\n }\n\n /**\n * Determines if highlight can use the original source to avoid tile clipping.\n */\n private _getHighlightTarget(\n inspectedFeature: InspectedFeature\n ): { sourceId: string; sourceLayer?: string; filter: maplibregl.FilterSpecification } | null {\n if (!this._map) return null;\n\n const { sourceId, sourceLayer, featureId, layerId } = inspectedFeature;\n if (!sourceId || sourceId === 'unknown') return null;\n if (featureId === null || featureId === undefined) return null;\n\n const source = this._map.getSource(sourceId) as maplibregl.Source | undefined;\n if (!source) return null;\n\n if (source.type === 'vector' && !sourceLayer) return null;\n\n const idFilter: maplibregl.FilterSpecification = ['==', ['id'], featureId];\n const layerFilter = this._map.getLayer(layerId)?.filter;\n const combinedFilter = layerFilter\n ? (['all', idFilter, layerFilter] as maplibregl.FilterSpecification)\n : idFilter;\n\n return { sourceId, sourceLayer, filter: combinedFilter };\n }\n\n /**\n * Removes highlight layers.\n */\n private _removeHighlight(): void {\n if (!this._map) return;\n\n // Remove layers\n for (const layerId of this._highlightLayerIds) {\n if (this._map.getLayer(layerId)) {\n this._map.removeLayer(layerId);\n }\n }\n this._highlightLayerIds = [];\n\n // Remove source\n if (this._map.getSource(this._highlightSourceId)) {\n this._map.removeSource(this._highlightSourceId);\n }\n }\n\n /**\n * Shows the popup with feature properties.\n */\n private _showPopup(_inspectedFeature: InspectedFeature, lngLat: [number, number]): void {\n if (!this._map) return;\n\n // Remove existing popup\n this._hidePopup();\n\n const html = this._renderPopupContent();\n\n this._popup = new Popup({\n closeButton: true,\n closeOnClick: false,\n maxWidth: `${this._options.maxWidth}px`,\n className: 'maplibre-gl-inspect-popup',\n })\n .setLngLat(lngLat)\n .setHTML(html)\n .addTo(this._map);\n\n // Attach listeners after DOM is ready\n requestAnimationFrame(() => {\n this._attachPopupListeners();\n });\n }\n\n /**\n * Hides the popup.\n */\n private _hidePopup(): void {\n if (this._popup) {\n this._popup.remove();\n this._popup = undefined;\n }\n }\n\n /**\n * Updates the popup content without recreating it.\n */\n private _updatePopupContent(): void {\n if (this._popup) {\n const html = this._renderPopupContent();\n this._popup.setHTML(html);\n this._attachPopupListeners();\n }\n }\n\n /**\n * Attaches event listeners to popup navigation buttons.\n */\n private _attachPopupListeners(): void {\n if (!this._popup) return;\n\n // Get the popup's DOM element\n const popupEl = this._popup.getElement();\n if (!popupEl) return;\n\n const prevBtn = popupEl.querySelector('.maplibre-gl-inspect-nav-prev') as HTMLButtonElement;\n const nextBtn = popupEl.querySelector('.maplibre-gl-inspect-nav-next') as HTMLButtonElement;\n\n if (prevBtn) {\n // Use onclick to replace any existing handler\n prevBtn.onclick = (e) => {\n e.stopPropagation();\n e.preventDefault();\n this.previousFeature();\n };\n }\n\n if (nextBtn) {\n // Use onclick to replace any existing handler\n nextBtn.onclick = (e) => {\n e.stopPropagation();\n e.preventDefault();\n this.nextFeature();\n };\n }\n }\n\n /**\n * Renders the popup HTML content.\n */\n private _renderPopupContent(): string {\n const features = this._state.inspectedFeatures;\n const selectedIndex = this._state.selectedIndex;\n const feature = features[selectedIndex];\n\n if (!feature) {\n return '<div class=\"maplibre-gl-inspect-empty\">No feature selected</div>';\n }\n\n const geometryType = feature.feature.geometry.type;\n const layerId = feature.layerId;\n const properties = feature.feature.properties || {};\n\n // Header\n let html = '<div class=\"maplibre-gl-inspect-header\">';\n\n if (this._options.showGeometryType) {\n html += `<span class=\"maplibre-gl-inspect-geometry\">${this._formatGeometryType(geometryType)}</span>`;\n }\n\n if (this._options.showLayerName) {\n html += `<span class=\"maplibre-gl-inspect-layer\" title=\"${layerId}\">${layerId}</span>`;\n }\n\n // Navigation (if multiple features)\n if (features.length > 1) {\n const prevDisabled = features.length <= 1 ? 'disabled' : '';\n const nextDisabled = features.length <= 1 ? 'disabled' : '';\n html += `\n <span class=\"maplibre-gl-inspect-nav\">\n <button class=\"maplibre-gl-inspect-nav-prev\" ${prevDisabled} title=\"Previous feature\"><</button>\n <span class=\"maplibre-gl-inspect-nav-count\">${selectedIndex + 1}/${features.length}</span>\n <button class=\"maplibre-gl-inspect-nav-next\" ${nextDisabled} title=\"Next feature\">></button>\n </span>\n `;\n }\n\n html += '</div>';\n\n // Properties table\n html += `<div class=\"maplibre-gl-inspect-content\" style=\"max-height: ${this._options.maxHeight}px;\">`;\n\n const propertyKeys = Object.keys(properties).filter(\n (key) => !this._options.excludeProperties.includes(key)\n );\n\n if (propertyKeys.length === 0) {\n html += '<div class=\"maplibre-gl-inspect-empty\">No properties</div>';\n } else {\n html += '<table class=\"maplibre-gl-inspect-properties\">';\n for (const key of propertyKeys) {\n const value = properties[key];\n const formattedValue = this._formatPropertyValue(value);\n const valueClass = value === null || value === undefined ? 'value null' : 'value';\n html += `\n <tr>\n <td class=\"key\">${this._escapeHtml(key)}</td>\n <td class=\"${valueClass}\">${formattedValue}</td>\n </tr>\n `;\n }\n html += '</table>';\n }\n\n html += '</div>';\n\n return html;\n }\n\n /**\n * Formats geometry type for display.\n */\n private _formatGeometryType(type: string): string {\n // Remove \"Multi\" prefix for cleaner display\n return type.replace('Multi', '');\n }\n\n /**\n * Formats a property value for display.\n */\n private _formatPropertyValue(value: unknown): string {\n if (value === null || value === undefined) {\n return '<em>N/A</em>';\n }\n\n if (typeof value === 'boolean') {\n return value ? 'Yes' : 'No';\n }\n\n if (typeof value === 'number') {\n // Format numbers with appropriate precision\n if (Number.isInteger(value)) {\n return this._escapeHtml(value.toLocaleString());\n }\n return this._escapeHtml(value.toFixed(4));\n }\n\n if (typeof value === 'string') {\n // Check if it looks like a date\n if (/^\\d{4}-\\d{2}-\\d{2}/.test(value)) {\n try {\n const date = new Date(value);\n if (!isNaN(date.getTime())) {\n return this._escapeHtml(date.toLocaleString());\n }\n } catch {\n // Not a valid date, continue\n }\n }\n\n // Truncate long strings\n if (value.length > 100) {\n return this._escapeHtml(value.substring(0, 100)) + '...';\n }\n\n return this._escapeHtml(value);\n }\n\n if (typeof value === 'object') {\n // For arrays and objects, show JSON\n try {\n const json = JSON.stringify(value, null, 2);\n if (json.length > 200) {\n return `<pre>${this._escapeHtml(json.substring(0, 200))}...</pre>`;\n }\n return `<pre>${this._escapeHtml(json)}</pre>`;\n } catch {\n return '[Object]';\n }\n }\n\n return this._escapeHtml(String(value));\n }\n\n /**\n * Escapes HTML special characters.\n */\n private _escapeHtml(str: string): string {\n const div = document.createElement('div');\n div.textContent = str;\n return div.innerHTML;\n }\n\n /**\n * Checks zoom visibility and updates display state.\n */\n private _checkZoomVisibility(): void {\n if (!this._map) return;\n const zoom = this._map.getZoom();\n const { minzoom, maxzoom } = this._options;\n const inRange = zoom >= minzoom && zoom <= maxzoom;\n\n if (inRange !== this._zoomVisible) {\n this._zoomVisible = inRange;\n this._updateDisplayState();\n }\n }\n\n /**\n * Updates the display state based on visibility settings.\n */\n private _updateDisplayState(): void {\n if (!this._container) return;\n const shouldShow = this._state.visible && this._zoomVisible;\n this._container.style.display = shouldShow ? 'block' : 'none';\n }\n}\n","import type { IControl, Map as MapLibreMap, MapMouseEvent, GeoJSONSource } from 'maplibre-gl';\nimport type {\n ViewStateControlOptions,\n ViewStateControlState,\n ViewStateEvent,\n ViewStateEventHandler,\n} from './types';\nimport { generateId } from '../utils/helpers';\n\n/**\n * Default options for the ViewStateControl.\n */\nconst DEFAULT_OPTIONS: Required<ViewStateControlOptions> = {\n position: 'bottom-left',\n className: '',\n visible: true,\n collapsed: true,\n precision: 4,\n showCenter: true,\n showBounds: true,\n showZoom: true,\n showPitch: true,\n showBearing: true,\n enableBBox: false,\n bboxFillColor: 'rgba(0, 120, 215, 0.1)',\n bboxStrokeColor: '#0078d7',\n bboxStrokeWidth: 2,\n panelWidth: 280,\n backgroundColor: 'rgba(255, 255, 255, 0.95)',\n borderRadius: 4,\n opacity: 1,\n fontSize: 12,\n fontColor: '#333',\n minzoom: 0,\n maxzoom: 24,\n};\n\n/**\n * SVG icon for the view state button (crosshair/target).\n */\nconst VIEWSTATE_ICON = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"3\"/><line x1=\"12\" y1=\"2\" x2=\"12\" y2=\"6\"/><line x1=\"12\" y1=\"18\" x2=\"12\" y2=\"22\"/><line x1=\"2\" y1=\"12\" x2=\"6\" y2=\"12\"/><line x1=\"18\" y1=\"12\" x2=\"22\" y2=\"12\"/></svg>`;\n\n/**\n * SVG icon for copy button.\n */\nconst COPY_ICON = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\"/><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"/></svg>`;\n\n/**\n * SVG checkmark icon for copy feedback.\n */\nconst CHECK_ICON = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#22c55e\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"/></svg>`;\n\n/**\n * SVG icon for bbox draw button.\n */\nconst BBOX_ICON = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"1\" stroke-dasharray=\"4 2\"/></svg>`;\n\n/**\n * A control that displays live map view state (center, bounds, zoom, pitch, bearing)\n * and optionally supports drawing a bounding box to get bbox coordinates.\n *\n * @example\n * ```typescript\n * const viewStateControl = new ViewStateControl({\n * collapsed: false,\n * enableBBox: true,\n * precision: 4,\n * });\n * map.addControl(viewStateControl, 'bottom-left');\n *\n * viewStateControl.on('bboxdraw', (event) => {\n * console.log('Drawn bbox:', event.bbox);\n * });\n * ```\n */\nexport class ViewStateControl implements IControl {\n private _container?: HTMLElement;\n private _button?: HTMLButtonElement;\n private _panel?: HTMLElement;\n private _options: Required<ViewStateControlOptions>;\n private _state: ViewStateControlState;\n private _eventHandlers: Map<ViewStateEvent, Set<ViewStateEventHandler>> = new Map();\n private _map?: MapLibreMap;\n private _handleZoom?: () => void;\n private _zoomVisible: boolean = true;\n\n // DOM references for live updates\n private _centerValueEl?: HTMLElement;\n private _boundsValueEl?: HTMLElement;\n private _zoomValueEl?: HTMLElement;\n private _pitchValueEl?: HTMLElement;\n private _bearingValueEl?: HTMLElement;\n\n // Move handler for live updates\n private _boundMoveHandler?: () => void;\n\n // BBox drawing state\n private _bboxSourceId: string = '';\n private _bboxLayerFillId: string = '';\n private _bboxLayerLineId: string = '';\n private _bboxDrawStart?: { lng: number; lat: number };\n private _boundBBoxMouseDown?: (e: MapMouseEvent) => void;\n private _boundBBoxMouseMove?: (e: MouseEvent) => void;\n private _boundBBoxMouseUp?: (e: MouseEvent) => void;\n private _boundBBoxDragStart?: (e: DragEvent) => void;\n private _bboxToggleBtn?: HTMLButtonElement;\n private _bboxResultEl?: HTMLElement;\n\n /**\n * Creates a new ViewStateControl instance.\n *\n * @param options - Configuration options for the control.\n */\n constructor(options?: ViewStateControlOptions) {\n this._options = { ...DEFAULT_OPTIONS, ...options };\n this._state = {\n visible: this._options.visible,\n collapsed: this._options.collapsed,\n center: [0, 0],\n bounds: [0, 0, 0, 0],\n zoom: 0,\n pitch: 0,\n bearing: 0,\n drawingBBox: false,\n drawnBBox: null,\n };\n const uid = generateId('viewstate');\n this._bboxSourceId = `${uid}-bbox-src`;\n this._bboxLayerFillId = `${uid}-bbox-fill`;\n this._bboxLayerLineId = `${uid}-bbox-line`;\n }\n\n /**\n * Called when the control is added to the map.\n *\n * @param map - The MapLibre GL map instance.\n * @returns The control's container element.\n */\n onAdd(map: MapLibreMap): HTMLElement {\n this._map = map;\n this._readMapState();\n this._container = this._createContainer();\n\n // Set up zoom listener\n this._handleZoom = () => this._checkZoomVisibility();\n this._map.on('zoom', this._handleZoom);\n this._checkZoomVisibility();\n\n // Set up move listener for live updates\n this._boundMoveHandler = () => this._onMapMove();\n this._map.on('move', this._boundMoveHandler);\n\n return this._container;\n }\n\n /**\n * Called when the control is removed from the map.\n */\n onRemove(): void {\n if (this._map) {\n if (this._handleZoom) {\n this._map.off('zoom', this._handleZoom);\n this._handleZoom = undefined;\n }\n if (this._boundMoveHandler) {\n this._map.off('move', this._boundMoveHandler);\n this._boundMoveHandler = undefined;\n }\n if (this._state.drawingBBox) {\n this._stopBBoxDrawing();\n }\n this._removeBBoxLayers();\n }\n this._map = undefined;\n this._container?.parentNode?.removeChild(this._container);\n this._container = undefined;\n this._button = undefined;\n this._panel = undefined;\n this._centerValueEl = undefined;\n this._boundsValueEl = undefined;\n this._zoomValueEl = undefined;\n this._pitchValueEl = undefined;\n this._bearingValueEl = undefined;\n this._bboxToggleBtn = undefined;\n this._bboxResultEl = undefined;\n this._eventHandlers.clear();\n }\n\n /**\n * Expands the info panel.\n */\n expand(): void {\n if (this._state.collapsed) {\n this._state.collapsed = false;\n this._updatePanelVisibility();\n this._updateButtonState();\n this._emit('expand');\n }\n }\n\n /**\n * Collapses the info panel.\n */\n collapse(): void {\n if (!this._state.collapsed) {\n this._state.collapsed = true;\n this._updatePanelVisibility();\n this._updateButtonState();\n this._emit('collapse');\n }\n }\n\n /**\n * Toggles the panel expanded/collapsed state.\n */\n toggle(): void {\n if (this._state.collapsed) {\n this.expand();\n } else {\n this.collapse();\n }\n }\n\n /**\n * Returns whether the panel is collapsed.\n */\n isCollapsed(): boolean {\n return this._state.collapsed;\n }\n\n /**\n * Shows the control.\n */\n show(): void {\n if (!this._state.visible) {\n this._state.visible = true;\n this._updateDisplayState();\n this._emit('show');\n }\n }\n\n /**\n * Hides the control.\n */\n hide(): void {\n if (this._state.visible) {\n this._state.visible = false;\n this._updateDisplayState();\n this._emit('hide');\n }\n }\n\n /**\n * Returns a copy of the current state.\n */\n getState(): ViewStateControlState {\n return { ...this._state };\n }\n\n /**\n * Starts bounding box drawing mode.\n */\n startBBoxDraw(): void {\n if (!this._options.enableBBox || this._state.drawingBBox) return;\n this._state.drawingBBox = true;\n this._setupBBoxListeners();\n this._updateBBoxToggleState();\n this._emit('drawstart');\n }\n\n /**\n * Stops bounding box drawing mode.\n */\n stopBBoxDraw(): void {\n if (!this._state.drawingBBox) return;\n this._stopBBoxDrawing();\n this._emit('drawend');\n }\n\n /**\n * Clears the drawn bounding box.\n */\n clearBBox(): void {\n this._state.drawnBBox = null;\n this._removeBBoxLayers();\n this._updateBBoxResult();\n this._emit('bboxclear');\n }\n\n /**\n * Updates the control options.\n */\n update(options: Partial<ViewStateControlOptions>): void {\n Object.assign(this._options, options);\n if (options.visible !== undefined) {\n this._state.visible = options.visible;\n this._updateDisplayState();\n }\n if (options.collapsed !== undefined) {\n this._state.collapsed = options.collapsed;\n this._updatePanelVisibility();\n this._updateButtonState();\n }\n if (options.panelWidth !== undefined && this._panel) {\n this._panel.style.width = `${options.panelWidth}px`;\n }\n this._emit('update');\n }\n\n /**\n * Registers an event handler.\n */\n on(event: ViewStateEvent, handler: ViewStateEventHandler): void {\n if (!this._eventHandlers.has(event)) {\n this._eventHandlers.set(event, new Set());\n }\n this._eventHandlers.get(event)!.add(handler);\n }\n\n /**\n * Removes an event handler.\n */\n off(event: ViewStateEvent, handler: ViewStateEventHandler): void {\n this._eventHandlers.get(event)?.delete(handler);\n }\n\n /**\n * Emits an event to all registered handlers.\n */\n private _emit(event: ViewStateEvent, bbox?: [number, number, number, number]): void {\n const handlers = this._eventHandlers.get(event);\n if (handlers) {\n handlers.forEach((handler) =>\n handler({\n type: event,\n state: this.getState(),\n bbox,\n })\n );\n }\n }\n\n /**\n * Reads the current map state into internal state.\n */\n private _readMapState(): void {\n if (!this._map) return;\n const center = this._map.getCenter();\n const bounds = this._map.getBounds();\n this._state.center = [center.lng, center.lat];\n this._state.bounds = [\n bounds.getWest(),\n bounds.getSouth(),\n bounds.getEast(),\n bounds.getNorth(),\n ];\n this._state.zoom = this._map.getZoom();\n this._state.pitch = this._map.getPitch();\n this._state.bearing = this._map.getBearing();\n }\n\n /**\n * Handles map move events for live updates.\n */\n private _onMapMove(): void {\n this._readMapState();\n this._updateValues();\n this._emit('viewchange');\n }\n\n /**\n * Updates the DOM value elements with current state.\n */\n private _updateValues(): void {\n const p = this._options.precision;\n if (this._centerValueEl) {\n this._centerValueEl.textContent = `${this._state.center[0].toFixed(p)}, ${this._state.center[1].toFixed(p)}`;\n }\n if (this._boundsValueEl) {\n const b = this._state.bounds;\n this._boundsValueEl.textContent = `${b[0].toFixed(p)}, ${b[1].toFixed(p)}, ${b[2].toFixed(p)}, ${b[3].toFixed(p)}`;\n }\n if (this._zoomValueEl) {\n this._zoomValueEl.textContent = this._state.zoom.toFixed(2);\n }\n if (this._pitchValueEl) {\n this._pitchValueEl.textContent = `${this._state.pitch.toFixed(1)}°`;\n }\n if (this._bearingValueEl) {\n this._bearingValueEl.textContent = `${this._state.bearing.toFixed(1)}°`;\n }\n }\n\n /**\n * Creates the control container with button and panel.\n */\n private _createContainer(): HTMLElement {\n const container = document.createElement('div');\n container.className = `maplibregl-ctrl maplibregl-ctrl-group maplibre-gl-view-state ${this._options.className}`.trim();\n\n if (this._options.backgroundColor) {\n container.style.backgroundColor = this._options.backgroundColor;\n }\n if (this._options.borderRadius) {\n container.style.borderRadius = `${this._options.borderRadius}px`;\n }\n if (this._options.opacity !== undefined && this._options.opacity !== 1) {\n container.style.opacity = String(this._options.opacity);\n }\n\n // Create button\n this._button = document.createElement('button');\n this._button.type = 'button';\n this._button.className = 'maplibre-gl-view-state-button';\n this._button.title = 'View map state';\n this._button.innerHTML = VIEWSTATE_ICON;\n this._button.addEventListener('click', () => this.toggle());\n container.appendChild(this._button);\n\n // Create panel\n this._panel = this._createPanel();\n container.appendChild(this._panel);\n\n // Set initial states\n container.style.display = this._state.visible ? 'block' : 'none';\n this._updatePanelVisibility();\n this._updateButtonState();\n\n return container;\n }\n\n /**\n * Creates the expandable info panel.\n */\n private _createPanel(): HTMLElement {\n const panel = document.createElement('div');\n panel.className = 'maplibre-gl-view-state-panel';\n panel.style.width = `${this._options.panelWidth}px`;\n\n if (this._options.fontSize) {\n panel.style.fontSize = `${this._options.fontSize}px`;\n }\n if (this._options.fontColor) {\n panel.style.color = this._options.fontColor;\n }\n\n // Header\n const header = document.createElement('div');\n header.className = 'maplibre-gl-view-state-header';\n header.textContent = 'View State';\n panel.appendChild(header);\n\n const p = this._options.precision;\n\n // Center row\n if (this._options.showCenter) {\n const { row, valueEl } = this._createRow(\n 'Center',\n `${this._state.center[0].toFixed(p)}, ${this._state.center[1].toFixed(p)}`,\n );\n this._centerValueEl = valueEl;\n panel.appendChild(row);\n }\n\n // Bounds row\n if (this._options.showBounds) {\n const b = this._state.bounds;\n const { row, valueEl } = this._createRow(\n 'Bounds',\n `${b[0].toFixed(p)}, ${b[1].toFixed(p)}, ${b[2].toFixed(p)}, ${b[3].toFixed(p)}`,\n );\n this._boundsValueEl = valueEl;\n panel.appendChild(row);\n }\n\n // Zoom row\n if (this._options.showZoom) {\n const { row, valueEl } = this._createRow('Zoom', this._state.zoom.toFixed(2));\n this._zoomValueEl = valueEl;\n panel.appendChild(row);\n }\n\n // Pitch row\n if (this._options.showPitch) {\n const { row, valueEl } = this._createRow('Pitch', `${this._state.pitch.toFixed(1)}°`);\n this._pitchValueEl = valueEl;\n panel.appendChild(row);\n }\n\n // Bearing row\n if (this._options.showBearing) {\n const { row, valueEl } = this._createRow('Bearing', `${this._state.bearing.toFixed(1)}°`);\n this._bearingValueEl = valueEl;\n panel.appendChild(row);\n }\n\n // BBox section\n if (this._options.enableBBox) {\n panel.appendChild(this._createBBoxSection());\n }\n\n return panel;\n }\n\n /**\n * Creates a labeled data row with a copy button.\n */\n private _createRow(label: string, value: string): { row: HTMLElement; valueEl: HTMLElement } {\n const row = document.createElement('div');\n row.className = 'maplibre-gl-view-state-row';\n\n const labelEl = document.createElement('span');\n labelEl.className = 'maplibre-gl-view-state-label';\n labelEl.textContent = label;\n\n const valueEl = document.createElement('span');\n valueEl.className = 'maplibre-gl-view-state-value';\n valueEl.textContent = value;\n\n const copyBtn = document.createElement('button');\n copyBtn.type = 'button';\n copyBtn.className = 'maplibre-gl-view-state-copy';\n copyBtn.title = `Copy ${label.toLowerCase()}`;\n copyBtn.innerHTML = COPY_ICON;\n copyBtn.addEventListener('click', (e) => {\n e.stopPropagation();\n this._copyToClipboard(valueEl.textContent || '', copyBtn);\n });\n\n row.appendChild(labelEl);\n row.appendChild(valueEl);\n row.appendChild(copyBtn);\n\n return { row, valueEl };\n }\n\n /**\n * Creates the bounding box drawing section.\n */\n private _createBBoxSection(): HTMLElement {\n const section = document.createElement('div');\n section.className = 'maplibre-gl-view-state-bbox-section';\n\n // Draw toggle button\n this._bboxToggleBtn = document.createElement('button');\n this._bboxToggleBtn.type = 'button';\n this._bboxToggleBtn.className = 'maplibre-gl-view-state-bbox-toggle';\n this._bboxToggleBtn.innerHTML = `${BBOX_ICON} Draw BBox`;\n this._bboxToggleBtn.addEventListener('click', () => {\n if (this._state.drawingBBox) {\n this.stopBBoxDraw();\n } else {\n this.startBBoxDraw();\n }\n });\n section.appendChild(this._bboxToggleBtn);\n\n // Result container (initially hidden)\n this._bboxResultEl = document.createElement('div');\n this._bboxResultEl.className = 'maplibre-gl-view-state-bbox-result';\n this._bboxResultEl.style.display = 'none';\n section.appendChild(this._bboxResultEl);\n\n return section;\n }\n\n /**\n * Updates the bbox result display.\n */\n private _updateBBoxResult(): void {\n if (!this._bboxResultEl) return;\n\n if (!this._state.drawnBBox) {\n this._bboxResultEl.style.display = 'none';\n return;\n }\n\n this._bboxResultEl.style.display = 'block';\n const b = this._state.drawnBBox;\n const p = this._options.precision;\n const bboxStr = `${b[0].toFixed(p)}, ${b[1].toFixed(p)}, ${b[2].toFixed(p)}, ${b[3].toFixed(p)}`;\n\n this._bboxResultEl.innerHTML = '';\n\n const valueDiv = document.createElement('div');\n valueDiv.className = 'maplibre-gl-view-state-bbox-value';\n valueDiv.textContent = bboxStr;\n this._bboxResultEl.appendChild(valueDiv);\n\n const actionsDiv = document.createElement('div');\n actionsDiv.className = 'maplibre-gl-view-state-bbox-actions';\n\n // Copy button\n const copyBtn = document.createElement('button');\n copyBtn.type = 'button';\n copyBtn.className = 'maplibre-gl-view-state-bbox-action';\n copyBtn.innerHTML = `${COPY_ICON} Copy`;\n copyBtn.addEventListener('click', () => {\n this._copyToClipboard(bboxStr, copyBtn);\n });\n actionsDiv.appendChild(copyBtn);\n\n // Clear button\n const clearBtn = document.createElement('button');\n clearBtn.type = 'button';\n clearBtn.className = 'maplibre-gl-view-state-bbox-action maplibre-gl-view-state-bbox-action--clear';\n clearBtn.textContent = 'Clear';\n clearBtn.addEventListener('click', () => this.clearBBox());\n actionsDiv.appendChild(clearBtn);\n\n this._bboxResultEl.appendChild(actionsDiv);\n }\n\n /**\n * Copies text to clipboard and shows feedback on the button.\n */\n private _copyToClipboard(text: string, btn: HTMLButtonElement): void {\n navigator.clipboard.writeText(text).then(() => {\n const originalHtml = btn.innerHTML;\n btn.innerHTML = CHECK_ICON;\n setTimeout(() => {\n btn.innerHTML = originalHtml;\n }, 1000);\n }).catch(() => {\n // Fallback: select the text\n });\n }\n\n /**\n * Updates the panel visibility based on collapsed state.\n */\n private _updatePanelVisibility(): void {\n if (this._panel) {\n if (this._state.collapsed) {\n this._panel.classList.remove('maplibre-gl-view-state-panel--visible');\n } else {\n this._panel.classList.add('maplibre-gl-view-state-panel--visible');\n }\n }\n }\n\n /**\n * Updates the button's active state appearance.\n */\n private _updateButtonState(): void {\n if (this._button) {\n if (!this._state.collapsed) {\n this._button.classList.add('maplibre-gl-view-state-button--active');\n this._button.title = 'Hide view state';\n } else {\n this._button.classList.remove('maplibre-gl-view-state-button--active');\n this._button.title = 'View map state';\n }\n }\n }\n\n /**\n * Updates the bbox toggle button state.\n */\n private _updateBBoxToggleState(): void {\n if (this._bboxToggleBtn) {\n if (this._state.drawingBBox) {\n this._bboxToggleBtn.classList.add('maplibre-gl-view-state-bbox-toggle--active');\n this._bboxToggleBtn.innerHTML = `${BBOX_ICON} Cancel Draw`;\n } else {\n this._bboxToggleBtn.classList.remove('maplibre-gl-view-state-bbox-toggle--active');\n this._bboxToggleBtn.innerHTML = `${BBOX_ICON} Draw BBox`;\n }\n }\n }\n\n /**\n * Converts a native MouseEvent to map lng/lat using map.unproject().\n */\n private _mouseEventToLngLat(e: MouseEvent): { lng: number; lat: number } {\n const canvas = this._map!.getCanvas();\n const rect = canvas.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const y = e.clientY - rect.top;\n const lngLat = this._map!.unproject([x, y]);\n return { lng: lngLat.lng, lat: lngLat.lat };\n }\n\n /**\n * Sets up mouse listeners for bbox drawing.\n */\n private _setupBBoxListeners(): void {\n if (!this._map) return;\n\n const canvas = this._map.getCanvas();\n canvas.style.cursor = 'crosshair';\n this._map.dragPan.disable();\n this._map.boxZoom.disable();\n\n this._boundBBoxMouseDown = (e: MapMouseEvent) => this._onBBoxMouseDown(e);\n this._map.on('mousedown', this._boundBBoxMouseDown);\n\n // Prevent native drag behavior on the canvas, which can swallow mousemove/mouseup events.\n this._boundBBoxDragStart = (e: DragEvent) => e.preventDefault();\n canvas.addEventListener('dragstart', this._boundBBoxDragStart);\n }\n\n /**\n * Removes bbox drawing listeners and restores map state.\n */\n private _stopBBoxDrawing(): void {\n if (!this._map) return;\n\n const canvas = this._map.getCanvas();\n canvas.style.cursor = '';\n this._map.dragPan.enable();\n this._map.boxZoom.enable();\n\n if (this._boundBBoxMouseDown) {\n this._map.off('mousedown', this._boundBBoxMouseDown);\n this._boundBBoxMouseDown = undefined;\n }\n if (this._boundBBoxMouseMove) {\n document.removeEventListener('mousemove', this._boundBBoxMouseMove);\n this._boundBBoxMouseMove = undefined;\n }\n if (this._boundBBoxMouseUp) {\n document.removeEventListener('mouseup', this._boundBBoxMouseUp);\n this._boundBBoxMouseUp = undefined;\n }\n if (this._boundBBoxDragStart) {\n canvas.removeEventListener('dragstart', this._boundBBoxDragStart);\n this._boundBBoxDragStart = undefined;\n }\n\n this._bboxDrawStart = undefined;\n this._state.drawingBBox = false;\n this._updateBBoxToggleState();\n }\n\n /**\n * Handles mouse down for bbox drawing start.\n */\n private _onBBoxMouseDown(e: MapMouseEvent): void {\n if (!this._map) return;\n e.preventDefault();\n e.originalEvent.preventDefault();\n e.originalEvent.stopPropagation();\n\n const lng = e.lngLat.lng;\n const lat = e.lngLat.lat;\n this._bboxDrawStart = { lng, lat };\n\n // Remove any existing bbox layers before drawing a new one\n this._removeBBoxLayers();\n\n // Initialize source with a degenerate polygon at the click point\n const pt: [number, number] = [lng, lat];\n this._map.addSource(this._bboxSourceId, {\n type: 'geojson',\n data: {\n type: 'Feature',\n geometry: { type: 'Polygon', coordinates: [[pt, pt, pt, pt, pt]] },\n properties: {},\n },\n });\n\n this._map.addLayer({\n id: this._bboxLayerFillId,\n type: 'fill',\n source: this._bboxSourceId,\n paint: {\n 'fill-color': this._options.bboxFillColor,\n 'fill-opacity': 1,\n },\n });\n\n this._map.addLayer({\n id: this._bboxLayerLineId,\n type: 'line',\n source: this._bboxSourceId,\n paint: {\n 'line-color': this._options.bboxStrokeColor,\n 'line-width': this._options.bboxStrokeWidth,\n },\n });\n\n // Use native DOM events on document for mousemove/mouseup — MapLibre's\n // map events do not fire reliably during a button-held drag when dragPan\n // is disabled, because the browser may initiate a native drag on the canvas.\n this._boundBBoxMouseMove = (ev: MouseEvent) => this._onBBoxMouseMove(ev);\n this._boundBBoxMouseUp = (ev: MouseEvent) => this._onBBoxMouseUp(ev);\n document.addEventListener('mousemove', this._boundBBoxMouseMove);\n document.addEventListener('mouseup', this._boundBBoxMouseUp);\n }\n\n /**\n * Handles mouse move during bbox drawing.\n */\n private _onBBoxMouseMove(e: MouseEvent): void {\n if (!this._map || !this._bboxDrawStart) return;\n\n const start = this._bboxDrawStart;\n const current = this._mouseEventToLngLat(e);\n const coords = [\n [start.lng, start.lat],\n [current.lng, start.lat],\n [current.lng, current.lat],\n [start.lng, current.lat],\n [start.lng, start.lat],\n ];\n\n const source = this._map.getSource(this._bboxSourceId) as GeoJSONSource | undefined;\n if (source) {\n source.setData({\n type: 'Feature',\n geometry: { type: 'Polygon', coordinates: [coords] },\n properties: {},\n });\n }\n }\n\n /**\n * Handles mouse up to complete bbox drawing.\n */\n private _onBBoxMouseUp(e: MouseEvent): void {\n if (!this._map || !this._bboxDrawStart) return;\n\n const start = this._bboxDrawStart;\n const end = this._mouseEventToLngLat(e);\n\n // Normalize to [west, south, east, north]\n const west = Math.min(start.lng, end.lng);\n const south = Math.min(start.lat, end.lat);\n const east = Math.max(start.lng, end.lng);\n const north = Math.max(start.lat, end.lat);\n\n this._state.drawnBBox = [west, south, east, north];\n this._updateBBoxResult();\n\n // Update the source with the final rectangle so it remains visible\n const coords = [\n [west, south],\n [east, south],\n [east, north],\n [west, north],\n [west, south],\n ];\n const source = this._map.getSource(this._bboxSourceId) as GeoJSONSource | undefined;\n if (source) {\n source.setData({\n type: 'Feature',\n geometry: { type: 'Polygon', coordinates: [coords] },\n properties: {},\n });\n }\n\n // Stop drawing mode\n this._stopBBoxDrawing();\n\n this._emit('bboxdraw', this._state.drawnBBox);\n this._emit('drawend');\n }\n\n /**\n * Removes bbox layers and source from the map.\n */\n private _removeBBoxLayers(): void {\n if (!this._map) return;\n\n if (this._map.getLayer(this._bboxLayerFillId)) {\n this._map.removeLayer(this._bboxLayerFillId);\n }\n if (this._map.getLayer(this._bboxLayerLineId)) {\n this._map.removeLayer(this._bboxLayerLineId);\n }\n if (this._map.getSource(this._bboxSourceId)) {\n this._map.removeSource(this._bboxSourceId);\n }\n }\n\n /**\n * Checks zoom visibility and updates display state.\n */\n private _checkZoomVisibility(): void {\n if (!this._map) return;\n const zoom = this._map.getZoom();\n const { minzoom, maxzoom } = this._options;\n const inRange = zoom >= minzoom && zoom <= maxzoom;\n\n if (inRange !== this._zoomVisible) {\n this._zoomVisible = inRange;\n this._updateDisplayState();\n }\n }\n\n /**\n * Updates the display state based on visibility settings.\n */\n private _updateDisplayState(): void {\n if (!this._container) return;\n const shouldShow = this._state.visible && this._zoomVisible;\n this._container.style.display = shouldShow ? 'block' : 'none';\n }\n}\n","import { GlobeControl, type IControl, type Map as MapLibreMap } from 'maplibre-gl';\nimport type {\n ControlGridOptions,\n ControlGridState,\n ControlGridEvent,\n ControlGridEventHandler,\n DefaultControlName,\n} from './types';\nimport { TerrainControl } from './Terrain';\nimport { SearchControl } from './SearchControl';\nimport { ViewStateControl } from './ViewStateControl';\nimport { InspectControl } from './InspectControl';\nimport { VectorDatasetControl } from './VectorDataset';\nimport { BasemapControl } from './Basemap';\n\n/**\n * Default options for the ControlGrid.\n */\nconst DEFAULT_OPTIONS: Required<\n Omit<ControlGridOptions, 'controls' | 'defaultControls'>\n> & { controls?: IControl[]; defaultControls?: DefaultControlName[] } = {\n title: '',\n position: 'top-right',\n className: '',\n visible: true,\n collapsible: true,\n collapsed: true,\n rows: 1,\n columns: 3,\n showRowColumnControls: true,\n controls: [],\n backgroundColor: 'rgba(255, 255, 255, 0.9)',\n padding: 10,\n borderRadius: 4,\n opacity: 1,\n gap: 6,\n minzoom: 0,\n maxzoom: 24,\n};\n\n/** Wrench icon SVG for collapsed state – stroke style matching MapLibre globe icon. */\nconst WRENCH_ICON = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#333\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z\"/></svg>`;\n\ninterface ChildEntry {\n control: IControl;\n element: HTMLElement | null;\n}\n\n/**\n * A collapsible grid container for MapLibre IControl instances.\n *\n * Hosts multiple controls (e.g. SearchControl, TerrainControl) in a grid layout.\n * Users can configure rows/columns and dynamically add or remove controls.\n *\n * @example\n * ```typescript\n * const grid = new ControlGrid({\n * title: 'Map Tools',\n * rows: 2,\n * columns: 2,\n * collapsible: true,\n * });\n * grid.addControl(new TerrainControl());\n * grid.addControl(new SearchControl());\n * map.addControl(grid, 'top-right');\n * ```\n */\nexport class ControlGrid implements IControl {\n private _container?: HTMLElement;\n private _gridEl?: HTMLElement;\n private _options: Required<Omit<ControlGridOptions, 'controls' | 'defaultControls'>> & { controls?: IControl[]; defaultControls?: DefaultControlName[] };\n private _state: ControlGridState;\n private _children: ChildEntry[] = [];\n private _eventHandlers: Map<ControlGridEvent, Set<ControlGridEventHandler>> = new Map();\n private _map?: MapLibreMap;\n private _handleZoom?: () => void;\n private _zoomVisible: boolean = true;\n\n constructor(options?: ControlGridOptions) {\n this._options = { ...DEFAULT_OPTIONS, ...options };\n this._state = {\n visible: this._options.visible,\n collapsed: this._options.collapsed,\n rows: this._options.rows,\n columns: this._options.columns,\n };\n // Add explicitly passed controls\n const initial = options?.controls ?? this._options.controls ?? [];\n initial.forEach((c) => this._children.push({ control: c, element: null }));\n\n // Create and add built-in default controls\n const defaults = options?.defaultControls ?? [];\n for (const name of defaults) {\n const ctrl = ControlGrid._createDefaultControl(name);\n if (ctrl) this._children.push({ control: ctrl, element: null });\n }\n this._autoGrowRows();\n }\n\n private static _createDefaultControl(name: DefaultControlName): IControl | null {\n switch (name) {\n case 'globe': return new GlobeControl();\n case 'terrain': return new TerrainControl({ hillshade: true });\n case 'search': return new SearchControl({ collapsed: true });\n case 'viewState': return new ViewStateControl({ collapsed: true });\n case 'inspect': return new InspectControl();\n case 'vectorDataset': return new VectorDatasetControl();\n case 'basemap': return new BasemapControl({ collapsed: true });\n default: return null;\n }\n }\n\n onAdd(map: MapLibreMap): HTMLElement {\n this._map = map;\n this._container = this._createContainer();\n\n this._handleZoom = () => this._checkZoomVisibility();\n this._map.on('zoom', this._handleZoom);\n this._checkZoomVisibility();\n\n this._render();\n this._mountChildren();\n\n return this._container;\n }\n\n onRemove(): void {\n if (this._map && this._handleZoom) {\n this._map.off('zoom', this._handleZoom);\n this._handleZoom = undefined;\n }\n this._unmountChildren();\n this._map = undefined;\n this._container?.parentNode?.removeChild(this._container);\n this._container = undefined;\n this._gridEl = undefined;\n this._children = [];\n this._eventHandlers.clear();\n }\n\n /**\n * Add a control to the grid. If the control is already on the map, it is mounted into the grid.\n */\n addControl(control: IControl): void {\n if (this._children.some((e) => e.control === control)) return;\n const entry: ChildEntry = { control, element: null };\n this._children.push(entry);\n this._autoGrowRows();\n if (this._map && this._gridEl) {\n entry.element = control.onAdd(this._map);\n this._gridEl.appendChild(entry.element);\n }\n this._emit('controladd', control);\n }\n\n /**\n * Remove a control from the grid. The control's onRemove is called.\n */\n removeControl(control: IControl): void {\n const index = this._children.findIndex((e) => e.control === control);\n if (index === -1) return;\n const entry = this._children[index];\n if (entry.element?.parentNode) {\n entry.element.parentNode.removeChild(entry.element);\n }\n if (this._map) control.onRemove(this._map);\n this._children.splice(index, 1);\n this._emit('controlremove', control);\n }\n\n /**\n * Set the number of grid rows.\n */\n setRows(rows: number): void {\n const n = Math.max(1, Math.min(12, Math.round(rows)));\n if (this._state.rows === n) return;\n this._state.rows = n;\n this._applyGridStyle();\n this._emit('update');\n }\n\n /**\n * Set the number of grid columns.\n */\n setColumns(columns: number): void {\n const n = Math.max(1, Math.min(12, Math.round(columns)));\n if (this._state.columns === n) return;\n this._state.columns = n;\n this._applyGridStyle();\n this._emit('update');\n }\n\n /**\n * Get the list of controls currently in the grid.\n */\n getControls(): IControl[] {\n return this._children.map((e) => e.control);\n }\n\n show(): void {\n if (!this._state.visible) {\n this._state.visible = true;\n this._updateDisplayState();\n this._emit('show');\n }\n }\n\n hide(): void {\n if (this._state.visible) {\n this._state.visible = false;\n this._updateDisplayState();\n this._emit('hide');\n }\n }\n\n expand(): void {\n if (this._state.collapsed) {\n this._state.collapsed = false;\n this._render();\n this._emit('expand');\n }\n }\n\n collapse(): void {\n if (!this._state.collapsed) {\n this._state.collapsed = true;\n this._render();\n this._emit('collapse');\n }\n }\n\n toggle(): void {\n if (this._state.collapsed) this.expand();\n else this.collapse();\n }\n\n getState(): ControlGridState {\n return { ...this._state };\n }\n\n update(options: Partial<ControlGridOptions>): void {\n this._options = { ...this._options, ...options };\n if (options.visible !== undefined) this._state.visible = options.visible;\n if (options.collapsed !== undefined) this._state.collapsed = options.collapsed;\n if (options.rows !== undefined) this._state.rows = Math.max(1, Math.min(12, options.rows));\n if (options.columns !== undefined)\n this._state.columns = Math.max(1, Math.min(12, options.columns));\n this._render();\n this._emit('update');\n }\n\n on(event: ControlGridEvent, handler: ControlGridEventHandler): void {\n if (!this._eventHandlers.has(event)) {\n this._eventHandlers.set(event, new Set());\n }\n this._eventHandlers.get(event)!.add(handler);\n }\n\n off(event: ControlGridEvent, handler: ControlGridEventHandler): void {\n this._eventHandlers.get(event)?.delete(handler);\n }\n\n private _emit(event: ControlGridEvent, control?: IControl): void {\n const handlers = this._eventHandlers.get(event);\n if (handlers) {\n const payload = { type: event, state: this.getState(), control };\n handlers.forEach((h) => h(payload));\n }\n }\n\n private _checkZoomVisibility(): void {\n if (!this._map) return;\n const zoom = this._map.getZoom();\n const { minzoom, maxzoom } = this._options;\n const inRange = zoom >= minzoom && zoom <= maxzoom;\n if (inRange !== this._zoomVisible) {\n this._zoomVisible = inRange;\n this._updateDisplayState();\n }\n }\n\n private _updateDisplayState(): void {\n if (!this._container) return;\n const shouldShow = this._state.visible && this._zoomVisible;\n this._container.style.display = shouldShow ? 'block' : 'none';\n }\n\n private _createContainer(): HTMLElement {\n const container = document.createElement('div');\n container.className = `maplibregl-ctrl maplibre-gl-control-grid${\n this._options.className ? ` ${this._options.className}` : ''\n }`;\n const shouldShow = this._state.visible && this._zoomVisible;\n if (!shouldShow) container.style.display = 'none';\n return container;\n }\n\n private _autoGrowRows(): void {\n const capacity = this._state.rows * this._state.columns;\n if (this._children.length > capacity) {\n this._state.rows = Math.ceil(this._children.length / this._state.columns);\n this._applyGridStyle();\n }\n }\n\n private _applyGridStyle(): void {\n if (!this._gridEl) return;\n if (this._state.collapsed) {\n this._gridEl.style.display = 'none';\n return;\n }\n const gap = this._options.gap;\n this._gridEl.style.display = 'grid';\n this._gridEl.style.gridTemplateColumns = `repeat(${this._state.columns}, auto)`;\n this._gridEl.style.gridTemplateRows = `repeat(${this._state.rows}, auto)`;\n this._gridEl.style.gap = `${gap}px`;\n // Center grid tracks and controls to balance left/right padding when the header is wider.\n this._gridEl.style.width = '100%';\n this._gridEl.style.justifyContent = 'center';\n this._gridEl.style.alignContent = 'center';\n this._gridEl.style.justifyItems = 'center';\n this._gridEl.style.alignItems = 'center';\n }\n\n private _mountChildren(): void {\n if (!this._map || !this._gridEl) return;\n this._children.forEach((entry) => {\n if (entry.element) {\n if (entry.element.parentNode !== this._gridEl) {\n this._gridEl!.appendChild(entry.element);\n }\n } else {\n entry.element = entry.control.onAdd(this._map!);\n this._gridEl!.appendChild(entry.element);\n }\n });\n }\n\n private _unmountChildren(): void {\n const map = this._map;\n this._children.forEach((entry) => {\n if (entry.element?.parentNode) {\n entry.element.parentNode.removeChild(entry.element);\n }\n if (map) entry.control.onRemove(map);\n });\n this._children = this._children.map((e) => ({ control: e.control, element: null }));\n }\n\n private _render(): void {\n if (!this._container) return;\n\n const {\n title,\n collapsible,\n backgroundColor,\n opacity,\n borderRadius,\n padding,\n showRowColumnControls,\n } = this._options;\n\n this._container.innerHTML = '';\n\n if (this._state.collapsed) {\n this._container.classList.add('maplibre-gl-control-grid--collapsed');\n } else {\n this._container.classList.remove('maplibre-gl-control-grid--collapsed');\n }\n\n const isCollapsedWithHeader = this._state.collapsed && (title || collapsible);\n const vertPadding = isCollapsedWithHeader ? 0 : padding;\n const leftPadding = isCollapsedWithHeader ? 0 : padding;\n const rightPadding = isCollapsedWithHeader ? 0 : Math.max(0, padding - 4);\n const shouldShow = this._state.visible && this._zoomVisible;\n\n Object.assign(this._container.style, {\n backgroundColor,\n opacity: String(opacity),\n borderRadius: `${borderRadius}px`,\n padding: `${vertPadding}px ${rightPadding}px ${vertPadding}px ${leftPadding}px`,\n boxShadow: '0 0 0 2px rgba(0, 0, 0, 0.1)',\n display: shouldShow ? 'block' : 'none',\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n color: '#1a1a1a',\n });\n\n if (collapsible || title) {\n const header = document.createElement('div');\n header.className = 'maplibre-gl-control-grid-header';\n Object.assign(header.style, {\n display: 'flex',\n alignItems: 'center',\n justifyContent: this._state.collapsed ? 'center' : 'space-between',\n flexWrap: 'wrap',\n gap: '6px',\n paddingBottom: this._state.collapsed ? '0' : '0',\n cursor: collapsible ? 'pointer' : 'default',\n });\n\n if (this._state.collapsed && collapsible) {\n // Collapsed: show only a square wrench icon (no grid, no title)\n const iconWrap = document.createElement('span');\n iconWrap.className = 'maplibre-gl-control-grid-wrench';\n iconWrap.innerHTML = WRENCH_ICON;\n Object.assign(iconWrap.style, {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '29px',\n height: '29px',\n lineHeight: '0',\n boxSizing: 'border-box',\n });\n iconWrap.setAttribute('aria-label', 'Map tools');\n header.appendChild(iconWrap);\n header.addEventListener('click', () => this.toggle());\n } else {\n // Expanded: title, row/column inputs, toggle arrow\n const left = document.createElement('div');\n left.style.display = 'flex';\n left.style.alignItems = 'center';\n left.style.gap = '6px';\n\n if (title) {\n const titleEl = document.createElement('span');\n titleEl.className = 'maplibre-gl-control-grid-title';\n titleEl.textContent = title;\n titleEl.style.fontWeight = '600';\n titleEl.style.color = '#333';\n left.appendChild(titleEl);\n }\n\n if (showRowColumnControls && !this._state.collapsed) {\n const rowLabel = document.createElement('label');\n rowLabel.style.display = 'inline-flex';\n rowLabel.style.alignItems = 'center';\n rowLabel.style.gap = '2px';\n rowLabel.style.fontSize = '11px';\n rowLabel.style.color = '#333';\n rowLabel.innerHTML = 'R:';\n const rowInput = document.createElement('input');\n rowInput.type = 'number';\n rowInput.min = '1';\n rowInput.max = '12';\n rowInput.value = String(this._state.rows);\n rowInput.style.width = '40px';\n rowInput.style.padding = '2px 2px';\n rowInput.style.boxSizing = 'border-box';\n rowInput.style.textAlign = 'center';\n rowInput.style.color = '#333';\n rowInput.addEventListener('change', () => this.setRows(Number(rowInput.value) || 1));\n rowLabel.appendChild(rowInput);\n\n const colLabel = document.createElement('label');\n colLabel.style.display = 'inline-flex';\n colLabel.style.alignItems = 'center';\n colLabel.style.gap = '2px';\n colLabel.style.fontSize = '11px';\n colLabel.style.color = '#333';\n colLabel.innerHTML = 'C:';\n const colInput = document.createElement('input');\n colInput.type = 'number';\n colInput.min = '1';\n colInput.max = '12';\n colInput.value = String(this._state.columns);\n colInput.style.width = '40px';\n colInput.style.padding = '2px 2px';\n colInput.style.boxSizing = 'border-box';\n colInput.style.textAlign = 'center';\n colInput.style.color = '#333';\n colInput.addEventListener('change', () => this.setColumns(Number(colInput.value) || 1));\n colLabel.appendChild(colInput);\n\n left.appendChild(rowLabel);\n left.appendChild(colLabel);\n }\n\n header.appendChild(left);\n\n if (collapsible) {\n const toggleBtn = document.createElement('span');\n toggleBtn.className = 'maplibre-gl-control-grid-toggle';\n toggleBtn.innerHTML = '▼';\n Object.assign(toggleBtn.style, { fontSize: '10px', userSelect: 'none', color: '#333' });\n header.appendChild(toggleBtn);\n header.addEventListener('click', (ev) => {\n if (!showRowColumnControls || !left.contains(ev.target as Node)) this.toggle();\n });\n }\n }\n\n this._container.appendChild(header);\n }\n\n const content = document.createElement('div');\n content.className = 'maplibre-gl-control-grid-content';\n Object.assign(content.style, {\n display: this._state.collapsed ? 'none' : 'block',\n });\n this._gridEl = content;\n this._applyGridStyle();\n this._container.appendChild(content);\n\n this._mountChildren();\n }\n}\n"],"names":["DEFAULT_OPTIONS"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ControlGrid-CbLTUHJu.js","sources":["../src/lib/colormaps/sequential.ts","../src/lib/colormaps/diverging.ts","../src/lib/colormaps/misc.ts","../src/lib/colormaps/index.ts","../src/lib/utils/helpers.ts","../src/lib/utils/providers.ts","../src/lib/core/Colorbar.ts","../src/lib/core/Legend.ts","../src/lib/core/HtmlControl.ts","../src/lib/core/Basemap.ts","../src/lib/core/Terrain.ts","../src/lib/core/SearchControl.ts","../src/lib/utils/fileHelpers.ts","../src/lib/core/VectorDataset.ts","../src/lib/core/InspectControl.ts","../src/lib/core/ViewStateControl.ts","../src/lib/core/ControlGrid.ts"],"sourcesContent":["import type { ColorStop } from '../core/types';\n\n/**\n * Viridis colormap - perceptually uniform, colorblind-friendly.\n */\nexport const viridis: ColorStop[] = [\n { position: 0.0, color: '#440154' },\n { position: 0.1, color: '#482878' },\n { position: 0.2, color: '#3e4a89' },\n { position: 0.3, color: '#31688e' },\n { position: 0.4, color: '#26838f' },\n { position: 0.5, color: '#1f9e89' },\n { position: 0.6, color: '#35b779' },\n { position: 0.7, color: '#6ece58' },\n { position: 0.8, color: '#b5de2b' },\n { position: 0.9, color: '#fde725' },\n { position: 1.0, color: '#fde725' },\n];\n\n/**\n * Plasma colormap - perceptually uniform.\n */\nexport const plasma: ColorStop[] = [\n { position: 0.0, color: '#0d0887' },\n { position: 0.1, color: '#41049d' },\n { position: 0.2, color: '#6a00a8' },\n { position: 0.3, color: '#8f0da4' },\n { position: 0.4, color: '#b12a90' },\n { position: 0.5, color: '#cc4778' },\n { position: 0.6, color: '#e16462' },\n { position: 0.7, color: '#f2844b' },\n { position: 0.8, color: '#fca636' },\n { position: 0.9, color: '#fcce25' },\n { position: 1.0, color: '#f0f921' },\n];\n\n/**\n * Inferno colormap - perceptually uniform.\n */\nexport const inferno: ColorStop[] = [\n { position: 0.0, color: '#000004' },\n { position: 0.1, color: '#1b0c41' },\n { position: 0.2, color: '#4a0c6b' },\n { position: 0.3, color: '#781c6d' },\n { position: 0.4, color: '#a52c60' },\n { position: 0.5, color: '#cf4446' },\n { position: 0.6, color: '#ed6925' },\n { position: 0.7, color: '#fb9b06' },\n { position: 0.8, color: '#f7d13d' },\n { position: 0.9, color: '#fcffa4' },\n { position: 1.0, color: '#fcffa4' },\n];\n\n/**\n * Magma colormap - perceptually uniform.\n */\nexport const magma: ColorStop[] = [\n { position: 0.0, color: '#000004' },\n { position: 0.1, color: '#180f3d' },\n { position: 0.2, color: '#440f76' },\n { position: 0.3, color: '#721f81' },\n { position: 0.4, color: '#9e2f7f' },\n { position: 0.5, color: '#cd4071' },\n { position: 0.6, color: '#f1605d' },\n { position: 0.7, color: '#fd9668' },\n { position: 0.8, color: '#fec98d' },\n { position: 0.9, color: '#fcfdbf' },\n { position: 1.0, color: '#fcfdbf' },\n];\n\n/**\n * Cividis colormap - colorblind-friendly.\n */\nexport const cividis: ColorStop[] = [\n { position: 0.0, color: '#00204d' },\n { position: 0.1, color: '#00306f' },\n { position: 0.2, color: '#2a406c' },\n { position: 0.3, color: '#4a5068' },\n { position: 0.4, color: '#636166' },\n { position: 0.5, color: '#7b7362' },\n { position: 0.6, color: '#94865c' },\n { position: 0.7, color: '#af9b51' },\n { position: 0.8, color: '#cab040' },\n { position: 0.9, color: '#e6c628' },\n { position: 1.0, color: '#ffdd00' },\n];\n","import type { ColorStop } from '../core/types';\n\n/**\n * Coolwarm diverging colormap.\n */\nexport const coolwarm: ColorStop[] = [\n { position: 0.0, color: '#3b4cc0' },\n { position: 0.1, color: '#5977e3' },\n { position: 0.2, color: '#7b9ff9' },\n { position: 0.3, color: '#9ebeff' },\n { position: 0.4, color: '#c0d4f5' },\n { position: 0.5, color: '#dddcdc' },\n { position: 0.6, color: '#f2cbb7' },\n { position: 0.7, color: '#f7ac8e' },\n { position: 0.8, color: '#ee8468' },\n { position: 0.9, color: '#d65244' },\n { position: 1.0, color: '#b40426' },\n];\n\n/**\n * Blue-White-Red diverging colormap.\n */\nexport const bwr: ColorStop[] = [\n { position: 0.0, color: '#0000ff' },\n { position: 0.5, color: '#ffffff' },\n { position: 1.0, color: '#ff0000' },\n];\n\n/**\n * Seismic diverging colormap.\n */\nexport const seismic: ColorStop[] = [\n { position: 0.0, color: '#00004d' },\n { position: 0.25, color: '#0000ff' },\n { position: 0.5, color: '#ffffff' },\n { position: 0.75, color: '#ff0000' },\n { position: 1.0, color: '#4d0000' },\n];\n\n/**\n * Red-Blue diverging colormap.\n */\nexport const RdBu: ColorStop[] = [\n { position: 0.0, color: '#67001f' },\n { position: 0.1, color: '#b2182b' },\n { position: 0.2, color: '#d6604d' },\n { position: 0.3, color: '#f4a582' },\n { position: 0.4, color: '#fddbc7' },\n { position: 0.5, color: '#f7f7f7' },\n { position: 0.6, color: '#d1e5f0' },\n { position: 0.7, color: '#92c5de' },\n { position: 0.8, color: '#4393c3' },\n { position: 0.9, color: '#2166ac' },\n { position: 1.0, color: '#053061' },\n];\n\n/**\n * Red-Yellow-Blue diverging colormap.\n */\nexport const RdYlBu: ColorStop[] = [\n { position: 0.0, color: '#a50026' },\n { position: 0.1, color: '#d73027' },\n { position: 0.2, color: '#f46d43' },\n { position: 0.3, color: '#fdae61' },\n { position: 0.4, color: '#fee090' },\n { position: 0.5, color: '#ffffbf' },\n { position: 0.6, color: '#e0f3f8' },\n { position: 0.7, color: '#abd9e9' },\n { position: 0.8, color: '#74add1' },\n { position: 0.9, color: '#4575b4' },\n { position: 1.0, color: '#313695' },\n];\n\n/**\n * Red-Yellow-Green diverging colormap.\n */\nexport const RdYlGn: ColorStop[] = [\n { position: 0.0, color: '#a50026' },\n { position: 0.1, color: '#d73027' },\n { position: 0.2, color: '#f46d43' },\n { position: 0.3, color: '#fdae61' },\n { position: 0.4, color: '#fee08b' },\n { position: 0.5, color: '#ffffbf' },\n { position: 0.6, color: '#d9ef8b' },\n { position: 0.7, color: '#a6d96a' },\n { position: 0.8, color: '#66bd63' },\n { position: 0.9, color: '#1a9850' },\n { position: 1.0, color: '#006837' },\n];\n\n/**\n * Spectral diverging colormap.\n */\nexport const spectral: ColorStop[] = [\n { position: 0.0, color: '#9e0142' },\n { position: 0.1, color: '#d53e4f' },\n { position: 0.2, color: '#f46d43' },\n { position: 0.3, color: '#fdae61' },\n { position: 0.4, color: '#fee08b' },\n { position: 0.5, color: '#ffffbf' },\n { position: 0.6, color: '#e6f598' },\n { position: 0.7, color: '#abdda4' },\n { position: 0.8, color: '#66c2a5' },\n { position: 0.9, color: '#3288bd' },\n { position: 1.0, color: '#5e4fa2' },\n];\n","import type { ColorStop } from '../core/types';\n\n/**\n * Jet colormap (classic rainbow-like).\n */\nexport const jet: ColorStop[] = [\n { position: 0.0, color: '#00007f' },\n { position: 0.125, color: '#0000ff' },\n { position: 0.25, color: '#007fff' },\n { position: 0.375, color: '#00ffff' },\n { position: 0.5, color: '#7fff7f' },\n { position: 0.625, color: '#ffff00' },\n { position: 0.75, color: '#ff7f00' },\n { position: 0.875, color: '#ff0000' },\n { position: 1.0, color: '#7f0000' },\n];\n\n/**\n * Rainbow colormap.\n */\nexport const rainbow: ColorStop[] = [\n { position: 0.0, color: '#ff0000' },\n { position: 0.17, color: '#ff8000' },\n { position: 0.33, color: '#ffff00' },\n { position: 0.5, color: '#00ff00' },\n { position: 0.67, color: '#00ffff' },\n { position: 0.83, color: '#0000ff' },\n { position: 1.0, color: '#8000ff' },\n];\n\n/**\n * Turbo colormap (improved rainbow).\n */\nexport const turbo: ColorStop[] = [\n { position: 0.0, color: '#30123b' },\n { position: 0.1, color: '#4662d7' },\n { position: 0.2, color: '#36aaf9' },\n { position: 0.3, color: '#1ae4b6' },\n { position: 0.4, color: '#72fe5e' },\n { position: 0.5, color: '#c8ef34' },\n { position: 0.6, color: '#faba39' },\n { position: 0.7, color: '#f66b19' },\n { position: 0.8, color: '#ca2a04' },\n { position: 0.9, color: '#7a0403' },\n { position: 1.0, color: '#7a0403' },\n];\n\n/**\n * Terrain colormap.\n */\nexport const terrain: ColorStop[] = [\n { position: 0.0, color: '#333399' },\n { position: 0.15, color: '#0099cc' },\n { position: 0.25, color: '#00cc99' },\n { position: 0.35, color: '#99cc00' },\n { position: 0.5, color: '#ffcc00' },\n { position: 0.65, color: '#cc6600' },\n { position: 0.75, color: '#993300' },\n { position: 0.85, color: '#996633' },\n { position: 1.0, color: '#ffffff' },\n];\n\n/**\n * Ocean colormap.\n */\nexport const ocean: ColorStop[] = [\n { position: 0.0, color: '#007f00' },\n { position: 0.25, color: '#00007f' },\n { position: 0.5, color: '#0000ff' },\n { position: 0.75, color: '#7fffff' },\n { position: 1.0, color: '#ffffff' },\n];\n\n/**\n * Hot colormap (black-red-yellow-white).\n */\nexport const hot: ColorStop[] = [\n { position: 0.0, color: '#000000' },\n { position: 0.33, color: '#ff0000' },\n { position: 0.67, color: '#ffff00' },\n { position: 1.0, color: '#ffffff' },\n];\n\n/**\n * Cool colormap (cyan-magenta).\n */\nexport const cool: ColorStop[] = [\n { position: 0.0, color: '#00ffff' },\n { position: 1.0, color: '#ff00ff' },\n];\n\n/**\n * Gray/Grayscale colormap.\n */\nexport const gray: ColorStop[] = [\n { position: 0.0, color: '#000000' },\n { position: 1.0, color: '#ffffff' },\n];\n\n/**\n * Bone colormap.\n */\nexport const bone: ColorStop[] = [\n { position: 0.0, color: '#000000' },\n { position: 0.375, color: '#545474' },\n { position: 0.75, color: '#a9c8c8' },\n { position: 1.0, color: '#ffffff' },\n];\n","import type { ColorStop, ColormapName } from '../core/types';\nimport { viridis, plasma, inferno, magma, cividis } from './sequential';\nimport { coolwarm, bwr, seismic, RdBu, RdYlBu, RdYlGn, spectral } from './diverging';\nimport { jet, rainbow, turbo, terrain, ocean, hot, cool, gray, bone } from './misc';\n\n/**\n * Map of all built-in colormaps.\n */\nexport const COLORMAPS: Record<ColormapName, ColorStop[]> = {\n // Sequential\n viridis,\n plasma,\n inferno,\n magma,\n cividis,\n // Diverging\n coolwarm,\n bwr,\n seismic,\n RdBu,\n RdYlBu,\n RdYlGn,\n spectral,\n // Miscellaneous\n jet,\n rainbow,\n turbo,\n terrain,\n ocean,\n hot,\n cool,\n gray,\n bone,\n};\n\n/**\n * Gets a colormap by name.\n *\n * @param name - The colormap name.\n * @returns Array of color stops.\n */\nexport function getColormap(name: ColormapName): ColorStop[] {\n return COLORMAPS[name] || COLORMAPS.viridis;\n}\n\n/**\n * Checks if a colormap name is valid.\n *\n * @param name - The name to check.\n * @returns True if the name is a valid colormap.\n */\nexport function isValidColormap(name: string): name is ColormapName {\n return name in COLORMAPS;\n}\n\n/**\n * Gets all available colormap names.\n *\n * @returns Array of colormap names.\n */\nexport function getColormapNames(): ColormapName[] {\n return Object.keys(COLORMAPS) as ColormapName[];\n}\n\n// Re-export individual colormaps\nexport { viridis, plasma, inferno, magma, cividis };\nexport { coolwarm, bwr, seismic, RdBu, RdYlBu, RdYlGn, spectral };\nexport { jet, rainbow, turbo, terrain, ocean, hot, cool, gray, bone };\n","/**\n * Clamps a value between min and max.\n *\n * @param value - The value to clamp.\n * @param min - The minimum value.\n * @param max - The maximum value.\n * @returns The clamped value.\n */\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\n/**\n * Formats a numeric value based on the range.\n *\n * @param value - The value to format.\n * @param range - The total range (max - min).\n * @returns Formatted string.\n */\nexport function formatNumericValue(value: number, range: number): string {\n if (range >= 100) {\n return Math.round(value).toString();\n } else if (range >= 1) {\n return value.toFixed(1);\n } else if (range >= 0.1) {\n return value.toFixed(2);\n } else {\n return value.toFixed(3);\n }\n}\n\n/**\n * Generates a unique ID with optional prefix.\n *\n * @param prefix - Optional prefix for the ID.\n * @returns A unique ID string.\n */\nexport function generateId(prefix = 'mlgl'): string {\n return `${prefix}-${Math.random().toString(36).substring(2, 9)}`;\n}\n\n/**\n * Debounces a function call.\n *\n * @param fn - The function to debounce.\n * @param delay - The delay in milliseconds.\n * @returns A debounced function.\n */\nexport function debounce<T extends (...args: unknown[]) => void>(\n fn: T,\n delay: number\n): (...args: Parameters<T>) => void {\n let timeoutId: ReturnType<typeof setTimeout>;\n return (...args: Parameters<T>) => {\n clearTimeout(timeoutId);\n timeoutId = setTimeout(() => fn(...args), delay);\n };\n}\n\n/**\n * Throttles a function call.\n *\n * @param fn - The function to throttle.\n * @param limit - The minimum time between calls in milliseconds.\n * @returns A throttled function.\n */\nexport function throttle<T extends (...args: unknown[]) => void>(\n fn: T,\n limit: number\n): (...args: Parameters<T>) => void {\n let inThrottle = false;\n return (...args: Parameters<T>) => {\n if (!inThrottle) {\n fn(...args);\n inThrottle = true;\n setTimeout(() => (inThrottle = false), limit);\n }\n };\n}\n\n/**\n * Joins class names, filtering out falsy values.\n *\n * @param classes - Class names to join.\n * @returns Joined class string.\n */\nexport function classNames(...classes: (string | undefined | null | false)[]): string {\n return classes.filter(Boolean).join(' ');\n}\n","import type { BasemapItem } from '../core/types';\n\n/**\n * Default URL for xyzservices providers.json.\n */\nexport const XYZSERVICES_URL =\n 'https://raw.githubusercontent.com/geopandas/xyzservices/main/xyzservices/data/providers.json';\n\n/**\n * XYZservices provider structure from providers.json.\n */\ninterface XYZProvider {\n url: string;\n name: string;\n max_zoom?: number;\n min_zoom?: number;\n attribution?: string;\n html_attribution?: string;\n bounds?: [[number, number], [number, number]];\n accessToken?: string;\n variant?: string;\n ext?: string;\n subdomains?: string;\n status?: string;\n}\n\n/**\n * Parsed provider group from xyzservices.\n */\ninterface ProviderGroup {\n [key: string]: XYZProvider | ProviderGroup;\n}\n\n/**\n * Options for parsing providers.\n */\ninterface ParseOptions {\n filterGroups?: string[];\n excludeGroups?: string[];\n excludeBroken?: boolean;\n}\n\n/**\n * Check if an object is an XYZ provider (has url field).\n */\nfunction isXYZProvider(obj: unknown): obj is XYZProvider {\n return typeof obj === 'object' && obj !== null && 'url' in obj && typeof (obj as XYZProvider).url === 'string';\n}\n\n/**\n * Build the tile URL from an XYZ provider.\n * Replaces placeholders like {s}, {r}, {variant}, {ext}.\n */\nexport function buildTileUrl(basemap: BasemapItem): string {\n let url = basemap.url || '';\n\n // Replace subdomains placeholder with 'a' (first subdomain)\n url = url.replace('{s}', 'a');\n\n // Replace retina placeholder\n url = url.replace('{r}', '');\n\n // Replace variant placeholder (e.g., CartoDB uses {variant} for 'light_all', 'dark_all', etc.)\n if (basemap.variant) {\n url = url.replace('{variant}', basemap.variant);\n }\n\n // Replace file extension placeholder (e.g., some providers use {ext} for 'png', 'jpg')\n if (basemap.ext) {\n url = url.replace('{ext}', basemap.ext);\n }\n\n // Handle API key placeholders\n if (basemap.apiKey) {\n url = url.replace('{apikey}', basemap.apiKey);\n url = url.replace('{accessToken}', basemap.apiKey);\n url = url.replace('<insert your api key here>', basemap.apiKey);\n url = url.replace('<insert your access token here>', basemap.apiKey);\n }\n\n return url;\n}\n\n/**\n * Generate a thumbnail URL from a basemap's tile URL.\n * Uses zoom level 3 for a reasonable world view.\n */\nexport function generateThumbnailUrl(basemap: BasemapItem): string {\n if (basemap.thumbnail) {\n return basemap.thumbnail;\n }\n\n if (basemap.url) {\n let url = buildTileUrl(basemap);\n // Generate thumbnail at zoom 3, tile 4/2 (roughly centered on Europe)\n url = url.replace('{z}', '3');\n url = url.replace('{x}', '4');\n url = url.replace('{y}', '2');\n return url;\n }\n\n return '';\n}\n\n/**\n * Parse xyzservices providers.json data into BasemapItem array.\n */\nexport function parseProviders(data: Record<string, unknown>, options: ParseOptions = {}): BasemapItem[] {\n const { filterGroups, excludeGroups, excludeBroken = true } = options;\n const basemaps: BasemapItem[] = [];\n\n function processProvider(provider: XYZProvider, groupName: string, providerName: string): void {\n // Skip broken providers\n if (excludeBroken && provider.status === 'broken') {\n return;\n }\n\n // Skip providers without URL\n if (!provider.url) {\n return;\n }\n\n // Check if requires API key\n const requiresApiKey =\n provider.accessToken?.includes('insert your') ||\n provider.url.includes('{apikey}') ||\n provider.url.includes('{accessToken}');\n\n basemaps.push({\n id: provider.name || `${groupName}.${providerName}`,\n name: providerName,\n group: groupName,\n url: provider.url,\n attribution: provider.html_attribution || provider.attribution,\n maxZoom: provider.max_zoom,\n minZoom: provider.min_zoom,\n requiresApiKey,\n variant: provider.variant,\n ext: provider.ext,\n });\n }\n\n function processGroup(group: ProviderGroup, groupName: string): void {\n for (const [key, value] of Object.entries(group)) {\n if (isXYZProvider(value)) {\n processProvider(value, groupName, key);\n }\n }\n }\n\n for (const [groupName, groupValue] of Object.entries(data)) {\n // Apply group filtering\n if (excludeGroups?.includes(groupName)) {\n continue;\n }\n if (filterGroups?.length && !filterGroups.includes(groupName)) {\n continue;\n }\n\n // Check if this is a direct provider or a group of providers\n if (isXYZProvider(groupValue)) {\n // Direct provider (like OpenSeaMap)\n processProvider(groupValue, groupName, groupName);\n } else if (typeof groupValue === 'object' && groupValue !== null) {\n // Group of providers (like OpenStreetMap with Mapnik, HOT, etc.)\n processGroup(groupValue as ProviderGroup, groupName);\n }\n }\n\n return basemaps;\n}\n\n/**\n * Fetch and parse providers from xyzservices URL.\n */\nexport async function fetchProviders(\n url: string = XYZSERVICES_URL,\n options: ParseOptions = {}\n): Promise<BasemapItem[]> {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`Failed to fetch providers: ${response.statusText}`);\n }\n const data = await response.json();\n return parseProviders(data, options);\n}\n\n/**\n * Group basemaps by their group property.\n */\nexport function groupBasemaps(basemaps: BasemapItem[]): Map<string, BasemapItem[]> {\n const groups = new Map<string, BasemapItem[]>();\n\n for (const basemap of basemaps) {\n const groupName = basemap.group || 'Other';\n const existing = groups.get(groupName) || [];\n existing.push(basemap);\n groups.set(groupName, existing);\n }\n\n return groups;\n}\n\n/**\n * Filter basemaps by search text.\n */\nexport function filterBasemaps(basemaps: BasemapItem[], searchText: string): BasemapItem[] {\n if (!searchText.trim()) {\n return basemaps;\n }\n\n const search = searchText.toLowerCase();\n return basemaps.filter(\n (b) =>\n b.name.toLowerCase().includes(search) ||\n b.id.toLowerCase().includes(search) ||\n b.group?.toLowerCase().includes(search)\n );\n}\n\n/**\n * Google basemap definitions.\n * These are not included in xyzservices but are commonly requested.\n */\nexport const GOOGLE_BASEMAPS: BasemapItem[] = [\n {\n id: 'Google.Roadmap',\n name: 'Roadmap',\n group: 'Google',\n url: 'https://mt1.google.com/vt/lyrs=m&x={x}&y={y}&z={z}',\n attribution: '© Google Maps',\n maxZoom: 22,\n },\n {\n id: 'Google.Satellite',\n name: 'Satellite',\n group: 'Google',\n url: 'https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}',\n attribution: '© Google Maps',\n maxZoom: 22,\n },\n {\n id: 'Google.Terrain',\n name: 'Terrain',\n group: 'Google',\n url: 'https://mt1.google.com/vt/lyrs=p&x={x}&y={y}&z={z}',\n attribution: '© Google Maps',\n maxZoom: 22,\n },\n {\n id: 'Google.Hybrid',\n name: 'Hybrid',\n group: 'Google',\n url: 'https://mt1.google.com/vt/lyrs=y&x={x}&y={y}&z={z}',\n attribution: '© Google Maps',\n maxZoom: 22,\n },\n];\n","import '../styles/common.css';\nimport '../styles/colorbar.css';\nimport type { IControl, Map as MapLibreMap } from 'maplibre-gl';\nimport type {\n ColorbarOptions,\n ColorbarState,\n ComponentEvent,\n ComponentEventHandler,\n ColorStop,\n} from './types';\nimport { getColormap, isValidColormap } from '../colormaps';\nimport { formatNumericValue } from '../utils';\n\n/**\n * Default options for the Colorbar control.\n */\nconst DEFAULT_OPTIONS: Required<Omit<ColorbarOptions, 'colorStops'>> & { colorStops: ColorStop[] } = {\n colormap: 'viridis',\n colorStops: [],\n vmin: 0,\n vmax: 1,\n label: '',\n units: '',\n orientation: 'vertical',\n position: 'bottom-right',\n barThickness: 20,\n barLength: 200,\n ticks: { count: 5 },\n className: '',\n visible: true,\n opacity: 1,\n backgroundColor: 'rgba(255, 255, 255, 0.9)',\n fontSize: 11,\n fontColor: '#333',\n borderRadius: 4,\n padding: 8,\n minzoom: 0,\n maxzoom: 24,\n};\n\n/**\n * A continuous gradient colorbar control for MapLibre GL maps.\n *\n * Displays a color gradient legend with customizable colormaps,\n * tick marks, labels, and positioning.\n *\n * @example\n * ```typescript\n * const colorbar = new Colorbar({\n * colormap: 'viridis',\n * vmin: 0,\n * vmax: 100,\n * label: 'Temperature',\n * units: '°C',\n * orientation: 'vertical',\n * });\n * map.addControl(colorbar, 'bottom-right');\n * ```\n */\nexport class Colorbar implements IControl {\n private _container?: HTMLElement;\n private _options: Required<Omit<ColorbarOptions, 'colorStops'>> & { colorStops: ColorStop[] };\n private _state: ColorbarState;\n private _eventHandlers: Map<ComponentEvent, Set<ComponentEventHandler<ColorbarState>>> =\n new Map();\n private _map?: MapLibreMap;\n private _handleZoom?: () => void;\n private _zoomVisible: boolean = true;\n\n /**\n * Creates a new Colorbar instance.\n *\n * @param options - Configuration options for the colorbar.\n */\n constructor(options?: ColorbarOptions) {\n this._options = { ...DEFAULT_OPTIONS, ...options };\n this._state = {\n visible: this._options.visible,\n vmin: this._options.vmin,\n vmax: this._options.vmax,\n colormap: this._options.colormap,\n };\n }\n\n /**\n * Called when the control is added to the map.\n * Implements the IControl interface.\n *\n * @param map - The MapLibre GL map instance.\n * @returns The control's container element.\n */\n onAdd(map: MapLibreMap): HTMLElement {\n this._map = map;\n this._container = this._createContainer();\n this._render();\n\n // Set up zoom listener\n this._handleZoom = () => this._checkZoomVisibility();\n this._map.on('zoom', this._handleZoom);\n\n // Check initial zoom\n this._checkZoomVisibility();\n\n return this._container;\n }\n\n /**\n * Called when the control is removed from the map.\n * Implements the IControl interface.\n */\n onRemove(): void {\n if (this._map && this._handleZoom) {\n this._map.off('zoom', this._handleZoom);\n this._handleZoom = undefined;\n }\n this._map = undefined;\n this._container?.parentNode?.removeChild(this._container);\n this._container = undefined;\n this._eventHandlers.clear();\n }\n\n /**\n * Shows the colorbar.\n */\n show(): void {\n if (!this._state.visible) {\n this._state.visible = true;\n this._updateDisplayState();\n this._emit('show');\n }\n }\n\n /**\n * Hides the colorbar.\n */\n hide(): void {\n if (this._state.visible) {\n this._state.visible = false;\n this._updateDisplayState();\n this._emit('hide');\n }\n }\n\n /**\n * Updates the colorbar options and re-renders.\n *\n * @param options - Partial options to update.\n */\n update(options: Partial<ColorbarOptions>): void {\n this._options = { ...this._options, ...options };\n if (options.vmin !== undefined) this._state.vmin = options.vmin;\n if (options.vmax !== undefined) this._state.vmax = options.vmax;\n if (options.colormap !== undefined) this._state.colormap = options.colormap;\n if (options.visible !== undefined) this._state.visible = options.visible;\n this._render();\n this._emit('update');\n }\n\n /**\n * Gets the current state.\n *\n * @returns The current colorbar state.\n */\n getState(): ColorbarState {\n return { ...this._state };\n }\n\n /**\n * Registers an event handler.\n *\n * @param event - The event type to listen for.\n * @param handler - The callback function.\n */\n on(event: ComponentEvent, handler: ComponentEventHandler<ColorbarState>): void {\n if (!this._eventHandlers.has(event)) {\n this._eventHandlers.set(event, new Set());\n }\n this._eventHandlers.get(event)!.add(handler);\n }\n\n /**\n * Removes an event handler.\n *\n * @param event - The event type.\n * @param handler - The callback function to remove.\n */\n off(event: ComponentEvent, handler: ComponentEventHandler<ColorbarState>): void {\n this._eventHandlers.get(event)?.delete(handler);\n }\n\n /**\n * Gets the resolved color stops for the current colormap.\n *\n * @returns Array of color stops.\n */\n private _getColorStops(): ColorStop[] {\n // Custom color stops take priority\n if (this._options.colorStops && this._options.colorStops.length > 0) {\n return this._options.colorStops;\n }\n\n const colormap = this._options.colormap;\n\n // If colormap is a string array, convert to color stops\n if (Array.isArray(colormap)) {\n return colormap.map((color, i) => ({\n position: i / (colormap.length - 1),\n color,\n }));\n }\n\n // If colormap is a name, get the built-in colormap\n if (typeof colormap === 'string' && isValidColormap(colormap)) {\n return getColormap(colormap);\n }\n\n // Default to viridis\n return getColormap('viridis');\n }\n\n /**\n * Generates the CSS gradient string.\n *\n * @returns CSS linear-gradient string.\n */\n private _generateGradient(): string {\n const stops = this._getColorStops();\n const direction = this._options.orientation === 'horizontal' ? 'to right' : 'to top';\n const colorStops = stops.map((stop) => `${stop.color} ${stop.position * 100}%`).join(', ');\n return `linear-gradient(${direction}, ${colorStops})`;\n }\n\n /**\n * Generates tick values.\n *\n * @returns Array of tick values.\n */\n private _generateTicks(): number[] {\n const { ticks, vmin, vmax } = this._options;\n\n if (ticks.values && ticks.values.length > 0) {\n return ticks.values;\n }\n\n const count = ticks.count || 5;\n const step = (vmax - vmin) / (count - 1);\n return Array.from({ length: count }, (_, i) => vmin + i * step);\n }\n\n /**\n * Formats a tick value for display.\n *\n * @param value - The tick value.\n * @returns Formatted string.\n */\n private _formatTick(value: number): string {\n const { ticks, units } = this._options;\n\n if (ticks.format) {\n return ticks.format(value);\n }\n\n // Auto-format based on range\n const range = this._options.vmax - this._options.vmin;\n const formatted = formatNumericValue(value, range);\n\n return units ? `${formatted}${units}` : formatted;\n }\n\n /**\n * Emits an event to all registered handlers.\n *\n * @param event - The event type to emit.\n */\n private _emit(event: ComponentEvent): void {\n const handlers = this._eventHandlers.get(event);\n if (handlers) {\n const eventData = { type: event, state: this.getState() };\n handlers.forEach((handler) => handler(eventData));\n }\n }\n\n /**\n * Checks if the current zoom level is within the visibility range.\n */\n private _checkZoomVisibility(): void {\n if (!this._map) return;\n\n const zoom = this._map.getZoom();\n const { minzoom, maxzoom } = this._options;\n const inRange = zoom >= minzoom && zoom <= maxzoom;\n\n if (inRange !== this._zoomVisible) {\n this._zoomVisible = inRange;\n this._updateDisplayState();\n }\n }\n\n /**\n * Updates the display state based on visibility and zoom level.\n */\n private _updateDisplayState(): void {\n if (!this._container) return;\n const shouldShow = this._state.visible && this._zoomVisible;\n this._container.style.display = shouldShow ? 'flex' : 'none';\n }\n\n /**\n * Creates the main container element.\n *\n * @returns The container element.\n */\n private _createContainer(): HTMLElement {\n const container = document.createElement('div');\n container.className = `maplibregl-ctrl maplibre-gl-colorbar${\n this._options.className ? ` ${this._options.className}` : ''\n }`;\n\n const shouldShow = this._state.visible && this._zoomVisible;\n if (!shouldShow) {\n container.style.display = 'none';\n }\n\n return container;\n }\n\n /**\n * Renders the colorbar content.\n */\n private _render(): void {\n if (!this._container) return;\n\n const {\n orientation,\n barThickness,\n barLength,\n label,\n backgroundColor,\n opacity,\n fontSize,\n fontColor,\n borderRadius,\n padding,\n } = this._options;\n const isVertical = orientation === 'vertical';\n const ticks = this._generateTicks();\n\n // Clear existing content\n this._container.innerHTML = '';\n\n // Apply container styles\n const shouldShow = this._state.visible && this._zoomVisible;\n Object.assign(this._container.style, {\n backgroundColor,\n opacity: opacity.toString(),\n borderRadius: `${borderRadius}px`,\n padding: `${padding}px`,\n fontSize: `${fontSize}px`,\n color: fontColor,\n display: shouldShow ? 'flex' : 'none',\n flexDirection: isVertical ? 'row' : 'column',\n alignItems: 'stretch',\n gap: '6px',\n boxShadow: '0 0 0 2px rgba(0, 0, 0, 0.1)',\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n });\n\n // Add label if provided\n if (label) {\n const labelEl = document.createElement('div');\n labelEl.className = 'maplibre-gl-colorbar-label';\n labelEl.textContent = label;\n Object.assign(labelEl.style, {\n fontWeight: '600',\n textAlign: 'center',\n marginBottom: isVertical ? '0' : '4px',\n writingMode: isVertical ? 'vertical-rl' : 'horizontal-tb',\n transform: isVertical ? 'rotate(180deg)' : 'none',\n });\n this._container.appendChild(labelEl);\n }\n\n // Create gradient bar with ticks\n const barWrapper = document.createElement('div');\n barWrapper.className = 'maplibre-gl-colorbar-bar-wrapper';\n Object.assign(barWrapper.style, {\n display: 'flex',\n flexDirection: isVertical ? 'row' : 'column',\n alignItems: 'stretch',\n });\n\n // Gradient bar\n const bar = document.createElement('div');\n bar.className = 'maplibre-gl-colorbar-bar';\n Object.assign(bar.style, {\n background: this._generateGradient(),\n width: isVertical ? `${barThickness}px` : `${barLength}px`,\n height: isVertical ? `${barLength}px` : `${barThickness}px`,\n borderRadius: '2px',\n border: '1px solid rgba(0, 0, 0, 0.2)',\n });\n\n // Ticks container\n const ticksContainer = document.createElement('div');\n ticksContainer.className = 'maplibre-gl-colorbar-ticks';\n Object.assign(ticksContainer.style, {\n display: 'flex',\n flexDirection: isVertical ? 'column-reverse' : 'row',\n justifyContent: 'space-between',\n width: isVertical ? 'auto' : `${barLength}px`,\n height: isVertical ? `${barLength}px` : 'auto',\n marginLeft: isVertical ? '4px' : '0',\n marginTop: isVertical ? '0' : '4px',\n });\n\n ticks.forEach((value) => {\n const tick = document.createElement('span');\n tick.className = 'maplibre-gl-colorbar-tick';\n tick.textContent = this._formatTick(value);\n tick.style.fontSize = `${fontSize - 1}px`;\n ticksContainer.appendChild(tick);\n });\n\n barWrapper.appendChild(bar);\n barWrapper.appendChild(ticksContainer);\n this._container.appendChild(barWrapper);\n }\n}\n","import '../styles/common.css';\nimport '../styles/legend.css';\nimport type { IControl, Map as MapLibreMap } from 'maplibre-gl';\nimport type {\n LegendOptions,\n LegendState,\n LegendItem,\n ComponentEvent,\n ComponentEventHandler,\n} from './types';\n\n/**\n * Default options for the Legend control.\n */\nconst DEFAULT_OPTIONS: Required<LegendOptions> = {\n title: '',\n items: [],\n position: 'bottom-left',\n className: '',\n visible: true,\n collapsible: false,\n collapsed: false,\n width: 200,\n maxHeight: 300,\n opacity: 1,\n backgroundColor: 'rgba(255, 255, 255, 0.9)',\n fontSize: 12,\n fontColor: '#333',\n swatchSize: 16,\n borderRadius: 4,\n padding: 10,\n minzoom: 0,\n maxzoom: 24,\n};\n\n/**\n * A categorical legend control for MapLibre GL maps.\n *\n * Displays discrete legend items with color swatches and labels.\n *\n * @example\n * ```typescript\n * const legend = new Legend({\n * title: 'Land Use',\n * items: [\n * { label: 'Residential', color: '#ff6b6b' },\n * { label: 'Commercial', color: '#4ecdc4' },\n * { label: 'Industrial', color: '#95a5a6' },\n * ],\n * });\n * map.addControl(legend, 'bottom-left');\n * ```\n */\nexport class Legend implements IControl {\n private _container?: HTMLElement;\n private _options: Required<LegendOptions>;\n private _state: LegendState;\n private _eventHandlers: Map<ComponentEvent, Set<ComponentEventHandler<LegendState>>> = new Map();\n private _map?: MapLibreMap;\n private _handleZoom?: () => void;\n private _zoomVisible: boolean = true;\n\n /**\n * Creates a new Legend instance.\n *\n * @param options - Configuration options for the legend.\n */\n constructor(options?: LegendOptions) {\n this._options = { ...DEFAULT_OPTIONS, ...options };\n this._state = {\n visible: this._options.visible,\n collapsed: this._options.collapsed,\n items: [...this._options.items],\n };\n }\n\n /**\n * Called when the control is added to the map.\n *\n * @param map - The MapLibre GL map instance.\n * @returns The control's container element.\n */\n onAdd(map: MapLibreMap): HTMLElement {\n this._map = map;\n this._container = this._createContainer();\n this._render();\n\n // Set up zoom listener\n this._handleZoom = () => this._checkZoomVisibility();\n this._map.on('zoom', this._handleZoom);\n\n // Check initial zoom\n this._checkZoomVisibility();\n\n return this._container;\n }\n\n /**\n * Called when the control is removed from the map.\n */\n onRemove(): void {\n if (this._map && this._handleZoom) {\n this._map.off('zoom', this._handleZoom);\n this._handleZoom = undefined;\n }\n this._map = undefined;\n this._container?.parentNode?.removeChild(this._container);\n this._container = undefined;\n this._eventHandlers.clear();\n }\n\n /**\n * Shows the legend.\n */\n show(): void {\n if (!this._state.visible) {\n this._state.visible = true;\n this._updateDisplayState();\n this._emit('show');\n }\n }\n\n /**\n * Hides the legend.\n */\n hide(): void {\n if (this._state.visible) {\n this._state.visible = false;\n this._updateDisplayState();\n this._emit('hide');\n }\n }\n\n /**\n * Expands the legend (if collapsible).\n */\n expand(): void {\n if (this._state.collapsed) {\n this._state.collapsed = false;\n this._render();\n this._emit('expand');\n }\n }\n\n /**\n * Collapses the legend (if collapsible).\n */\n collapse(): void {\n if (!this._state.collapsed) {\n this._state.collapsed = true;\n this._render();\n this._emit('collapse');\n }\n }\n\n /**\n * Toggles the collapsed state.\n */\n toggle(): void {\n if (this._state.collapsed) {\n this.expand();\n } else {\n this.collapse();\n }\n }\n\n /**\n * Updates the legend items.\n *\n * @param items - New legend items.\n */\n setItems(items: LegendItem[]): void {\n this._state.items = [...items];\n this._options.items = [...items];\n this._render();\n this._emit('update');\n }\n\n /**\n * Adds a legend item.\n *\n * @param item - Legend item to add.\n */\n addItem(item: LegendItem): void {\n this._state.items.push(item);\n this._options.items.push(item);\n this._render();\n this._emit('update');\n }\n\n /**\n * Removes a legend item by label.\n *\n * @param label - Label of the item to remove.\n */\n removeItem(label: string): void {\n this._state.items = this._state.items.filter((item) => item.label !== label);\n this._options.items = [...this._state.items];\n this._render();\n this._emit('update');\n }\n\n /**\n * Updates legend options and re-renders.\n *\n * @param options - Partial options to update.\n */\n update(options: Partial<LegendOptions>): void {\n this._options = { ...this._options, ...options };\n if (options.items) this._state.items = [...options.items];\n if (options.visible !== undefined) this._state.visible = options.visible;\n if (options.collapsed !== undefined) this._state.collapsed = options.collapsed;\n this._render();\n this._emit('update');\n }\n\n /**\n * Gets the current state.\n *\n * @returns The current legend state.\n */\n getState(): LegendState {\n return { ...this._state, items: [...this._state.items] };\n }\n\n /**\n * Registers an event handler.\n *\n * @param event - The event type to listen for.\n * @param handler - The callback function.\n */\n on(event: ComponentEvent, handler: ComponentEventHandler<LegendState>): void {\n if (!this._eventHandlers.has(event)) {\n this._eventHandlers.set(event, new Set());\n }\n this._eventHandlers.get(event)!.add(handler);\n }\n\n /**\n * Removes an event handler.\n *\n * @param event - The event type.\n * @param handler - The callback function to remove.\n */\n off(event: ComponentEvent, handler: ComponentEventHandler<LegendState>): void {\n this._eventHandlers.get(event)?.delete(handler);\n }\n\n /**\n * Emits an event to all registered handlers.\n *\n * @param event - The event type to emit.\n */\n private _emit(event: ComponentEvent): void {\n const handlers = this._eventHandlers.get(event);\n if (handlers) {\n const eventData = { type: event, state: this.getState() };\n handlers.forEach((handler) => handler(eventData));\n }\n }\n\n /**\n * Checks if the current zoom level is within the visibility range.\n */\n private _checkZoomVisibility(): void {\n if (!this._map) return;\n\n const zoom = this._map.getZoom();\n const { minzoom, maxzoom } = this._options;\n const inRange = zoom >= minzoom && zoom <= maxzoom;\n\n if (inRange !== this._zoomVisible) {\n this._zoomVisible = inRange;\n this._updateDisplayState();\n }\n }\n\n /**\n * Updates the display state based on visibility and zoom level.\n */\n private _updateDisplayState(): void {\n if (!this._container) return;\n const shouldShow = this._state.visible && this._zoomVisible;\n this._container.style.display = shouldShow ? 'block' : 'none';\n }\n\n /**\n * Creates the main container element.\n *\n * @returns The container element.\n */\n private _createContainer(): HTMLElement {\n const container = document.createElement('div');\n container.className = `maplibregl-ctrl maplibre-gl-legend${\n this._options.className ? ` ${this._options.className}` : ''\n }`;\n\n const shouldShow = this._state.visible && this._zoomVisible;\n if (!shouldShow) {\n container.style.display = 'none';\n }\n\n return container;\n }\n\n /**\n * Creates a color swatch element.\n *\n * @param item - Legend item configuration.\n * @returns The swatch element.\n */\n private _createSwatch(item: LegendItem): HTMLElement {\n const { swatchSize = 16 } = this._options;\n const shape = item.shape || 'square';\n const swatch = document.createElement('span');\n swatch.className = `maplibre-gl-legend-swatch maplibre-gl-legend-swatch-${shape}`;\n\n // Base styles\n const baseStyles: Record<string, string> = {\n flexShrink: '0',\n display: 'inline-block',\n };\n\n if (shape === 'line') {\n // Line shape: horizontal line with rounded ends\n Object.assign(swatch.style, {\n ...baseStyles,\n width: `${swatchSize}px`,\n height: '4px',\n backgroundColor: item.color,\n borderRadius: '2px',\n border: 'none',\n alignSelf: 'center',\n });\n } else if (shape === 'circle') {\n // Circle shape\n Object.assign(swatch.style, {\n ...baseStyles,\n width: `${swatchSize}px`,\n height: `${swatchSize}px`,\n backgroundColor: item.color,\n borderRadius: '50%',\n border: item.strokeColor ? `2px solid ${item.strokeColor}` : '1px solid rgba(0,0,0,0.1)',\n });\n } else {\n // Square shape (default)\n Object.assign(swatch.style, {\n ...baseStyles,\n width: `${swatchSize}px`,\n height: `${swatchSize}px`,\n backgroundColor: item.color,\n borderRadius: '2px',\n border: item.strokeColor ? `2px solid ${item.strokeColor}` : '1px solid rgba(0,0,0,0.1)',\n });\n }\n\n // If icon is provided, use background image\n if (item.icon) {\n Object.assign(swatch.style, {\n backgroundImage: `url(${item.icon})`,\n backgroundSize: 'contain',\n backgroundRepeat: 'no-repeat',\n backgroundPosition: 'center',\n backgroundColor: 'transparent',\n border: 'none',\n width: `${swatchSize}px`,\n height: `${swatchSize}px`,\n });\n }\n\n return swatch;\n }\n\n /**\n * Renders the legend content.\n */\n private _render(): void {\n if (!this._container) return;\n\n const {\n title,\n backgroundColor,\n opacity,\n fontSize,\n fontColor,\n borderRadius,\n padding,\n width,\n maxHeight,\n collapsible,\n } = this._options;\n\n // Clear existing content\n this._container.innerHTML = '';\n\n // Apply container styles\n // When collapsed with header, use minimal vertical padding to match HtmlControl\n const isCollapsedWithHeader = this._state.collapsed && (title || collapsible);\n const vertPadding = isCollapsedWithHeader ? 4 : padding;\n const shouldShow = this._state.visible && this._zoomVisible;\n Object.assign(this._container.style, {\n backgroundColor,\n opacity: opacity.toString(),\n borderRadius: `${borderRadius}px`,\n padding: `${vertPadding}px ${padding}px`,\n fontSize: `${fontSize}px`,\n color: fontColor,\n width: isCollapsedWithHeader ? 'auto' : `${width}px`,\n maxWidth: `${width}px`,\n boxShadow: '0 0 0 2px rgba(0, 0, 0, 0.1)',\n display: shouldShow ? 'block' : 'none',\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n });\n\n // Add title/header\n if (title || collapsible) {\n const header = document.createElement('div');\n header.className = 'maplibre-gl-legend-header';\n Object.assign(header.style, {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n paddingBottom: this._state.collapsed ? '0' : '4px',\n cursor: collapsible ? 'pointer' : 'default',\n });\n\n if (title) {\n const titleEl = document.createElement('span');\n titleEl.className = 'maplibre-gl-legend-title';\n titleEl.textContent = title;\n titleEl.style.fontWeight = '600';\n header.appendChild(titleEl);\n }\n\n if (collapsible) {\n const toggleBtn = document.createElement('span');\n toggleBtn.className = 'maplibre-gl-legend-toggle';\n toggleBtn.innerHTML = this._state.collapsed ? '▶' : '▼';\n toggleBtn.style.marginLeft = '8px';\n header.appendChild(toggleBtn);\n header.addEventListener('click', () => this.toggle());\n }\n\n this._container.appendChild(header);\n }\n\n // Content area\n const content = document.createElement('div');\n content.className = 'maplibre-gl-legend-content';\n Object.assign(content.style, {\n maxHeight: `${maxHeight}px`,\n overflowY: 'auto',\n display: this._state.collapsed ? 'none' : 'block',\n });\n\n // Render legend items\n this._state.items.forEach((item) => {\n const row = document.createElement('div');\n row.className = 'maplibre-gl-legend-item';\n Object.assign(row.style, {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n padding: '4px 0',\n });\n\n const swatch = this._createSwatch(item);\n const label = document.createElement('span');\n label.className = 'maplibre-gl-legend-label';\n label.textContent = item.label;\n\n row.appendChild(swatch);\n row.appendChild(label);\n content.appendChild(row);\n });\n\n this._container.appendChild(content);\n }\n}\n","import '../styles/common.css';\nimport '../styles/html-control.css';\nimport type { IControl, Map as MapLibreMap } from 'maplibre-gl';\nimport type {\n HtmlControlOptions,\n HtmlControlState,\n ComponentEvent,\n ComponentEventHandler,\n} from './types';\n\n/**\n * Default options for the HtmlControl.\n */\nconst DEFAULT_OPTIONS: Required<Omit<HtmlControlOptions, 'element'>> & { element?: HTMLElement } = {\n html: '',\n element: undefined,\n title: '',\n position: 'top-left',\n className: '',\n visible: true,\n collapsible: false,\n collapsed: false,\n backgroundColor: 'rgba(255, 255, 255, 0.9)',\n padding: 10,\n borderRadius: 4,\n opacity: 1,\n maxWidth: 300,\n maxHeight: 400,\n fontSize: 12,\n fontColor: '#333',\n minzoom: 0,\n maxzoom: 24,\n};\n\n/**\n * A flexible HTML content control for MapLibre GL maps.\n *\n * Allows displaying arbitrary HTML content that can be dynamically updated.\n * Supports collapsible mode with a toggle button.\n *\n * @example\n * ```typescript\n * const htmlControl = new HtmlControl({\n * html: '<div><strong>Stats:</strong> 1,234 features</div>',\n * position: 'top-left',\n * collapsible: true,\n * title: 'Statistics',\n * });\n * map.addControl(htmlControl, 'top-left');\n *\n * // Update content dynamically\n * htmlControl.setHtml('<div><strong>Stats:</strong> 5,678 features</div>');\n * ```\n */\nexport class HtmlControl implements IControl {\n private _container?: HTMLElement;\n private _contentEl?: HTMLElement;\n private _options: Required<Omit<HtmlControlOptions, 'element'>> & { element?: HTMLElement };\n private _state: HtmlControlState;\n private _eventHandlers: Map<ComponentEvent, Set<ComponentEventHandler<HtmlControlState>>> =\n new Map();\n private _map?: MapLibreMap;\n private _handleZoom?: () => void;\n private _zoomVisible: boolean = true;\n\n /**\n * Creates a new HtmlControl instance.\n *\n * @param options - Configuration options for the control.\n */\n constructor(options?: HtmlControlOptions) {\n this._options = { ...DEFAULT_OPTIONS, ...options };\n this._state = {\n visible: this._options.visible,\n collapsed: this._options.collapsed,\n html: this._options.html,\n };\n }\n\n /**\n * Called when the control is added to the map.\n * Implements the IControl interface.\n *\n * @param map - The MapLibre GL map instance.\n * @returns The control's container element.\n */\n onAdd(map: MapLibreMap): HTMLElement {\n this._map = map;\n this._container = this._createContainer();\n this._render();\n\n // Set up zoom listener\n this._handleZoom = () => this._checkZoomVisibility();\n this._map.on('zoom', this._handleZoom);\n\n // Check initial zoom\n this._checkZoomVisibility();\n\n return this._container;\n }\n\n /**\n * Called when the control is removed from the map.\n * Implements the IControl interface.\n */\n onRemove(): void {\n if (this._map && this._handleZoom) {\n this._map.off('zoom', this._handleZoom);\n this._handleZoom = undefined;\n }\n this._map = undefined;\n this._container?.parentNode?.removeChild(this._container);\n this._container = undefined;\n this._contentEl = undefined;\n this._eventHandlers.clear();\n }\n\n /**\n * Shows the control.\n */\n show(): void {\n if (!this._state.visible) {\n this._state.visible = true;\n this._updateDisplayState();\n this._emit('show');\n }\n }\n\n /**\n * Hides the control.\n */\n hide(): void {\n if (this._state.visible) {\n this._state.visible = false;\n this._updateDisplayState();\n this._emit('hide');\n }\n }\n\n /**\n * Expands the control (if collapsible).\n */\n expand(): void {\n if (this._state.collapsed) {\n this._state.collapsed = false;\n this._render();\n this._emit('expand');\n }\n }\n\n /**\n * Collapses the control (if collapsible).\n */\n collapse(): void {\n if (!this._state.collapsed) {\n this._state.collapsed = true;\n this._render();\n this._emit('collapse');\n }\n }\n\n /**\n * Toggles the collapsed state.\n */\n toggle(): void {\n if (this._state.collapsed) {\n this.expand();\n } else {\n this.collapse();\n }\n }\n\n /**\n * Sets the HTML content.\n *\n * @param html - The HTML string to display.\n */\n setHtml(html: string): void {\n this._state.html = html;\n this._options.html = html;\n this._options.element = undefined; // Clear element when setting HTML\n if (this._contentEl) {\n this._contentEl.innerHTML = html;\n }\n this._emit('update');\n }\n\n /**\n * Sets a DOM element as content.\n *\n * @param element - The DOM element to display.\n */\n setElement(element: HTMLElement): void {\n this._options.element = element;\n this._options.html = '';\n this._state.html = '';\n if (this._contentEl) {\n this._contentEl.innerHTML = '';\n this._contentEl.appendChild(element);\n }\n this._emit('update');\n }\n\n /**\n * Gets the content container element.\n *\n * @returns The content container element, or undefined if not yet added to map.\n */\n getElement(): HTMLElement | undefined {\n return this._contentEl;\n }\n\n /**\n * Updates control options and re-renders.\n *\n * @param options - Partial options to update.\n */\n update(options: Partial<HtmlControlOptions>): void {\n this._options = { ...this._options, ...options };\n if (options.html !== undefined) this._state.html = options.html;\n if (options.visible !== undefined) this._state.visible = options.visible;\n if (options.collapsed !== undefined) this._state.collapsed = options.collapsed;\n this._render();\n this._emit('update');\n }\n\n /**\n * Gets the current state.\n *\n * @returns The current control state.\n */\n getState(): HtmlControlState {\n return { ...this._state };\n }\n\n /**\n * Registers an event handler.\n *\n * @param event - The event type to listen for.\n * @param handler - The callback function.\n */\n on(event: ComponentEvent, handler: ComponentEventHandler<HtmlControlState>): void {\n if (!this._eventHandlers.has(event)) {\n this._eventHandlers.set(event, new Set());\n }\n this._eventHandlers.get(event)!.add(handler);\n }\n\n /**\n * Removes an event handler.\n *\n * @param event - The event type.\n * @param handler - The callback function to remove.\n */\n off(event: ComponentEvent, handler: ComponentEventHandler<HtmlControlState>): void {\n this._eventHandlers.get(event)?.delete(handler);\n }\n\n /**\n * Emits an event to all registered handlers.\n *\n * @param event - The event type to emit.\n */\n private _emit(event: ComponentEvent): void {\n const handlers = this._eventHandlers.get(event);\n if (handlers) {\n const eventData = { type: event, state: this.getState() };\n handlers.forEach((handler) => handler(eventData));\n }\n }\n\n /**\n * Checks if the current zoom level is within the visibility range.\n */\n private _checkZoomVisibility(): void {\n if (!this._map) return;\n\n const zoom = this._map.getZoom();\n const { minzoom, maxzoom } = this._options;\n const inRange = zoom >= minzoom && zoom <= maxzoom;\n\n if (inRange !== this._zoomVisible) {\n this._zoomVisible = inRange;\n this._updateDisplayState();\n }\n }\n\n /**\n * Updates the display state based on visibility and zoom level.\n */\n private _updateDisplayState(): void {\n if (!this._container) return;\n const shouldShow = this._state.visible && this._zoomVisible;\n this._container.style.display = shouldShow ? 'block' : 'none';\n }\n\n /**\n * Creates the main container element.\n *\n * @returns The container element.\n */\n private _createContainer(): HTMLElement {\n const container = document.createElement('div');\n container.className = `maplibregl-ctrl maplibre-gl-html-control${\n this._options.className ? ` ${this._options.className}` : ''\n }`;\n\n const shouldShow = this._state.visible && this._zoomVisible;\n if (!shouldShow) {\n container.style.display = 'none';\n }\n\n return container;\n }\n\n /**\n * Renders the control content.\n */\n private _render(): void {\n if (!this._container) return;\n\n const {\n title = '',\n collapsible = false,\n backgroundColor = 'rgba(255, 255, 255, 0.9)',\n opacity = 1,\n borderRadius = 4,\n padding = 10,\n maxWidth = 300,\n maxHeight = 400,\n fontSize = 12,\n fontColor = '#333',\n } = this._options;\n\n // Clear existing content\n this._container.innerHTML = '';\n\n // Apply container styles\n // When collapsed with header, use minimal vertical padding\n const isCollapsedWithHeader = this._state.collapsed && (title || collapsible);\n const vertPadding = isCollapsedWithHeader ? 4 : padding;\n const shouldShow = this._state.visible && this._zoomVisible;\n Object.assign(this._container.style, {\n backgroundColor,\n opacity: String(opacity),\n borderRadius: `${borderRadius}px`,\n padding: `${vertPadding}px ${padding}px`,\n maxWidth: `${maxWidth}px`,\n fontSize: `${fontSize}px`,\n color: fontColor,\n boxShadow: '0 0 0 2px rgba(0, 0, 0, 0.1)',\n display: shouldShow ? 'block' : 'none',\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n });\n\n // Add header with toggle if collapsible\n if (collapsible || title) {\n const header = document.createElement('div');\n header.className = 'maplibre-gl-html-control-header';\n Object.assign(header.style, {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n paddingBottom: this._state.collapsed ? '0' : '8px',\n cursor: collapsible ? 'pointer' : 'default',\n });\n\n if (title) {\n const titleEl = document.createElement('span');\n titleEl.className = 'maplibre-gl-html-control-title';\n titleEl.textContent = title;\n titleEl.style.fontWeight = '600';\n header.appendChild(titleEl);\n }\n\n if (collapsible) {\n const toggleBtn = document.createElement('span');\n toggleBtn.className = 'maplibre-gl-html-control-toggle';\n toggleBtn.innerHTML = this._state.collapsed ? '▶' : '▼';\n Object.assign(toggleBtn.style, {\n marginLeft: '8px',\n fontSize: '10px',\n userSelect: 'none',\n });\n header.appendChild(toggleBtn);\n header.addEventListener('click', () => this.toggle());\n }\n\n this._container.appendChild(header);\n }\n\n // Create content element\n const content = document.createElement('div');\n content.className = 'maplibre-gl-html-control-content';\n Object.assign(content.style, {\n maxHeight: `${maxHeight}px`,\n overflowY: 'auto',\n display: this._state.collapsed ? 'none' : 'block',\n });\n this._contentEl = content;\n\n // Set content\n if (this._options.element) {\n content.appendChild(this._options.element);\n } else if (this._options.html) {\n content.innerHTML = this._options.html;\n }\n\n this._container.appendChild(content);\n }\n}\n","import '../styles/common.css';\nimport '../styles/basemap.css';\nimport type { IControl, Map as MapLibreMap } from 'maplibre-gl';\nimport type {\n BasemapControlOptions,\n BasemapControlState,\n BasemapItem,\n BasemapEvent,\n ComponentEvent,\n} from './types';\nimport {\n XYZSERVICES_URL,\n parseProviders,\n buildTileUrl,\n groupBasemaps,\n filterBasemaps,\n GOOGLE_BASEMAPS,\n} from '../utils/providers';\n\n/**\n * Event handler type for basemap events.\n */\ntype BasemapEventHandler = (event: { type: BasemapEvent; state: BasemapControlState; basemap?: BasemapItem }) => void;\n\n/**\n * Default options for the BasemapControl.\n */\nconst DEFAULT_OPTIONS: Required<Omit<BasemapControlOptions, 'basemaps' | 'filterGroups' | 'excludeGroups' | 'beforeId'>> & {\n basemaps: BasemapItem[];\n filterGroups: string[] | undefined;\n excludeGroups: string[] | undefined;\n beforeId: string | undefined;\n} = {\n basemaps: [],\n providersUrl: XYZSERVICES_URL,\n defaultBasemap: '',\n position: 'top-right',\n className: '',\n visible: true,\n collapsible: true,\n collapsed: true,\n displayMode: 'dropdown',\n showSearch: true,\n filterGroups: undefined,\n excludeGroups: undefined,\n excludeBroken: true,\n backgroundColor: 'rgba(255, 255, 255, 0.9)',\n padding: 10,\n borderRadius: 4,\n opacity: 1,\n maxWidth: 250,\n maxHeight: 300,\n fontSize: 12,\n fontColor: '#333',\n minzoom: 0,\n maxzoom: 24,\n beforeId: undefined,\n belowLabels: false,\n};\n\n/**\n * Source and layer IDs for the basemap raster layer.\n */\nconst BASEMAP_SOURCE_ID = 'basemap-raster-source';\nconst BASEMAP_LAYER_ID = 'basemap-raster-layer';\n\n/**\n * A basemap switcher control for MapLibre GL maps.\n *\n * Allows users to interactively switch between different basemap tile sources.\n * Supports loading basemaps from xyzservices or custom basemap arrays.\n *\n * @example\n * ```typescript\n * const basemapControl = new BasemapControl({\n * defaultBasemap: 'OpenStreetMap.Mapnik',\n * showSearch: true,\n * filterGroups: ['OpenStreetMap', 'CartoDB', 'Stadia'],\n * });\n * map.addControl(basemapControl, 'top-right');\n * ```\n */\nexport class BasemapControl implements IControl {\n private _container?: HTMLElement;\n private _options: typeof DEFAULT_OPTIONS;\n private _state: BasemapControlState;\n private _basemaps: BasemapItem[] = [];\n private _eventHandlers: Map<BasemapEvent, Set<BasemapEventHandler>> = new Map();\n private _map?: MapLibreMap;\n private _handleZoom?: () => void;\n private _zoomVisible: boolean = true;\n\n /**\n * Creates a new BasemapControl instance.\n *\n * @param options - Configuration options for the control.\n */\n constructor(options?: BasemapControlOptions) {\n this._options = { ...DEFAULT_OPTIONS, ...options };\n this._state = {\n visible: this._options.visible,\n collapsed: this._options.collapsed,\n selectedBasemap: this._options.defaultBasemap || null,\n searchText: '',\n loading: false,\n error: null,\n belowLabels: this._options.belowLabels,\n };\n\n // Use provided basemaps if any\n if (this._options.basemaps.length > 0) {\n this._basemaps = [...this._options.basemaps];\n }\n }\n\n /**\n * Called when the control is added to the map.\n *\n * @param map - The MapLibre GL map instance.\n * @returns The control's container element.\n */\n onAdd(map: MapLibreMap): HTMLElement {\n this._map = map;\n this._container = this._createContainer();\n\n // Fetch providers if no basemaps provided\n if (this._basemaps.length === 0 && this._options.providersUrl) {\n this._fetchProviders();\n } else {\n this._render();\n // Apply initial basemap if specified\n if (this._state.selectedBasemap) {\n const basemap = this._basemaps.find((b) => b.id === this._state.selectedBasemap);\n if (basemap) {\n this._applyBasemap(basemap);\n }\n }\n }\n\n // Set up zoom listener\n this._handleZoom = () => this._checkZoomVisibility();\n this._map.on('zoom', this._handleZoom);\n this._checkZoomVisibility();\n\n return this._container;\n }\n\n /**\n * Called when the control is removed from the map.\n */\n onRemove(): void {\n if (this._map && this._handleZoom) {\n this._map.off('zoom', this._handleZoom);\n this._handleZoom = undefined;\n }\n\n // Remove basemap layer and source\n this._removeBasemapLayer();\n\n this._map = undefined;\n this._container?.parentNode?.removeChild(this._container);\n this._container = undefined;\n this._eventHandlers.clear();\n }\n\n /**\n * Shows the control.\n */\n show(): void {\n if (!this._state.visible) {\n this._state.visible = true;\n this._updateDisplayState();\n this._emit('show');\n }\n }\n\n /**\n * Hides the control.\n */\n hide(): void {\n if (this._state.visible) {\n this._state.visible = false;\n this._updateDisplayState();\n this._emit('hide');\n }\n }\n\n /**\n * Expands the control (if collapsible).\n */\n expand(): void {\n if (this._state.collapsed) {\n this._state.collapsed = false;\n this._render();\n this._emit('expand');\n }\n }\n\n /**\n * Collapses the control (if collapsible).\n */\n collapse(): void {\n if (!this._state.collapsed) {\n this._state.collapsed = true;\n this._render();\n this._emit('collapse');\n }\n }\n\n /**\n * Toggles the collapsed state.\n */\n toggle(): void {\n if (this._state.collapsed) {\n this.expand();\n } else {\n this.collapse();\n }\n }\n\n /**\n * Sets the active basemap by ID.\n *\n * @param basemapId - The ID of the basemap to activate.\n */\n setBasemap(basemapId: string): void {\n const basemap = this._basemaps.find((b) => b.id === basemapId);\n if (basemap) {\n this._state.selectedBasemap = basemapId;\n this._applyBasemap(basemap);\n this._render();\n this._emit('basemapchange', basemap);\n this._emit('update');\n }\n }\n\n /**\n * Gets the list of available basemaps.\n *\n * @returns Array of basemap items.\n */\n getBasemaps(): BasemapItem[] {\n return [...this._basemaps];\n }\n\n /**\n * Adds a custom basemap.\n *\n * @param basemap - The basemap item to add.\n */\n addBasemap(basemap: BasemapItem): void {\n this._basemaps.push(basemap);\n this._render();\n }\n\n /**\n * Removes a basemap by ID.\n *\n * @param basemapId - The ID of the basemap to remove.\n */\n removeBasemap(basemapId: string): void {\n this._basemaps = this._basemaps.filter((b) => b.id !== basemapId);\n this._render();\n }\n\n /**\n * Sets an API key for a basemap.\n *\n * @param basemapId - The ID of the basemap.\n * @param apiKey - The API key to set.\n */\n setApiKey(basemapId: string, apiKey: string): void {\n const basemap = this._basemaps.find((b) => b.id === basemapId);\n if (basemap) {\n basemap.apiKey = apiKey;\n basemap.requiresApiKey = false;\n }\n }\n\n /**\n * Updates control options and re-renders.\n *\n * @param options - Partial options to update.\n */\n update(options: Partial<BasemapControlOptions>): void {\n this._options = { ...this._options, ...options };\n if (options.basemaps) {\n this._basemaps = [...options.basemaps];\n }\n if (options.visible !== undefined) this._state.visible = options.visible;\n if (options.collapsed !== undefined) this._state.collapsed = options.collapsed;\n this._render();\n this._emit('update');\n }\n\n /**\n * Gets the current state.\n *\n * @returns The current control state.\n */\n getState(): BasemapControlState {\n return { ...this._state };\n }\n\n /**\n * Gets the currently selected basemap.\n *\n * @returns The selected basemap item, or null if none selected.\n */\n getSelectedBasemap(): BasemapItem | null {\n if (!this._state.selectedBasemap) return null;\n return this._basemaps.find((b) => b.id === this._state.selectedBasemap) || null;\n }\n\n /**\n * Registers an event handler.\n *\n * @param event - The event type to listen for.\n * @param handler - The callback function.\n */\n on(event: BasemapEvent, handler: BasemapEventHandler): void {\n if (!this._eventHandlers.has(event)) {\n this._eventHandlers.set(event, new Set());\n }\n this._eventHandlers.get(event)!.add(handler);\n }\n\n /**\n * Removes an event handler.\n *\n * @param event - The event type.\n * @param handler - The callback function to remove.\n */\n off(event: BasemapEvent, handler: BasemapEventHandler): void {\n this._eventHandlers.get(event)?.delete(handler);\n }\n\n /**\n * Emits an event to all registered handlers.\n */\n private _emit(event: ComponentEvent | 'basemapchange', basemap?: BasemapItem): void {\n const handlers = this._eventHandlers.get(event);\n if (handlers) {\n const eventData = { type: event, state: this.getState(), basemap };\n handlers.forEach((handler) => handler(eventData));\n }\n }\n\n /**\n * Fetches providers from the xyzservices URL.\n */\n private async _fetchProviders(): Promise<void> {\n this._state.loading = true;\n this._state.error = null;\n this._render();\n\n try {\n const response = await fetch(this._options.providersUrl);\n if (!response.ok) {\n throw new Error(`Failed to fetch: ${response.statusText}`);\n }\n const data = await response.json();\n\n this._basemaps = parseProviders(data, {\n filterGroups: this._options.filterGroups,\n excludeGroups: this._options.excludeGroups,\n excludeBroken: this._options.excludeBroken,\n });\n\n // Add Google basemaps if not excluded\n const shouldIncludeGoogle =\n !this._options.excludeGroups?.includes('Google') &&\n (!this._options.filterGroups?.length || this._options.filterGroups.includes('Google'));\n\n if (shouldIncludeGoogle) {\n this._basemaps = [...this._basemaps, ...GOOGLE_BASEMAPS];\n }\n\n this._state.loading = false;\n this._state.error = null;\n\n // Apply initial basemap if specified\n if (this._state.selectedBasemap) {\n const basemap = this._basemaps.find((b) => b.id === this._state.selectedBasemap);\n if (basemap) {\n this._applyBasemap(basemap);\n }\n }\n } catch (error) {\n this._state.loading = false;\n this._state.error = error instanceof Error ? error.message : 'Failed to load providers';\n console.error('BasemapControl: Failed to fetch providers', error);\n }\n\n this._render();\n }\n\n /**\n * Applies a basemap to the map.\n */\n private _applyBasemap(basemap: BasemapItem): void {\n if (!this._map) return;\n\n // Check if basemap requires API key\n if (basemap.requiresApiKey && !basemap.apiKey) {\n console.warn(`BasemapControl: Basemap \"${basemap.name}\" requires an API key`);\n return;\n }\n\n if (basemap.style) {\n // Vector style - use setStyle\n this._applyStyleBasemap(basemap);\n } else if (basemap.url) {\n // XYZ tiles - add as raster source/layer\n this._applyXYZBasemap(basemap);\n }\n }\n\n /**\n * Applies an XYZ tile basemap.\n */\n private _applyXYZBasemap(basemap: BasemapItem): void {\n if (!this._map) return;\n\n // Remove existing basemap layer\n this._removeBasemapLayer();\n\n // Build the tile URL\n const tileUrl = buildTileUrl(basemap);\n\n // Add raster source\n this._map.addSource(BASEMAP_SOURCE_ID, {\n type: 'raster',\n tiles: [tileUrl],\n tileSize: 256,\n attribution: basemap.attribution,\n maxzoom: basemap.maxZoom || 19,\n minzoom: basemap.minZoom || 0,\n });\n\n // Find the layer to insert before\n let beforeLayerId: string | undefined;\n if (this._state.belowLabels) {\n // Find the first symbol layer to insert basemap below labels\n const layers = this._map.getStyle()?.layers;\n if (layers) {\n for (const layer of layers) {\n if (layer.type === 'symbol') {\n beforeLayerId = layer.id;\n break;\n }\n }\n }\n }\n\n // Add raster layer\n this._map.addLayer(\n {\n id: BASEMAP_LAYER_ID,\n type: 'raster',\n source: BASEMAP_SOURCE_ID,\n },\n beforeLayerId\n );\n }\n\n /**\n * Applies a vector style basemap.\n */\n private _applyStyleBasemap(basemap: BasemapItem): void {\n if (!this._map || !basemap.style) return;\n\n // Remove existing basemap layer first\n this._removeBasemapLayer();\n\n // For style-based basemaps, we need to be careful about preserving user layers\n // This is a simplified approach - for full layer preservation, more complex logic is needed\n this._map.setStyle(basemap.style);\n }\n\n /**\n * Removes the basemap layer and source.\n */\n private _removeBasemapLayer(): void {\n if (!this._map) return;\n\n if (this._map.getLayer(BASEMAP_LAYER_ID)) {\n this._map.removeLayer(BASEMAP_LAYER_ID);\n }\n if (this._map.getSource(BASEMAP_SOURCE_ID)) {\n this._map.removeSource(BASEMAP_SOURCE_ID);\n }\n }\n\n /**\n * Checks if the current zoom level is within the visibility range.\n */\n private _checkZoomVisibility(): void {\n if (!this._map) return;\n\n const zoom = this._map.getZoom();\n const { minzoom, maxzoom } = this._options;\n const inRange = zoom >= minzoom && zoom <= maxzoom;\n\n if (inRange !== this._zoomVisible) {\n this._zoomVisible = inRange;\n this._updateDisplayState();\n }\n }\n\n /**\n * Updates the display state based on visibility and zoom level.\n */\n private _updateDisplayState(): void {\n if (!this._container) return;\n const shouldShow = this._state.visible && this._zoomVisible;\n this._container.style.display = shouldShow ? 'block' : 'none';\n }\n\n /**\n * Creates the main container element.\n */\n private _createContainer(): HTMLElement {\n const container = document.createElement('div');\n container.className = `maplibregl-ctrl maplibre-gl-basemap${\n this._options.className ? ` ${this._options.className}` : ''\n }`;\n\n const shouldShow = this._state.visible && this._zoomVisible;\n if (!shouldShow) {\n container.style.display = 'none';\n }\n\n return container;\n }\n\n /**\n * Renders the control content.\n */\n private _render(): void {\n if (!this._container) return;\n\n const {\n backgroundColor,\n opacity,\n fontSize,\n fontColor,\n borderRadius,\n padding,\n maxWidth,\n maxHeight,\n collapsible,\n displayMode,\n showSearch,\n } = this._options;\n\n // Save scroll position before clearing content\n const contentEl = this._container.querySelector('.maplibre-gl-basemap-content');\n const scrollTop = contentEl ? contentEl.scrollTop : 0;\n\n // Clear existing content\n this._container.innerHTML = '';\n\n const shouldShow = this._state.visible && this._zoomVisible;\n\n // When collapsed and collapsible, show only icon button\n if (collapsible && this._state.collapsed) {\n Object.assign(this._container.style, {\n backgroundColor,\n opacity: opacity.toString(),\n borderRadius: `${borderRadius}px`,\n boxShadow: '0 0 0 2px rgba(0, 0, 0, 0.1)',\n display: shouldShow ? 'block' : 'none',\n padding: '0',\n maxWidth: 'none',\n });\n\n const iconButton = this._createIconButton();\n this._container.appendChild(iconButton);\n return;\n }\n\n // Apply container styles for expanded state\n Object.assign(this._container.style, {\n backgroundColor,\n opacity: opacity.toString(),\n borderRadius: `${borderRadius}px`,\n fontSize: `${fontSize}px`,\n color: fontColor,\n maxWidth: `${maxWidth}px`,\n boxShadow: '0 0 0 2px rgba(0, 0, 0, 0.1)',\n display: shouldShow ? 'block' : 'none',\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n position: 'relative',\n padding: '0',\n });\n\n // Header with close button\n if (collapsible) {\n const header = this._createHeader();\n this._container.appendChild(header);\n }\n\n // Content\n const content = document.createElement('div');\n content.className = 'maplibre-gl-basemap-content';\n Object.assign(content.style, {\n padding: `0 ${padding}px ${padding}px ${padding}px`,\n maxHeight: `${maxHeight}px`,\n overflowY: 'auto',\n });\n\n // Loading state\n if (this._state.loading) {\n const loading = document.createElement('div');\n loading.className = 'maplibre-gl-basemap-loading';\n loading.textContent = 'Loading basemaps...';\n Object.assign(loading.style, {\n padding: '20px',\n textAlign: 'center',\n color: '#666',\n });\n content.appendChild(loading);\n }\n // Error state\n else if (this._state.error) {\n const error = document.createElement('div');\n error.className = 'maplibre-gl-basemap-error';\n error.textContent = this._state.error;\n Object.assign(error.style, {\n padding: '10px',\n color: '#d32f2f',\n fontSize: '0.9em',\n });\n content.appendChild(error);\n }\n // Normal content\n else {\n // Search input\n if (showSearch && this._basemaps.length > 5) {\n const searchInput = this._createSearchInput();\n content.appendChild(searchInput);\n }\n\n // Below labels checkbox\n const checkboxContainer = this._createBelowLabelsCheckbox();\n content.appendChild(checkboxContainer);\n\n // Basemap list - always use list mode when panel is expanded\n // (dropdown mode only affects collapsed icon behavior)\n const filteredBasemaps = filterBasemaps(this._basemaps, this._state.searchText);\n\n if (displayMode === 'gallery') {\n const gallery = this._renderGallery(filteredBasemaps);\n content.appendChild(gallery);\n } else {\n // Both 'dropdown' and 'list' modes show a scrollable list when expanded\n const list = this._renderList(filteredBasemaps);\n content.appendChild(list);\n }\n }\n\n this._container.appendChild(content);\n\n // Restore scroll position\n if (scrollTop > 0) {\n content.scrollTop = scrollTop;\n }\n }\n\n /**\n * Creates the icon button for collapsed state.\n */\n private _createIconButton(): HTMLElement {\n const button = document.createElement('button');\n button.className = 'maplibre-gl-basemap-icon-button';\n button.title = 'Basemaps';\n\n // Map icon SVG (folded map with pin)\n button.innerHTML = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polygon points=\"1 6 1 22 8 18 16 22 23 18 23 2 16 6 8 2 1 6\"></polygon>\n <line x1=\"8\" y1=\"2\" x2=\"8\" y2=\"18\"></line>\n <line x1=\"16\" y1=\"6\" x2=\"16\" y2=\"22\"></line>\n </svg>\n `;\n\n Object.assign(button.style, {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '29px',\n height: '29px',\n padding: '0',\n border: 'none',\n background: 'transparent',\n cursor: 'pointer',\n color: '#333',\n });\n\n button.addEventListener('click', (e) => {\n e.stopPropagation();\n this.expand();\n });\n\n button.addEventListener('mouseenter', () => {\n button.style.color = '#0078d7';\n });\n\n button.addEventListener('mouseleave', () => {\n button.style.color = '#333';\n });\n\n return button;\n }\n\n /**\n * Creates the header element.\n */\n private _createHeader(): HTMLElement {\n const { padding } = this._options;\n\n const header = document.createElement('div');\n header.className = 'maplibre-gl-basemap-header';\n Object.assign(header.style, {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: `${padding}px`,\n borderBottom: '1px solid rgba(0,0,0,0.1)',\n });\n\n const title = document.createElement('span');\n title.className = 'maplibre-gl-basemap-title';\n title.textContent = 'Basemaps';\n title.style.fontWeight = '600';\n header.appendChild(title);\n\n // Close button\n const closeBtn = document.createElement('button');\n closeBtn.className = 'maplibre-gl-basemap-close';\n closeBtn.title = 'Close';\n closeBtn.innerHTML = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n </svg>\n `;\n Object.assign(closeBtn.style, {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '24px',\n height: '24px',\n padding: '0',\n border: 'none',\n background: 'transparent',\n cursor: 'pointer',\n color: '#666',\n borderRadius: '4px',\n });\n\n closeBtn.addEventListener('click', (e) => {\n e.stopPropagation();\n this.collapse();\n });\n\n closeBtn.addEventListener('mouseenter', () => {\n closeBtn.style.background = 'rgba(0,0,0,0.1)';\n closeBtn.style.color = '#333';\n });\n\n closeBtn.addEventListener('mouseleave', () => {\n closeBtn.style.background = 'transparent';\n closeBtn.style.color = '#666';\n });\n\n header.appendChild(closeBtn);\n\n return header;\n }\n\n /**\n * Creates the search input element.\n */\n private _createSearchInput(): HTMLElement {\n const container = document.createElement('div');\n container.style.marginBottom = '8px';\n\n const input = document.createElement('input');\n input.type = 'text';\n input.placeholder = 'Search basemaps...';\n input.className = 'maplibre-gl-basemap-search';\n input.value = this._state.searchText;\n Object.assign(input.style, {\n width: '100%',\n padding: '6px 10px',\n border: '1px solid #ddd',\n borderRadius: '4px',\n fontSize: 'inherit',\n boxSizing: 'border-box',\n });\n\n input.addEventListener('input', (e) => {\n this._state.searchText = (e.target as HTMLInputElement).value;\n this._render();\n });\n\n input.addEventListener('click', (e) => {\n e.stopPropagation();\n });\n\n container.appendChild(input);\n return container;\n }\n\n /**\n * Creates the below labels checkbox element.\n */\n private _createBelowLabelsCheckbox(): HTMLElement {\n const container = document.createElement('div');\n container.className = 'maplibre-gl-basemap-checkbox';\n Object.assign(container.style, {\n display: 'flex',\n alignItems: 'center',\n marginBottom: '8px',\n padding: '4px 0',\n borderBottom: '1px solid #eee',\n });\n\n const checkbox = document.createElement('input');\n checkbox.type = 'checkbox';\n checkbox.id = 'basemap-below-labels';\n checkbox.checked = this._state.belowLabels;\n Object.assign(checkbox.style, {\n marginRight: '8px',\n cursor: 'pointer',\n });\n\n checkbox.addEventListener('change', (e) => {\n e.stopPropagation();\n this._state.belowLabels = (e.target as HTMLInputElement).checked;\n // Re-apply current basemap with new layer ordering\n if (this._state.selectedBasemap) {\n const basemap = this._basemaps.find((b) => b.id === this._state.selectedBasemap);\n if (basemap) {\n this._applyBasemap(basemap);\n }\n }\n });\n\n const label = document.createElement('label');\n label.htmlFor = 'basemap-below-labels';\n label.textContent = 'Below labels';\n Object.assign(label.style, {\n cursor: 'pointer',\n fontSize: '0.9em',\n color: '#666',\n });\n\n container.appendChild(checkbox);\n container.appendChild(label);\n return container;\n }\n\n /**\n * Renders the list mode.\n */\n private _renderList(basemaps: BasemapItem[]): HTMLElement {\n const container = document.createElement('div');\n container.className = 'maplibre-gl-basemap-list';\n\n // Group basemaps\n const groups = groupBasemaps(basemaps);\n\n groups.forEach((items, groupName) => {\n // Group header\n const groupHeader = document.createElement('div');\n groupHeader.className = 'maplibre-gl-basemap-group';\n groupHeader.textContent = groupName;\n Object.assign(groupHeader.style, {\n fontWeight: '600',\n padding: '8px 0 4px',\n color: '#666',\n fontSize: '0.9em',\n });\n container.appendChild(groupHeader);\n\n // Group items\n items.forEach((basemap) => {\n const item = this._createBasemapItem(basemap, true);\n container.appendChild(item);\n });\n });\n\n return container;\n }\n\n /**\n * Renders the gallery mode.\n */\n private _renderGallery(basemaps: BasemapItem[]): HTMLElement {\n const container = document.createElement('div');\n container.className = 'maplibre-gl-basemap-gallery';\n Object.assign(container.style, {\n display: 'grid',\n gridTemplateColumns: 'repeat(auto-fill, minmax(70px, 1fr))',\n gap: '8px',\n maxHeight: `${this._options.maxHeight}px`,\n overflowY: 'auto',\n });\n\n basemaps.forEach((basemap) => {\n const item = document.createElement('div');\n item.className = `maplibre-gl-basemap-gallery-item${\n basemap.id === this._state.selectedBasemap ? ' maplibre-gl-basemap-gallery-item--selected' : ''\n }`;\n Object.assign(item.style, {\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n cursor: 'pointer',\n padding: '4px',\n borderRadius: '4px',\n transition: 'background-color 0.15s',\n outline: basemap.id === this._state.selectedBasemap ? '2px solid #0078d7' : 'none',\n });\n\n // Thumbnail\n const thumbnail = document.createElement('div');\n thumbnail.className = 'maplibre-gl-basemap-thumbnail';\n Object.assign(thumbnail.style, {\n width: '60px',\n height: '60px',\n borderRadius: '4px',\n border: '1px solid rgba(0, 0, 0, 0.1)',\n backgroundColor: '#f0f0f0',\n backgroundSize: 'cover',\n backgroundPosition: 'center',\n });\n\n // Generate thumbnail URL\n if (basemap.thumbnail || basemap.url) {\n let thumbUrl = basemap.thumbnail;\n if (!thumbUrl && basemap.url) {\n thumbUrl = buildTileUrl(basemap)\n .replace('{z}', '3')\n .replace('{x}', '4')\n .replace('{y}', '2');\n }\n if (thumbUrl) {\n thumbnail.style.backgroundImage = `url(${thumbUrl})`;\n }\n }\n\n // Name\n const name = document.createElement('div');\n name.className = 'maplibre-gl-basemap-name';\n name.textContent = basemap.name;\n Object.assign(name.style, {\n marginTop: '4px',\n fontSize: '0.75em',\n textAlign: 'center',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n maxWidth: '70px',\n });\n\n item.appendChild(thumbnail);\n item.appendChild(name);\n\n item.addEventListener('click', (e) => {\n e.stopPropagation();\n this.setBasemap(basemap.id);\n });\n\n item.addEventListener('mouseenter', () => {\n if (basemap.id !== this._state.selectedBasemap) {\n item.style.backgroundColor = 'rgba(0, 0, 0, 0.05)';\n }\n });\n\n item.addEventListener('mouseleave', () => {\n item.style.backgroundColor = '';\n });\n\n container.appendChild(item);\n });\n\n return container;\n }\n\n /**\n * Creates a basemap item element.\n */\n private _createBasemapItem(basemap: BasemapItem, showRadio = false): HTMLElement {\n const item = document.createElement('div');\n item.className = `maplibre-gl-basemap-item${\n basemap.id === this._state.selectedBasemap ? ' maplibre-gl-basemap-item--selected' : ''\n }`;\n Object.assign(item.style, {\n display: 'flex',\n alignItems: 'center',\n padding: '6px 12px',\n cursor: 'pointer',\n borderRadius: '4px',\n transition: 'background-color 0.15s',\n backgroundColor: basemap.id === this._state.selectedBasemap ? 'rgba(0, 120, 215, 0.1)' : '',\n });\n\n if (showRadio) {\n const radio = document.createElement('input');\n radio.type = 'radio';\n radio.name = 'basemap';\n radio.checked = basemap.id === this._state.selectedBasemap;\n radio.className = 'maplibre-gl-basemap-item-radio';\n radio.style.marginRight = '8px';\n item.appendChild(radio);\n }\n\n const label = document.createElement('span');\n label.textContent = basemap.name;\n label.style.flex = '1';\n label.style.overflow = 'hidden';\n label.style.textOverflow = 'ellipsis';\n label.style.whiteSpace = 'nowrap';\n item.appendChild(label);\n\n // API key badge\n if (basemap.requiresApiKey && !basemap.apiKey) {\n const badge = document.createElement('span');\n badge.className = 'maplibre-gl-basemap-apikey-badge';\n badge.textContent = 'API';\n Object.assign(badge.style, {\n fontSize: '0.7em',\n background: '#ff9800',\n color: 'white',\n padding: '2px 6px',\n borderRadius: '3px',\n marginLeft: '4px',\n flexShrink: '0',\n });\n item.appendChild(badge);\n }\n\n item.addEventListener('click', (e) => {\n e.stopPropagation();\n if (!basemap.requiresApiKey || basemap.apiKey) {\n this.setBasemap(basemap.id);\n }\n });\n\n item.addEventListener('mouseenter', () => {\n if (basemap.id !== this._state.selectedBasemap) {\n item.style.backgroundColor = 'rgba(0, 0, 0, 0.05)';\n }\n });\n\n item.addEventListener('mouseleave', () => {\n item.style.backgroundColor =\n basemap.id === this._state.selectedBasemap ? 'rgba(0, 120, 215, 0.1)' : '';\n });\n\n return item;\n }\n}\n","import '../styles/common.css';\nimport '../styles/terrain.css';\nimport type { IControl, Map as MapLibreMap } from 'maplibre-gl';\nimport type {\n TerrainControlOptions,\n TerrainControlState,\n TerrainEvent,\n TerrainEventHandler,\n} from './types';\n\n/**\n * AWS Terrarium terrain tiles URL.\n */\nconst DEFAULT_TERRAIN_URL =\n 'https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png';\n\n/**\n * Unique source ID for terrain DEM.\n */\nconst TERRAIN_SOURCE_ID = 'maplibre-gl-terrain-dem';\n\n/**\n * Unique layer ID for hillshade.\n */\nconst HILLSHADE_LAYER_ID = 'maplibre-gl-terrain-hillshade';\n\n/**\n * Default options for the TerrainControl.\n */\nconst DEFAULT_OPTIONS: Required<TerrainControlOptions> = {\n sourceUrl: DEFAULT_TERRAIN_URL,\n encoding: 'terrarium',\n exaggeration: 1.0,\n enabled: false,\n hillshade: true,\n hillshadeExaggeration: 0.5,\n sourceMinzoom: 0,\n sourceMaxzoom: 15,\n tileSize: 256,\n position: 'top-right',\n className: '',\n visible: true,\n backgroundColor: 'rgba(255, 255, 255, 0.9)',\n borderRadius: 4,\n opacity: 1,\n minzoom: 0,\n maxzoom: 24,\n};\n\n/**\n * Mountain icon SVG for the terrain toggle button.\n */\nconst TERRAIN_ICON = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"m8 3 4 8 5-5 5 15H2L8 3z\"/></svg>`;\n\n/**\n * A terrain toggle control for MapLibre GL maps.\n *\n * Enables/disables 3D terrain rendering using AWS Terrarium elevation tiles.\n *\n * @example\n * ```typescript\n * const terrain = new TerrainControl({\n * exaggeration: 1.5,\n * hillshade: true,\n * });\n * map.addControl(terrain, 'top-right');\n *\n * terrain.on('terrainchange', (event) => {\n * console.log('Terrain enabled:', event.state.enabled);\n * });\n * ```\n */\nexport class TerrainControl implements IControl {\n private _container?: HTMLElement;\n private _button?: HTMLButtonElement;\n private _options: Required<TerrainControlOptions>;\n private _state: TerrainControlState;\n private _eventHandlers: Map<TerrainEvent, Set<TerrainEventHandler>> = new Map();\n private _map?: MapLibreMap;\n private _handleZoom?: () => void;\n private _handleStyleLoad?: () => void;\n private _zoomVisible: boolean = true;\n\n /**\n * Creates a new TerrainControl instance.\n *\n * @param options - Configuration options for the terrain control.\n */\n constructor(options?: TerrainControlOptions) {\n this._options = { ...DEFAULT_OPTIONS, ...options };\n this._state = {\n visible: this._options.visible,\n enabled: this._options.enabled,\n exaggeration: this._options.exaggeration,\n hillshade: this._options.hillshade,\n };\n }\n\n /**\n * Called when the control is added to the map.\n *\n * @param map - The MapLibre GL map instance.\n * @returns The control's container element.\n */\n onAdd(map: MapLibreMap): HTMLElement {\n this._map = map;\n this._container = this._createContainer();\n this._render();\n\n // Set up zoom listener\n this._handleZoom = () => this._checkZoomVisibility();\n this._map.on('zoom', this._handleZoom);\n\n // Handle style changes (e.g., when basemap changes)\n this._handleStyleLoad = () => {\n if (this._state.enabled) {\n // Re-apply terrain after style change\n this._setupTerrain();\n }\n };\n this._map.on('style.load', this._handleStyleLoad);\n\n // Check initial zoom\n this._checkZoomVisibility();\n\n // Enable terrain if default enabled\n if (this._options.enabled) {\n // Wait for map to be ready\n if (this._map.isStyleLoaded()) {\n this._setupTerrain();\n } else {\n this._map.once('load', () => this._setupTerrain());\n }\n }\n\n return this._container;\n }\n\n /**\n * Called when the control is removed from the map.\n */\n onRemove(): void {\n // Remove terrain and hillshade\n this._removeTerrain();\n\n // Remove event listeners\n if (this._map && this._handleZoom) {\n this._map.off('zoom', this._handleZoom);\n this._handleZoom = undefined;\n }\n if (this._map && this._handleStyleLoad) {\n this._map.off('style.load', this._handleStyleLoad);\n this._handleStyleLoad = undefined;\n }\n\n this._map = undefined;\n this._container?.parentNode?.removeChild(this._container);\n this._container = undefined;\n this._button = undefined;\n this._eventHandlers.clear();\n }\n\n /**\n * Shows the control.\n */\n show(): void {\n if (!this._state.visible) {\n this._state.visible = true;\n this._updateDisplayState();\n this._emit('show');\n }\n }\n\n /**\n * Hides the control.\n */\n hide(): void {\n if (this._state.visible) {\n this._state.visible = false;\n this._updateDisplayState();\n this._emit('hide');\n }\n }\n\n /**\n * Enables terrain rendering.\n */\n enable(): void {\n if (!this._state.enabled) {\n this._setupTerrain();\n this._render();\n this._emit('terrainchange');\n this._emit('update');\n }\n }\n\n /**\n * Disables terrain rendering.\n */\n disable(): void {\n if (this._state.enabled) {\n this._removeTerrain();\n this._render();\n this._emit('terrainchange');\n this._emit('update');\n }\n }\n\n /**\n * Toggles terrain on/off.\n */\n toggle(): void {\n if (this._state.enabled) {\n this.disable();\n } else {\n this.enable();\n }\n }\n\n /**\n * Checks if terrain is currently enabled.\n *\n * @returns True if terrain is enabled.\n */\n isEnabled(): boolean {\n return this._state.enabled;\n }\n\n /**\n * Sets the terrain exaggeration factor.\n *\n * @param value - Exaggeration value (typically 0.1 to 10.0).\n */\n setExaggeration(value: number): void {\n const clampedValue = Math.max(0.1, Math.min(10, value));\n this._state.exaggeration = clampedValue;\n this._options.exaggeration = clampedValue;\n\n if (this._map && this._state.enabled) {\n this._map.setTerrain({\n source: TERRAIN_SOURCE_ID,\n exaggeration: clampedValue,\n });\n }\n\n this._emit('update');\n }\n\n /**\n * Gets the current exaggeration value.\n *\n * @returns The current exaggeration factor.\n */\n getExaggeration(): number {\n return this._state.exaggeration;\n }\n\n /**\n * Enables the hillshade layer.\n */\n enableHillshade(): void {\n if (!this._state.hillshade) {\n this._state.hillshade = true;\n this._options.hillshade = true;\n if (this._state.enabled) {\n this._addHillshadeLayer();\n }\n this._emit('update');\n }\n }\n\n /**\n * Disables the hillshade layer.\n */\n disableHillshade(): void {\n if (this._state.hillshade) {\n this._state.hillshade = false;\n this._options.hillshade = false;\n this._removeHillshadeLayer();\n this._emit('update');\n }\n }\n\n /**\n * Toggles the hillshade layer.\n */\n toggleHillshade(): void {\n if (this._state.hillshade) {\n this.disableHillshade();\n } else {\n this.enableHillshade();\n }\n }\n\n /**\n * Updates control options and re-renders.\n *\n * @param options - Partial options to update.\n */\n update(options: Partial<TerrainControlOptions>): void {\n const prevEnabled = this._state.enabled;\n\n this._options = { ...this._options, ...options };\n\n if (options.visible !== undefined) this._state.visible = options.visible;\n if (options.enabled !== undefined) this._state.enabled = options.enabled;\n if (options.exaggeration !== undefined) {\n this._state.exaggeration = options.exaggeration;\n }\n if (options.hillshade !== undefined) this._state.hillshade = options.hillshade;\n\n // Handle terrain enable/disable\n if (options.enabled !== undefined && options.enabled !== prevEnabled) {\n if (options.enabled) {\n this._setupTerrain();\n } else {\n this._removeTerrain();\n }\n } else if (this._state.enabled && options.exaggeration !== undefined) {\n // Update exaggeration if terrain is already enabled\n this.setExaggeration(options.exaggeration);\n }\n\n this._render();\n this._emit('update');\n }\n\n /**\n * Gets the current state.\n *\n * @returns The current terrain control state.\n */\n getState(): TerrainControlState {\n return { ...this._state };\n }\n\n /**\n * Registers an event handler.\n *\n * @param event - The event type to listen for.\n * @param handler - The callback function.\n */\n on(event: TerrainEvent, handler: TerrainEventHandler): void {\n if (!this._eventHandlers.has(event)) {\n this._eventHandlers.set(event, new Set());\n }\n this._eventHandlers.get(event)!.add(handler);\n }\n\n /**\n * Removes an event handler.\n *\n * @param event - The event type.\n * @param handler - The callback function to remove.\n */\n off(event: TerrainEvent, handler: TerrainEventHandler): void {\n this._eventHandlers.get(event)?.delete(handler);\n }\n\n /**\n * Emits an event to all registered handlers.\n *\n * @param event - The event type to emit.\n */\n private _emit(event: TerrainEvent): void {\n const handlers = this._eventHandlers.get(event);\n if (handlers) {\n const eventData = { type: event, state: this.getState() };\n handlers.forEach((handler) => handler(eventData));\n }\n }\n\n /**\n * Sets up the terrain source and enables terrain rendering.\n */\n private _setupTerrain(): void {\n if (!this._map) return;\n\n try {\n // Add raster-dem source if not already present\n if (!this._map.getSource(TERRAIN_SOURCE_ID)) {\n this._map.addSource(TERRAIN_SOURCE_ID, {\n type: 'raster-dem',\n tiles: [this._options.sourceUrl],\n encoding: this._options.encoding,\n tileSize: this._options.tileSize,\n minzoom: this._options.sourceMinzoom,\n maxzoom: this._options.sourceMaxzoom,\n });\n }\n\n // Enable terrain on the map\n this._map.setTerrain({\n source: TERRAIN_SOURCE_ID,\n exaggeration: this._state.exaggeration,\n });\n\n // Add hillshade if enabled\n if (this._state.hillshade) {\n this._addHillshadeLayer();\n }\n\n this._state.enabled = true;\n } catch (error) {\n console.error('Failed to setup terrain:', error);\n }\n }\n\n /**\n * Removes terrain and cleans up sources/layers.\n */\n private _removeTerrain(): void {\n if (!this._map) return;\n\n try {\n // Disable terrain\n this._map.setTerrain(null);\n\n // Remove hillshade layer\n this._removeHillshadeLayer();\n\n // Remove source\n if (this._map.getSource(TERRAIN_SOURCE_ID)) {\n this._map.removeSource(TERRAIN_SOURCE_ID);\n }\n\n this._state.enabled = false;\n } catch (error) {\n console.error('Failed to remove terrain:', error);\n }\n }\n\n /**\n * Adds the hillshade layer for better terrain visualization.\n */\n private _addHillshadeLayer(): void {\n if (!this._map || this._map.getLayer(HILLSHADE_LAYER_ID)) return;\n\n try {\n // Find the first symbol layer to insert hillshade below labels\n const layers = this._map.getStyle().layers || [];\n let firstSymbolId: string | undefined;\n for (const layer of layers) {\n if (layer.type === 'symbol') {\n firstSymbolId = layer.id;\n break;\n }\n }\n\n this._map.addLayer(\n {\n id: HILLSHADE_LAYER_ID,\n type: 'hillshade',\n source: TERRAIN_SOURCE_ID,\n paint: {\n 'hillshade-exaggeration': this._options.hillshadeExaggeration,\n },\n },\n firstSymbolId\n );\n } catch (error) {\n console.error('Failed to add hillshade layer:', error);\n }\n }\n\n /**\n * Removes the hillshade layer.\n */\n private _removeHillshadeLayer(): void {\n if (!this._map) return;\n\n try {\n if (this._map.getLayer(HILLSHADE_LAYER_ID)) {\n this._map.removeLayer(HILLSHADE_LAYER_ID);\n }\n } catch (error) {\n console.error('Failed to remove hillshade layer:', error);\n }\n }\n\n /**\n * Checks if the current zoom level is within the visibility range.\n */\n private _checkZoomVisibility(): void {\n if (!this._map) return;\n\n const zoom = this._map.getZoom();\n const { minzoom, maxzoom } = this._options;\n const inRange = zoom >= minzoom && zoom <= maxzoom;\n\n if (inRange !== this._zoomVisible) {\n this._zoomVisible = inRange;\n this._updateDisplayState();\n }\n }\n\n /**\n * Updates the display state based on visibility and zoom level.\n */\n private _updateDisplayState(): void {\n if (!this._container) return;\n const shouldShow = this._state.visible && this._zoomVisible;\n this._container.style.display = shouldShow ? 'flex' : 'none';\n }\n\n /**\n * Creates the main container element.\n *\n * @returns The container element.\n */\n private _createContainer(): HTMLElement {\n const container = document.createElement('div');\n container.className = `maplibregl-ctrl maplibregl-ctrl-group maplibre-gl-terrain${\n this._options.className ? ` ${this._options.className}` : ''\n }`;\n\n const shouldShow = this._state.visible && this._zoomVisible;\n if (!shouldShow) {\n container.style.display = 'none';\n }\n\n // Apply custom styles\n if (this._options.backgroundColor) {\n container.style.backgroundColor = this._options.backgroundColor;\n }\n if (this._options.borderRadius) {\n container.style.borderRadius = `${this._options.borderRadius}px`;\n }\n if (this._options.opacity !== 1) {\n container.style.opacity = String(this._options.opacity);\n }\n\n // Create button\n this._button = document.createElement('button');\n this._button.type = 'button';\n this._button.className = 'maplibre-gl-terrain-button';\n this._button.title = 'Toggle terrain';\n this._button.setAttribute('aria-label', 'Toggle terrain');\n this._button.innerHTML = TERRAIN_ICON;\n\n this._button.addEventListener('click', () => this.toggle());\n\n container.appendChild(this._button);\n\n return container;\n }\n\n /**\n * Renders/updates the control appearance based on current state.\n */\n private _render(): void {\n if (!this._button) return;\n\n // Update button active state\n if (this._state.enabled) {\n this._button.classList.add('maplibre-gl-terrain-button--active');\n this._button.title = 'Disable terrain';\n this._button.setAttribute('aria-label', 'Disable terrain');\n } else {\n this._button.classList.remove('maplibre-gl-terrain-button--active');\n this._button.title = 'Enable terrain';\n this._button.setAttribute('aria-label', 'Enable terrain');\n }\n\n this._updateDisplayState();\n }\n}\n","import '../styles/common.css';\nimport '../styles/search-control.css';\nimport type { IControl, Map as MapLibreMap, Marker } from 'maplibre-gl';\nimport type {\n SearchControlOptions,\n SearchControlState,\n SearchResult,\n SearchEvent,\n SearchEventHandler,\n} from './types';\n\n/**\n * Default Nominatim geocoding URL (OpenStreetMap).\n */\nconst NOMINATIM_URL = 'https://nominatim.openstreetmap.org/search';\n\n/**\n * Default options for the SearchControl.\n */\nconst DEFAULT_OPTIONS: Required<Omit<SearchControlOptions, 'geocoder'>> & { geocoder?: SearchControlOptions['geocoder'] } = {\n position: 'top-right',\n className: '',\n visible: true,\n collapsed: true,\n placeholder: 'Search places...',\n geocoderUrl: NOMINATIM_URL,\n maxResults: 5,\n debounceMs: 300,\n flyToZoom: 14,\n showMarker: true,\n markerColor: '#4264fb',\n collapseOnSelect: true,\n clearOnSelect: true,\n geocoder: undefined,\n backgroundColor: 'rgba(255, 255, 255, 0.95)',\n borderRadius: 4,\n opacity: 1,\n width: 280,\n fontSize: 13,\n fontColor: '#333',\n minzoom: 0,\n maxzoom: 24,\n};\n\n/**\n * A collapsible search control for MapLibre GL maps.\n *\n * Provides place search functionality using Nominatim (or custom geocoder).\n * Shows a search icon that expands to reveal a search input with autocomplete results.\n *\n * @example\n * ```typescript\n * const searchControl = new SearchControl({\n * placeholder: 'Search for a place...',\n * flyToZoom: 12,\n * showMarker: true,\n * });\n * map.addControl(searchControl, 'top-right');\n *\n * // Listen for result selection\n * searchControl.on('resultselect', (event) => {\n * console.log('Selected:', event.result);\n * });\n * ```\n */\nexport class SearchControl implements IControl {\n private _container?: HTMLElement;\n private _inputEl?: HTMLInputElement;\n private _inputWrapper?: HTMLElement;\n private _resultsContainer?: HTMLElement;\n private _loadingEl?: HTMLElement;\n private _clearBtn?: HTMLButtonElement;\n private _options: Required<Omit<SearchControlOptions, 'geocoder'>> & { geocoder?: SearchControlOptions['geocoder'] };\n private _state: SearchControlState;\n private _eventHandlers: Map<SearchEvent, Set<SearchEventHandler>> = new Map();\n private _map?: MapLibreMap;\n private _handleZoom?: () => void;\n private _zoomVisible: boolean = true;\n private _marker?: Marker;\n private _debounceTimer?: ReturnType<typeof setTimeout>;\n\n /**\n * Creates a new SearchControl instance.\n *\n * @param options - Configuration options for the control.\n */\n constructor(options?: SearchControlOptions) {\n this._options = { ...DEFAULT_OPTIONS, ...options };\n this._state = {\n visible: this._options.visible,\n collapsed: this._options.collapsed,\n query: '',\n results: [],\n loading: false,\n selectedResult: null,\n error: null,\n };\n }\n\n /**\n * Called when the control is added to the map.\n *\n * @param map - The MapLibre GL map instance.\n * @returns The control's container element.\n */\n onAdd(map: MapLibreMap): HTMLElement {\n this._map = map;\n this._container = this._createContainer();\n this._render();\n\n // Set up zoom listener\n this._handleZoom = () => this._checkZoomVisibility();\n this._map.on('zoom', this._handleZoom);\n\n // Check initial zoom\n this._checkZoomVisibility();\n\n return this._container;\n }\n\n /**\n * Called when the control is removed from the map.\n */\n onRemove(): void {\n if (this._map && this._handleZoom) {\n this._map.off('zoom', this._handleZoom);\n this._handleZoom = undefined;\n }\n this._removeMarker();\n this._map = undefined;\n this._container?.parentNode?.removeChild(this._container);\n this._container = undefined;\n this._inputEl = undefined;\n this._inputWrapper = undefined;\n this._resultsContainer = undefined;\n this._loadingEl = undefined;\n this._clearBtn = undefined;\n this._eventHandlers.clear();\n if (this._debounceTimer) {\n clearTimeout(this._debounceTimer);\n }\n }\n\n /**\n * Shows the control.\n */\n show(): void {\n if (!this._state.visible) {\n this._state.visible = true;\n this._updateDisplayState();\n this._emit('show');\n }\n }\n\n /**\n * Hides the control.\n */\n hide(): void {\n if (this._state.visible) {\n this._state.visible = false;\n this._updateDisplayState();\n this._emit('hide');\n }\n }\n\n /**\n * Expands the search control to show the input.\n */\n expand(): void {\n if (this._state.collapsed) {\n this._state.collapsed = false;\n this._render();\n this._emit('expand');\n // Focus the input when expanded\n setTimeout(() => this._inputEl?.focus(), 50);\n }\n }\n\n /**\n * Collapses the search control to icon only.\n */\n collapse(): void {\n if (!this._state.collapsed) {\n this._state.collapsed = true;\n this._state.results = [];\n this._render();\n this._emit('collapse');\n }\n }\n\n /**\n * Toggles the collapsed state.\n */\n toggle(): void {\n if (this._state.collapsed) {\n this.expand();\n } else {\n this.collapse();\n }\n }\n\n /**\n * Performs a search with the given query.\n *\n * @param query - The search query string.\n */\n async search(query: string): Promise<void> {\n this._state.query = query;\n\n if (!query.trim()) {\n this._state.results = [];\n this._state.error = null;\n this._updateLoadingState();\n this._renderResultsOnly();\n return;\n }\n\n this._state.loading = true;\n this._state.error = null;\n this._updateLoadingState();\n this._renderResultsOnly();\n\n try {\n let results: SearchResult[];\n\n if (this._options.geocoder) {\n // Use custom geocoder\n results = await this._options.geocoder(query);\n } else {\n // Use Nominatim\n results = await this._nominatimSearch(query);\n }\n\n // Check if query has changed while we were waiting (user typed something new)\n if (this._state.query !== query) {\n return; // Discard stale results\n }\n\n this._state.results = results.slice(0, this._options.maxResults);\n this._state.loading = false;\n this._updateLoadingState();\n this._renderResultsOnly();\n this._emit('search');\n } catch (error) {\n // Check if query has changed while we were waiting\n if (this._state.query !== query) {\n return; // Discard stale error\n }\n\n this._state.loading = false;\n this._state.error = error instanceof Error ? error.message : 'Search failed';\n this._state.results = [];\n this._updateLoadingState();\n this._renderResultsOnly();\n }\n }\n\n /**\n * Selects a search result and flies to its location.\n *\n * @param result - The search result to select.\n */\n selectResult(result: SearchResult): void {\n this._state.selectedResult = result;\n\n if (this._map) {\n // Fly to the result location\n if (result.bbox) {\n this._map.fitBounds(\n [[result.bbox[0], result.bbox[1]], [result.bbox[2], result.bbox[3]]],\n { padding: 50, maxZoom: this._options.flyToZoom }\n );\n } else {\n this._map.flyTo({\n center: [result.lng, result.lat],\n zoom: this._options.flyToZoom,\n });\n }\n\n // Add marker if enabled\n if (this._options.showMarker) {\n this._addMarker(result);\n }\n }\n\n if (this._options.clearOnSelect) {\n this._state.query = '';\n this._state.results = [];\n }\n\n if (this._options.collapseOnSelect) {\n this._state.collapsed = true;\n }\n\n this._render();\n this._emit('resultselect', result);\n }\n\n /**\n * Clears the search query and results.\n */\n clear(): void {\n this._state.query = '';\n this._state.results = [];\n this._state.selectedResult = null;\n this._state.error = null;\n this._state.loading = false;\n this._removeMarker();\n\n // Update input value directly if it exists\n if (this._inputEl) {\n this._inputEl.value = '';\n }\n\n // Use partial rendering to avoid losing focus\n this._updateLoadingState();\n this._renderResultsOnly();\n this._emit('clear');\n }\n\n /**\n * Gets the current state.\n *\n * @returns The current control state.\n */\n getState(): SearchControlState {\n return { ...this._state, results: [...this._state.results] };\n }\n\n /**\n * Updates control options.\n *\n * @param options - Partial options to update.\n */\n update(options: Partial<SearchControlOptions>): void {\n this._options = { ...this._options, ...options };\n if (options.visible !== undefined) this._state.visible = options.visible;\n if (options.collapsed !== undefined) this._state.collapsed = options.collapsed;\n this._render();\n this._emit('update');\n }\n\n /**\n * Registers an event handler.\n *\n * @param event - The event type to listen for.\n * @param handler - The callback function.\n */\n on(event: SearchEvent, handler: SearchEventHandler): void {\n if (!this._eventHandlers.has(event)) {\n this._eventHandlers.set(event, new Set());\n }\n this._eventHandlers.get(event)!.add(handler);\n }\n\n /**\n * Removes an event handler.\n *\n * @param event - The event type.\n * @param handler - The callback function to remove.\n */\n off(event: SearchEvent, handler: SearchEventHandler): void {\n this._eventHandlers.get(event)?.delete(handler);\n }\n\n /**\n * Emits an event to all registered handlers.\n */\n private _emit(event: SearchEvent, result?: SearchResult): void {\n const handlers = this._eventHandlers.get(event);\n if (handlers) {\n const eventData = { type: event, state: this.getState(), result };\n handlers.forEach((handler) => handler(eventData));\n }\n }\n\n /**\n * Performs a search using Nominatim geocoding service.\n */\n private async _nominatimSearch(query: string): Promise<SearchResult[]> {\n const params = new URLSearchParams({\n q: query,\n format: 'json',\n limit: String(this._options.maxResults),\n addressdetails: '1',\n });\n\n const response = await fetch(`${this._options.geocoderUrl}?${params}`, {\n headers: {\n 'Accept': 'application/json',\n },\n });\n\n if (!response.ok) {\n throw new Error(`Geocoding failed: ${response.statusText}`);\n }\n\n const data = await response.json();\n\n return data.map((item: {\n place_id: number;\n display_name: string;\n name?: string;\n lon: string;\n lat: string;\n boundingbox?: string[];\n type?: string;\n importance?: number;\n }) => ({\n id: String(item.place_id),\n name: item.name || item.display_name.split(',')[0],\n displayName: item.display_name,\n lng: parseFloat(item.lon),\n lat: parseFloat(item.lat),\n bbox: item.boundingbox\n ? [\n parseFloat(item.boundingbox[2]),\n parseFloat(item.boundingbox[0]),\n parseFloat(item.boundingbox[3]),\n parseFloat(item.boundingbox[1]),\n ] as [number, number, number, number]\n : undefined,\n type: item.type,\n importance: item.importance,\n }));\n }\n\n /**\n * Checks if the current zoom level is within the visibility range.\n */\n private _checkZoomVisibility(): void {\n if (!this._map) return;\n\n const zoom = this._map.getZoom();\n const { minzoom, maxzoom } = this._options;\n const inRange = zoom >= minzoom && zoom <= maxzoom;\n\n if (inRange !== this._zoomVisible) {\n this._zoomVisible = inRange;\n this._updateDisplayState();\n }\n }\n\n /**\n * Updates the display state based on visibility and zoom level.\n */\n private _updateDisplayState(): void {\n if (!this._container) return;\n const shouldShow = this._state.visible && this._zoomVisible;\n this._container.style.display = shouldShow ? 'block' : 'none';\n }\n\n /**\n * Adds a marker at the result location.\n */\n private _addMarker(result: SearchResult): void {\n this._removeMarker();\n\n if (!this._map) return;\n\n // Import maplibre-gl dynamically to avoid circular dependencies\n import('maplibre-gl').then(({ Marker }) => {\n // Create custom marker element\n const el = document.createElement('div');\n el.className = 'maplibre-gl-search-marker';\n el.innerHTML = `\n <svg width=\"28\" height=\"36\" viewBox=\"0 0 28 36\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M14 0C6.268 0 0 6.268 0 14C0 24.5 14 36 14 36C14 36 28 24.5 28 14C28 6.268 21.732 0 14 0Z\" fill=\"${this._options.markerColor}\"/>\n <circle cx=\"14\" cy=\"14\" r=\"6\" fill=\"white\"/>\n </svg>\n `;\n el.style.cursor = 'pointer';\n\n this._marker = new Marker({ element: el })\n .setLngLat([result.lng, result.lat])\n .addTo(this._map!);\n });\n }\n\n /**\n * Removes the current marker.\n */\n private _removeMarker(): void {\n if (this._marker) {\n this._marker.remove();\n this._marker = undefined;\n }\n }\n\n /**\n * Updates only the results section without rebuilding the entire DOM.\n * This prevents input focus loss during search.\n */\n private _renderResultsOnly(): void {\n if (!this._container || this._state.collapsed) return;\n\n // Remove existing results container if present\n if (this._resultsContainer) {\n this._resultsContainer.remove();\n this._resultsContainer = undefined;\n }\n\n // Remove existing error element if present\n const existingError = this._container.querySelector('.maplibre-gl-search-error');\n if (existingError) {\n existingError.remove();\n }\n\n // Render error if present\n if (this._state.error) {\n const errorEl = document.createElement('div');\n errorEl.className = 'maplibre-gl-search-error';\n errorEl.textContent = this._state.error;\n Object.assign(errorEl.style, {\n padding: '8px 10px',\n color: '#d32f2f',\n fontSize: '12px',\n borderTop: '1px solid rgba(0, 0, 0, 0.08)',\n });\n this._container.appendChild(errorEl);\n }\n\n // Render results if present\n if (this._state.results.length > 0) {\n this._resultsContainer = document.createElement('div');\n this._resultsContainer.className = 'maplibre-gl-search-results';\n Object.assign(this._resultsContainer.style, {\n borderTop: '1px solid rgba(0, 0, 0, 0.08)',\n maxHeight: '250px',\n overflowY: 'auto',\n });\n\n this._state.results.forEach((result) => {\n const resultEl = document.createElement('div');\n resultEl.className = 'maplibre-gl-search-result';\n Object.assign(resultEl.style, {\n padding: '10px 12px',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'flex-start',\n gap: '10px',\n transition: 'background-color 0.15s ease',\n });\n\n // Location icon\n const icon = document.createElement('span');\n icon.innerHTML = `\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" style=\"flex-shrink: 0; margin-top: 2px;\">\n <path d=\"M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z\"/>\n <circle cx=\"12\" cy=\"10\" r=\"3\"/>\n </svg>\n `;\n icon.style.color = '#888';\n resultEl.appendChild(icon);\n\n // Text content\n const textWrapper = document.createElement('div');\n textWrapper.style.flex = '1';\n textWrapper.style.minWidth = '0';\n\n const nameEl = document.createElement('div');\n nameEl.className = 'maplibre-gl-search-result-name';\n nameEl.textContent = result.name;\n Object.assign(nameEl.style, {\n fontWeight: '500',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n });\n textWrapper.appendChild(nameEl);\n\n const detailEl = document.createElement('div');\n detailEl.className = 'maplibre-gl-search-result-detail';\n detailEl.textContent = result.displayName;\n Object.assign(detailEl.style, {\n fontSize: '11px',\n color: '#666',\n marginTop: '2px',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n });\n textWrapper.appendChild(detailEl);\n\n resultEl.appendChild(textWrapper);\n\n resultEl.addEventListener('mouseenter', () => {\n resultEl.style.backgroundColor = 'rgba(0, 0, 0, 0.04)';\n });\n resultEl.addEventListener('mouseleave', () => {\n resultEl.style.backgroundColor = 'transparent';\n });\n resultEl.addEventListener('click', () => this.selectResult(result));\n\n this._resultsContainer!.appendChild(resultEl);\n });\n\n this._container.appendChild(this._resultsContainer);\n }\n }\n\n /**\n * Updates only the loading/clear button state without full DOM rebuild.\n */\n private _updateLoadingState(): void {\n if (!this._inputWrapper) return;\n\n // Remove existing loading element\n if (this._loadingEl) {\n this._loadingEl.remove();\n this._loadingEl = undefined;\n }\n\n // Remove existing clear button\n if (this._clearBtn) {\n this._clearBtn.remove();\n this._clearBtn = undefined;\n }\n\n // Find the collapse button to insert before it\n const collapseBtn = this._inputWrapper.querySelector('.maplibre-gl-search-collapse');\n\n if (this._state.loading) {\n this._loadingEl = document.createElement('span');\n this._loadingEl.className = 'maplibre-gl-search-loader';\n this._loadingEl.innerHTML = `\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke-opacity=\"0.25\"/>\n <path d=\"M12 2a10 10 0 0 1 10 10\" stroke-linecap=\"round\">\n <animateTransform attributeName=\"transform\" type=\"rotate\" from=\"0 12 12\" to=\"360 12 12\" dur=\"1s\" repeatCount=\"indefinite\"/>\n </path>\n </svg>\n `;\n Object.assign(this._loadingEl.style, {\n display: 'flex',\n alignItems: 'center',\n color: '#888',\n flexShrink: '0',\n });\n if (collapseBtn) {\n this._inputWrapper.insertBefore(this._loadingEl, collapseBtn);\n } else {\n this._inputWrapper.appendChild(this._loadingEl);\n }\n } else if (this._state.query) {\n this._clearBtn = document.createElement('button');\n this._clearBtn.className = 'maplibre-gl-search-clear';\n this._clearBtn.type = 'button';\n this._clearBtn.title = 'Clear';\n this._clearBtn.innerHTML = `\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M18 6L6 18M6 6l12 12\"/>\n </svg>\n `;\n Object.assign(this._clearBtn.style, {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '24px',\n height: '24px',\n padding: '4px',\n border: 'none',\n background: 'transparent',\n cursor: 'pointer',\n color: '#888',\n flexShrink: '0',\n });\n this._clearBtn.addEventListener('click', (e) => {\n e.stopPropagation();\n this.clear();\n });\n if (collapseBtn) {\n this._inputWrapper.insertBefore(this._clearBtn, collapseBtn);\n } else {\n this._inputWrapper.appendChild(this._clearBtn);\n }\n }\n }\n\n /**\n * Creates the main container element.\n */\n private _createContainer(): HTMLElement {\n const container = document.createElement('div');\n container.className = `maplibregl-ctrl maplibre-gl-search${\n this._options.className ? ` ${this._options.className}` : ''\n }`;\n\n const shouldShow = this._state.visible && this._zoomVisible;\n if (!shouldShow) {\n container.style.display = 'none';\n }\n\n return container;\n }\n\n /**\n * Handles input change with debouncing.\n */\n private _handleInput = (e: Event): void => {\n const value = (e.target as HTMLInputElement).value;\n this._state.query = value;\n\n if (this._debounceTimer) {\n clearTimeout(this._debounceTimer);\n }\n\n this._debounceTimer = setTimeout(() => {\n this.search(value);\n }, this._options.debounceMs);\n };\n\n /**\n * Renders the control content.\n */\n private _render(): void {\n if (!this._container) return;\n\n const {\n backgroundColor,\n borderRadius,\n opacity,\n width,\n fontSize,\n fontColor,\n placeholder,\n } = this._options;\n\n // Clear existing content and DOM references\n this._container.innerHTML = '';\n this._inputEl = undefined;\n this._inputWrapper = undefined;\n this._resultsContainer = undefined;\n this._loadingEl = undefined;\n this._clearBtn = undefined;\n\n // Apply base container styles\n Object.assign(this._container.style, {\n backgroundColor,\n borderRadius: `${borderRadius}px`,\n opacity: String(opacity),\n boxShadow: '0 0 0 2px rgba(0, 0, 0, 0.1)',\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n fontSize: `${fontSize}px`,\n color: fontColor,\n overflow: 'hidden',\n });\n\n if (this._state.collapsed) {\n // Collapsed state - just show the search icon\n this._container.style.width = 'auto';\n this._renderCollapsedState();\n } else {\n // Expanded state - show search input and results\n Object.assign(this._container.style, {\n width: `${width}px`,\n });\n this._renderExpandedState(placeholder, fontColor);\n }\n }\n\n /**\n * Renders the collapsed state (search icon only).\n */\n private _renderCollapsedState(): void {\n const button = document.createElement('button');\n button.className = 'maplibre-gl-search-toggle';\n button.type = 'button';\n button.title = 'Search places';\n button.innerHTML = `\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"11\" cy=\"11\" r=\"8\"/>\n <path d=\"M21 21l-4.35-4.35\"/>\n </svg>\n `;\n Object.assign(button.style, {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '30px',\n height: '30px',\n padding: '0',\n border: 'none',\n background: 'transparent',\n cursor: 'pointer',\n color: this._options.fontColor,\n });\n button.addEventListener('click', (e) => {\n e.stopPropagation();\n this.expand();\n });\n this._container!.appendChild(button);\n }\n\n /**\n * Renders the expanded state (search input and results).\n */\n private _renderExpandedState(placeholder: string, fontColor: string): void {\n // Search input wrapper\n const inputWrapper = document.createElement('div');\n inputWrapper.className = 'maplibre-gl-search-input-wrapper';\n Object.assign(inputWrapper.style, {\n display: 'flex',\n alignItems: 'center',\n padding: '0 10px',\n gap: '8px',\n height: '30px',\n boxSizing: 'border-box',\n });\n\n // Search icon\n const searchIcon = document.createElement('span');\n searchIcon.className = 'maplibre-gl-search-icon';\n searchIcon.innerHTML = `\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"11\" cy=\"11\" r=\"8\"/>\n <path d=\"M21 21l-4.35-4.35\"/>\n </svg>\n `;\n Object.assign(searchIcon.style, {\n display: 'flex',\n alignItems: 'center',\n color: '#888',\n flexShrink: '0',\n });\n inputWrapper.appendChild(searchIcon);\n\n // Input element\n const input = document.createElement('input');\n input.type = 'text';\n input.className = 'maplibre-gl-search-input';\n input.placeholder = placeholder;\n input.value = this._state.query;\n Object.assign(input.style, {\n flex: '1',\n border: 'none',\n outline: 'none',\n background: 'transparent',\n fontSize: 'inherit',\n color: fontColor,\n minWidth: '0',\n });\n input.addEventListener('input', this._handleInput);\n input.addEventListener('keydown', (e) => {\n if (e.key === 'Escape') {\n this.collapse();\n }\n });\n this._inputEl = input;\n inputWrapper.appendChild(input);\n\n // Loading indicator or clear button\n if (this._state.loading) {\n const loader = document.createElement('span');\n loader.className = 'maplibre-gl-search-loader';\n loader.innerHTML = `\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke-opacity=\"0.25\"/>\n <path d=\"M12 2a10 10 0 0 1 10 10\" stroke-linecap=\"round\">\n <animateTransform attributeName=\"transform\" type=\"rotate\" from=\"0 12 12\" to=\"360 12 12\" dur=\"1s\" repeatCount=\"indefinite\"/>\n </path>\n </svg>\n `;\n Object.assign(loader.style, {\n display: 'flex',\n alignItems: 'center',\n color: '#888',\n flexShrink: '0',\n });\n inputWrapper.appendChild(loader);\n } else if (this._state.query) {\n const clearBtn = document.createElement('button');\n clearBtn.className = 'maplibre-gl-search-clear';\n clearBtn.type = 'button';\n clearBtn.title = 'Clear';\n clearBtn.innerHTML = `\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M18 6L6 18M6 6l12 12\"/>\n </svg>\n `;\n Object.assign(clearBtn.style, {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '24px',\n height: '24px',\n padding: '4px',\n border: 'none',\n background: 'transparent',\n cursor: 'pointer',\n color: '#888',\n flexShrink: '0',\n });\n clearBtn.addEventListener('click', (e) => {\n e.stopPropagation();\n this.clear();\n });\n inputWrapper.appendChild(clearBtn);\n }\n\n // Collapse button\n const collapseBtn = document.createElement('button');\n collapseBtn.className = 'maplibre-gl-search-collapse';\n collapseBtn.type = 'button';\n collapseBtn.title = 'Close';\n collapseBtn.innerHTML = `\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M19 12H5M12 19l-7-7 7-7\"/>\n </svg>\n `;\n Object.assign(collapseBtn.style, {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '24px',\n height: '24px',\n padding: '4px',\n border: 'none',\n background: 'transparent',\n cursor: 'pointer',\n color: '#888',\n flexShrink: '0',\n });\n collapseBtn.addEventListener('click', (e) => {\n e.stopPropagation();\n this.collapse();\n });\n inputWrapper.appendChild(collapseBtn);\n\n // Store reference for partial rendering\n this._inputWrapper = inputWrapper;\n this._container!.appendChild(inputWrapper);\n\n // Error message\n if (this._state.error) {\n const errorEl = document.createElement('div');\n errorEl.className = 'maplibre-gl-search-error';\n errorEl.textContent = this._state.error;\n Object.assign(errorEl.style, {\n padding: '8px 10px',\n color: '#d32f2f',\n fontSize: '12px',\n borderTop: '1px solid rgba(0, 0, 0, 0.08)',\n });\n this._container!.appendChild(errorEl);\n }\n\n // Results list\n if (this._state.results.length > 0) {\n const resultsEl = document.createElement('div');\n resultsEl.className = 'maplibre-gl-search-results';\n Object.assign(resultsEl.style, {\n borderTop: '1px solid rgba(0, 0, 0, 0.08)',\n maxHeight: '250px',\n overflowY: 'auto',\n });\n\n this._state.results.forEach((result) => {\n const resultEl = document.createElement('div');\n resultEl.className = 'maplibre-gl-search-result';\n Object.assign(resultEl.style, {\n padding: '10px 12px',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'flex-start',\n gap: '10px',\n transition: 'background-color 0.15s ease',\n });\n\n // Location icon\n const icon = document.createElement('span');\n icon.innerHTML = `\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" style=\"flex-shrink: 0; margin-top: 2px;\">\n <path d=\"M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z\"/>\n <circle cx=\"12\" cy=\"10\" r=\"3\"/>\n </svg>\n `;\n icon.style.color = '#888';\n resultEl.appendChild(icon);\n\n // Text content\n const textWrapper = document.createElement('div');\n textWrapper.style.flex = '1';\n textWrapper.style.minWidth = '0';\n\n const nameEl = document.createElement('div');\n nameEl.className = 'maplibre-gl-search-result-name';\n nameEl.textContent = result.name;\n Object.assign(nameEl.style, {\n fontWeight: '500',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n });\n textWrapper.appendChild(nameEl);\n\n const detailEl = document.createElement('div');\n detailEl.className = 'maplibre-gl-search-result-detail';\n detailEl.textContent = result.displayName;\n Object.assign(detailEl.style, {\n fontSize: '11px',\n color: '#666',\n marginTop: '2px',\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n });\n textWrapper.appendChild(detailEl);\n\n resultEl.appendChild(textWrapper);\n\n resultEl.addEventListener('mouseenter', () => {\n resultEl.style.backgroundColor = 'rgba(0, 0, 0, 0.04)';\n });\n resultEl.addEventListener('mouseleave', () => {\n resultEl.style.backgroundColor = 'transparent';\n });\n resultEl.addEventListener('click', () => this.selectResult(result));\n\n resultsEl.appendChild(resultEl);\n });\n\n this._container!.appendChild(resultsEl);\n }\n }\n}\n","/**\n * Supported vector file formats.\n *\n * DuckDB's spatial extension uses GDAL under the hood, enabling support\n * for many common geospatial formats via ST_Read().\n */\nexport type VectorFormat =\n | 'geojson'\n | 'shapefile'\n | 'geopackage'\n | 'geoparquet'\n | 'kml'\n | 'kmz'\n | 'gpx'\n | 'flatgeobuf'\n | 'gml'\n | 'topojson'\n | 'csv'\n | 'xlsx'\n | 'dxf'\n | 'unknown';\n\n/**\n * File extensions for GeoJSON files.\n */\nexport const GEOJSON_EXTENSIONS = ['.geojson', '.json'];\n\n/**\n * File extensions for Shapefile files.\n * Includes .zip for zipped shapefiles (most common distribution).\n */\nexport const SHAPEFILE_EXTENSIONS = ['.shp', '.zip'];\n\n/**\n * File extensions for GeoPackage files.\n */\nexport const GEOPACKAGE_EXTENSIONS = ['.gpkg'];\n\n/**\n * File extensions for GeoParquet files.\n */\nexport const GEOPARQUET_EXTENSIONS = ['.parquet', '.geoparquet'];\n\n/**\n * File extensions for KML (Keyhole Markup Language) files.\n * Used by Google Earth.\n */\nexport const KML_EXTENSIONS = ['.kml'];\n\n/**\n * File extensions for KMZ (compressed KML) files.\n * KMZ is a zipped KML file used by Google Earth.\n */\nexport const KMZ_EXTENSIONS = ['.kmz'];\n\n/**\n * File extensions for GPX (GPS Exchange Format) files.\n * Common format for GPS tracks, waypoints, and routes.\n */\nexport const GPX_EXTENSIONS = ['.gpx'];\n\n/**\n * File extensions for FlatGeobuf files.\n * A performant binary encoding for geographic data.\n */\nexport const FLATGEOBUF_EXTENSIONS = ['.fgb'];\n\n/**\n * File extensions for GML (Geography Markup Language) files.\n * OGC standard XML-based format.\n */\nexport const GML_EXTENSIONS = ['.gml'];\n\n/**\n * File extensions for TopoJSON files.\n * An extension of GeoJSON that encodes topology.\n */\nexport const TOPOJSON_EXTENSIONS = ['.topojson'];\n\n/**\n * File extensions for CSV files with geometry.\n * Can contain WKT geometry or lat/lon columns.\n */\nexport const CSV_EXTENSIONS = ['.csv'];\n\n/**\n * File extensions for Excel files with geometry.\n * Can contain WKT geometry or lat/lon columns.\n */\nexport const XLSX_EXTENSIONS = ['.xlsx', '.xls'];\n\n/**\n * File extensions for DXF (AutoCAD Drawing Exchange Format) files.\n */\nexport const DXF_EXTENSIONS = ['.dxf'];\n\n/**\n * Extensions processed via shpjs (Shapefile library).\n */\nexport const SHPJS_EXTENSIONS = [...SHAPEFILE_EXTENSIONS];\n\n/**\n * Extensions processed via DuckDB spatial (GDAL-powered).\n */\nexport const DUCKDB_EXTENSIONS = [\n ...GEOPACKAGE_EXTENSIONS,\n ...GEOPARQUET_EXTENSIONS,\n ...KML_EXTENSIONS,\n ...KMZ_EXTENSIONS,\n ...GPX_EXTENSIONS,\n ...FLATGEOBUF_EXTENSIONS,\n ...GML_EXTENSIONS,\n ...TOPOJSON_EXTENSIONS,\n ...CSV_EXTENSIONS,\n ...XLSX_EXTENSIONS,\n ...DXF_EXTENSIONS,\n];\n\n/**\n * All supported extensions for advanced formats (require DuckDB or shpjs).\n */\nexport const ADVANCED_EXTENSIONS = [...SHPJS_EXTENSIONS, ...DUCKDB_EXTENSIONS];\n\n/**\n * All supported vector file extensions.\n */\nexport const ALL_EXTENSIONS = [...GEOJSON_EXTENSIONS, ...ADVANCED_EXTENSIONS];\n\n/**\n * Detects the vector format from a filename.\n *\n * @param filename - The filename to check.\n * @returns The detected vector format.\n *\n * @example\n * ```typescript\n * detectFormat('data.geojson'); // 'geojson'\n * detectFormat('counties.shp'); // 'shapefile'\n * detectFormat('data.gpkg'); // 'geopackage'\n * detectFormat('track.gpx'); // 'gpx'\n * detectFormat('places.kml'); // 'kml'\n * detectFormat('data.zip'); // 'shapefile'\n * detectFormat('data.txt'); // 'unknown'\n * ```\n */\nexport function detectFormat(filename: string): VectorFormat {\n const ext = getFileExtension(filename);\n\n if (GEOJSON_EXTENSIONS.includes(ext)) {\n return 'geojson';\n }\n\n if (SHAPEFILE_EXTENSIONS.includes(ext)) {\n return 'shapefile';\n }\n\n if (GEOPACKAGE_EXTENSIONS.includes(ext)) {\n return 'geopackage';\n }\n\n if (GEOPARQUET_EXTENSIONS.includes(ext)) {\n return 'geoparquet';\n }\n\n if (KML_EXTENSIONS.includes(ext)) {\n return 'kml';\n }\n\n if (KMZ_EXTENSIONS.includes(ext)) {\n return 'kmz';\n }\n\n if (GPX_EXTENSIONS.includes(ext)) {\n return 'gpx';\n }\n\n if (FLATGEOBUF_EXTENSIONS.includes(ext)) {\n return 'flatgeobuf';\n }\n\n if (GML_EXTENSIONS.includes(ext)) {\n return 'gml';\n }\n\n if (TOPOJSON_EXTENSIONS.includes(ext)) {\n return 'topojson';\n }\n\n if (CSV_EXTENSIONS.includes(ext)) {\n return 'csv';\n }\n\n if (XLSX_EXTENSIONS.includes(ext)) {\n return 'xlsx';\n }\n\n if (DXF_EXTENSIONS.includes(ext)) {\n return 'dxf';\n }\n\n return 'unknown';\n}\n\n/**\n * Checks if a format requires DuckDB for processing.\n * Note: Shapefiles use shpjs, not DuckDB.\n *\n * @param format - The vector format to check.\n * @returns True if the format requires DuckDB.\n *\n * @example\n * ```typescript\n * requiresDuckDB('geojson'); // false\n * requiresDuckDB('shapefile'); // false (uses shpjs)\n * requiresDuckDB('geopackage'); // true\n * requiresDuckDB('geoparquet'); // true\n * requiresDuckDB('kml'); // true\n * requiresDuckDB('gpx'); // true\n * ```\n */\nexport function requiresDuckDB(format: VectorFormat): boolean {\n return (\n format === 'geopackage' ||\n format === 'geoparquet' ||\n format === 'kml' ||\n format === 'kmz' ||\n format === 'gpx' ||\n format === 'flatgeobuf' ||\n format === 'gml' ||\n format === 'topojson' ||\n format === 'csv' ||\n format === 'xlsx' ||\n format === 'dxf'\n );\n}\n\n/**\n * Checks if a format requires a special converter (not native GeoJSON).\n *\n * @param format - The vector format to check.\n * @returns True if the format requires conversion.\n */\nexport function requiresConversion(format: VectorFormat): boolean {\n return format !== 'geojson' && format !== 'unknown';\n}\n\n/**\n * Gets the file extension from a filename (lowercase, with leading dot).\n *\n * @param filename - The filename to extract extension from.\n * @returns The file extension (e.g., '.geojson') or empty string.\n *\n * @example\n * ```typescript\n * getFileExtension('data.GeoJSON'); // '.geojson'\n * getFileExtension('file.tar.gz'); // '.gz'\n * getFileExtension('noextension'); // ''\n * ```\n */\nexport function getFileExtension(filename: string): string {\n const lastDot = filename.lastIndexOf('.');\n if (lastDot === -1 || lastDot === filename.length - 1) {\n return '';\n }\n return filename.slice(lastDot).toLowerCase();\n}\n\n/**\n * Reads a File object as an ArrayBuffer.\n *\n * @param file - The file to read.\n * @returns Promise resolving to the file contents as ArrayBuffer.\n *\n * @example\n * ```typescript\n * const input = document.querySelector('input[type=\"file\"]');\n * const file = input.files[0];\n * const buffer = await readFileAsBuffer(file);\n * ```\n */\nexport function readFileAsBuffer(file: File): Promise<ArrayBuffer> {\n return file.arrayBuffer();\n}\n\n/**\n * Gets the list of accepted file extensions based on options.\n *\n * @param enableAdvanced - Whether to include advanced format extensions.\n * @returns Array of accepted file extensions.\n *\n * @example\n * ```typescript\n * getAcceptedExtensions(false); // ['.geojson', '.json']\n * getAcceptedExtensions(true); // ['.geojson', '.json', '.shp', '.zip', '.gpkg', '.kml', ...]\n * ```\n */\nexport function getAcceptedExtensions(enableAdvanced: boolean): string[] {\n if (enableAdvanced) {\n return ALL_EXTENSIONS;\n }\n return GEOJSON_EXTENSIONS;\n}\n\n/**\n * Checks if a file extension is valid for the given options.\n *\n * @param filename - The filename to check.\n * @param enableAdvanced - Whether advanced formats are enabled.\n * @returns True if the extension is accepted.\n *\n * @example\n * ```typescript\n * isValidExtension('data.geojson', false); // true\n * isValidExtension('data.gpkg', false); // false\n * isValidExtension('data.gpkg', true); // true\n * isValidExtension('track.gpx', true); // true\n * ```\n */\nexport function isValidExtension(filename: string, enableAdvanced: boolean): boolean {\n const ext = getFileExtension(filename);\n const accepted = getAcceptedExtensions(enableAdvanced);\n return accepted.includes(ext);\n}\n\n/**\n * Gets a human-readable format name for display.\n *\n * @param format - The vector format.\n * @returns Human-readable format name.\n *\n * @example\n * ```typescript\n * getFormatDisplayName('geojson'); // 'GeoJSON'\n * getFormatDisplayName('shapefile'); // 'Shapefile'\n * getFormatDisplayName('kml'); // 'KML'\n * getFormatDisplayName('gpx'); // 'GPX'\n * ```\n */\nexport function getFormatDisplayName(format: VectorFormat): string {\n switch (format) {\n case 'geojson':\n return 'GeoJSON';\n case 'shapefile':\n return 'Shapefile';\n case 'geopackage':\n return 'GeoPackage';\n case 'geoparquet':\n return 'GeoParquet';\n case 'kml':\n return 'KML';\n case 'kmz':\n return 'KMZ';\n case 'gpx':\n return 'GPX';\n case 'flatgeobuf':\n return 'FlatGeobuf';\n case 'gml':\n return 'GML';\n case 'topojson':\n return 'TopoJSON';\n case 'csv':\n return 'CSV';\n case 'xlsx':\n return 'Excel';\n case 'dxf':\n return 'DXF';\n default:\n return 'Unknown';\n }\n}\n\n/**\n * Gets a description of the format for tooltips/help text.\n *\n * @param format - The vector format.\n * @returns Description of the format.\n */\nexport function getFormatDescription(format: VectorFormat): string {\n switch (format) {\n case 'geojson':\n return 'GeoJSON - Open standard format for geographic data';\n case 'shapefile':\n return 'Shapefile - Esri vector data format (.shp or .zip)';\n case 'geopackage':\n return 'GeoPackage - OGC standard SQLite-based format';\n case 'geoparquet':\n return 'GeoParquet - Columnar format for geospatial data';\n case 'kml':\n return 'KML - Keyhole Markup Language (Google Earth)';\n case 'kmz':\n return 'KMZ - Compressed KML (Google Earth)';\n case 'gpx':\n return 'GPX - GPS Exchange Format for tracks and waypoints';\n case 'flatgeobuf':\n return 'FlatGeobuf - Fast binary encoding for geographic data';\n case 'gml':\n return 'GML - Geography Markup Language (OGC standard)';\n case 'topojson':\n return 'TopoJSON - Topology-encoded GeoJSON extension';\n case 'csv':\n return 'CSV - Comma-separated values with geometry (WKT or lat/lon)';\n case 'xlsx':\n return 'Excel - Spreadsheet with geometry (WKT or lat/lon)';\n case 'dxf':\n return 'DXF - AutoCAD Drawing Exchange Format';\n default:\n return 'Unknown format';\n }\n}\n","import '../styles/common.css';\nimport '../styles/vector-dataset.css';\nimport type { IControl, Map as MapLibreMap } from 'maplibre-gl';\nimport type {\n VectorDatasetControlOptions,\n VectorDatasetControlState,\n VectorDatasetEvent,\n VectorDatasetEventHandler,\n LoadedDataset,\n VectorLayerStyle,\n VectorFormat,\n} from './types';\nimport { generateId } from '../utils/helpers';\nimport {\n detectFormat,\n requiresConversion,\n requiresDuckDB,\n getAcceptedExtensions,\n isValidExtension,\n getFormatDisplayName,\n readFileAsBuffer,\n} from '../utils/fileHelpers';\nimport type { DuckDBConverter } from '../converters/DuckDBConverter';\nimport type { ShapefileConverter } from '../converters/ShapefileConverter';\n\n/**\n * Default style for vector layers.\n */\nconst DEFAULT_STYLE: Required<VectorLayerStyle> = {\n fillColor: '#3388ff',\n fillOpacity: 0.3,\n strokeColor: '#3388ff',\n strokeWidth: 2,\n strokeOpacity: 1,\n circleRadius: 6,\n circleColor: '#3388ff',\n circleStrokeColor: '#ffffff',\n circleStrokeWidth: 2,\n};\n\n/**\n * Default options for the VectorDatasetControl.\n */\nconst DEFAULT_OPTIONS: Required<Omit<VectorDatasetControlOptions, 'onConversionProgress' | 'duckdbBundleUrl'>> & {\n onConversionProgress: VectorDatasetControlOptions['onConversionProgress'];\n duckdbBundleUrl: VectorDatasetControlOptions['duckdbBundleUrl'];\n} = {\n position: 'top-right',\n className: '',\n visible: true,\n showDropZone: true,\n acceptedExtensions: ['.geojson', '.json'],\n multiple: true,\n defaultStyle: DEFAULT_STYLE,\n fitBounds: true,\n fitBoundsPadding: 50,\n maxFileSize: 52428800, // 50MB\n backgroundColor: 'rgba(255, 255, 255, 0.9)',\n borderRadius: 4,\n opacity: 1,\n minzoom: 0,\n maxzoom: 24,\n enableAdvancedFormats: false,\n duckdbBundleUrl: undefined,\n onConversionProgress: undefined,\n};\n\n/**\n * Upload icon SVG for the button.\n */\nconst UPLOAD_ICON = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"/><polyline points=\"17 8 12 3 7 8\"/><line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"15\"/></svg>`;\n\n/**\n * A vector dataset upload control for MapLibre GL maps.\n *\n * Enables loading GeoJSON files via file upload button or drag-and-drop.\n *\n * @example\n * ```typescript\n * const vectorControl = new VectorDatasetControl({\n * fitBounds: true,\n * defaultStyle: {\n * fillColor: '#ff0000',\n * fillOpacity: 0.5,\n * },\n * });\n * map.addControl(vectorControl, 'top-right');\n *\n * vectorControl.on('load', (event) => {\n * console.log('Loaded dataset:', event.dataset?.filename);\n * });\n * ```\n */\nexport class VectorDatasetControl implements IControl {\n private _container?: HTMLElement;\n private _button?: HTMLButtonElement;\n private _fileInput?: HTMLInputElement;\n private _dropZone?: HTMLElement;\n private _options: Required<Omit<VectorDatasetControlOptions, 'onConversionProgress' | 'duckdbBundleUrl'>> & {\n onConversionProgress: VectorDatasetControlOptions['onConversionProgress'];\n duckdbBundleUrl: VectorDatasetControlOptions['duckdbBundleUrl'];\n };\n private _state: VectorDatasetControlState;\n private _eventHandlers: Map<VectorDatasetEvent, Set<VectorDatasetEventHandler>> = new Map();\n private _map?: MapLibreMap;\n private _handleZoom?: () => void;\n private _zoomVisible: boolean = true;\n private _boundDragOver?: (e: DragEvent) => void;\n private _boundDragLeave?: (e: DragEvent) => void;\n private _boundDrop?: (e: DragEvent) => void;\n private _duckdbConverter?: DuckDBConverter;\n private _shapefileConverter?: ShapefileConverter;\n private _loadingOverlay?: HTMLElement;\n private _loadingText?: HTMLElement;\n private _loadingProgress?: HTMLElement;\n\n /**\n * Creates a new VectorDatasetControl instance.\n *\n * @param options - Configuration options for the vector dataset control.\n */\n constructor(options?: VectorDatasetControlOptions) {\n // Determine accepted extensions based on enableAdvancedFormats\n const enableAdvanced = options?.enableAdvancedFormats ?? DEFAULT_OPTIONS.enableAdvancedFormats;\n const acceptedExtensions =\n options?.acceptedExtensions ?? getAcceptedExtensions(enableAdvanced);\n\n this._options = {\n ...DEFAULT_OPTIONS,\n ...options,\n acceptedExtensions,\n defaultStyle: { ...DEFAULT_STYLE, ...options?.defaultStyle },\n };\n this._state = {\n visible: this._options.visible,\n isDragging: false,\n isLoading: false,\n loadedDatasets: [],\n error: null,\n };\n }\n\n /**\n * Called when the control is added to the map.\n *\n * @param map - The MapLibre GL map instance.\n * @returns The control's container element.\n */\n onAdd(map: MapLibreMap): HTMLElement {\n this._map = map;\n this._container = this._createContainer();\n\n // Set up zoom listener\n this._handleZoom = () => this._checkZoomVisibility();\n this._map.on('zoom', this._handleZoom);\n\n // Set up drag-and-drop on the map container\n if (this._options.showDropZone) {\n this._setupDragAndDrop();\n }\n\n this._checkZoomVisibility();\n\n return this._container;\n }\n\n /**\n * Called when the control is removed from the map.\n */\n onRemove(): void {\n // Remove drag-and-drop listeners\n this._removeDragAndDrop();\n\n // Remove all loaded sources and layers\n this._removeAllDatasets();\n\n // Dispose converters if present\n if (this._duckdbConverter) {\n this._duckdbConverter.dispose();\n this._duckdbConverter = undefined;\n }\n if (this._shapefileConverter) {\n this._shapefileConverter.dispose();\n this._shapefileConverter = undefined;\n }\n\n // Remove zoom listener\n if (this._map && this._handleZoom) {\n this._map.off('zoom', this._handleZoom);\n this._handleZoom = undefined;\n }\n\n this._map = undefined;\n this._container?.parentNode?.removeChild(this._container);\n this._container = undefined;\n this._button = undefined;\n this._fileInput = undefined;\n this._dropZone = undefined;\n this._eventHandlers.clear();\n }\n\n /**\n * Shows the control.\n */\n show(): void {\n if (!this._state.visible) {\n this._state.visible = true;\n this._updateDisplayState();\n this._emit('show');\n }\n }\n\n /**\n * Hides the control.\n */\n hide(): void {\n if (this._state.visible) {\n this._state.visible = false;\n this._updateDisplayState();\n this._emit('hide');\n }\n }\n\n /**\n * Gets the current state.\n *\n * @returns The current vector dataset control state.\n */\n getState(): VectorDatasetControlState {\n return { ...this._state, loadedDatasets: [...this._state.loadedDatasets] };\n }\n\n /**\n * Gets all loaded datasets.\n *\n * @returns Array of loaded datasets.\n */\n getLoadedDatasets(): LoadedDataset[] {\n return [...this._state.loadedDatasets];\n }\n\n /**\n * Removes a dataset by ID.\n *\n * @param datasetId - The ID of the dataset to remove.\n */\n removeDataset(datasetId: string): void {\n const dataset = this._state.loadedDatasets.find((d) => d.id === datasetId);\n if (!dataset || !this._map) return;\n\n try {\n // Remove layers first\n for (const layerId of dataset.layerIds) {\n if (this._map.getLayer(layerId)) {\n this._map.removeLayer(layerId);\n }\n }\n\n // Remove source\n if (this._map.getSource(dataset.sourceId)) {\n this._map.removeSource(dataset.sourceId);\n }\n\n // Update state\n this._state.loadedDatasets = this._state.loadedDatasets.filter((d) => d.id !== datasetId);\n this._emit('update');\n } catch (error) {\n console.error('Failed to remove dataset:', error);\n }\n }\n\n /**\n * Removes all loaded datasets.\n */\n removeAllDatasets(): void {\n this._removeAllDatasets();\n this._emit('update');\n }\n\n /**\n * Programmatically loads a GeoJSON object.\n *\n * @param geojson - The GeoJSON object to load.\n * @param filename - Optional filename for the dataset.\n * @returns The loaded dataset or null if failed.\n */\n async loadGeoJSON(\n geojson: GeoJSON.GeoJSON,\n filename: string = 'data.geojson'\n ): Promise<LoadedDataset | null> {\n return this._processGeoJSON(geojson, filename, 'geojson');\n }\n\n /**\n * Registers an event handler.\n *\n * @param event - The event type to listen for.\n * @param handler - The callback function.\n */\n on(event: VectorDatasetEvent, handler: VectorDatasetEventHandler): void {\n if (!this._eventHandlers.has(event)) {\n this._eventHandlers.set(event, new Set());\n }\n this._eventHandlers.get(event)!.add(handler);\n }\n\n /**\n * Removes an event handler.\n *\n * @param event - The event type.\n * @param handler - The callback function to remove.\n */\n off(event: VectorDatasetEvent, handler: VectorDatasetEventHandler): void {\n this._eventHandlers.get(event)?.delete(handler);\n }\n\n /**\n * Updates control options and re-renders.\n *\n * @param options - Partial options to update.\n */\n update(options: Partial<VectorDatasetControlOptions>): void {\n this._options = {\n ...this._options,\n ...options,\n defaultStyle: { ...this._options.defaultStyle, ...options?.defaultStyle },\n };\n\n if (options.visible !== undefined) {\n this._state.visible = options.visible;\n }\n\n this._updateDisplayState();\n this._emit('update');\n }\n\n /**\n * Emits an event to all registered handlers.\n *\n * @param event - The event type to emit.\n * @param dataset - Optional dataset for load events.\n * @param error - Optional error message for error events.\n * @param filename - Optional filename for error events.\n */\n private _emit(\n event: VectorDatasetEvent,\n dataset?: LoadedDataset,\n error?: string,\n filename?: string\n ): void {\n const handlers = this._eventHandlers.get(event);\n if (handlers) {\n const eventData = {\n type: event,\n state: this.getState(),\n dataset,\n error,\n filename,\n };\n handlers.forEach((handler) => handler(eventData));\n }\n }\n\n /**\n * Creates the main container element.\n *\n * @returns The container element.\n */\n private _createContainer(): HTMLElement {\n const container = document.createElement('div');\n container.className = `maplibregl-ctrl maplibregl-ctrl-group maplibre-gl-vector-dataset${\n this._options.className ? ` ${this._options.className}` : ''\n }`;\n\n const shouldShow = this._state.visible && this._zoomVisible;\n if (!shouldShow) {\n container.style.display = 'none';\n }\n\n // Apply custom styles\n if (this._options.backgroundColor) {\n container.style.backgroundColor = this._options.backgroundColor;\n }\n if (this._options.borderRadius) {\n container.style.borderRadius = `${this._options.borderRadius}px`;\n }\n if (this._options.opacity !== 1) {\n container.style.opacity = String(this._options.opacity);\n }\n\n // Create hidden file input\n this._fileInput = document.createElement('input');\n this._fileInput.type = 'file';\n this._fileInput.accept = this._options.acceptedExtensions.join(',');\n this._fileInput.multiple = this._options.multiple;\n this._fileInput.style.display = 'none';\n this._fileInput.addEventListener('change', (e) => this._handleFileSelect(e));\n container.appendChild(this._fileInput);\n\n // Create button\n this._button = document.createElement('button');\n this._button.type = 'button';\n this._button.className = 'maplibre-gl-vector-dataset-button';\n const buttonLabel = this._options.enableAdvancedFormats\n ? 'Load vector file (GeoJSON, Shapefile, GeoPackage, KML, GPX, and more)'\n : 'Load GeoJSON file';\n this._button.title = buttonLabel;\n this._button.setAttribute('aria-label', buttonLabel);\n this._button.innerHTML = UPLOAD_ICON;\n this._button.addEventListener('click', () => this._fileInput?.click());\n container.appendChild(this._button);\n\n return container;\n }\n\n /**\n * Sets up drag-and-drop event listeners on the map container.\n */\n private _setupDragAndDrop(): void {\n if (!this._map) return;\n\n const mapContainer = this._map.getContainer();\n\n // Create drop zone overlay\n this._dropZone = document.createElement('div');\n this._dropZone.className = 'maplibre-gl-vector-dataset-dropzone';\n const dropzoneText = this._options.enableAdvancedFormats\n ? 'Drop vector files here (GeoJSON, Shapefile, GeoPackage, KML, GPX, CSV, and more)'\n : 'Drop GeoJSON files here';\n this._dropZone.innerHTML = `\n <div class=\"maplibre-gl-vector-dataset-dropzone-content\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"48\" height=\"48\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"/>\n <polyline points=\"17 8 12 3 7 8\"/>\n <line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"15\"/>\n </svg>\n <p>${dropzoneText}</p>\n </div>\n `;\n this._dropZone.style.display = 'none';\n mapContainer.appendChild(this._dropZone);\n\n // Create loading overlay\n this._loadingOverlay = document.createElement('div');\n this._loadingOverlay.className = 'maplibre-gl-vector-dataset-loading';\n this._loadingOverlay.innerHTML = `\n <div class=\"maplibre-gl-vector-dataset-loading-content\">\n <div class=\"maplibre-gl-vector-dataset-spinner\"></div>\n <p class=\"maplibre-gl-vector-dataset-loading-text\">Loading...</p>\n <p class=\"maplibre-gl-vector-dataset-loading-progress\"></p>\n </div>\n `;\n this._loadingOverlay.style.display = 'none';\n this._loadingText = this._loadingOverlay.querySelector('.maplibre-gl-vector-dataset-loading-text') as HTMLElement;\n this._loadingProgress = this._loadingOverlay.querySelector('.maplibre-gl-vector-dataset-loading-progress') as HTMLElement;\n mapContainer.appendChild(this._loadingOverlay);\n\n // Bind event handlers\n this._boundDragOver = (e: DragEvent) => this._handleDragOver(e);\n this._boundDragLeave = (e: DragEvent) => this._handleDragLeave(e);\n this._boundDrop = (e: DragEvent) => this._handleDrop(e);\n\n mapContainer.addEventListener('dragover', this._boundDragOver);\n mapContainer.addEventListener('dragleave', this._boundDragLeave);\n mapContainer.addEventListener('drop', this._boundDrop);\n }\n\n /**\n * Removes drag-and-drop event listeners.\n */\n private _removeDragAndDrop(): void {\n if (!this._map) return;\n\n const mapContainer = this._map.getContainer();\n\n if (this._boundDragOver) {\n mapContainer.removeEventListener('dragover', this._boundDragOver);\n }\n if (this._boundDragLeave) {\n mapContainer.removeEventListener('dragleave', this._boundDragLeave);\n }\n if (this._boundDrop) {\n mapContainer.removeEventListener('drop', this._boundDrop);\n }\n\n if (this._dropZone && this._dropZone.parentNode) {\n this._dropZone.parentNode.removeChild(this._dropZone);\n }\n\n if (this._loadingOverlay && this._loadingOverlay.parentNode) {\n this._loadingOverlay.parentNode.removeChild(this._loadingOverlay);\n }\n }\n\n /**\n * Handles dragover event.\n *\n * @param e - The drag event.\n */\n private _handleDragOver(e: DragEvent): void {\n e.preventDefault();\n e.stopPropagation();\n\n if (!this._state.isDragging) {\n this._state.isDragging = true;\n if (this._dropZone) {\n this._dropZone.style.display = 'flex';\n }\n this._emit('dragenter');\n }\n }\n\n /**\n * Handles dragleave event.\n *\n * @param e - The drag event.\n */\n private _handleDragLeave(e: DragEvent): void {\n e.preventDefault();\n e.stopPropagation();\n\n // Check if we're leaving the map container entirely\n const mapContainer = this._map?.getContainer();\n if (mapContainer && !mapContainer.contains(e.relatedTarget as Node)) {\n this._state.isDragging = false;\n if (this._dropZone) {\n this._dropZone.style.display = 'none';\n }\n this._emit('dragleave');\n }\n }\n\n /**\n * Handles drop event.\n *\n * @param e - The drag event.\n */\n private _handleDrop(e: DragEvent): void {\n e.preventDefault();\n e.stopPropagation();\n\n this._state.isDragging = false;\n if (this._dropZone) {\n this._dropZone.style.display = 'none';\n }\n\n const files = e.dataTransfer?.files;\n if (files && files.length > 0) {\n this._processFiles(Array.from(files));\n }\n }\n\n /**\n * Handles file input change event.\n *\n * @param e - The change event.\n */\n private _handleFileSelect(e: Event): void {\n const input = e.target as HTMLInputElement;\n const files = input.files;\n if (files && files.length > 0) {\n this._processFiles(Array.from(files));\n }\n // Reset input to allow selecting the same file again\n input.value = '';\n }\n\n /**\n * Processes uploaded files.\n *\n * @param files - Array of files to process.\n */\n private async _processFiles(files: File[]): Promise<void> {\n this._state.isLoading = true;\n this._state.error = null;\n this._updateButtonState();\n\n for (const file of files) {\n // Validate file extension\n if (!isValidExtension(file.name, this._options.enableAdvancedFormats)) {\n this._state.error = `Invalid file type: ${file.name}. Accepted: ${this._options.acceptedExtensions.join(', ')}`;\n this._emit('error', undefined, this._state.error, file.name);\n continue;\n }\n\n // Validate file size\n if (file.size > this._options.maxFileSize) {\n const maxSizeMB = (this._options.maxFileSize / (1024 * 1024)).toFixed(1);\n this._state.error = `File too large: ${file.name}. Maximum size: ${maxSizeMB}MB`;\n this._emit('error', undefined, this._state.error, file.name);\n continue;\n }\n\n // Detect format and route to appropriate handler\n const format = detectFormat(file.name);\n\n try {\n if (requiresConversion(format)) {\n // Process with appropriate converter (shpjs for Shapefile, DuckDB for GeoPackage/GeoParquet)\n if (!this._options.enableAdvancedFormats) {\n this._state.error = `${getFormatDisplayName(format)} files require enableAdvancedFormats: true`;\n this._emit('error', undefined, this._state.error, file.name);\n continue;\n }\n // Show loading indicator for advanced formats\n this._showLoading(`Loading ${file.name}...`);\n await this._processAdvancedFormat(file, format);\n this._hideLoading();\n } else {\n // Process as GeoJSON\n this._showLoading(`Loading ${file.name}...`);\n const text = await file.text();\n const geojson = JSON.parse(text) as GeoJSON.GeoJSON;\n await this._processGeoJSON(geojson, file.name, 'geojson');\n this._hideLoading();\n }\n } catch (error) {\n this._hideLoading();\n this._state.error = `Failed to process ${file.name}: ${error instanceof Error ? error.message : 'Unknown error'}`;\n this._emit('error', undefined, this._state.error, file.name);\n }\n }\n\n this._state.isLoading = false;\n this._updateButtonState();\n }\n\n /**\n * Processes a file using the appropriate converter.\n *\n * @param file - The file to process.\n * @param format - The detected vector format.\n */\n private async _processAdvancedFormat(file: File, format: VectorFormat): Promise<void> {\n // Create a progress callback that updates both the loading indicator and user's callback\n const progressCallback = (progress: { stage: string; percent?: number; message?: string }) => {\n // Update loading indicator\n const message = progress.message || `Processing ${file.name}...`;\n const progressText = progress.percent !== undefined ? `${progress.percent}%` : '';\n this._updateLoading(message, progressText);\n\n // Call user's callback if provided\n this._options.onConversionProgress?.(progress as Parameters<NonNullable<typeof this._options.onConversionProgress>>[0]);\n };\n\n // Read file as buffer\n this._updateLoading(`Reading ${file.name}...`);\n const buffer = await readFileAsBuffer(file);\n\n if (format === 'shapefile') {\n // Use shpjs for Shapefiles\n if (!this._shapefileConverter) {\n this._updateLoading('Loading Shapefile converter...');\n const { getShapefileConverter } = await import('../converters/ShapefileConverter');\n this._shapefileConverter = getShapefileConverter();\n }\n\n const result = await this._shapefileConverter.convert(\n buffer,\n file.name,\n progressCallback\n );\n\n if (result.geojson) {\n this._updateLoading('Adding to map...');\n await this._processGeoJSON(result.geojson, file.name, format);\n }\n } else if (requiresDuckDB(format)) {\n // Use DuckDB for GeoPackage, GeoParquet, KML, GPX, FlatGeobuf, GML, TopoJSON, CSV, Excel, DXF\n if (!this._duckdbConverter) {\n this._updateLoading('Loading DuckDB converter...');\n const { getDuckDBConverter } = await import('../converters/DuckDBConverter');\n this._duckdbConverter = getDuckDBConverter();\n\n // Configure custom bundle URL if provided\n if (this._options.duckdbBundleUrl) {\n const { DuckDBConverter } = await import('../converters/DuckDBConverter');\n this._duckdbConverter = new DuckDBConverter(this._options.duckdbBundleUrl);\n }\n }\n\n const result = await this._duckdbConverter.convert(\n buffer,\n file.name,\n progressCallback\n );\n\n if (result.geojson) {\n this._updateLoading('Adding to map...');\n await this._processGeoJSON(result.geojson, file.name, format);\n }\n }\n }\n\n /**\n * Processes a GeoJSON object and adds it to the map.\n *\n * @param geojson - The GeoJSON object to process.\n * @param filename - The filename of the dataset.\n * @param originalFormat - The original file format.\n * @returns The loaded dataset or null if failed.\n */\n private async _processGeoJSON(\n geojson: GeoJSON.GeoJSON,\n filename: string,\n originalFormat: VectorFormat = 'geojson'\n ): Promise<LoadedDataset | null> {\n if (!this._map) return null;\n\n // Validate GeoJSON structure\n if (!geojson.type) {\n this._state.error = `Invalid GeoJSON: missing type property in ${filename}`;\n this._emit('error', undefined, this._state.error, filename);\n return null;\n }\n\n // Normalize to FeatureCollection\n let featureCollection: GeoJSON.FeatureCollection;\n if (geojson.type === 'FeatureCollection') {\n featureCollection = geojson as GeoJSON.FeatureCollection;\n } else if (geojson.type === 'Feature') {\n featureCollection = {\n type: 'FeatureCollection',\n features: [geojson as GeoJSON.Feature],\n };\n } else {\n // It's a geometry object\n featureCollection = {\n type: 'FeatureCollection',\n features: [\n {\n type: 'Feature',\n properties: {},\n geometry: geojson as GeoJSON.Geometry,\n },\n ],\n };\n }\n\n // Generate unique IDs\n const datasetId = generateId('vds');\n const sourceId = `${datasetId}-source`;\n\n // Analyze geometry types\n const geometryTypes = new Set<string>();\n for (const feature of featureCollection.features) {\n if (feature.geometry) {\n geometryTypes.add(feature.geometry.type);\n }\n }\n\n try {\n // Add source\n this._map.addSource(sourceId, {\n type: 'geojson',\n data: featureCollection,\n generateId: true,\n });\n\n // Add layers based on geometry types\n const layerIds: string[] = [];\n const style = this._options.defaultStyle;\n\n // Add polygon fill layer\n if (geometryTypes.has('Polygon') || geometryTypes.has('MultiPolygon')) {\n const fillLayerId = `${datasetId}-fill`;\n this._map.addLayer({\n id: fillLayerId,\n type: 'fill',\n source: sourceId,\n filter: [\n 'any',\n ['==', ['geometry-type'], 'Polygon'],\n ['==', ['geometry-type'], 'MultiPolygon'],\n ],\n paint: {\n 'fill-color': style.fillColor,\n 'fill-opacity': style.fillOpacity,\n },\n });\n layerIds.push(fillLayerId);\n\n // Add polygon outline\n const outlineLayerId = `${datasetId}-outline`;\n this._map.addLayer({\n id: outlineLayerId,\n type: 'line',\n source: sourceId,\n filter: [\n 'any',\n ['==', ['geometry-type'], 'Polygon'],\n ['==', ['geometry-type'], 'MultiPolygon'],\n ],\n paint: {\n 'line-color': style.strokeColor,\n 'line-width': style.strokeWidth,\n 'line-opacity': style.strokeOpacity,\n },\n });\n layerIds.push(outlineLayerId);\n }\n\n // Add line layer\n if (geometryTypes.has('LineString') || geometryTypes.has('MultiLineString')) {\n const lineLayerId = `${datasetId}-line`;\n this._map.addLayer({\n id: lineLayerId,\n type: 'line',\n source: sourceId,\n filter: [\n 'any',\n ['==', ['geometry-type'], 'LineString'],\n ['==', ['geometry-type'], 'MultiLineString'],\n ],\n paint: {\n 'line-color': style.strokeColor,\n 'line-width': style.strokeWidth,\n 'line-opacity': style.strokeOpacity,\n },\n });\n layerIds.push(lineLayerId);\n }\n\n // Add point layer\n if (geometryTypes.has('Point') || geometryTypes.has('MultiPoint')) {\n const pointLayerId = `${datasetId}-point`;\n this._map.addLayer({\n id: pointLayerId,\n type: 'circle',\n source: sourceId,\n filter: [\n 'any',\n ['==', ['geometry-type'], 'Point'],\n ['==', ['geometry-type'], 'MultiPoint'],\n ],\n paint: {\n 'circle-radius': style.circleRadius,\n 'circle-color': style.circleColor,\n 'circle-stroke-color': style.circleStrokeColor,\n 'circle-stroke-width': style.circleStrokeWidth,\n },\n });\n layerIds.push(pointLayerId);\n }\n\n // Create dataset record\n const dataset: LoadedDataset = {\n id: datasetId,\n filename,\n sourceId,\n layerIds,\n featureCount: featureCollection.features.length,\n geometryTypes: Array.from(geometryTypes) as LoadedDataset['geometryTypes'],\n loadedAt: new Date(),\n originalFormat,\n };\n\n this._state.loadedDatasets.push(dataset);\n\n // Fit bounds if enabled\n if (this._options.fitBounds && featureCollection.features.length > 0) {\n this._fitToData(featureCollection);\n }\n\n this._emit('load', dataset);\n this._emit('update');\n\n return dataset;\n } catch (error) {\n this._state.error = `Failed to add ${filename} to map: ${error instanceof Error ? error.message : 'Unknown error'}`;\n this._emit('error', undefined, this._state.error, filename);\n return null;\n }\n }\n\n /**\n * Fits the map view to the loaded data bounds.\n *\n * @param geojson - The GeoJSON FeatureCollection to fit to.\n */\n private _fitToData(geojson: GeoJSON.FeatureCollection): void {\n if (!this._map) return;\n\n // Calculate bounds from all features\n let minLng = Infinity,\n minLat = Infinity,\n maxLng = -Infinity,\n maxLat = -Infinity;\n\n const processCoords = (coords: number[]) => {\n minLng = Math.min(minLng, coords[0]);\n maxLng = Math.max(maxLng, coords[0]);\n minLat = Math.min(minLat, coords[1]);\n maxLat = Math.max(maxLat, coords[1]);\n };\n\n const processCoordArray = (coords: number[][] | number[][][] | number[][][][]) => {\n for (const item of coords) {\n if (typeof item[0] === 'number') {\n processCoords(item as number[]);\n } else {\n processCoordArray(item as number[][] | number[][][]);\n }\n }\n };\n\n for (const feature of geojson.features) {\n if (!feature.geometry) continue;\n\n const geom = feature.geometry;\n if (geom.type === 'Point') {\n processCoords(geom.coordinates);\n } else if (geom.type === 'MultiPoint' || geom.type === 'LineString') {\n processCoordArray(geom.coordinates);\n } else if (geom.type === 'MultiLineString' || geom.type === 'Polygon') {\n processCoordArray(geom.coordinates);\n } else if (geom.type === 'MultiPolygon') {\n processCoordArray(geom.coordinates);\n }\n }\n\n if (minLng !== Infinity) {\n this._map.fitBounds(\n [\n [minLng, minLat],\n [maxLng, maxLat],\n ],\n { padding: this._options.fitBoundsPadding }\n );\n }\n }\n\n /**\n * Removes all loaded datasets from the map.\n */\n private _removeAllDatasets(): void {\n for (const dataset of this._state.loadedDatasets) {\n if (this._map) {\n for (const layerId of dataset.layerIds) {\n if (this._map.getLayer(layerId)) {\n this._map.removeLayer(layerId);\n }\n }\n if (this._map.getSource(dataset.sourceId)) {\n this._map.removeSource(dataset.sourceId);\n }\n }\n }\n this._state.loadedDatasets = [];\n }\n\n /**\n * Checks if the current zoom level is within the visibility range.\n */\n private _checkZoomVisibility(): void {\n if (!this._map) return;\n\n const zoom = this._map.getZoom();\n const { minzoom, maxzoom } = this._options;\n const inRange = zoom >= minzoom && zoom <= maxzoom;\n\n if (inRange !== this._zoomVisible) {\n this._zoomVisible = inRange;\n this._updateDisplayState();\n }\n }\n\n /**\n * Updates the display state based on visibility and zoom level.\n */\n private _updateDisplayState(): void {\n if (!this._container) return;\n const shouldShow = this._state.visible && this._zoomVisible;\n this._container.style.display = shouldShow ? 'flex' : 'none';\n }\n\n /**\n * Updates the button state to reflect loading status.\n */\n private _updateButtonState(): void {\n if (!this._button) return;\n\n if (this._state.isLoading) {\n this._button.classList.add('maplibre-gl-vector-dataset-button--loading');\n this._button.disabled = true;\n } else {\n this._button.classList.remove('maplibre-gl-vector-dataset-button--loading');\n this._button.disabled = false;\n }\n }\n\n /**\n * Shows the loading overlay with an optional message.\n *\n * @param message - The loading message to display.\n * @param progress - Optional progress percentage or status.\n */\n private _showLoading(message: string, progress?: string): void {\n if (!this._loadingOverlay) return;\n this._loadingOverlay.style.display = 'flex';\n if (this._loadingText) {\n this._loadingText.textContent = message;\n }\n if (this._loadingProgress) {\n this._loadingProgress.textContent = progress || '';\n }\n }\n\n /**\n * Updates the loading overlay message.\n *\n * @param message - The loading message to display.\n * @param progress - Optional progress percentage or status.\n */\n private _updateLoading(message: string, progress?: string): void {\n if (this._loadingText) {\n this._loadingText.textContent = message;\n }\n if (this._loadingProgress) {\n this._loadingProgress.textContent = progress || '';\n }\n }\n\n /**\n * Hides the loading overlay.\n */\n private _hideLoading(): void {\n if (!this._loadingOverlay) return;\n this._loadingOverlay.style.display = 'none';\n }\n}\n","import '../styles/common.css';\nimport '../styles/inspect-control.css';\nimport maplibregl, { type IControl, type Map as MapLibreMap, type MapMouseEvent, Popup } from 'maplibre-gl';\nimport type {\n InspectControlOptions,\n InspectControlState,\n InspectedFeature,\n InspectHighlightStyle,\n InspectEvent,\n InspectEventHandler,\n} from './types';\nimport { generateId } from '../utils/helpers';\n\n/**\n * Default highlight style for selected features.\n */\nconst DEFAULT_HIGHLIGHT_STYLE: Required<InspectHighlightStyle> = {\n fillColor: '#ffff00',\n fillOpacity: 0.3,\n strokeColor: '#ffff00',\n strokeWidth: 3,\n circleRadius: 10,\n circleStrokeWidth: 3,\n};\n\n/**\n * Default options for the InspectControl.\n */\nconst DEFAULT_OPTIONS: Required<InspectControlOptions> = {\n position: 'top-right',\n className: '',\n visible: true,\n enabled: false,\n maxFeatures: 10,\n includeLayers: [],\n excludeLayers: [],\n highlightStyle: DEFAULT_HIGHLIGHT_STYLE,\n excludeProperties: [],\n showGeometryType: true,\n showLayerName: true,\n maxWidth: 320,\n maxHeight: 300,\n backgroundColor: 'rgba(255, 255, 255, 0.95)',\n borderRadius: 4,\n opacity: 1,\n fontSize: 13,\n fontColor: '#333',\n minzoom: 0,\n maxzoom: 24,\n};\n\n/**\n * SVG icon for the inspect button (info circle).\n */\nconst INSPECT_ICON = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"M12 16v-4\"/><path d=\"M12 8h.01\"/></svg>`;\n\n/**\n * A control for inspecting vector features on the map.\n *\n * Provides click-to-inspect functionality that shows feature properties/attributes\n * in a popup. Supports multiple features at the same location with navigation.\n *\n * @example\n * ```typescript\n * const inspectControl = new InspectControl({\n * excludeLayers: ['background'],\n * highlightStyle: { strokeColor: '#00ff00', strokeWidth: 4 },\n * });\n * map.addControl(inspectControl, 'top-right');\n *\n * // Listen for feature selection\n * inspectControl.on('featureselect', (event) => {\n * console.log('Selected:', event.feature);\n * });\n * ```\n */\nexport class InspectControl implements IControl {\n private _container?: HTMLElement;\n private _button?: HTMLButtonElement;\n private _options: Required<InspectControlOptions>;\n private _state: InspectControlState;\n private _eventHandlers: Map<InspectEvent, Set<InspectEventHandler>> = new Map();\n private _map?: MapLibreMap;\n private _handleZoom?: () => void;\n private _zoomVisible: boolean = true;\n private _popup?: Popup;\n private _highlightSourceId: string = '';\n private _highlightLayerIds: string[] = [];\n\n // Bound event handlers for proper cleanup\n private _boundClickHandler?: (e: MapMouseEvent) => void;\n\n /**\n * Creates a new InspectControl instance.\n *\n * @param options - Configuration options for the control.\n */\n constructor(options?: InspectControlOptions) {\n this._options = {\n ...DEFAULT_OPTIONS,\n ...options,\n highlightStyle: { ...DEFAULT_HIGHLIGHT_STYLE, ...options?.highlightStyle },\n };\n this._state = {\n visible: this._options.visible,\n enabled: this._options.enabled,\n inspectedFeatures: [],\n selectedIndex: 0,\n error: null,\n };\n this._highlightSourceId = `inspect-highlight-${generateId()}`;\n }\n\n /**\n * Called when the control is added to the map.\n *\n * @param map - The MapLibre GL map instance.\n * @returns The control's container element.\n */\n onAdd(map: MapLibreMap): HTMLElement {\n this._map = map;\n this._container = this._createContainer();\n\n // Set up zoom listener\n this._handleZoom = () => this._checkZoomVisibility();\n this._map.on('zoom', this._handleZoom);\n\n // Check initial zoom\n this._checkZoomVisibility();\n\n // If enabled by default, set up click handler\n if (this._state.enabled) {\n this._setupMapListeners();\n }\n\n return this._container;\n }\n\n /**\n * Called when the control is removed from the map.\n */\n onRemove(): void {\n if (this._map && this._handleZoom) {\n this._map.off('zoom', this._handleZoom);\n this._handleZoom = undefined;\n }\n this._removeMapListeners();\n this._removeHighlight();\n this._hidePopup();\n this._map = undefined;\n this._container?.parentNode?.removeChild(this._container);\n this._container = undefined;\n this._button = undefined;\n this._eventHandlers.clear();\n }\n\n /**\n * Enables inspect mode.\n */\n enable(): void {\n if (!this._state.enabled) {\n this._state.enabled = true;\n this._updateButtonState();\n this._setupMapListeners();\n this._updateCursor(true);\n this._emit('enable');\n }\n }\n\n /**\n * Disables inspect mode.\n */\n disable(): void {\n if (this._state.enabled) {\n this._state.enabled = false;\n this._updateButtonState();\n this._removeMapListeners();\n this._updateCursor(false);\n this.clear();\n this._emit('disable');\n }\n }\n\n /**\n * Toggles inspect mode on/off.\n */\n toggle(): void {\n if (this._state.enabled) {\n this.disable();\n } else {\n this.enable();\n }\n }\n\n /**\n * Returns whether inspect mode is enabled.\n */\n isEnabled(): boolean {\n return this._state.enabled;\n }\n\n /**\n * Shows the control.\n */\n show(): void {\n if (!this._state.visible) {\n this._state.visible = true;\n this._updateDisplayState();\n this._emit('show');\n }\n }\n\n /**\n * Hides the control.\n */\n hide(): void {\n if (this._state.visible) {\n this._state.visible = true;\n this._updateDisplayState();\n this._emit('hide');\n }\n }\n\n /**\n * Clears the current inspection.\n */\n clear(): void {\n this._state.inspectedFeatures = [];\n this._state.selectedIndex = 0;\n this._removeHighlight();\n this._hidePopup();\n this._emit('clear');\n }\n\n /**\n * Returns a copy of the current state.\n */\n getState(): InspectControlState {\n return { ...this._state };\n }\n\n /**\n * Returns the currently inspected features.\n */\n getInspectedFeatures(): InspectedFeature[] {\n return [...this._state.inspectedFeatures];\n }\n\n /**\n * Returns the currently selected feature.\n */\n getSelectedFeature(): InspectedFeature | null {\n return this._state.inspectedFeatures[this._state.selectedIndex] || null;\n }\n\n /**\n * Selects a feature by index.\n */\n selectFeature(index: number): void {\n if (index >= 0 && index < this._state.inspectedFeatures.length) {\n this._state.selectedIndex = index;\n const feature = this._state.inspectedFeatures[index];\n this._addHighlight(feature);\n this._updatePopupContent();\n this._emit('featureselect', feature);\n }\n }\n\n /**\n * Selects the next feature.\n */\n nextFeature(): void {\n if (this._state.inspectedFeatures.length > 1) {\n const nextIndex = (this._state.selectedIndex + 1) % this._state.inspectedFeatures.length;\n this.selectFeature(nextIndex);\n }\n }\n\n /**\n * Selects the previous feature.\n */\n previousFeature(): void {\n if (this._state.inspectedFeatures.length > 1) {\n const prevIndex = this._state.selectedIndex === 0\n ? this._state.inspectedFeatures.length - 1\n : this._state.selectedIndex - 1;\n this.selectFeature(prevIndex);\n }\n }\n\n /**\n * Updates the control options.\n */\n update(options: Partial<InspectControlOptions>): void {\n Object.assign(this._options, options);\n if (options.highlightStyle) {\n this._options.highlightStyle = { ...DEFAULT_HIGHLIGHT_STYLE, ...options.highlightStyle };\n }\n if (options.visible !== undefined) {\n this._state.visible = options.visible;\n this._updateDisplayState();\n }\n if (options.enabled !== undefined) {\n if (options.enabled) {\n this.enable();\n } else {\n this.disable();\n }\n }\n this._emit('update');\n }\n\n /**\n * Registers an event handler.\n */\n on(event: InspectEvent, handler: InspectEventHandler): void {\n if (!this._eventHandlers.has(event)) {\n this._eventHandlers.set(event, new Set());\n }\n this._eventHandlers.get(event)!.add(handler);\n }\n\n /**\n * Removes an event handler.\n */\n off(event: InspectEvent, handler: InspectEventHandler): void {\n this._eventHandlers.get(event)?.delete(handler);\n }\n\n /**\n * Emits an event to all registered handlers.\n */\n private _emit(event: InspectEvent, feature?: InspectedFeature): void {\n const handlers = this._eventHandlers.get(event);\n if (handlers) {\n handlers.forEach((handler) =>\n handler({\n type: event,\n state: this.getState(),\n feature,\n features: this._state.inspectedFeatures,\n })\n );\n }\n }\n\n /**\n * Creates the control container.\n */\n private _createContainer(): HTMLElement {\n const container = document.createElement('div');\n container.className = `maplibregl-ctrl maplibregl-ctrl-group maplibre-gl-inspect ${this._options.className}`.trim();\n\n // Apply custom styling\n if (this._options.backgroundColor) {\n container.style.backgroundColor = this._options.backgroundColor;\n }\n if (this._options.borderRadius) {\n container.style.borderRadius = `${this._options.borderRadius}px`;\n }\n if (this._options.opacity !== undefined && this._options.opacity !== 1) {\n container.style.opacity = String(this._options.opacity);\n }\n\n // Create button\n this._button = document.createElement('button');\n this._button.type = 'button';\n this._button.className = 'maplibre-gl-inspect-button';\n this._button.title = 'Inspect features';\n this._button.innerHTML = INSPECT_ICON;\n this._button.addEventListener('click', () => this.toggle());\n\n container.appendChild(this._button);\n\n // Set initial display state\n container.style.display = this._state.visible ? 'block' : 'none';\n\n return container;\n }\n\n /**\n * Updates the button's active state appearance.\n */\n private _updateButtonState(): void {\n if (this._button) {\n if (this._state.enabled) {\n this._button.classList.add('maplibre-gl-inspect-button--active');\n this._button.title = 'Disable inspect mode';\n } else {\n this._button.classList.remove('maplibre-gl-inspect-button--active');\n this._button.title = 'Inspect features';\n }\n }\n }\n\n /**\n * Updates the cursor style when inspect mode is active.\n */\n private _updateCursor(inspectMode: boolean): void {\n if (this._map) {\n const canvas = this._map.getCanvas();\n if (inspectMode) {\n canvas.style.cursor = 'crosshair';\n } else {\n canvas.style.cursor = '';\n }\n }\n }\n\n /**\n * Sets up map click listener for inspect mode.\n */\n private _setupMapListeners(): void {\n if (!this._map || this._boundClickHandler) return;\n\n this._boundClickHandler = (e: MapMouseEvent) => this._handleMapClick(e);\n this._map.on('click', this._boundClickHandler);\n }\n\n /**\n * Removes map click listener.\n */\n private _removeMapListeners(): void {\n if (this._map && this._boundClickHandler) {\n this._map.off('click', this._boundClickHandler);\n this._boundClickHandler = undefined;\n }\n }\n\n /**\n * Handles map click events to inspect features.\n */\n private _handleMapClick(e: MapMouseEvent): void {\n if (!this._map) return;\n\n const point = e.point;\n const lngLat: [number, number] = [e.lngLat.lng, e.lngLat.lat];\n\n // Query features at click point\n const features = this._queryFeatures(point);\n\n if (features.length === 0) {\n this.clear();\n return;\n }\n\n // Convert to InspectedFeature format\n const inspectedFeatures: InspectedFeature[] = features\n .slice(0, this._options.maxFeatures)\n .map((f) => {\n const featureId = f.id;\n const feature: GeoJSON.Feature = {\n type: 'Feature' as const,\n geometry: f.geometry,\n properties: f.properties || {},\n };\n if (featureId !== undefined) {\n feature.id = featureId;\n }\n\n return {\n id: generateId('inspect'),\n feature,\n layerId: f.layer?.id || 'unknown',\n sourceId: f.source || 'unknown',\n sourceLayer: f.sourceLayer,\n featureId: featureId === undefined ? undefined : featureId,\n lngLat,\n };\n });\n\n this._state.inspectedFeatures = inspectedFeatures;\n this._state.selectedIndex = 0;\n\n const selectedFeature = inspectedFeatures[0];\n this._addHighlight(selectedFeature);\n this._showPopup(selectedFeature, lngLat);\n this._emit('featureselect', selectedFeature);\n }\n\n /**\n * Queries features at a point.\n */\n private _queryFeatures(point: maplibregl.PointLike): maplibregl.MapGeoJSONFeature[] {\n if (!this._map) return [];\n\n const queryOptions: { layers?: string[] } = {};\n\n // If includeLayers is specified, only query those layers\n if (this._options.includeLayers.length > 0) {\n queryOptions.layers = this._options.includeLayers;\n }\n\n let features = this._map.queryRenderedFeatures(point, queryOptions);\n\n // Filter out excluded layers\n if (this._options.excludeLayers.length > 0) {\n features = features.filter(\n (f) => f.layer && !this._options.excludeLayers.includes(f.layer.id)\n );\n }\n\n // Filter out highlight layers\n features = features.filter(\n (f) => f.layer && !f.layer.id.startsWith('inspect-highlight-')\n );\n\n return features;\n }\n\n /**\n * Adds highlight layer for the selected feature.\n */\n private _addHighlight(inspectedFeature: InspectedFeature): void {\n if (!this._map) return;\n\n // Remove existing highlight\n this._removeHighlight();\n\n const feature = inspectedFeature.feature;\n const geometryType = feature.geometry.type;\n const style = this._options.highlightStyle;\n\n const highlightTarget = this._getHighlightTarget(inspectedFeature);\n const highlightSourceId = highlightTarget?.sourceId ?? this._highlightSourceId;\n const highlightSourceLayer = highlightTarget?.sourceLayer;\n const highlightFilter = highlightTarget?.filter;\n\n if (!highlightTarget) {\n // Add source only when we can't use the original source for highlighting.\n this._map.addSource(this._highlightSourceId, {\n type: 'geojson',\n data: feature,\n });\n }\n\n const layerBase: {\n source: string;\n 'source-layer'?: string;\n filter?: maplibregl.FilterSpecification;\n } = { source: highlightSourceId };\n\n if (highlightSourceLayer) {\n layerBase['source-layer'] = highlightSourceLayer;\n }\n\n if (highlightFilter) {\n layerBase.filter = highlightFilter;\n }\n\n // Add appropriate layer(s) based on geometry type\n if (geometryType === 'Point' || geometryType === 'MultiPoint') {\n const layerId = `${this._highlightSourceId}-circle`;\n this._map.addLayer({\n id: layerId,\n type: 'circle',\n ...layerBase,\n paint: {\n 'circle-radius': style.circleRadius,\n 'circle-color': style.fillColor,\n 'circle-opacity': style.fillOpacity,\n 'circle-stroke-color': style.strokeColor,\n 'circle-stroke-width': style.circleStrokeWidth,\n },\n });\n this._highlightLayerIds.push(layerId);\n } else if (geometryType === 'LineString' || geometryType === 'MultiLineString') {\n const layerId = `${this._highlightSourceId}-line`;\n this._map.addLayer({\n id: layerId,\n type: 'line',\n ...layerBase,\n paint: {\n 'line-color': style.strokeColor,\n 'line-width': style.strokeWidth,\n 'line-opacity': 1,\n },\n });\n this._highlightLayerIds.push(layerId);\n } else if (geometryType === 'Polygon' || geometryType === 'MultiPolygon') {\n // Fill layer\n const fillLayerId = `${this._highlightSourceId}-fill`;\n this._map.addLayer({\n id: fillLayerId,\n type: 'fill',\n ...layerBase,\n paint: {\n 'fill-color': style.fillColor,\n 'fill-opacity': style.fillOpacity,\n },\n });\n this._highlightLayerIds.push(fillLayerId);\n\n // Outline layer\n const lineLayerId = `${this._highlightSourceId}-outline`;\n this._map.addLayer({\n id: lineLayerId,\n type: 'line',\n ...layerBase,\n paint: {\n 'line-color': style.strokeColor,\n 'line-width': style.strokeWidth,\n },\n });\n this._highlightLayerIds.push(lineLayerId);\n }\n }\n\n /**\n * Determines if highlight can use the original source to avoid tile clipping.\n */\n private _getHighlightTarget(\n inspectedFeature: InspectedFeature\n ): { sourceId: string; sourceLayer?: string; filter: maplibregl.FilterSpecification } | null {\n if (!this._map) return null;\n\n const { sourceId, sourceLayer, featureId, layerId } = inspectedFeature;\n if (!sourceId || sourceId === 'unknown') return null;\n if (featureId === null || featureId === undefined) return null;\n\n const source = this._map.getSource(sourceId) as maplibregl.Source | undefined;\n if (!source) return null;\n\n if (source.type === 'vector' && !sourceLayer) return null;\n\n const idFilter: maplibregl.FilterSpecification = ['==', ['id'], featureId];\n const layerFilter = this._map.getLayer(layerId)?.filter;\n const combinedFilter = layerFilter\n ? (['all', idFilter, layerFilter] as maplibregl.FilterSpecification)\n : idFilter;\n\n return { sourceId, sourceLayer, filter: combinedFilter };\n }\n\n /**\n * Removes highlight layers.\n */\n private _removeHighlight(): void {\n if (!this._map) return;\n\n // Remove layers\n for (const layerId of this._highlightLayerIds) {\n if (this._map.getLayer(layerId)) {\n this._map.removeLayer(layerId);\n }\n }\n this._highlightLayerIds = [];\n\n // Remove source\n if (this._map.getSource(this._highlightSourceId)) {\n this._map.removeSource(this._highlightSourceId);\n }\n }\n\n /**\n * Shows the popup with feature properties.\n */\n private _showPopup(_inspectedFeature: InspectedFeature, lngLat: [number, number]): void {\n if (!this._map) return;\n\n // Remove existing popup\n this._hidePopup();\n\n const html = this._renderPopupContent();\n\n this._popup = new Popup({\n closeButton: true,\n closeOnClick: false,\n maxWidth: `${this._options.maxWidth}px`,\n className: 'maplibre-gl-inspect-popup',\n })\n .setLngLat(lngLat)\n .setHTML(html)\n .addTo(this._map);\n\n // Attach listeners after DOM is ready\n requestAnimationFrame(() => {\n this._attachPopupListeners();\n });\n }\n\n /**\n * Hides the popup.\n */\n private _hidePopup(): void {\n if (this._popup) {\n this._popup.remove();\n this._popup = undefined;\n }\n }\n\n /**\n * Updates the popup content without recreating it.\n */\n private _updatePopupContent(): void {\n if (this._popup) {\n const html = this._renderPopupContent();\n this._popup.setHTML(html);\n this._attachPopupListeners();\n }\n }\n\n /**\n * Attaches event listeners to popup navigation buttons.\n */\n private _attachPopupListeners(): void {\n if (!this._popup) return;\n\n // Get the popup's DOM element\n const popupEl = this._popup.getElement();\n if (!popupEl) return;\n\n const prevBtn = popupEl.querySelector('.maplibre-gl-inspect-nav-prev') as HTMLButtonElement;\n const nextBtn = popupEl.querySelector('.maplibre-gl-inspect-nav-next') as HTMLButtonElement;\n\n if (prevBtn) {\n // Use onclick to replace any existing handler\n prevBtn.onclick = (e) => {\n e.stopPropagation();\n e.preventDefault();\n this.previousFeature();\n };\n }\n\n if (nextBtn) {\n // Use onclick to replace any existing handler\n nextBtn.onclick = (e) => {\n e.stopPropagation();\n e.preventDefault();\n this.nextFeature();\n };\n }\n }\n\n /**\n * Renders the popup HTML content.\n */\n private _renderPopupContent(): string {\n const features = this._state.inspectedFeatures;\n const selectedIndex = this._state.selectedIndex;\n const feature = features[selectedIndex];\n\n if (!feature) {\n return '<div class=\"maplibre-gl-inspect-empty\">No feature selected</div>';\n }\n\n const geometryType = feature.feature.geometry.type;\n const layerId = feature.layerId;\n const properties = feature.feature.properties || {};\n\n // Header\n let html = '<div class=\"maplibre-gl-inspect-header\">';\n\n if (this._options.showGeometryType) {\n html += `<span class=\"maplibre-gl-inspect-geometry\">${this._formatGeometryType(geometryType)}</span>`;\n }\n\n if (this._options.showLayerName) {\n html += `<span class=\"maplibre-gl-inspect-layer\" title=\"${layerId}\">${layerId}</span>`;\n }\n\n // Navigation (if multiple features)\n if (features.length > 1) {\n const prevDisabled = features.length <= 1 ? 'disabled' : '';\n const nextDisabled = features.length <= 1 ? 'disabled' : '';\n html += `\n <span class=\"maplibre-gl-inspect-nav\">\n <button class=\"maplibre-gl-inspect-nav-prev\" ${prevDisabled} title=\"Previous feature\"><</button>\n <span class=\"maplibre-gl-inspect-nav-count\">${selectedIndex + 1}/${features.length}</span>\n <button class=\"maplibre-gl-inspect-nav-next\" ${nextDisabled} title=\"Next feature\">></button>\n </span>\n `;\n }\n\n html += '</div>';\n\n // Properties table\n html += `<div class=\"maplibre-gl-inspect-content\" style=\"max-height: ${this._options.maxHeight}px;\">`;\n\n const propertyKeys = Object.keys(properties).filter(\n (key) => !this._options.excludeProperties.includes(key)\n );\n\n if (propertyKeys.length === 0) {\n html += '<div class=\"maplibre-gl-inspect-empty\">No properties</div>';\n } else {\n html += '<table class=\"maplibre-gl-inspect-properties\">';\n for (const key of propertyKeys) {\n const value = properties[key];\n const formattedValue = this._formatPropertyValue(value);\n const valueClass = value === null || value === undefined ? 'value null' : 'value';\n html += `\n <tr>\n <td class=\"key\">${this._escapeHtml(key)}</td>\n <td class=\"${valueClass}\">${formattedValue}</td>\n </tr>\n `;\n }\n html += '</table>';\n }\n\n html += '</div>';\n\n return html;\n }\n\n /**\n * Formats geometry type for display.\n */\n private _formatGeometryType(type: string): string {\n // Remove \"Multi\" prefix for cleaner display\n return type.replace('Multi', '');\n }\n\n /**\n * Formats a property value for display.\n */\n private _formatPropertyValue(value: unknown): string {\n if (value === null || value === undefined) {\n return '<em>N/A</em>';\n }\n\n if (typeof value === 'boolean') {\n return value ? 'Yes' : 'No';\n }\n\n if (typeof value === 'number') {\n // Format numbers with appropriate precision\n if (Number.isInteger(value)) {\n return this._escapeHtml(value.toLocaleString());\n }\n return this._escapeHtml(value.toFixed(4));\n }\n\n if (typeof value === 'string') {\n // Check if it looks like a date\n if (/^\\d{4}-\\d{2}-\\d{2}/.test(value)) {\n try {\n const date = new Date(value);\n if (!isNaN(date.getTime())) {\n return this._escapeHtml(date.toLocaleString());\n }\n } catch {\n // Not a valid date, continue\n }\n }\n\n // Truncate long strings\n if (value.length > 100) {\n return this._escapeHtml(value.substring(0, 100)) + '...';\n }\n\n return this._escapeHtml(value);\n }\n\n if (typeof value === 'object') {\n // For arrays and objects, show JSON\n try {\n const json = JSON.stringify(value, null, 2);\n if (json.length > 200) {\n return `<pre>${this._escapeHtml(json.substring(0, 200))}...</pre>`;\n }\n return `<pre>${this._escapeHtml(json)}</pre>`;\n } catch {\n return '[Object]';\n }\n }\n\n return this._escapeHtml(String(value));\n }\n\n /**\n * Escapes HTML special characters.\n */\n private _escapeHtml(str: string): string {\n const div = document.createElement('div');\n div.textContent = str;\n return div.innerHTML;\n }\n\n /**\n * Checks zoom visibility and updates display state.\n */\n private _checkZoomVisibility(): void {\n if (!this._map) return;\n const zoom = this._map.getZoom();\n const { minzoom, maxzoom } = this._options;\n const inRange = zoom >= minzoom && zoom <= maxzoom;\n\n if (inRange !== this._zoomVisible) {\n this._zoomVisible = inRange;\n this._updateDisplayState();\n }\n }\n\n /**\n * Updates the display state based on visibility settings.\n */\n private _updateDisplayState(): void {\n if (!this._container) return;\n const shouldShow = this._state.visible && this._zoomVisible;\n this._container.style.display = shouldShow ? 'block' : 'none';\n }\n}\n","import '../styles/common.css';\nimport '../styles/view-state.css';\nimport type { IControl, Map as MapLibreMap, MapMouseEvent, GeoJSONSource } from 'maplibre-gl';\nimport type {\n ViewStateControlOptions,\n ViewStateControlState,\n ViewStateEvent,\n ViewStateEventHandler,\n} from './types';\nimport { generateId } from '../utils/helpers';\n\n/**\n * Default options for the ViewStateControl.\n */\nconst DEFAULT_OPTIONS: Required<ViewStateControlOptions> = {\n position: 'bottom-left',\n className: '',\n visible: true,\n collapsed: true,\n precision: 4,\n showCenter: true,\n showBounds: true,\n showZoom: true,\n showPitch: true,\n showBearing: true,\n enableBBox: false,\n bboxFillColor: 'rgba(0, 120, 215, 0.1)',\n bboxStrokeColor: '#0078d7',\n bboxStrokeWidth: 2,\n panelWidth: 280,\n backgroundColor: 'rgba(255, 255, 255, 0.95)',\n borderRadius: 4,\n opacity: 1,\n fontSize: 12,\n fontColor: '#333',\n minzoom: 0,\n maxzoom: 24,\n};\n\n/**\n * SVG icon for the view state button (crosshair/target).\n */\nconst VIEWSTATE_ICON = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"3\"/><line x1=\"12\" y1=\"2\" x2=\"12\" y2=\"6\"/><line x1=\"12\" y1=\"18\" x2=\"12\" y2=\"22\"/><line x1=\"2\" y1=\"12\" x2=\"6\" y2=\"12\"/><line x1=\"18\" y1=\"12\" x2=\"22\" y2=\"12\"/></svg>`;\n\n/**\n * SVG icon for copy button.\n */\nconst COPY_ICON = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\"/><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"/></svg>`;\n\n/**\n * SVG checkmark icon for copy feedback.\n */\nconst CHECK_ICON = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#22c55e\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"20 6 9 17 4 12\"/></svg>`;\n\n/**\n * SVG icon for bbox draw button.\n */\nconst BBOX_ICON = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"1\" stroke-dasharray=\"4 2\"/></svg>`;\n\n/**\n * A control that displays live map view state (center, bounds, zoom, pitch, bearing)\n * and optionally supports drawing a bounding box to get bbox coordinates.\n *\n * @example\n * ```typescript\n * const viewStateControl = new ViewStateControl({\n * collapsed: false,\n * enableBBox: true,\n * precision: 4,\n * });\n * map.addControl(viewStateControl, 'bottom-left');\n *\n * viewStateControl.on('bboxdraw', (event) => {\n * console.log('Drawn bbox:', event.bbox);\n * });\n * ```\n */\nexport class ViewStateControl implements IControl {\n private _container?: HTMLElement;\n private _button?: HTMLButtonElement;\n private _panel?: HTMLElement;\n private _options: Required<ViewStateControlOptions>;\n private _state: ViewStateControlState;\n private _eventHandlers: Map<ViewStateEvent, Set<ViewStateEventHandler>> = new Map();\n private _map?: MapLibreMap;\n private _handleZoom?: () => void;\n private _zoomVisible: boolean = true;\n\n // DOM references for live updates\n private _centerValueEl?: HTMLElement;\n private _boundsValueEl?: HTMLElement;\n private _zoomValueEl?: HTMLElement;\n private _pitchValueEl?: HTMLElement;\n private _bearingValueEl?: HTMLElement;\n\n // Move handler for live updates\n private _boundMoveHandler?: () => void;\n\n // BBox drawing state\n private _bboxSourceId: string = '';\n private _bboxLayerFillId: string = '';\n private _bboxLayerLineId: string = '';\n private _bboxDrawStart?: { lng: number; lat: number };\n private _boundBBoxMouseDown?: (e: MapMouseEvent) => void;\n private _boundBBoxMouseMove?: (e: MouseEvent) => void;\n private _boundBBoxMouseUp?: (e: MouseEvent) => void;\n private _boundBBoxDragStart?: (e: DragEvent) => void;\n private _bboxToggleBtn?: HTMLButtonElement;\n private _bboxResultEl?: HTMLElement;\n\n /**\n * Creates a new ViewStateControl instance.\n *\n * @param options - Configuration options for the control.\n */\n constructor(options?: ViewStateControlOptions) {\n this._options = { ...DEFAULT_OPTIONS, ...options };\n this._state = {\n visible: this._options.visible,\n collapsed: this._options.collapsed,\n center: [0, 0],\n bounds: [0, 0, 0, 0],\n zoom: 0,\n pitch: 0,\n bearing: 0,\n drawingBBox: false,\n drawnBBox: null,\n };\n const uid = generateId('viewstate');\n this._bboxSourceId = `${uid}-bbox-src`;\n this._bboxLayerFillId = `${uid}-bbox-fill`;\n this._bboxLayerLineId = `${uid}-bbox-line`;\n }\n\n /**\n * Called when the control is added to the map.\n *\n * @param map - The MapLibre GL map instance.\n * @returns The control's container element.\n */\n onAdd(map: MapLibreMap): HTMLElement {\n this._map = map;\n this._readMapState();\n this._container = this._createContainer();\n\n // Set up zoom listener\n this._handleZoom = () => this._checkZoomVisibility();\n this._map.on('zoom', this._handleZoom);\n this._checkZoomVisibility();\n\n // Set up move listener for live updates\n this._boundMoveHandler = () => this._onMapMove();\n this._map.on('move', this._boundMoveHandler);\n\n return this._container;\n }\n\n /**\n * Called when the control is removed from the map.\n */\n onRemove(): void {\n if (this._map) {\n if (this._handleZoom) {\n this._map.off('zoom', this._handleZoom);\n this._handleZoom = undefined;\n }\n if (this._boundMoveHandler) {\n this._map.off('move', this._boundMoveHandler);\n this._boundMoveHandler = undefined;\n }\n if (this._state.drawingBBox) {\n this._stopBBoxDrawing();\n }\n this._removeBBoxLayers();\n }\n this._map = undefined;\n this._container?.parentNode?.removeChild(this._container);\n this._container = undefined;\n this._button = undefined;\n this._panel = undefined;\n this._centerValueEl = undefined;\n this._boundsValueEl = undefined;\n this._zoomValueEl = undefined;\n this._pitchValueEl = undefined;\n this._bearingValueEl = undefined;\n this._bboxToggleBtn = undefined;\n this._bboxResultEl = undefined;\n this._eventHandlers.clear();\n }\n\n /**\n * Expands the info panel.\n */\n expand(): void {\n if (this._state.collapsed) {\n this._state.collapsed = false;\n this._updatePanelVisibility();\n this._updateButtonState();\n this._emit('expand');\n }\n }\n\n /**\n * Collapses the info panel.\n */\n collapse(): void {\n if (!this._state.collapsed) {\n this._state.collapsed = true;\n this._updatePanelVisibility();\n this._updateButtonState();\n this._emit('collapse');\n }\n }\n\n /**\n * Toggles the panel expanded/collapsed state.\n */\n toggle(): void {\n if (this._state.collapsed) {\n this.expand();\n } else {\n this.collapse();\n }\n }\n\n /**\n * Returns whether the panel is collapsed.\n */\n isCollapsed(): boolean {\n return this._state.collapsed;\n }\n\n /**\n * Shows the control.\n */\n show(): void {\n if (!this._state.visible) {\n this._state.visible = true;\n this._updateDisplayState();\n this._emit('show');\n }\n }\n\n /**\n * Hides the control.\n */\n hide(): void {\n if (this._state.visible) {\n this._state.visible = false;\n this._updateDisplayState();\n this._emit('hide');\n }\n }\n\n /**\n * Returns a copy of the current state.\n */\n getState(): ViewStateControlState {\n return { ...this._state };\n }\n\n /**\n * Starts bounding box drawing mode.\n */\n startBBoxDraw(): void {\n if (!this._options.enableBBox || this._state.drawingBBox) return;\n this._state.drawingBBox = true;\n this._setupBBoxListeners();\n this._updateBBoxToggleState();\n this._emit('drawstart');\n }\n\n /**\n * Stops bounding box drawing mode.\n */\n stopBBoxDraw(): void {\n if (!this._state.drawingBBox) return;\n this._stopBBoxDrawing();\n this._emit('drawend');\n }\n\n /**\n * Clears the drawn bounding box.\n */\n clearBBox(): void {\n this._state.drawnBBox = null;\n this._removeBBoxLayers();\n this._updateBBoxResult();\n this._emit('bboxclear');\n }\n\n /**\n * Updates the control options.\n */\n update(options: Partial<ViewStateControlOptions>): void {\n Object.assign(this._options, options);\n if (options.visible !== undefined) {\n this._state.visible = options.visible;\n this._updateDisplayState();\n }\n if (options.collapsed !== undefined) {\n this._state.collapsed = options.collapsed;\n this._updatePanelVisibility();\n this._updateButtonState();\n }\n if (options.panelWidth !== undefined && this._panel) {\n this._panel.style.width = `${options.panelWidth}px`;\n }\n this._emit('update');\n }\n\n /**\n * Registers an event handler.\n */\n on(event: ViewStateEvent, handler: ViewStateEventHandler): void {\n if (!this._eventHandlers.has(event)) {\n this._eventHandlers.set(event, new Set());\n }\n this._eventHandlers.get(event)!.add(handler);\n }\n\n /**\n * Removes an event handler.\n */\n off(event: ViewStateEvent, handler: ViewStateEventHandler): void {\n this._eventHandlers.get(event)?.delete(handler);\n }\n\n /**\n * Emits an event to all registered handlers.\n */\n private _emit(event: ViewStateEvent, bbox?: [number, number, number, number]): void {\n const handlers = this._eventHandlers.get(event);\n if (handlers) {\n handlers.forEach((handler) =>\n handler({\n type: event,\n state: this.getState(),\n bbox,\n })\n );\n }\n }\n\n /**\n * Reads the current map state into internal state.\n */\n private _readMapState(): void {\n if (!this._map) return;\n const center = this._map.getCenter();\n const bounds = this._map.getBounds();\n this._state.center = [center.lng, center.lat];\n this._state.bounds = [\n bounds.getWest(),\n bounds.getSouth(),\n bounds.getEast(),\n bounds.getNorth(),\n ];\n this._state.zoom = this._map.getZoom();\n this._state.pitch = this._map.getPitch();\n this._state.bearing = this._map.getBearing();\n }\n\n /**\n * Handles map move events for live updates.\n */\n private _onMapMove(): void {\n this._readMapState();\n this._updateValues();\n this._emit('viewchange');\n }\n\n /**\n * Updates the DOM value elements with current state.\n */\n private _updateValues(): void {\n const p = this._options.precision;\n if (this._centerValueEl) {\n this._centerValueEl.textContent = `${this._state.center[0].toFixed(p)}, ${this._state.center[1].toFixed(p)}`;\n }\n if (this._boundsValueEl) {\n const b = this._state.bounds;\n this._boundsValueEl.textContent = `${b[0].toFixed(p)}, ${b[1].toFixed(p)}, ${b[2].toFixed(p)}, ${b[3].toFixed(p)}`;\n }\n if (this._zoomValueEl) {\n this._zoomValueEl.textContent = this._state.zoom.toFixed(2);\n }\n if (this._pitchValueEl) {\n this._pitchValueEl.textContent = `${this._state.pitch.toFixed(1)}°`;\n }\n if (this._bearingValueEl) {\n this._bearingValueEl.textContent = `${this._state.bearing.toFixed(1)}°`;\n }\n }\n\n /**\n * Creates the control container with button and panel.\n */\n private _createContainer(): HTMLElement {\n const container = document.createElement('div');\n container.className = `maplibregl-ctrl maplibregl-ctrl-group maplibre-gl-view-state ${this._options.className}`.trim();\n\n if (this._options.backgroundColor) {\n container.style.backgroundColor = this._options.backgroundColor;\n }\n if (this._options.borderRadius) {\n container.style.borderRadius = `${this._options.borderRadius}px`;\n }\n if (this._options.opacity !== undefined && this._options.opacity !== 1) {\n container.style.opacity = String(this._options.opacity);\n }\n\n // Create button\n this._button = document.createElement('button');\n this._button.type = 'button';\n this._button.className = 'maplibre-gl-view-state-button';\n this._button.title = 'View map state';\n this._button.innerHTML = VIEWSTATE_ICON;\n this._button.addEventListener('click', () => this.toggle());\n container.appendChild(this._button);\n\n // Create panel\n this._panel = this._createPanel();\n container.appendChild(this._panel);\n\n // Set initial states\n container.style.display = this._state.visible ? 'block' : 'none';\n this._updatePanelVisibility();\n this._updateButtonState();\n\n return container;\n }\n\n /**\n * Creates the expandable info panel.\n */\n private _createPanel(): HTMLElement {\n const panel = document.createElement('div');\n panel.className = 'maplibre-gl-view-state-panel';\n panel.style.width = `${this._options.panelWidth}px`;\n\n if (this._options.fontSize) {\n panel.style.fontSize = `${this._options.fontSize}px`;\n }\n if (this._options.fontColor) {\n panel.style.color = this._options.fontColor;\n }\n\n // Header\n const header = document.createElement('div');\n header.className = 'maplibre-gl-view-state-header';\n header.textContent = 'View State';\n panel.appendChild(header);\n\n const p = this._options.precision;\n\n // Center row\n if (this._options.showCenter) {\n const { row, valueEl } = this._createRow(\n 'Center',\n `${this._state.center[0].toFixed(p)}, ${this._state.center[1].toFixed(p)}`,\n );\n this._centerValueEl = valueEl;\n panel.appendChild(row);\n }\n\n // Bounds row\n if (this._options.showBounds) {\n const b = this._state.bounds;\n const { row, valueEl } = this._createRow(\n 'Bounds',\n `${b[0].toFixed(p)}, ${b[1].toFixed(p)}, ${b[2].toFixed(p)}, ${b[3].toFixed(p)}`,\n );\n this._boundsValueEl = valueEl;\n panel.appendChild(row);\n }\n\n // Zoom row\n if (this._options.showZoom) {\n const { row, valueEl } = this._createRow('Zoom', this._state.zoom.toFixed(2));\n this._zoomValueEl = valueEl;\n panel.appendChild(row);\n }\n\n // Pitch row\n if (this._options.showPitch) {\n const { row, valueEl } = this._createRow('Pitch', `${this._state.pitch.toFixed(1)}°`);\n this._pitchValueEl = valueEl;\n panel.appendChild(row);\n }\n\n // Bearing row\n if (this._options.showBearing) {\n const { row, valueEl } = this._createRow('Bearing', `${this._state.bearing.toFixed(1)}°`);\n this._bearingValueEl = valueEl;\n panel.appendChild(row);\n }\n\n // BBox section\n if (this._options.enableBBox) {\n panel.appendChild(this._createBBoxSection());\n }\n\n return panel;\n }\n\n /**\n * Creates a labeled data row with a copy button.\n */\n private _createRow(label: string, value: string): { row: HTMLElement; valueEl: HTMLElement } {\n const row = document.createElement('div');\n row.className = 'maplibre-gl-view-state-row';\n\n const labelEl = document.createElement('span');\n labelEl.className = 'maplibre-gl-view-state-label';\n labelEl.textContent = label;\n\n const valueEl = document.createElement('span');\n valueEl.className = 'maplibre-gl-view-state-value';\n valueEl.textContent = value;\n\n const copyBtn = document.createElement('button');\n copyBtn.type = 'button';\n copyBtn.className = 'maplibre-gl-view-state-copy';\n copyBtn.title = `Copy ${label.toLowerCase()}`;\n copyBtn.innerHTML = COPY_ICON;\n copyBtn.addEventListener('click', (e) => {\n e.stopPropagation();\n this._copyToClipboard(valueEl.textContent || '', copyBtn);\n });\n\n row.appendChild(labelEl);\n row.appendChild(valueEl);\n row.appendChild(copyBtn);\n\n return { row, valueEl };\n }\n\n /**\n * Creates the bounding box drawing section.\n */\n private _createBBoxSection(): HTMLElement {\n const section = document.createElement('div');\n section.className = 'maplibre-gl-view-state-bbox-section';\n\n // Draw toggle button\n this._bboxToggleBtn = document.createElement('button');\n this._bboxToggleBtn.type = 'button';\n this._bboxToggleBtn.className = 'maplibre-gl-view-state-bbox-toggle';\n this._bboxToggleBtn.innerHTML = `${BBOX_ICON} Draw BBox`;\n this._bboxToggleBtn.addEventListener('click', () => {\n if (this._state.drawingBBox) {\n this.stopBBoxDraw();\n } else {\n this.startBBoxDraw();\n }\n });\n section.appendChild(this._bboxToggleBtn);\n\n // Result container (initially hidden)\n this._bboxResultEl = document.createElement('div');\n this._bboxResultEl.className = 'maplibre-gl-view-state-bbox-result';\n this._bboxResultEl.style.display = 'none';\n section.appendChild(this._bboxResultEl);\n\n return section;\n }\n\n /**\n * Updates the bbox result display.\n */\n private _updateBBoxResult(): void {\n if (!this._bboxResultEl) return;\n\n if (!this._state.drawnBBox) {\n this._bboxResultEl.style.display = 'none';\n return;\n }\n\n this._bboxResultEl.style.display = 'block';\n const b = this._state.drawnBBox;\n const p = this._options.precision;\n const bboxStr = `${b[0].toFixed(p)}, ${b[1].toFixed(p)}, ${b[2].toFixed(p)}, ${b[3].toFixed(p)}`;\n\n this._bboxResultEl.innerHTML = '';\n\n const valueDiv = document.createElement('div');\n valueDiv.className = 'maplibre-gl-view-state-bbox-value';\n valueDiv.textContent = bboxStr;\n this._bboxResultEl.appendChild(valueDiv);\n\n const actionsDiv = document.createElement('div');\n actionsDiv.className = 'maplibre-gl-view-state-bbox-actions';\n\n // Copy button\n const copyBtn = document.createElement('button');\n copyBtn.type = 'button';\n copyBtn.className = 'maplibre-gl-view-state-bbox-action';\n copyBtn.innerHTML = `${COPY_ICON} Copy`;\n copyBtn.addEventListener('click', () => {\n this._copyToClipboard(bboxStr, copyBtn);\n });\n actionsDiv.appendChild(copyBtn);\n\n // Clear button\n const clearBtn = document.createElement('button');\n clearBtn.type = 'button';\n clearBtn.className = 'maplibre-gl-view-state-bbox-action maplibre-gl-view-state-bbox-action--clear';\n clearBtn.textContent = 'Clear';\n clearBtn.addEventListener('click', () => this.clearBBox());\n actionsDiv.appendChild(clearBtn);\n\n this._bboxResultEl.appendChild(actionsDiv);\n }\n\n /**\n * Copies text to clipboard and shows feedback on the button.\n */\n private _copyToClipboard(text: string, btn: HTMLButtonElement): void {\n navigator.clipboard.writeText(text).then(() => {\n const originalHtml = btn.innerHTML;\n btn.innerHTML = CHECK_ICON;\n setTimeout(() => {\n btn.innerHTML = originalHtml;\n }, 1000);\n }).catch(() => {\n // Fallback: select the text\n });\n }\n\n /**\n * Updates the panel visibility based on collapsed state.\n */\n private _updatePanelVisibility(): void {\n if (this._panel) {\n if (this._state.collapsed) {\n this._panel.classList.remove('maplibre-gl-view-state-panel--visible');\n } else {\n this._panel.classList.add('maplibre-gl-view-state-panel--visible');\n }\n }\n }\n\n /**\n * Updates the button's active state appearance.\n */\n private _updateButtonState(): void {\n if (this._button) {\n if (!this._state.collapsed) {\n this._button.classList.add('maplibre-gl-view-state-button--active');\n this._button.title = 'Hide view state';\n } else {\n this._button.classList.remove('maplibre-gl-view-state-button--active');\n this._button.title = 'View map state';\n }\n }\n }\n\n /**\n * Updates the bbox toggle button state.\n */\n private _updateBBoxToggleState(): void {\n if (this._bboxToggleBtn) {\n if (this._state.drawingBBox) {\n this._bboxToggleBtn.classList.add('maplibre-gl-view-state-bbox-toggle--active');\n this._bboxToggleBtn.innerHTML = `${BBOX_ICON} Cancel Draw`;\n } else {\n this._bboxToggleBtn.classList.remove('maplibre-gl-view-state-bbox-toggle--active');\n this._bboxToggleBtn.innerHTML = `${BBOX_ICON} Draw BBox`;\n }\n }\n }\n\n /**\n * Converts a native MouseEvent to map lng/lat using map.unproject().\n */\n private _mouseEventToLngLat(e: MouseEvent): { lng: number; lat: number } {\n const canvas = this._map!.getCanvas();\n const rect = canvas.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const y = e.clientY - rect.top;\n const lngLat = this._map!.unproject([x, y]);\n return { lng: lngLat.lng, lat: lngLat.lat };\n }\n\n /**\n * Sets up mouse listeners for bbox drawing.\n */\n private _setupBBoxListeners(): void {\n if (!this._map) return;\n\n const canvas = this._map.getCanvas();\n canvas.style.cursor = 'crosshair';\n this._map.dragPan.disable();\n this._map.boxZoom.disable();\n\n this._boundBBoxMouseDown = (e: MapMouseEvent) => this._onBBoxMouseDown(e);\n this._map.on('mousedown', this._boundBBoxMouseDown);\n\n // Prevent native drag behavior on the canvas, which can swallow mousemove/mouseup events.\n this._boundBBoxDragStart = (e: DragEvent) => e.preventDefault();\n canvas.addEventListener('dragstart', this._boundBBoxDragStart);\n }\n\n /**\n * Removes bbox drawing listeners and restores map state.\n */\n private _stopBBoxDrawing(): void {\n if (!this._map) return;\n\n const canvas = this._map.getCanvas();\n canvas.style.cursor = '';\n this._map.dragPan.enable();\n this._map.boxZoom.enable();\n\n if (this._boundBBoxMouseDown) {\n this._map.off('mousedown', this._boundBBoxMouseDown);\n this._boundBBoxMouseDown = undefined;\n }\n if (this._boundBBoxMouseMove) {\n document.removeEventListener('mousemove', this._boundBBoxMouseMove);\n this._boundBBoxMouseMove = undefined;\n }\n if (this._boundBBoxMouseUp) {\n document.removeEventListener('mouseup', this._boundBBoxMouseUp);\n this._boundBBoxMouseUp = undefined;\n }\n if (this._boundBBoxDragStart) {\n canvas.removeEventListener('dragstart', this._boundBBoxDragStart);\n this._boundBBoxDragStart = undefined;\n }\n\n this._bboxDrawStart = undefined;\n this._state.drawingBBox = false;\n this._updateBBoxToggleState();\n }\n\n /**\n * Handles mouse down for bbox drawing start.\n */\n private _onBBoxMouseDown(e: MapMouseEvent): void {\n if (!this._map) return;\n e.preventDefault();\n e.originalEvent.preventDefault();\n e.originalEvent.stopPropagation();\n\n const lng = e.lngLat.lng;\n const lat = e.lngLat.lat;\n this._bboxDrawStart = { lng, lat };\n\n // Remove any existing bbox layers before drawing a new one\n this._removeBBoxLayers();\n\n // Initialize source with a degenerate polygon at the click point\n const pt: [number, number] = [lng, lat];\n this._map.addSource(this._bboxSourceId, {\n type: 'geojson',\n data: {\n type: 'Feature',\n geometry: { type: 'Polygon', coordinates: [[pt, pt, pt, pt, pt]] },\n properties: {},\n },\n });\n\n this._map.addLayer({\n id: this._bboxLayerFillId,\n type: 'fill',\n source: this._bboxSourceId,\n paint: {\n 'fill-color': this._options.bboxFillColor,\n 'fill-opacity': 1,\n },\n });\n\n this._map.addLayer({\n id: this._bboxLayerLineId,\n type: 'line',\n source: this._bboxSourceId,\n paint: {\n 'line-color': this._options.bboxStrokeColor,\n 'line-width': this._options.bboxStrokeWidth,\n },\n });\n\n // Use native DOM events on document for mousemove/mouseup — MapLibre's\n // map events do not fire reliably during a button-held drag when dragPan\n // is disabled, because the browser may initiate a native drag on the canvas.\n this._boundBBoxMouseMove = (ev: MouseEvent) => this._onBBoxMouseMove(ev);\n this._boundBBoxMouseUp = (ev: MouseEvent) => this._onBBoxMouseUp(ev);\n document.addEventListener('mousemove', this._boundBBoxMouseMove);\n document.addEventListener('mouseup', this._boundBBoxMouseUp);\n }\n\n /**\n * Handles mouse move during bbox drawing.\n */\n private _onBBoxMouseMove(e: MouseEvent): void {\n if (!this._map || !this._bboxDrawStart) return;\n\n const start = this._bboxDrawStart;\n const current = this._mouseEventToLngLat(e);\n const coords = [\n [start.lng, start.lat],\n [current.lng, start.lat],\n [current.lng, current.lat],\n [start.lng, current.lat],\n [start.lng, start.lat],\n ];\n\n const source = this._map.getSource(this._bboxSourceId) as GeoJSONSource | undefined;\n if (source) {\n source.setData({\n type: 'Feature',\n geometry: { type: 'Polygon', coordinates: [coords] },\n properties: {},\n });\n }\n }\n\n /**\n * Handles mouse up to complete bbox drawing.\n */\n private _onBBoxMouseUp(e: MouseEvent): void {\n if (!this._map || !this._bboxDrawStart) return;\n\n const start = this._bboxDrawStart;\n const end = this._mouseEventToLngLat(e);\n\n // Normalize to [west, south, east, north]\n const west = Math.min(start.lng, end.lng);\n const south = Math.min(start.lat, end.lat);\n const east = Math.max(start.lng, end.lng);\n const north = Math.max(start.lat, end.lat);\n\n this._state.drawnBBox = [west, south, east, north];\n this._updateBBoxResult();\n\n // Update the source with the final rectangle so it remains visible\n const coords = [\n [west, south],\n [east, south],\n [east, north],\n [west, north],\n [west, south],\n ];\n const source = this._map.getSource(this._bboxSourceId) as GeoJSONSource | undefined;\n if (source) {\n source.setData({\n type: 'Feature',\n geometry: { type: 'Polygon', coordinates: [coords] },\n properties: {},\n });\n }\n\n // Stop drawing mode\n this._stopBBoxDrawing();\n\n this._emit('bboxdraw', this._state.drawnBBox);\n this._emit('drawend');\n }\n\n /**\n * Removes bbox layers and source from the map.\n */\n private _removeBBoxLayers(): void {\n if (!this._map) return;\n\n if (this._map.getLayer(this._bboxLayerFillId)) {\n this._map.removeLayer(this._bboxLayerFillId);\n }\n if (this._map.getLayer(this._bboxLayerLineId)) {\n this._map.removeLayer(this._bboxLayerLineId);\n }\n if (this._map.getSource(this._bboxSourceId)) {\n this._map.removeSource(this._bboxSourceId);\n }\n }\n\n /**\n * Checks zoom visibility and updates display state.\n */\n private _checkZoomVisibility(): void {\n if (!this._map) return;\n const zoom = this._map.getZoom();\n const { minzoom, maxzoom } = this._options;\n const inRange = zoom >= minzoom && zoom <= maxzoom;\n\n if (inRange !== this._zoomVisible) {\n this._zoomVisible = inRange;\n this._updateDisplayState();\n }\n }\n\n /**\n * Updates the display state based on visibility settings.\n */\n private _updateDisplayState(): void {\n if (!this._container) return;\n const shouldShow = this._state.visible && this._zoomVisible;\n this._container.style.display = shouldShow ? 'block' : 'none';\n }\n}\n","import '../styles/common.css';\nimport '../styles/control-grid.css';\nimport { GlobeControl, type IControl, type Map as MapLibreMap } from 'maplibre-gl';\nimport type {\n ControlGridOptions,\n ControlGridState,\n ControlGridEvent,\n ControlGridEventHandler,\n DefaultControlName,\n} from './types';\nimport { TerrainControl } from './Terrain';\nimport { SearchControl } from './SearchControl';\nimport { ViewStateControl } from './ViewStateControl';\nimport { InspectControl } from './InspectControl';\nimport { VectorDatasetControl } from './VectorDataset';\nimport { BasemapControl } from './Basemap';\n\n/**\n * Default options for the ControlGrid.\n */\nconst DEFAULT_OPTIONS: Required<\n Omit<ControlGridOptions, 'controls' | 'defaultControls'>\n> & { controls?: IControl[]; defaultControls?: DefaultControlName[] } = {\n title: '',\n position: 'top-right',\n className: '',\n visible: true,\n collapsible: true,\n collapsed: true,\n rows: 1,\n columns: 3,\n showRowColumnControls: true,\n controls: [],\n backgroundColor: 'rgba(255, 255, 255, 0.9)',\n padding: 10,\n borderRadius: 4,\n opacity: 1,\n gap: 6,\n minzoom: 0,\n maxzoom: 24,\n};\n\n/** Wrench icon SVG for collapsed state – stroke style matching MapLibre globe icon. */\nconst WRENCH_ICON = `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#333\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z\"/></svg>`;\n\ninterface ChildEntry {\n control: IControl;\n element: HTMLElement | null;\n}\n\n/**\n * A collapsible grid container for MapLibre IControl instances.\n *\n * Hosts multiple controls (e.g. SearchControl, TerrainControl) in a grid layout.\n * Users can configure rows/columns and dynamically add or remove controls.\n *\n * @example\n * ```typescript\n * const grid = new ControlGrid({\n * title: 'Map Tools',\n * rows: 2,\n * columns: 2,\n * collapsible: true,\n * });\n * grid.addControl(new TerrainControl());\n * grid.addControl(new SearchControl());\n * map.addControl(grid, 'top-right');\n * ```\n */\nexport class ControlGrid implements IControl {\n private _container?: HTMLElement;\n private _gridEl?: HTMLElement;\n private _options: Required<Omit<ControlGridOptions, 'controls' | 'defaultControls'>> & { controls?: IControl[]; defaultControls?: DefaultControlName[] };\n private _state: ControlGridState;\n private _children: ChildEntry[] = [];\n private _eventHandlers: Map<ControlGridEvent, Set<ControlGridEventHandler>> = new Map();\n private _map?: MapLibreMap;\n private _handleZoom?: () => void;\n private _zoomVisible: boolean = true;\n\n constructor(options?: ControlGridOptions) {\n this._options = { ...DEFAULT_OPTIONS, ...options };\n this._state = {\n visible: this._options.visible,\n collapsed: this._options.collapsed,\n rows: this._options.rows,\n columns: this._options.columns,\n };\n // Add explicitly passed controls\n const initial = options?.controls ?? this._options.controls ?? [];\n initial.forEach((c) => this._children.push({ control: c, element: null }));\n\n // Create and add built-in default controls\n const defaults = options?.defaultControls ?? [];\n for (const name of defaults) {\n const ctrl = ControlGrid._createDefaultControl(name);\n if (ctrl) this._children.push({ control: ctrl, element: null });\n }\n this._autoGrowRows();\n }\n\n private static _createDefaultControl(name: DefaultControlName): IControl | null {\n switch (name) {\n case 'globe': return new GlobeControl();\n case 'terrain': return new TerrainControl({ hillshade: true });\n case 'search': return new SearchControl({ collapsed: true });\n case 'viewState': return new ViewStateControl({ collapsed: true });\n case 'inspect': return new InspectControl();\n case 'vectorDataset': return new VectorDatasetControl();\n case 'basemap': return new BasemapControl({ collapsed: true });\n default: return null;\n }\n }\n\n onAdd(map: MapLibreMap): HTMLElement {\n this._map = map;\n this._container = this._createContainer();\n\n this._handleZoom = () => this._checkZoomVisibility();\n this._map.on('zoom', this._handleZoom);\n this._checkZoomVisibility();\n\n this._render();\n this._mountChildren();\n\n return this._container;\n }\n\n onRemove(): void {\n if (this._map && this._handleZoom) {\n this._map.off('zoom', this._handleZoom);\n this._handleZoom = undefined;\n }\n this._unmountChildren();\n this._map = undefined;\n this._container?.parentNode?.removeChild(this._container);\n this._container = undefined;\n this._gridEl = undefined;\n this._children = [];\n this._eventHandlers.clear();\n }\n\n /**\n * Add a control to the grid. If the control is already on the map, it is mounted into the grid.\n */\n addControl(control: IControl): void {\n if (this._children.some((e) => e.control === control)) return;\n const entry: ChildEntry = { control, element: null };\n this._children.push(entry);\n this._autoGrowRows();\n if (this._map && this._gridEl) {\n entry.element = control.onAdd(this._map);\n this._gridEl.appendChild(entry.element);\n }\n this._emit('controladd', control);\n }\n\n /**\n * Remove a control from the grid. The control's onRemove is called.\n */\n removeControl(control: IControl): void {\n const index = this._children.findIndex((e) => e.control === control);\n if (index === -1) return;\n const entry = this._children[index];\n if (entry.element?.parentNode) {\n entry.element.parentNode.removeChild(entry.element);\n }\n if (this._map) control.onRemove(this._map);\n this._children.splice(index, 1);\n this._emit('controlremove', control);\n }\n\n /**\n * Set the number of grid rows.\n */\n setRows(rows: number): void {\n const n = Math.max(1, Math.min(12, Math.round(rows)));\n if (this._state.rows === n) return;\n this._state.rows = n;\n this._applyGridStyle();\n this._emit('update');\n }\n\n /**\n * Set the number of grid columns.\n */\n setColumns(columns: number): void {\n const n = Math.max(1, Math.min(12, Math.round(columns)));\n if (this._state.columns === n) return;\n this._state.columns = n;\n this._applyGridStyle();\n this._emit('update');\n }\n\n /**\n * Get the list of controls currently in the grid.\n */\n getControls(): IControl[] {\n return this._children.map((e) => e.control);\n }\n\n show(): void {\n if (!this._state.visible) {\n this._state.visible = true;\n this._updateDisplayState();\n this._emit('show');\n }\n }\n\n hide(): void {\n if (this._state.visible) {\n this._state.visible = false;\n this._updateDisplayState();\n this._emit('hide');\n }\n }\n\n expand(): void {\n if (this._state.collapsed) {\n this._state.collapsed = false;\n this._render();\n this._emit('expand');\n }\n }\n\n collapse(): void {\n if (!this._state.collapsed) {\n this._state.collapsed = true;\n this._render();\n this._emit('collapse');\n }\n }\n\n toggle(): void {\n if (this._state.collapsed) this.expand();\n else this.collapse();\n }\n\n getState(): ControlGridState {\n return { ...this._state };\n }\n\n update(options: Partial<ControlGridOptions>): void {\n this._options = { ...this._options, ...options };\n if (options.visible !== undefined) this._state.visible = options.visible;\n if (options.collapsed !== undefined) this._state.collapsed = options.collapsed;\n if (options.rows !== undefined) this._state.rows = Math.max(1, Math.min(12, options.rows));\n if (options.columns !== undefined)\n this._state.columns = Math.max(1, Math.min(12, options.columns));\n this._render();\n this._emit('update');\n }\n\n on(event: ControlGridEvent, handler: ControlGridEventHandler): void {\n if (!this._eventHandlers.has(event)) {\n this._eventHandlers.set(event, new Set());\n }\n this._eventHandlers.get(event)!.add(handler);\n }\n\n off(event: ControlGridEvent, handler: ControlGridEventHandler): void {\n this._eventHandlers.get(event)?.delete(handler);\n }\n\n private _emit(event: ControlGridEvent, control?: IControl): void {\n const handlers = this._eventHandlers.get(event);\n if (handlers) {\n const payload = { type: event, state: this.getState(), control };\n handlers.forEach((h) => h(payload));\n }\n }\n\n private _checkZoomVisibility(): void {\n if (!this._map) return;\n const zoom = this._map.getZoom();\n const { minzoom, maxzoom } = this._options;\n const inRange = zoom >= minzoom && zoom <= maxzoom;\n if (inRange !== this._zoomVisible) {\n this._zoomVisible = inRange;\n this._updateDisplayState();\n }\n }\n\n private _updateDisplayState(): void {\n if (!this._container) return;\n const shouldShow = this._state.visible && this._zoomVisible;\n this._container.style.display = shouldShow ? 'block' : 'none';\n }\n\n private _createContainer(): HTMLElement {\n const container = document.createElement('div');\n container.className = `maplibregl-ctrl maplibre-gl-control-grid${\n this._options.className ? ` ${this._options.className}` : ''\n }`;\n const shouldShow = this._state.visible && this._zoomVisible;\n if (!shouldShow) container.style.display = 'none';\n return container;\n }\n\n private _autoGrowRows(): void {\n const capacity = this._state.rows * this._state.columns;\n if (this._children.length > capacity) {\n this._state.rows = Math.ceil(this._children.length / this._state.columns);\n this._applyGridStyle();\n }\n }\n\n private _applyGridStyle(): void {\n if (!this._gridEl) return;\n if (this._state.collapsed) {\n this._gridEl.style.display = 'none';\n return;\n }\n const gap = this._options.gap;\n this._gridEl.style.display = 'grid';\n this._gridEl.style.gridTemplateColumns = `repeat(${this._state.columns}, auto)`;\n this._gridEl.style.gridTemplateRows = `repeat(${this._state.rows}, auto)`;\n this._gridEl.style.gap = `${gap}px`;\n // Center grid tracks and controls to balance left/right padding when the header is wider.\n this._gridEl.style.width = '100%';\n this._gridEl.style.justifyContent = 'center';\n this._gridEl.style.alignContent = 'center';\n this._gridEl.style.justifyItems = 'center';\n this._gridEl.style.alignItems = 'center';\n }\n\n private _mountChildren(): void {\n if (!this._map || !this._gridEl) return;\n this._children.forEach((entry) => {\n if (entry.element) {\n if (entry.element.parentNode !== this._gridEl) {\n this._gridEl!.appendChild(entry.element);\n }\n } else {\n entry.element = entry.control.onAdd(this._map!);\n this._gridEl!.appendChild(entry.element);\n }\n });\n }\n\n private _unmountChildren(): void {\n const map = this._map;\n this._children.forEach((entry) => {\n if (entry.element?.parentNode) {\n entry.element.parentNode.removeChild(entry.element);\n }\n if (map) entry.control.onRemove(map);\n });\n this._children = this._children.map((e) => ({ control: e.control, element: null }));\n }\n\n private _render(): void {\n if (!this._container) return;\n\n const {\n title,\n collapsible,\n backgroundColor,\n opacity,\n borderRadius,\n padding,\n showRowColumnControls,\n } = this._options;\n\n this._container.innerHTML = '';\n\n if (this._state.collapsed) {\n this._container.classList.add('maplibre-gl-control-grid--collapsed');\n } else {\n this._container.classList.remove('maplibre-gl-control-grid--collapsed');\n }\n\n const isCollapsedWithHeader = this._state.collapsed && (title || collapsible);\n const vertPadding = isCollapsedWithHeader ? 0 : padding;\n const leftPadding = isCollapsedWithHeader ? 0 : padding;\n const rightPadding = isCollapsedWithHeader ? 0 : Math.max(0, padding - 4);\n const shouldShow = this._state.visible && this._zoomVisible;\n\n Object.assign(this._container.style, {\n backgroundColor,\n opacity: String(opacity),\n borderRadius: `${borderRadius}px`,\n padding: `${vertPadding}px ${rightPadding}px ${vertPadding}px ${leftPadding}px`,\n boxShadow: '0 0 0 2px rgba(0, 0, 0, 0.1)',\n display: shouldShow ? 'block' : 'none',\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n color: '#1a1a1a',\n });\n\n if (collapsible || title) {\n const header = document.createElement('div');\n header.className = 'maplibre-gl-control-grid-header';\n Object.assign(header.style, {\n display: 'flex',\n alignItems: 'center',\n justifyContent: this._state.collapsed ? 'center' : 'space-between',\n flexWrap: 'wrap',\n gap: '6px',\n paddingBottom: this._state.collapsed ? '0' : '0',\n cursor: collapsible ? 'pointer' : 'default',\n });\n\n if (this._state.collapsed && collapsible) {\n // Collapsed: show only a square wrench icon (no grid, no title)\n const iconWrap = document.createElement('span');\n iconWrap.className = 'maplibre-gl-control-grid-wrench';\n iconWrap.innerHTML = WRENCH_ICON;\n Object.assign(iconWrap.style, {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '29px',\n height: '29px',\n lineHeight: '0',\n boxSizing: 'border-box',\n });\n iconWrap.setAttribute('aria-label', 'Map tools');\n header.appendChild(iconWrap);\n header.addEventListener('click', () => this.toggle());\n } else {\n // Expanded: title, row/column inputs, toggle arrow\n const left = document.createElement('div');\n left.style.display = 'flex';\n left.style.alignItems = 'center';\n left.style.gap = '6px';\n\n if (title) {\n const titleEl = document.createElement('span');\n titleEl.className = 'maplibre-gl-control-grid-title';\n titleEl.textContent = title;\n titleEl.style.fontWeight = '600';\n titleEl.style.color = '#333';\n left.appendChild(titleEl);\n }\n\n if (showRowColumnControls && !this._state.collapsed) {\n const rowLabel = document.createElement('label');\n rowLabel.style.display = 'inline-flex';\n rowLabel.style.alignItems = 'center';\n rowLabel.style.gap = '2px';\n rowLabel.style.fontSize = '11px';\n rowLabel.style.color = '#333';\n rowLabel.innerHTML = 'R:';\n const rowInput = document.createElement('input');\n rowInput.type = 'number';\n rowInput.min = '1';\n rowInput.max = '12';\n rowInput.value = String(this._state.rows);\n rowInput.style.width = '40px';\n rowInput.style.padding = '2px 2px';\n rowInput.style.boxSizing = 'border-box';\n rowInput.style.textAlign = 'center';\n rowInput.style.color = '#333';\n rowInput.addEventListener('change', () => this.setRows(Number(rowInput.value) || 1));\n rowLabel.appendChild(rowInput);\n\n const colLabel = document.createElement('label');\n colLabel.style.display = 'inline-flex';\n colLabel.style.alignItems = 'center';\n colLabel.style.gap = '2px';\n colLabel.style.fontSize = '11px';\n colLabel.style.color = '#333';\n colLabel.innerHTML = 'C:';\n const colInput = document.createElement('input');\n colInput.type = 'number';\n colInput.min = '1';\n colInput.max = '12';\n colInput.value = String(this._state.columns);\n colInput.style.width = '40px';\n colInput.style.padding = '2px 2px';\n colInput.style.boxSizing = 'border-box';\n colInput.style.textAlign = 'center';\n colInput.style.color = '#333';\n colInput.addEventListener('change', () => this.setColumns(Number(colInput.value) || 1));\n colLabel.appendChild(colInput);\n\n left.appendChild(rowLabel);\n left.appendChild(colLabel);\n }\n\n header.appendChild(left);\n\n if (collapsible) {\n const toggleBtn = document.createElement('span');\n toggleBtn.className = 'maplibre-gl-control-grid-toggle';\n toggleBtn.innerHTML = '▼';\n Object.assign(toggleBtn.style, { fontSize: '10px', userSelect: 'none', color: '#333' });\n header.appendChild(toggleBtn);\n header.addEventListener('click', (ev) => {\n if (!showRowColumnControls || !left.contains(ev.target as Node)) this.toggle();\n });\n }\n }\n\n this._container.appendChild(header);\n }\n\n const content = document.createElement('div');\n content.className = 'maplibre-gl-control-grid-content';\n Object.assign(content.style, {\n display: this._state.collapsed ? 'none' : 'block',\n });\n this._gridEl = content;\n this._applyGridStyle();\n this._container.appendChild(content);\n\n this._mountChildren();\n }\n}\n"],"names":["DEFAULT_OPTIONS"],"mappings":"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"}
|