zenit-sdk 0.1.8 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/react/ZenitMap.tsx","../src/maps/helpers.ts","../src/engine/LayerStateEngine.ts","../src/react/layerStyleHelpers.ts","../src/react/zoomOpacity.ts","../src/react/map/layer-geojson.tsx","../src/react/map/geojson-sanitize.ts","../src/react/map/location-control.tsx","../src/react/hooks/use-geolocation.ts","../src/react/map/map-utils.ts","../src/config/modalWhitelist.ts","../src/react/map/map-handlers.tsx","../src/react/ZenitLayerManager.tsx","../src/react/icons.tsx","../src/react/ui/ZenitSelect.tsx","../src/react/ui/ZenitCombobox.tsx","../src/react/ZenitFeatureFilterPanel.tsx","../src/react/ai/FloatingChatBox.tsx","../src/react/hooks/use-chat.ts","../src/ai/chat.service.ts","../src/react/components/MarkdownRenderer.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState, forwardRef } from 'react';\r\nimport { MapContainer, Marker, TileLayer, ZoomControl } from 'react-leaflet';\r\nimport L, { LatLngBoundsExpression, PathOptions } from 'leaflet';\r\nimport type { ZenitClient } from '../config/ZenitSdkConfig';\r\nimport type { Bbox, GeoJsonFeatureCollection, LayerDto } from '../layers/types';\r\nimport type { MapDto, MapLayerConfig } from '../maps/types';\r\nimport {\r\n centroidFromBBox,\r\n computeBBoxFromFeature,\r\n extractMapDto,\r\n normalizeMapCenter,\r\n normalizeMapLayers,\r\n} from '../maps/helpers';\r\nimport type { EffectiveLayerState, LayerOverrideState } from '../engine/LayerStateEngine';\r\nimport { applyLayerOverrides, initLayerStates, resetOverrides } from '../engine/LayerStateEngine';\r\nimport { getStyleByLayerId, type LayerStyle } from './layerStyleHelpers';\r\nimport { clampOpacity } from './zoomOpacity';\r\nimport { LayerGeoJson } from './map/layer-geojson';\r\nimport { LocationControl } from './map/location-control';\r\nimport { BBoxZoomHandler, MapInstanceBridge, MapInvalidator, ZoomBasedOpacityHandler } from './map/map-handlers';\r\nimport {\r\n calculateZoomBasedOpacity,\r\n createCustomIcon,\r\n createPopupContent,\r\n ensurePopupStyles,\r\n getPopupDimensions,\r\n layerStyleToLeaflet,\r\n} from './map/map-utils';\r\n\r\nexport interface LayerSnapshot {\r\n layerId: number | string;\r\n visible: boolean;\r\n opacity: number;\r\n}\r\n\r\nexport interface ZenitMapRef {\r\n setLayerOpacity: (layerId: number | string, opacity: number) => void;\r\n setLayerVisibility: (layerId: number | string, visible: boolean) => void;\r\n fitBounds: (bbox: Bbox, options?: { padding?: [number, number]; animate?: boolean }) => void;\r\n fitToBbox: (bbox: Bbox, padding?: number) => void;\r\n fitToGeoJson: (fc: GeoJsonFeatureCollection, padding?: number) => void;\r\n setView: (coordinates: { lat: number; lon: number }, zoom?: number) => void;\r\n getLayerSnapshot: () => LayerSnapshot[];\r\n restoreLayerSnapshot: (snapshot: LayerSnapshot[]) => void;\r\n highlightFeature: (layerId: number | string, featureId?: number | string) => void;\r\n updateLayerGeoJson: (layerId: number | string, featureCollection: GeoJsonFeatureCollection) => void;\r\n restoreLayerGeoJson: (layerId: number | string) => void;\r\n getMapInstance: () => L.Map | null;\r\n}\r\n\r\nexport interface ZenitMapProps {\r\n client: ZenitClient;\r\n mapId: number;\r\n height?: string;\r\n width?: string;\r\n initialZoom?: number;\r\n initialCenter?: [number, number];\r\n showLayerPanel?: boolean;\r\n overlayGeojson?: GeoJsonFeatureCollection | null;\r\n overlayStyle?: PathOptions;\r\n layerControls?: Array<{ layerId: number | string; visible?: boolean; opacity?: number }>;\r\n layerStates?: EffectiveLayerState[];\r\n layerGeojson?: Record<string | number, GeoJsonFeatureCollection | null | undefined>;\r\n onLayerStateChange?: (states: EffectiveLayerState[]) => void;\r\n onError?: (error: unknown, ctx: 'map') => void;\r\n onLoadingChange?: (ctx: 'map', loading: boolean) => void;\r\n onFeatureClick?: (feature: any, layerId?: number | string) => void;\r\n onFeatureHover?: (feature: any, layerId?: number | string) => void;\r\n featureInfoMode?: 'popup' | 'none';\r\n mapLayers?: Array<{\r\n layerId: number | string;\r\n style?: LayerStyle | null;\r\n }>;\r\n zoomToBbox?: Bbox | null;\r\n zoomToGeojson?: GeoJsonFeatureCollection | null;\r\n onZoomChange?: (zoom: number) => void;\r\n onMapReady?: (map: L.Map) => void;\r\n}\r\n\r\ntype MapLayerWithId = MapLayerConfig & { layerId: number | string };\r\n\r\ninterface LayerState {\r\n mapLayer: MapLayerWithId;\r\n layer?: LayerDto;\r\n displayOrder: number;\r\n effective?: EffectiveLayerState;\r\n}\r\n\r\nconst DEFAULT_CENTER: [number, number] = [0, 0];\r\nconst DEFAULT_ZOOM = 3;\r\nconst LABELS_PANE_NAME = 'zenit-labels-pane';\r\nconst DEV_MODE = typeof process !== 'undefined' && process.env.NODE_ENV !== 'production';\r\n\r\nfunction isRecord(value: unknown): value is Record<string, unknown> {\r\n return typeof value === 'object' && value !== null;\r\n}\r\n\r\nfunction isGeoJsonFeatureCollection(value: unknown): value is GeoJsonFeatureCollection {\r\n if (!isRecord(value)) return false;\r\n const features = value.features;\r\n if (!Array.isArray(features)) return false;\r\n const type = value.type;\r\n return type === undefined || type === 'FeatureCollection';\r\n}\r\n\r\nfunction extractGeoJsonFeatureCollection(value: unknown): GeoJsonFeatureCollection | null {\r\n if (isRecord(value) && 'data' in value) {\r\n const data = value.data;\r\n return isGeoJsonFeatureCollection(data) ? data : null;\r\n }\r\n return isGeoJsonFeatureCollection(value) ? value : null;\r\n}\r\n\r\nfunction getFeatureLayerId(feature?: { properties?: Record<string, unknown> }): number | string | null {\r\n const layerId =\r\n (feature?.properties as { __zenit_layerId?: number | string })?.__zenit_layerId ??\r\n (feature?.properties as { layerId?: number | string })?.layerId ??\r\n (feature?.properties as { layer_id?: number | string })?.layer_id;\r\n\r\n if (layerId === undefined || layerId === null) return null;\r\n return layerId;\r\n}\r\n\r\nconst DESCRIPTION_KEYS = new Set(['descripcion', 'description']);\r\nconst POINT_GEOMETRY_TYPES = new Set(['Point', 'MultiPoint']);\r\nconst POLYGON_GEOMETRY_TYPES = new Set(['Polygon', 'MultiPolygon']);\r\ntype ClickIntent = 'point' | 'polygon' | 'unknown';\r\n\r\nfunction normalizeDescriptionValue(value: unknown): string | null {\r\n if (value === undefined || value === null) return null;\r\n if (typeof value === 'string') {\r\n const trimmed = value.trim();\r\n return trimmed ? trimmed : null;\r\n }\r\n if (typeof value === 'number' || typeof value === 'boolean') {\r\n return String(value);\r\n }\r\n return null;\r\n}\r\n\r\nfunction extractDescriptionValue(properties?: Record<string, unknown>): string | null {\r\n if (!properties) return null;\r\n const matches = Object.entries(properties).find(([key]) =>\r\n DESCRIPTION_KEYS.has(key.toLowerCase())\r\n );\r\n if (!matches) return null;\r\n return normalizeDescriptionValue(matches[1]);\r\n}\r\n\r\nfunction normalizeLayerId(value: number | string | null | undefined): string | null {\r\n if (value === null || value === undefined) return null;\r\n const normalized = String(value).trim();\r\n return normalized ? normalized : null;\r\n}\r\n\r\nfunction isLayerIdMatch(a: number | string | null | undefined, b: number | string | null | undefined): boolean {\r\n const normalizedA = normalizeLayerId(a);\r\n const normalizedB = normalizeLayerId(b);\r\n return normalizedA !== null && normalizedB !== null && normalizedA === normalizedB;\r\n}\r\n\r\nfunction getClickIntent(params: { feature?: any; leafletLayer?: any }): ClickIntent {\r\n const geometryType = (params.feature as { geometry?: { type?: string } } | undefined)?.geometry?.type;\r\n if (geometryType && POINT_GEOMETRY_TYPES.has(geometryType)) return 'point';\r\n if (params.leafletLayer instanceof L.Marker) return 'point';\r\n if (geometryType && POLYGON_GEOMETRY_TYPES.has(geometryType)) return 'polygon';\r\n if (params.leafletLayer instanceof L.Path) return 'polygon';\r\n return 'unknown';\r\n}\r\n\r\nfunction candidateLayerId(candidate: any): number | string | null {\r\n return getFeatureLayerId(candidate as { properties?: Record<string, unknown> });\r\n}\r\n\r\nfunction isCandidateGeometryType(candidate: any, allowedTypes: Set<string>): boolean {\r\n const geometryType = (candidate as { geometry?: { type?: string } } | undefined)?.geometry?.type;\r\n return Boolean(geometryType && allowedTypes.has(geometryType));\r\n}\r\n\r\n\r\nfunction getFeatureStyleOverrides(feature?: any): LayerStyle | null {\r\n const candidate = feature?.properties?._style;\r\n if (!candidate || typeof candidate !== 'object' || Array.isArray(candidate)) return null;\r\n\r\n const styleCandidate = candidate as Partial<LayerStyle>;\r\n return {\r\n color: styleCandidate.color,\r\n weight: styleCandidate.weight,\r\n fillColor: styleCandidate.fillColor,\r\n fillOpacity: styleCandidate.fillOpacity,\r\n };\r\n}\r\n\r\nfunction buildFeaturePopupHtml(feature?: any): string | null {\r\n const properties = feature?.properties as Record<string, unknown> | undefined;\r\n if (!properties) return null;\r\n\r\n const rendered = createPopupContent(properties);\r\n return rendered ? rendered : null;\r\n}\r\n\r\nfunction pickIntersectFeature(params: {\r\n baseFeature: any;\r\n candidates: any[];\r\n expectedLayerId?: number | string;\r\n clickIntent: ClickIntent;\r\n}): { feature: any | null; selectedIdx: number; reason: string } | null {\r\n const { baseFeature, candidates, expectedLayerId, clickIntent } = params;\r\n if (!Array.isArray(candidates) || candidates.length === 0) return null;\r\n\r\n const pickByGeometry = (pool: any[], intent: ClickIntent) => {\r\n const preferredTypes = intent === 'point' ? POINT_GEOMETRY_TYPES : intent === 'polygon' ? POLYGON_GEOMETRY_TYPES : null;\r\n if (!preferredTypes) return null;\r\n const found = pool.find((candidate) => isCandidateGeometryType(candidate, preferredTypes));\r\n if (!found) return null;\r\n return { feature: found, reason: `geometry:${intent}` };\r\n };\r\n\r\n const getResult = (feature: any, reason: string) => ({\r\n feature,\r\n selectedIdx: candidates.findIndex((candidate) => candidate === feature),\r\n reason,\r\n });\r\n\r\n if (clickIntent === 'point') {\r\n const anyPoint = candidates.find((c) =>\r\n isCandidateGeometryType(c, POINT_GEOMETRY_TYPES)\r\n );\r\n if (anyPoint) {\r\n return getResult(anyPoint, 'point:first-point-geometry');\r\n }\r\n }\r\n\r\n const sameLayer = candidates.filter((candidate) =>\r\n isLayerIdMatch(candidateLayerId(candidate), expectedLayerId)\r\n );\r\n\r\n const geometryFromSameLayer = pickByGeometry(sameLayer, clickIntent);\r\n if (geometryFromSameLayer?.feature) {\r\n return getResult(geometryFromSameLayer.feature, `sameLayer>${geometryFromSameLayer.reason}`);\r\n }\r\n\r\n if (sameLayer.length > 0) {\r\n const sameLayerWithDescription = sameLayer.find((candidate) =>\r\n extractDescriptionValue(candidate?.properties)\r\n );\r\n if (sameLayerWithDescription) {\r\n return getResult(sameLayerWithDescription, 'sameLayer>description');\r\n }\r\n }\r\n\r\n const geometryFallback = pickByGeometry(candidates, clickIntent);\r\n if (geometryFallback?.feature) {\r\n return getResult(geometryFallback.feature, `anyLayer>${geometryFallback.reason}`);\r\n }\r\n\r\n const baseId = baseFeature?.id;\r\n if (baseId !== undefined && baseId !== null) {\r\n const matchById = candidates.find((candidate) => candidate?.id === baseId);\r\n if (matchById) return getResult(matchById, 'fallback>baseId');\r\n }\r\n\r\n const matchWithDescription = candidates.find((candidate) =>\r\n extractDescriptionValue(candidate?.properties)\r\n );\r\n if (matchWithDescription) return getResult(matchWithDescription, 'fallback>description');\r\n return getResult(candidates[0], 'fallback>first');\r\n}\r\n\r\n// ✅ center puede ser tuple o objeto, normalizamos a tuple siempre\r\ntype CenterInput = [number, number] | { lat: number; lon: number };\r\n\r\nfunction normalizeCenterTuple(center: unknown): [number, number] | null {\r\n if (!center) return null;\r\n\r\n if (Array.isArray(center) && center.length >= 2) {\r\n const lat = center[0];\r\n const lon = center[1];\r\n if (typeof lat === 'number' && typeof lon === 'number') return [lat, lon];\r\n return null;\r\n }\r\n\r\n const maybeObj = center as Partial<{ lat: unknown; lon: unknown }>;\r\n if (typeof maybeObj.lat === 'number' && typeof maybeObj.lon === 'number') {\r\n return [maybeObj.lat, maybeObj.lon];\r\n }\r\n\r\n return null;\r\n}\r\n\r\nexport const ZenitMap = forwardRef<ZenitMapRef, ZenitMapProps>(({\r\n client,\r\n mapId,\r\n height = '500px',\r\n width = '100%',\r\n initialZoom,\r\n initialCenter,\r\n showLayerPanel = true,\r\n overlayGeojson,\r\n overlayStyle,\r\n layerControls,\r\n layerStates,\r\n layerGeojson,\r\n onLayerStateChange,\r\n onError,\r\n onLoadingChange,\r\n onFeatureClick,\r\n onFeatureHover,\r\n featureInfoMode = 'popup',\r\n mapLayers,\r\n zoomToBbox,\r\n zoomToGeojson,\r\n onZoomChange,\r\n onMapReady,\r\n}, ref) => {\r\n const [map, setMap] = useState<MapDto | null>(null);\r\n const [layers, setLayers] = useState<LayerState[]>([]);\r\n const [effectiveStates, setEffectiveStates] = useState<EffectiveLayerState[]>([]);\r\n const [loadingMap, setLoadingMap] = useState(false);\r\n const [mapError, setMapError] = useState<string | null>(null);\r\n const [mapInstance, setMapInstance] = useState<L.Map | null>(null);\r\n const [layerGeojsonOverrides, setLayerGeojsonOverrides] = useState<Record<string, GeoJsonFeatureCollection | null>>({});\r\n const originalGeojsonByLayerIdRef = useRef<Record<string, GeoJsonFeatureCollection>>({});\r\n const [panesReady, setPanesReady] = useState(false);\r\n const [currentZoom, setCurrentZoom] = useState<number>(initialZoom ?? DEFAULT_ZOOM);\r\n const [isPopupOpen, setIsPopupOpen] = useState(false);\r\n const [isMobile, setIsMobile] = useState<boolean>(() => {\r\n if (typeof window === 'undefined') return false;\r\n return window.matchMedia('(max-width: 768px)').matches;\r\n });\r\n const normalizedLayers = useMemo(() => normalizeMapLayers(map), [map]);\r\n\r\n useEffect(() => {\r\n if (typeof window === 'undefined') return;\r\n\r\n const mql = window.matchMedia('(max-width: 768px)');\r\n\r\n const onChange = (e: MediaQueryListEvent) => {\r\n setIsMobile(e.matches);\r\n };\r\n\r\n setIsMobile(mql.matches);\r\n\r\n if (typeof mql.addEventListener === 'function') {\r\n mql.addEventListener('change', onChange);\r\n return () => mql.removeEventListener('change', onChange);\r\n }\r\n\r\n const legacy = mql as any;\r\n if (typeof legacy.addListener === 'function') {\r\n legacy.addListener(onChange);\r\n return () => legacy.removeListener(onChange);\r\n }\r\n\r\n return;\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (featureInfoMode === 'popup') {\r\n ensurePopupStyles();\r\n }\r\n }, [featureInfoMode]);\r\n\r\n useEffect(() => {\r\n if (featureInfoMode !== 'popup') {\r\n setIsPopupOpen(false);\r\n }\r\n }, [featureInfoMode]);\r\n\r\n useEffect(() => {\r\n if (!mapInstance) return;\r\n\r\n const popupPane = mapInstance.getPane('popupPane');\r\n if (popupPane) {\r\n popupPane.style.zIndex = '800';\r\n }\r\n\r\n const labelsPane = mapInstance.getPane(LABELS_PANE_NAME) ?? mapInstance.createPane(LABELS_PANE_NAME);\r\n labelsPane.style.zIndex = '600';\r\n }, [mapInstance]);\r\n\r\n useEffect(() => {\r\n if (!mapInstance) return;\r\n\r\n const handlePopupOpen = () => setIsPopupOpen(true);\r\n const handlePopupClose = () => setIsPopupOpen(false);\r\n\r\n mapInstance.on('popupopen', handlePopupOpen);\r\n mapInstance.on('popupclose', handlePopupClose);\r\n\r\n return () => {\r\n mapInstance.off('popupopen', handlePopupOpen);\r\n mapInstance.off('popupclose', handlePopupClose);\r\n };\r\n }, [mapInstance]);\r\n\r\n const layerStyleIndex = useMemo(() => {\r\n const index = new Map<string, LayerStyle>();\r\n\r\n (map?.mapLayers ?? []).forEach((entry) => {\r\n const layerStyle =\r\n (entry as { layer?: { style?: LayerStyle | null } }).layer?.style ??\r\n (entry as { mapLayer?: { layer?: { style?: LayerStyle | null } } }).mapLayer?.layer?.style ??\r\n (entry as { style?: LayerStyle | null }).style ??\r\n null;\r\n\r\n const layerId =\r\n (entry as { layerId?: number | string }).layerId ??\r\n (entry as { mapLayer?: { layerId?: number | string; layer?: { id?: number | string } } }).mapLayer\r\n ?.layerId ??\r\n (entry as { mapLayer?: { layer?: { id?: number | string } } }).mapLayer?.layer?.id ??\r\n (entry as { layer?: { id?: number | string } }).layer?.id;\r\n\r\n if (layerId !== undefined && layerId !== null && layerStyle) {\r\n index.set(String(layerId), layerStyle);\r\n }\r\n });\r\n\r\n return index;\r\n }, [map]);\r\n\r\n const labelKeyIndex = useMemo(() => {\r\n const index = new Map<string, string>();\r\n\r\n normalizedLayers.forEach((entry) => {\r\n const label =\r\n (entry.layer as { label?: string } | undefined)?.label ??\r\n (entry.mapLayer as { label?: string } | undefined)?.label ??\r\n (entry.mapLayer.layerConfig as { label?: string } | undefined)?.label;\r\n\r\n if (typeof label === 'string' && label.trim().length > 0) {\r\n index.set(String(entry.layerId), label);\r\n }\r\n });\r\n\r\n return index;\r\n }, [normalizedLayers]);\r\n\r\n const layerMetaIndex = useMemo(() => {\r\n const index = new Map<string, { layerType?: string; geometryType?: string }>();\r\n\r\n normalizedLayers.forEach((entry) => {\r\n index.set(String(entry.layerId), {\r\n layerType:\r\n typeof entry.layer?.layerType === 'string'\r\n ? entry.layer.layerType\r\n : typeof (entry.mapLayer as { layerType?: string }).layerType === 'string'\r\n ? (entry.mapLayer as { layerType?: string }).layerType\r\n : undefined,\r\n geometryType:\r\n typeof entry.layer?.geometryType === 'string'\r\n ? entry.layer.geometryType\r\n : typeof (entry.mapLayer.layerConfig as { geometryType?: string } | undefined)?.geometryType === 'string'\r\n ? (entry.mapLayer.layerConfig as { geometryType?: string }).geometryType\r\n : undefined,\r\n });\r\n });\r\n\r\n return index;\r\n }, [normalizedLayers]);\r\n\r\n const overlayStyleFunction = useMemo(() => {\r\n return (feature?: any): PathOptions => {\r\n const featureLayerId = getFeatureLayerId(feature);\r\n const featureStyleOverrides = getFeatureStyleOverrides(feature);\r\n\r\n let style: LayerStyle | null = null;\r\n\r\n if (featureLayerId !== null) {\r\n style =\r\n getStyleByLayerId(featureLayerId, mapLayers) ??\r\n layerStyleIndex.get(String(featureLayerId)) ??\r\n null;\r\n }\r\n\r\n const resolvedStyle: LayerStyle | null = featureStyleOverrides\r\n ? { ...(style ?? {}), ...featureStyleOverrides }\r\n : style;\r\n\r\n const defaultOptions: PathOptions = {\r\n color: resolvedStyle?.color ?? resolvedStyle?.fillColor ?? '#2563eb',\r\n weight: resolvedStyle?.weight ?? 2,\r\n fillColor: resolvedStyle?.fillColor ?? resolvedStyle?.color ?? '#2563eb',\r\n fillOpacity: resolvedStyle?.fillOpacity ?? 0.15,\r\n ...(overlayStyle ?? {}),\r\n };\r\n\r\n return defaultOptions;\r\n };\r\n }, [layerStyleIndex, mapLayers, overlayStyle]);\r\n\r\n const overlayStyleFn = useCallback(\r\n (feature: any, _layerType?: string, _baseOpacity?: number) => overlayStyleFunction(feature),\r\n [overlayStyleFunction]\r\n );\r\n\r\n const [baseStates, setBaseStates] = useState<EffectiveLayerState[]>([]);\r\n const [mapOverrides, setMapOverrides] = useState<LayerOverrideState[]>([]);\r\n const [controlOverrides, setControlOverrides] = useState<LayerOverrideState[]>([]);\r\n const [uiOverrides, setUiOverrides] = useState<LayerOverrideState[]>([]);\r\n\r\n useEffect(() => {\r\n let isMounted = true;\r\n setLoadingMap(true);\r\n setMapError(null);\r\n onLoadingChange?.('map', true);\r\n\r\n client.maps\r\n .getMap(mapId, true)\r\n .then((mapResponse) => {\r\n if (!isMounted) return;\r\n const extracted = extractMapDto(mapResponse);\r\n const resolved = extracted ? normalizeMapCenter(extracted) : null;\r\n setMap(resolved);\r\n })\r\n .catch((err: unknown) => {\r\n if (!isMounted) return;\r\n setMapError(err instanceof Error ? err.message : 'No se pudo obtener el mapa');\r\n onError?.(err, 'map');\r\n })\r\n .finally(() => {\r\n if (!isMounted) return;\r\n setLoadingMap(false);\r\n onLoadingChange?.('map', false);\r\n });\r\n\r\n return () => {\r\n isMounted = false;\r\n };\r\n }, [client.maps, mapId, onError, onLoadingChange]);\r\n\r\n useEffect(() => {\r\n if (normalizedLayers.length === 0) {\r\n setLayers([]);\r\n setBaseStates([]);\r\n setMapOverrides([]);\r\n setUiOverrides([]);\r\n return;\r\n }\r\n\r\n const nextLayers: LayerState[] = normalizedLayers.map((entry) => ({\r\n mapLayer: { ...entry.mapLayer, layerId: entry.layerId } as MapLayerWithId,\r\n layer: entry.layer,\r\n displayOrder: entry.displayOrder,\r\n }));\r\n\r\n const base = initLayerStates(\r\n normalizedLayers.map((entry) => ({\r\n ...entry.mapLayer,\r\n layerId: entry.layerId,\r\n opacity: entry.opacity,\r\n isVisible: entry.isVisible,\r\n })) as MapLayerWithId[]\r\n );\r\n\r\n const initialOverrides: LayerOverrideState[] = normalizedLayers.map((entry) => ({\r\n layerId: entry.layerId,\r\n overrideVisible: entry.isVisible,\r\n overrideOpacity: entry.opacity,\r\n }));\r\n\r\n setLayers(nextLayers);\r\n setBaseStates(base);\r\n setMapOverrides(initialOverrides);\r\n setUiOverrides([]);\r\n }, [normalizedLayers]);\r\n\r\n useEffect(() => {\r\n if (!layerControls) {\r\n setControlOverrides([]);\r\n return;\r\n }\r\n const overrides = layerControls.map((entry) => ({\r\n layerId: entry.layerId,\r\n overrideVisible: entry.visible,\r\n overrideOpacity: entry.opacity,\r\n }));\r\n setControlOverrides(overrides);\r\n }, [layerControls]);\r\n\r\n useEffect(() => {\r\n // Si layerStates se proporciona como prop, no sobrescribir\r\n if (layerStates) {\r\n return;\r\n }\r\n\r\n if (Array.isArray(layerControls) && layerControls.length === 0 && effectiveStates.length > 0) {\r\n const reset = resetOverrides(baseStates);\r\n setEffectiveStates(reset);\r\n onLayerStateChange?.(reset);\r\n }\r\n }, [baseStates, effectiveStates.length, layerControls, layerStates, onLayerStateChange]);\r\n\r\n useEffect(() => {\r\n if (layerStates) {\r\n setEffectiveStates(layerStates);\r\n }\r\n }, [layerStates]);\r\n\r\n useEffect(() => {\r\n // Si layerStates se proporciona como prop, no sobrescribir con baseStates\r\n // Esto permite que el componente padre controle completamente los estados\r\n if (layerStates) {\r\n return;\r\n }\r\n\r\n if (mapOverrides.length === 0 && controlOverrides.length === 0 && uiOverrides.length === 0) {\r\n setEffectiveStates(baseStates);\r\n return;\r\n }\r\n const combined = [...mapOverrides, ...controlOverrides, ...uiOverrides];\r\n const next = applyLayerOverrides(baseStates, combined);\r\n setEffectiveStates(next);\r\n onLayerStateChange?.(next);\r\n }, [baseStates, controlOverrides, layerStates, mapOverrides, onLayerStateChange, uiOverrides]);\r\n\r\n useEffect(() => {\r\n if (!Array.isArray(layerControls) || layerControls.length > 0) return;\r\n setUiOverrides([]);\r\n }, [layerControls]);\r\n\r\n useEffect(() => {\r\n // Si layerStates se proporciona como prop, no sobrescribir\r\n if (layerStates) {\r\n return;\r\n }\r\n\r\n if (!Array.isArray(layerControls) && effectiveStates.length > 0 && baseStates.length > 0) {\r\n const next = resetOverrides(baseStates);\r\n setEffectiveStates(next);\r\n onLayerStateChange?.(next);\r\n }\r\n }, [baseStates, effectiveStates.length, layerControls, layerStates, onLayerStateChange]);\r\n\r\n const upsertUiOverride = (layerId: number | string, patch: Partial<LayerOverrideState>) => {\r\n setUiOverrides((prev) => {\r\n const filtered = prev.filter((entry) => entry.layerId !== layerId);\r\n const nextEntry: LayerOverrideState = {\r\n layerId,\r\n ...patch,\r\n };\r\n return [...filtered, nextEntry];\r\n });\r\n };\r\n\r\n const updateOpacityFromUi = useCallback(\r\n (layerId: number | string, uiOpacity: number) => {\r\n const meta = layerMetaIndex.get(String(layerId));\r\n const baseOpacity = clampOpacity(uiOpacity);\r\n const effectiveOpacity = calculateZoomBasedOpacity(\r\n currentZoom,\r\n baseOpacity,\r\n meta?.layerType,\r\n meta?.geometryType\r\n );\r\n\r\n if (layerStates && onLayerStateChange) {\r\n const next = effectiveStates.map((state) =>\r\n state.layerId === layerId\r\n ? {\r\n ...state,\r\n baseOpacity,\r\n opacity: effectiveOpacity,\r\n overrideOpacity: uiOpacity,\r\n }\r\n : state\r\n );\r\n onLayerStateChange(next);\r\n return;\r\n }\r\n\r\n setBaseStates((prev) =>\r\n prev.map((state) => (state.layerId === layerId ? { ...state, baseOpacity } : state))\r\n );\r\n setUiOverrides((prev) => {\r\n const existing = prev.find((entry) => entry.layerId === layerId);\r\n const filtered = prev.filter((entry) => entry.layerId !== layerId);\r\n if (existing && existing.overrideVisible !== undefined) {\r\n return [\r\n ...filtered,\r\n { layerId, overrideVisible: existing.overrideVisible },\r\n ];\r\n }\r\n return filtered;\r\n });\r\n },\r\n [currentZoom, effectiveStates, layerMetaIndex, layerStates, onLayerStateChange]\r\n );\r\n\r\n const center = useMemo<[number, number]>(() => {\r\n if (initialCenter) {\r\n return initialCenter;\r\n }\r\n\r\n const normalized = normalizeCenterTuple(map?.settings?.center as unknown);\r\n if (normalized) {\r\n return normalized;\r\n }\r\n\r\n return DEFAULT_CENTER;\r\n }, [initialCenter, map?.settings?.center]);\r\n\r\n const zoom = initialZoom ?? map?.settings?.zoom ?? DEFAULT_ZOOM;\r\n\r\n useEffect(() => {\r\n setCurrentZoom(zoom);\r\n }, [zoom]);\r\n\r\n useEffect(() => {\r\n if (!layerGeojson) return;\r\n\r\n layers.forEach((layer) => {\r\n const layerKey = String(layer.mapLayer.layerId);\r\n const incoming =\r\n layerGeojson[layer.mapLayer.layerId] ??\r\n layerGeojson[layerKey] ??\r\n null;\r\n if (incoming && !originalGeojsonByLayerIdRef.current[layerKey]) {\r\n originalGeojsonByLayerIdRef.current[layerKey] = incoming;\r\n }\r\n });\r\n }, [layerGeojson, layers]);\r\n\r\n const decoratedLayers = useMemo(() => {\r\n return layers.map((layer) => {\r\n const layerKey = String(layer.mapLayer.layerId);\r\n const override = layerGeojsonOverrides[layerKey];\r\n return {\r\n ...layer,\r\n effective: effectiveStates.find((state) => state.layerId === layer.mapLayer.layerId),\r\n data:\r\n override ??\r\n layerGeojson?.[layer.mapLayer.layerId] ??\r\n layerGeojson?.[layerKey] ??\r\n null,\r\n };\r\n });\r\n }, [effectiveStates, layerGeojson, layerGeojsonOverrides, layers]);\r\n\r\n const orderedLayers = useMemo(() => {\r\n return [...decoratedLayers]\r\n .filter((layer) => layer.effective?.visible && layer.data)\r\n .sort((a, b) => a.displayOrder - b.displayOrder);\r\n }, [decoratedLayers]);\r\n\r\n const autoZoomGeojson = useMemo(\r\n () =>\r\n orderedLayers\r\n .map((layer) => layer.data)\r\n .filter((collection): collection is GeoJsonFeatureCollection => !!collection),\r\n [orderedLayers]\r\n );\r\n\r\n const resolveLayerStyle = useCallback(\r\n (layerId: number | string): LayerStyle | null => {\r\n return (\r\n getStyleByLayerId(layerId, mapLayers) ?? layerStyleIndex.get(String(layerId)) ?? null\r\n );\r\n },\r\n [layerStyleIndex, mapLayers]\r\n );\r\n\r\n const labelMarkers = useMemo(() => {\r\n const markers: Array<{\r\n key: string;\r\n position: [number, number];\r\n label: string;\r\n opacity: number;\r\n layerId: number | string;\r\n color: string;\r\n }> = [];\r\n\r\n decoratedLayers.forEach((layerState) => {\r\n if (!layerState.effective?.visible) return;\r\n\r\n const labelKey = labelKeyIndex.get(String(layerState.mapLayer.layerId));\r\n if (!labelKey) return;\r\n\r\n const data = layerState.data;\r\n if (!data) return;\r\n\r\n const resolvedStyle = resolveLayerStyle(layerState.mapLayer.layerId);\r\n const layerColor =\r\n resolvedStyle?.fillColor ?? resolvedStyle?.color ?? 'rgba(37, 99, 235, 1)';\r\n const meta = layerMetaIndex.get(String(layerState.mapLayer.layerId));\r\n const baseOpacity = layerState.effective?.baseOpacity ?? layerState.effective?.opacity ?? 1;\r\n const opacity = calculateZoomBasedOpacity(\r\n currentZoom,\r\n baseOpacity,\r\n meta?.layerType,\r\n meta?.geometryType\r\n );\r\n\r\n data.features.forEach((feature, index) => {\r\n const properties = feature.properties as Record<string, unknown> | undefined;\r\n const value = properties?.[labelKey];\r\n if (value === undefined || value === null || value === '') return;\r\n\r\n const bbox = computeBBoxFromFeature(feature);\r\n if (!bbox) return;\r\n\r\n const [lat, lng] = centroidFromBBox(bbox);\r\n markers.push({\r\n key: `${layerState.mapLayer.layerId}-label-${index}`,\r\n position: [lat, lng],\r\n label: String(value),\r\n opacity,\r\n layerId: layerState.mapLayer.layerId,\r\n color: layerColor,\r\n });\r\n });\r\n });\r\n\r\n return markers;\r\n }, [currentZoom, decoratedLayers, labelKeyIndex, layerMetaIndex, resolveLayerStyle]);\r\n\r\n const ensureLayerPanes = useCallback(\r\n (targetMap: L.Map, targetLayers: Array<{ layerId: number | string; displayOrder: number }>) => {\r\n const fillBaseZIndex = 400;\r\n const pointsBaseZIndex = 750;\r\n\r\n targetLayers.forEach((layer) => {\r\n const order = Number.isFinite(layer.displayOrder) ? layer.displayOrder : 0;\r\n const orderOffset = Math.max(0, Math.min(order, 150));\r\n const fillPaneName = `zenit-layer-${layer.layerId}-fill`;\r\n const pointPaneName = `zenit-layer-${layer.layerId}-points`;\r\n const fillPane = targetMap.getPane(fillPaneName) ?? targetMap.createPane(fillPaneName);\r\n const pointPane = targetMap.getPane(pointPaneName) ?? targetMap.createPane(pointPaneName);\r\n\r\n fillPane.style.zIndex = String(fillBaseZIndex + orderOffset);\r\n pointPane.style.zIndex = String(pointsBaseZIndex + orderOffset);\r\n });\r\n },\r\n []\r\n );\r\n\r\n const handleMapReady = useCallback(\r\n (instance: L.Map) => {\r\n setPanesReady(false);\r\n setMapInstance(instance);\r\n onMapReady?.(instance);\r\n // NO crear panes aquí, se hará en el useEffect\r\n },\r\n [onMapReady]\r\n );\r\n\r\n // Crear/actualizar panes cuando cambien orderedLayers\r\n useEffect(() => {\r\n // Si no hay instancia del mapa, resetear panesReady\r\n if (!mapInstance) {\r\n setPanesReady(false);\r\n return;\r\n }\r\n\r\n // Si no hay capas ordenadas y tampoco overlay, solo salir sin resetear panesReady\r\n if (orderedLayers.length === 0 && !overlayGeojson) {\r\n return;\r\n }\r\n\r\n const layerTargets = orderedLayers.map((layer) => ({\r\n layerId: layer.mapLayer.layerId,\r\n displayOrder: layer.displayOrder,\r\n }));\r\n if (overlayGeojson) {\r\n layerTargets.push({ layerId: 'overlay-geojson', displayOrder: 999 });\r\n }\r\n\r\n ensureLayerPanes(mapInstance, layerTargets);\r\n const first = layerTargets[0];\r\n const testPane = first ? mapInstance.getPane(`zenit-layer-${first.layerId}-fill`) : null;\r\n const labelsPane = mapInstance.getPane(LABELS_PANE_NAME);\r\n if (testPane && labelsPane) {\r\n setPanesReady(true);\r\n }\r\n }, [mapInstance, orderedLayers, overlayGeojson, ensureLayerPanes]);\r\n\r\n const overlayOnEachFeature = useCallback((feature: any, layer: any) => {\r\n const layerId = getFeatureLayerId(feature) ?? undefined;\r\n const geometryType = (feature as { geometry?: { type?: string } })?.geometry?.type;\r\n const clickIntent = getClickIntent({ feature, leafletLayer: layer });\r\n const isPointFeature = clickIntent === 'point';\r\n const originalStyle =\r\n layer instanceof L.Path\r\n ? {\r\n color: layer.options.color,\r\n weight: layer.options.weight,\r\n fillColor: layer.options.fillColor,\r\n opacity: layer.options.opacity,\r\n fillOpacity: layer.options.fillOpacity,\r\n }\r\n : null;\r\n const originalRadius =\r\n layer instanceof L.CircleMarker ? layer.getRadius() : null;\r\n\r\n if (featureInfoMode === 'popup') {\r\n const content = buildFeaturePopupHtml(feature);\r\n if (content) {\r\n const { maxWidth, minWidth, maxHeight } = getPopupDimensions();\r\n layer.bindPopup(content, {\r\n maxWidth,\r\n minWidth,\r\n maxHeight,\r\n className: 'custom-leaflet-popup',\r\n autoClose: true,\r\n closeOnClick: true,\r\n autoPan: true,\r\n closeButton: true,\r\n keepInView: true,\r\n autoPanPadding: [50, 50],\r\n });\r\n }\r\n }\r\n\r\n if (isPointFeature && layer.bindTooltip) {\r\n layer.bindTooltip('Click para ver detalle', {\r\n sticky: true,\r\n direction: 'top',\r\n opacity: 0.9,\r\n className: 'zenit-map-tooltip',\r\n });\r\n }\r\n\r\n layer.on('click', (e: L.LeafletMouseEvent) => {\r\n if (clickIntent === 'point') {\r\n L.DomEvent.stopPropagation(e);\r\n }\r\n if (\r\n featureInfoMode === 'popup' &&\r\n client &&\r\n layerId !== undefined &&\r\n !extractDescriptionValue(feature?.properties) &&\r\n feature?.geometry\r\n ) {\r\n if (DEV_MODE) {\r\n console.debug('[ZenitMap] click/intersect:start', {\r\n expectedLayerId: layerId,\r\n geometryType,\r\n clickIntent,\r\n leafletLayerType: layer?.constructor?.name,\r\n pane: (layer as { options?: { pane?: string } })?.options?.pane,\r\n });\r\n }\r\n\r\n const trackedFeature = feature as {\r\n __zenit_popup_loaded?: boolean;\r\n properties?: Record<string, unknown>;\r\n };\r\n if (!trackedFeature.__zenit_popup_loaded) {\r\n trackedFeature.__zenit_popup_loaded = true;\r\n client.layers\r\n .getLayerGeoJsonIntersect({\r\n id: layerId,\r\n geometry: feature.geometry,\r\n })\r\n .then((response) => {\r\n const geo = extractGeoJsonFeatureCollection(response);\r\n const candidates = geo?.features ?? [];\r\n const selection = pickIntersectFeature({\r\n baseFeature: feature,\r\n candidates,\r\n expectedLayerId: layerId,\r\n clickIntent,\r\n });\r\n const resolved = selection?.feature;\r\n\r\n if (DEV_MODE) {\r\n console.debug('[ZenitMap] click/intersect:result', {\r\n expectedLayerId: layerId,\r\n clickIntent,\r\n candidatesCount: candidates.length,\r\n candidates: candidates.map((candidate, idx) => ({\r\n idx,\r\n geomType: (candidate as { geometry?: { type?: string } })?.geometry?.type,\r\n candidateLayerId: candidateLayerId(candidate),\r\n hasDescription: Boolean(extractDescriptionValue(candidate?.properties)),\r\n })),\r\n selectedIdx: selection?.selectedIdx ?? -1,\r\n selectionRule: selection?.reason ?? 'none',\r\n });\r\n }\r\n\r\n if (!resolved?.properties) return;\r\n const mergedProperties = {\r\n ...(trackedFeature.properties ?? {}),\r\n ...(resolved.properties as Record<string, unknown>),\r\n };\r\n trackedFeature.properties = mergedProperties;\r\n const updatedHtml = buildFeaturePopupHtml({\r\n ...feature,\r\n properties: mergedProperties,\r\n });\r\n if (updatedHtml && layer.setPopupContent) {\r\n layer.setPopupContent(updatedHtml);\r\n }\r\n })\r\n .catch(() => {\r\n trackedFeature.__zenit_popup_loaded = false;\r\n });\r\n }\r\n }\r\n\r\n onFeatureClick?.(feature, layerId);\r\n });\r\n layer.on('mouseover', () => {\r\n if (layer instanceof L.Path && originalStyle) {\r\n layer.setStyle({\r\n ...originalStyle,\r\n weight: (originalStyle.weight ?? 2) + 1,\r\n opacity: Math.min(1, (originalStyle.opacity ?? 1) + 0.2),\r\n fillOpacity: Math.min(1, (originalStyle.fillOpacity ?? 0.8) + 0.1),\r\n });\r\n }\r\n if (layer instanceof L.CircleMarker && typeof originalRadius === 'number') {\r\n layer.setRadius(originalRadius + 1);\r\n }\r\n onFeatureHover?.(feature, layerId);\r\n });\r\n layer.on('mouseout', () => {\r\n if (layer instanceof L.Path && originalStyle) {\r\n layer.setStyle(originalStyle);\r\n }\r\n if (layer instanceof L.CircleMarker && typeof originalRadius === 'number') {\r\n layer.setRadius(originalRadius);\r\n }\r\n });\r\n }, [client, featureInfoMode, onFeatureClick, onFeatureHover]);\r\n\r\n const buildLayerStyle = useCallback((\r\n layerId: number | string,\r\n baseOpacity: number,\r\n feature?: any,\r\n layerType?: string\r\n ): PathOptions => {\r\n const style = resolveLayerStyle(layerId);\r\n const featureStyleOverrides = getFeatureStyleOverrides(feature);\r\n const resolvedStyle: LayerStyle | null = featureStyleOverrides\r\n ? { ...(style ?? {}), ...featureStyleOverrides }\r\n : style;\r\n const geometryType = (feature as { geometry?: { type?: string } } | undefined)?.geometry?.type;\r\n const resolvedLayerType = layerType ?? geometryType;\r\n\r\n return layerStyleToLeaflet({\r\n baseOpacity,\r\n zoom: currentZoom,\r\n layerStyle: resolvedStyle,\r\n geometryType,\r\n layerType: resolvedLayerType,\r\n properties: (feature?.properties as Record<string, unknown> | undefined) ?? undefined,\r\n });\r\n }, [currentZoom, resolveLayerStyle]);\r\n\r\n const styleFnByLayerId = useMemo(() => {\r\n const next = new Map<string, (feature: any, layerType?: string, baseOpacity?: number) => PathOptions>();\r\n orderedLayers.forEach((layerState) => {\r\n const layerId = layerState.mapLayer.layerId;\r\n next.set(String(layerId), (feature: any, layerType?: string, baseOpacity?: number) => {\r\n return buildLayerStyle(layerId, baseOpacity ?? 1, feature, layerType);\r\n });\r\n });\r\n return next;\r\n }, [buildLayerStyle, orderedLayers]);\r\n\r\n // Expose imperative API via ref\r\n useImperativeHandle(ref, () => ({\r\n setLayerOpacity: (layerId: number | string, opacity: number) => {\r\n upsertUiOverride(layerId, { overrideOpacity: opacity });\r\n },\r\n setLayerVisibility: (layerId: number | string, visible: boolean) => {\r\n upsertUiOverride(layerId, { overrideVisible: visible });\r\n },\r\n fitBounds: (bbox: Bbox, options?: { padding?: [number, number]; animate?: boolean }) => {\r\n if (!mapInstance) return;\r\n\r\n // Validate bbox before using it\r\n if (\r\n typeof bbox.minLat !== 'number' ||\r\n typeof bbox.minLon !== 'number' ||\r\n typeof bbox.maxLat !== 'number' ||\r\n typeof bbox.maxLon !== 'number' ||\r\n !Number.isFinite(bbox.minLat) ||\r\n !Number.isFinite(bbox.minLon) ||\r\n !Number.isFinite(bbox.maxLat) ||\r\n !Number.isFinite(bbox.maxLon)\r\n ) {\r\n console.warn('[ZenitMap.fitBounds] Invalid bbox: missing or non-finite coordinates', bbox);\r\n return;\r\n }\r\n\r\n const bounds: LatLngBoundsExpression = [\r\n [bbox.minLat, bbox.minLon],\r\n [bbox.maxLat, bbox.maxLon],\r\n ];\r\n const fitOptions = {\r\n padding: options?.padding ?? [12, 12],\r\n animate: options?.animate ?? true,\r\n };\r\n mapInstance.fitBounds(bounds, fitOptions);\r\n },\r\n fitToBbox: (bbox: Bbox, padding?: number) => {\r\n if (!mapInstance) return;\r\n\r\n if (\r\n typeof bbox.minLat !== 'number' ||\r\n typeof bbox.minLon !== 'number' ||\r\n typeof bbox.maxLat !== 'number' ||\r\n typeof bbox.maxLon !== 'number' ||\r\n !Number.isFinite(bbox.minLat) ||\r\n !Number.isFinite(bbox.minLon) ||\r\n !Number.isFinite(bbox.maxLat) ||\r\n !Number.isFinite(bbox.maxLon)\r\n ) {\r\n console.warn('[ZenitMap.fitToBbox] Invalid bbox', bbox);\r\n return;\r\n }\r\n\r\n const resolvedPadding = padding ?? (isMobile ? 40 : 24);\r\n const bounds = L.latLngBounds([bbox.minLat, bbox.minLon], [bbox.maxLat, bbox.maxLon]);\r\n mapInstance.fitBounds(bounds, { padding: [resolvedPadding, resolvedPadding], animate: true });\r\n },\r\n fitToGeoJson: (fc: GeoJsonFeatureCollection, padding?: number) => {\r\n if (!mapInstance) return;\r\n if (!fc?.features?.length) return;\r\n\r\n const bounds = L.geoJSON(fc as any).getBounds();\r\n if (!bounds.isValid()) return;\r\n\r\n const resolvedPadding = padding ?? (isMobile ? 40 : 24);\r\n mapInstance.fitBounds(bounds, { padding: [resolvedPadding, resolvedPadding], animate: true });\r\n },\r\n setView: (coordinates: { lat: number; lon: number }, zoom?: number) => {\r\n if (!mapInstance) return;\r\n mapInstance.setView([coordinates.lat, coordinates.lon], zoom ?? mapInstance.getZoom(), {\r\n animate: true,\r\n });\r\n },\r\n getLayerSnapshot: (): LayerSnapshot[] => {\r\n return effectiveStates.map((state) => ({\r\n layerId: state.layerId,\r\n visible: state.visible,\r\n opacity: state.opacity,\r\n }));\r\n },\r\n restoreLayerSnapshot: (snapshot: LayerSnapshot[]) => {\r\n const overrides = snapshot.map((s) => ({\r\n layerId: s.layerId,\r\n overrideVisible: s.visible,\r\n overrideOpacity: s.opacity,\r\n }));\r\n setUiOverrides(overrides);\r\n },\r\n highlightFeature: (layerId: number | string, featureId?: number | string) => {\r\n // For now, just ensure the layer is visible with high opacity\r\n // In a future enhancement, this could style specific features\r\n upsertUiOverride(layerId, { overrideVisible: true, overrideOpacity: 1.0 });\r\n },\r\n updateLayerGeoJson: (layerId: number | string, featureCollection: GeoJsonFeatureCollection) => {\r\n const layerKey = String(layerId);\r\n setLayerGeojsonOverrides((prev) => ({ ...prev, [layerKey]: featureCollection }));\r\n },\r\n restoreLayerGeoJson: (layerId: number | string) => {\r\n const layerKey = String(layerId);\r\n const original = originalGeojsonByLayerIdRef.current[layerKey];\r\n setLayerGeojsonOverrides((prev) => {\r\n const next = { ...prev };\r\n if (original) {\r\n next[layerKey] = original;\r\n } else {\r\n delete next[layerKey];\r\n }\r\n return next;\r\n });\r\n },\r\n getMapInstance: () => mapInstance,\r\n }), [effectiveStates, isMobile, mapInstance]);\r\n\r\n if (loadingMap) {\r\n return <div style={{ padding: 16, height, width }}>Cargando mapa...</div>;\r\n }\r\n\r\n if (mapError) {\r\n return (\r\n <div style={{ padding: 16, height, width, color: 'red' }}>\r\n Error al cargar mapa: {mapError}\r\n </div>\r\n );\r\n }\r\n\r\n if (!map) {\r\n return null;\r\n }\r\n\r\n const handleZoomChange = (zoomValue: number) => {\r\n setCurrentZoom(zoomValue);\r\n onZoomChange?.(zoomValue);\r\n };\r\n\r\n return (\r\n <div\r\n style={{\r\n display: 'flex',\r\n height,\r\n width,\r\n border: '1px solid #e2e8f0',\r\n borderRadius: 4,\r\n overflow: 'hidden',\r\n boxSizing: 'border-box',\r\n }}\r\n >\r\n <div\r\n className={`zenit-map-shell${isPopupOpen ? ' popup-open' : ''}`}\r\n style={{ flex: 1, position: 'relative' }}\r\n >\r\n <MapContainer\r\n center={center}\r\n zoom={zoom}\r\n style={{ height: '100%', width: '100%' }}\r\n scrollWheelZoom\r\n zoomControl={false}\r\n key={String(mapId)}\r\n >\r\n <TileLayer\r\n url=\"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png\"\r\n attribution=\"&copy; OpenStreetMap contributors\"\r\n />\r\n <ZoomControl position=\"topright\" />\r\n <MapInstanceBridge onReady={handleMapReady} />\r\n <MapInvalidator trigger={mapId} />\r\n <BBoxZoomHandler\r\n bbox={zoomToBbox ?? undefined}\r\n geojson={zoomToGeojson ?? undefined}\r\n autoGeojson={autoZoomGeojson}\r\n />\r\n <ZoomBasedOpacityHandler onZoomChange={handleZoomChange} />\r\n <LocationControl />\r\n {orderedLayers.map((layerState) => {\r\n const baseOpacity =\r\n layerState.effective?.baseOpacity ?? layerState.effective?.opacity ?? 1;\r\n const fillPaneName = `zenit-layer-${layerState.mapLayer.layerId}-fill`;\r\n const pointsPaneName = `zenit-layer-${layerState.mapLayer.layerId}-points`;\r\n const layerType =\r\n layerState.layer?.layerType ??\r\n (layerState.mapLayer as { layerType?: string }).layerType ??\r\n undefined;\r\n const labelKey = labelKeyIndex.get(String(layerState.mapLayer.layerId));\r\n\r\n return (\r\n <React.Fragment key={layerState.mapLayer.layerId.toString()}>\r\n {layerState.data && panesReady && (\r\n <LayerGeoJson\r\n layerId={layerState.mapLayer.layerId}\r\n data={layerState.data}\r\n baseOpacity={baseOpacity}\r\n isMobile={isMobile}\r\n panesReady={panesReady}\r\n mapInstance={mapInstance}\r\n fillPaneName={fillPaneName}\r\n pointsPaneName={pointsPaneName}\r\n layerType={layerType}\r\n styleFn={\r\n styleFnByLayerId.get(String(layerState.mapLayer.layerId)) ??\r\n ((feature: any, layerType?: string, baseOpacity?: number) =>\r\n buildLayerStyle(layerState.mapLayer.layerId, baseOpacity ?? 1, feature, layerType))\r\n }\r\n onEachFeature={overlayOnEachFeature}\r\n onPolygonLabel={\r\n labelKey\r\n ? (feature, layer) => {\r\n const geometryType = (feature as { geometry?: { type?: string } })\r\n ?.geometry?.type;\r\n if (geometryType !== 'Polygon' && geometryType !== 'MultiPolygon') return;\r\n const properties = feature?.properties as Record<string, unknown> | undefined;\r\n const value = properties?.[labelKey];\r\n if (!value || !layer.bindTooltip) return;\r\n layer.bindTooltip(String(value), {\r\n sticky: true,\r\n direction: 'center',\r\n opacity: 0.9,\r\n className: 'polygon-label-tooltip',\r\n });\r\n }\r\n : undefined\r\n }\r\n />\r\n )}\r\n {panesReady && mapInstance?.getPane(LABELS_PANE_NAME)\r\n ? labelMarkers\r\n .filter(\r\n (marker) => String(marker.layerId) === String(layerState.mapLayer.layerId)\r\n )\r\n .map((marker) => (\r\n <Marker\r\n key={marker.key}\r\n position={marker.position}\r\n icon={createCustomIcon(marker.label, marker.opacity, marker.color)}\r\n interactive={false}\r\n pane={LABELS_PANE_NAME}\r\n />\r\n ))\r\n : null}\r\n </React.Fragment>\r\n );\r\n })}\r\n {overlayGeojson && panesReady && (\r\n <LayerGeoJson\r\n layerId=\"overlay-geojson\"\r\n data={overlayGeojson as GeoJsonFeatureCollection}\r\n baseOpacity={1}\r\n isMobile={isMobile}\r\n panesReady={panesReady}\r\n mapInstance={mapInstance}\r\n fillPaneName=\"zenit-overlay-fill\"\r\n pointsPaneName=\"zenit-overlay-points\"\r\n styleFn={overlayStyleFn}\r\n onEachFeature={overlayOnEachFeature}\r\n />\r\n )}\r\n </MapContainer>\r\n </div>\r\n\r\n {showLayerPanel && decoratedLayers.length > 0 && (\r\n <div\r\n style={{\r\n width: 260,\r\n borderLeft: '1px solid #e2e8f0',\r\n padding: '12px 16px',\r\n background: '#fafafa',\r\n fontFamily: 'system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif',\r\n fontSize: 14,\r\n overflowY: 'auto',\r\n }}\r\n >\r\n {overlayGeojson && panesReady && (\r\n <div\r\n style={{\r\n border: '1px solid #bfdbfe',\r\n background: '#eff6ff',\r\n color: '#1e40af',\r\n padding: '8px 10px',\r\n borderRadius: 8,\r\n marginBottom: 12,\r\n }}\r\n >\r\n <div style={{ fontWeight: 600, marginBottom: 4 }}>Overlay activo</div>\r\n <div style={{ fontSize: 13 }}>\r\n GeoJSON externo con {(overlayGeojson.features?.length ?? 0).toLocaleString()} elementos.\r\n </div>\r\n </div>\r\n )}\r\n <div style={{ fontWeight: 600, marginBottom: 12 }}>Capas</div>\r\n {decoratedLayers.map((layerState) => (\r\n <div\r\n key={layerState.mapLayer.layerId.toString()}\r\n style={{ borderBottom: '1px solid #e5e7eb', paddingBottom: 10, marginBottom: 10 }}\r\n >\r\n <label style={{ display: 'flex', gap: 8, alignItems: 'center' }}>\r\n <input\r\n type=\"checkbox\"\r\n checked={layerState.effective?.visible ?? false}\r\n onChange={(e) => {\r\n const visible = e.target.checked;\r\n upsertUiOverride(layerState.mapLayer.layerId, { overrideVisible: visible });\r\n }}\r\n />\r\n <span>{layerState.layer?.name ?? `Capa ${layerState.mapLayer.layerId}`}</span>\r\n </label>\r\n\r\n <div style={{ marginTop: 8 }}>\r\n <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 4 }}>\r\n <span style={{ color: '#4a5568' }}>Opacidad</span>\r\n <span>{Math.round((layerState.effective?.opacity ?? 1) * 100)}%</span>\r\n </div>\r\n <input\r\n type=\"range\"\r\n min={0}\r\n max={1}\r\n step={0.05}\r\n value={layerState.effective?.opacity ?? 1}\r\n onChange={(e) => {\r\n const value = Number(e.target.value);\r\n updateOpacityFromUi(layerState.mapLayer.layerId, value);\r\n }}\r\n style={{ width: '100%' }}\r\n />\r\n </div>\r\n </div>\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n});\r\n\r\nZenitMap.displayName = 'ZenitMap';\r\n\r\nexport const GenericMap = ZenitMap;\r\n","import type {\r\n Bbox,\r\n FilterMultipleMetadata,\r\n GeoJsonFeature,\r\n GeoJsonFeatureCollection,\r\n LayerDto,\r\n} from '../layers/types';\r\nimport type { MapDto, MapLayerConfig, NormalizedMapLayer } from './types';\r\n\r\nfunction toNumber(value: unknown): number | undefined {\r\n if (typeof value === 'number' && Number.isFinite(value)) {\r\n return value;\r\n }\r\n if (typeof value === 'string') {\r\n const parsed = parseFloat(value);\r\n if (Number.isFinite(parsed)) {\r\n return parsed;\r\n }\r\n }\r\n return undefined;\r\n}\r\n\r\nfunction clampOpacity(value: number | undefined): number {\r\n if (!Number.isFinite(value ?? NaN)) {\r\n return 1;\r\n }\r\n return Math.min(1, Math.max(0, value ?? 1));\r\n}\r\n\r\nfunction resolveLayerId(mapLayer: MapLayerConfig): number | string | undefined {\r\n if (mapLayer.layerId !== undefined && mapLayer.layerId !== null) {\r\n return mapLayer.layerId;\r\n }\r\n const embedded = (mapLayer as MapLayerConfig & { layer?: LayerDto }).layer;\r\n return embedded?.id;\r\n}\r\n\r\nexport function extractMapDto(map: unknown): MapDto | null {\r\n if (map && typeof map === 'object' && 'data' in map) {\r\n const data = (map as { data?: MapDto | null }).data;\r\n return data ?? null;\r\n }\r\n if (map && typeof map === 'object') {\r\n return map as MapDto;\r\n }\r\n return null;\r\n}\r\n\r\nexport function normalizeMapCenter(map: MapDto): MapDto {\r\n const center = map.settings?.center as unknown;\r\n\r\n if (Array.isArray(center) && center.length >= 2) {\r\n const [lon, lat] = center;\r\n return {\r\n ...map,\r\n settings: {\r\n ...map.settings,\r\n center: { lon, lat },\r\n },\r\n };\r\n }\r\n\r\n return map;\r\n}\r\n\r\nexport function normalizeMapLayers(mapOrResponse: unknown): NormalizedMapLayer[] {\r\n const map = extractMapDto(mapOrResponse);\r\n if (!map?.mapLayers) {\r\n return [];\r\n }\r\n\r\n const normalized: NormalizedMapLayer[] = [];\r\n\r\n map.mapLayers.forEach((mapLayer, index) => {\r\n const layerId = resolveLayerId(mapLayer);\r\n if (layerId === undefined) {\r\n return;\r\n }\r\n\r\n const embeddedLayer = (mapLayer as MapLayerConfig & { layer?: LayerDto }).layer;\r\n const visible = mapLayer.isVisible !== false;\r\n const opacity = clampOpacity(toNumber(mapLayer.opacity) ?? 1);\r\n const layerType = embeddedLayer?.layerType ?? (mapLayer as { layerType?: string }).layerType;\r\n const geometryType =\r\n (embeddedLayer as { geometryType?: string } | undefined)?.geometryType ??\r\n (mapLayer as { geometryType?: string }).geometryType;\r\n const layerName = embeddedLayer?.name ?? (mapLayer as { name?: string }).name;\r\n const orderCandidate =\r\n toNumber((mapLayer as { displayOrder?: number | string }).displayOrder) ??\r\n toNumber(mapLayer.order) ??\r\n toNumber((embeddedLayer as { displayOrder?: number | string } | undefined)?.displayOrder) ??\r\n index;\r\n\r\n normalized.push({\r\n layerId,\r\n displayOrder: orderCandidate ?? index,\r\n isVisible: visible,\r\n opacity,\r\n layer: embeddedLayer,\r\n layerType,\r\n geometryType,\r\n layerName,\r\n mapLayer,\r\n });\r\n });\r\n\r\n return normalized.sort((a, b) => a.displayOrder - b.displayOrder);\r\n}\r\n\r\nexport function computeBBoxFromFeature(feature?: GeoJsonFeature | null): Bbox | null {\r\n if (!feature || typeof feature !== 'object') return null;\r\n\r\n const geometry = (feature as { geometry?: { coordinates?: unknown } }).geometry;\r\n if (!geometry || !('coordinates' in geometry)) return null;\r\n\r\n const coords: Array<[number, number]> = [];\r\n\r\n const collect = (candidate: unknown) => {\r\n if (!Array.isArray(candidate)) return;\r\n if (\r\n candidate.length === 2 &&\r\n typeof candidate[0] === 'number' &&\r\n typeof candidate[1] === 'number'\r\n ) {\r\n coords.push([candidate[0], candidate[1]]);\r\n return;\r\n }\r\n\r\n candidate.forEach((entry) => collect(entry));\r\n };\r\n\r\n collect(geometry.coordinates);\r\n\r\n if (coords.length === 0) return null;\r\n\r\n const [firstLon, firstLat] = coords[0];\r\n const bbox: Bbox = { minLon: firstLon, minLat: firstLat, maxLon: firstLon, maxLat: firstLat };\r\n\r\n coords.forEach(([lon, lat]) => {\r\n bbox.minLon = Math.min(bbox.minLon, lon);\r\n bbox.minLat = Math.min(bbox.minLat, lat);\r\n bbox.maxLon = Math.max(bbox.maxLon, lon);\r\n bbox.maxLat = Math.max(bbox.maxLat, lat);\r\n });\r\n\r\n return bbox;\r\n}\r\n\r\nexport function centroidFromBBox(bbox: Bbox): [number, number] {\r\n return [(bbox.minLat + bbox.maxLat) / 2, (bbox.minLon + bbox.maxLon) / 2];\r\n}\r\n\r\nexport interface FilteredGeoJSONApplication {\r\n overlay: GeoJsonFeatureCollection | null;\r\n metadata?: FilterMultipleMetadata;\r\n layerControls: Array<{\r\n layerId: number | string;\r\n visible: boolean;\r\n opacity: number;\r\n }>;\r\n}\r\n\r\nexport function applyFilteredGeoJSONStrategy(options: {\r\n normalizedLayers: NormalizedMapLayer[];\r\n filteredGeojson: GeoJsonFeatureCollection | null;\r\n metadata?: FilterMultipleMetadata;\r\n}): FilteredGeoJSONApplication {\r\n const layerControls = options.normalizedLayers.map((entry) => ({\r\n layerId: entry.layerId,\r\n visible: entry.isVisible,\r\n opacity: entry.opacity,\r\n }));\r\n\r\n return {\r\n overlay: options.filteredGeojson,\r\n metadata: options.metadata,\r\n layerControls,\r\n };\r\n}\r\n","import type { MapLayerConfig, NormalizedMapLayer } from '../maps/types';\r\n\r\ntype LayerLike = Pick<MapLayerConfig | NormalizedMapLayer, 'layerId' | 'isVisible' | 'opacity'>;\r\n\r\nexport interface LayerBaseState {\r\n layerId: number | string;\r\n baseVisible: boolean;\r\n baseOpacity: number;\r\n}\r\n\r\nexport interface LayerOverrideState {\r\n layerId: number | string;\r\n overrideVisible?: boolean | null;\r\n overrideOpacity?: number | string | null;\r\n}\r\n\r\nexport interface EffectiveLayerState extends LayerBaseState, LayerOverrideState {\r\n visible: boolean;\r\n opacity: number;\r\n}\r\n\r\nfunction clampOpacity(value: number | string | null | undefined): number {\r\n if (typeof value === 'number' && Number.isFinite(value)) {\r\n return Math.min(1, Math.max(0, value));\r\n }\r\n\r\n if (typeof value === 'string') {\r\n const parsed = parseFloat(value);\r\n if (Number.isFinite(parsed)) {\r\n return Math.min(1, Math.max(0, parsed));\r\n }\r\n }\r\n\r\n return 1;\r\n}\r\n\r\n// The SDK mirrors the frontend default: layers start hidden until toggled externally.\r\nconst resolveBaseVisibility = (_layer?: LayerLike): boolean => false;\r\n\r\nfunction resolveBaseOpacity(layer: LayerLike): number {\r\n if ('opacity' in layer) {\r\n return clampOpacity(layer.opacity as number | string | null | undefined);\r\n }\r\n\r\n return 1;\r\n}\r\n\r\nfunction toEffectiveState(base: LayerBaseState, override?: LayerOverrideState | null): EffectiveLayerState {\r\n const overrideVisible = override?.overrideVisible ?? undefined;\r\n const overrideOpacity = override?.overrideOpacity ?? undefined;\r\n\r\n const opacitySource =\r\n overrideOpacity !== undefined && overrideOpacity !== null ? overrideOpacity : base.baseOpacity;\r\n\r\n return {\r\n layerId: base.layerId,\r\n baseVisible: base.baseVisible,\r\n baseOpacity: base.baseOpacity,\r\n overrideVisible,\r\n overrideOpacity,\r\n visible: overrideVisible ?? base.baseVisible,\r\n opacity: clampOpacity(opacitySource),\r\n };\r\n}\r\n\r\nexport function initLayerStates(mapLayers: LayerLike[]): EffectiveLayerState[] {\r\n const bases: LayerBaseState[] = mapLayers\r\n .filter((layer): layer is LayerLike & { layerId: number | string } => layer.layerId !== undefined)\r\n .map((layer) => ({\r\n layerId: layer.layerId as number | string,\r\n baseVisible: resolveBaseVisibility(layer),\r\n baseOpacity: resolveBaseOpacity(layer),\r\n }));\r\n\r\n return bases.map((base) => toEffectiveState(base));\r\n}\r\n\r\nexport function applyLayerOverrides(\r\n states: EffectiveLayerState[],\r\n overrides: LayerOverrideState[],\r\n): EffectiveLayerState[] {\r\n const overrideMap = new Map<number | string, LayerOverrideState>();\r\n overrides.forEach((entry) => overrideMap.set(entry.layerId, entry));\r\n\r\n return states.map((state) => {\r\n const nextOverride = overrideMap.get(state.layerId);\r\n const mergedOverrideVisible =\r\n nextOverride && 'overrideVisible' in nextOverride && nextOverride.overrideVisible !== undefined\r\n ? nextOverride.overrideVisible\r\n : state.overrideVisible;\r\n\r\n const mergedOverrideOpacity =\r\n nextOverride && 'overrideOpacity' in nextOverride && nextOverride.overrideOpacity !== undefined\r\n ? nextOverride.overrideOpacity\r\n : state.overrideOpacity;\r\n\r\n return toEffectiveState(state, {\r\n layerId: state.layerId,\r\n overrideVisible: mergedOverrideVisible ?? undefined,\r\n overrideOpacity: mergedOverrideOpacity ?? undefined,\r\n });\r\n });\r\n}\r\n\r\nexport function resetOverrides(states: EffectiveLayerState[]): EffectiveLayerState[] {\r\n return states.map((state) => toEffectiveState(state));\r\n}\r\n","export interface LayerStyle {\r\n color?: string;\r\n weight?: number;\r\n fillColor?: string;\r\n fillOpacity?: number;\r\n}\r\n\r\n/**\r\n * Resuelve el color de acento para una capa basado en su estilo.\r\n * Prioridad: fillColor → color → null\r\n */\r\nexport function resolveLayerAccent(style?: LayerStyle | null): string | null {\r\n if (!style) return null;\r\n return style.fillColor ?? style.color ?? null;\r\n}\r\n\r\n/**\r\n * Obtiene el color de acento para una capa, con fallback a un color neutral.\r\n * @param style - El estilo de la capa\r\n * @param fallback - Color de fallback (por defecto gris neutral)\r\n */\r\nexport function getLayerColor(style?: LayerStyle | null, fallback = '#94a3b8'): string {\r\n return resolveLayerAccent(style) ?? fallback;\r\n}\r\n\r\n/**\r\n * Busca el estilo de una capa en un arreglo de mapLayers por su layerId.\r\n */\r\nexport function getStyleByLayerId(\r\n layerId: string | number,\r\n mapLayers?: Array<{\r\n layerId: number | string;\r\n style?: LayerStyle | null;\r\n }>,\r\n): LayerStyle | null {\r\n if (!mapLayers) return null;\r\n const match = mapLayers.find((ml) => String(ml.layerId) === String(layerId));\r\n return match?.style ?? null;\r\n}\r\n\r\n/**\r\n * Obtiene el color de acento de una capa por su layerId.\r\n */\r\nexport function getAccentByLayerId(\r\n layerId: string | number,\r\n mapLayers?: Array<{\r\n layerId: number | string;\r\n style?: LayerStyle | null;\r\n }>,\r\n): string | null {\r\n const style = getStyleByLayerId(layerId, mapLayers);\r\n return resolveLayerAccent(style);\r\n}\r\n","export interface ZoomOpacityOptions {\r\n minZoom?: number;\r\n maxZoom?: number;\r\n minFactor?: number;\r\n maxFactor?: number;\r\n minOpacity?: number;\r\n maxOpacity?: number;\r\n}\r\n\r\nconst DEFAULT_OPTIONS: Required<ZoomOpacityOptions> = {\r\n minZoom: 11,\r\n maxZoom: 15,\r\n minFactor: 0.3,\r\n maxFactor: 1,\r\n minOpacity: 0.1,\r\n maxOpacity: 0.92,\r\n};\r\n\r\nexport function clampNumber(value: number, min: number, max: number): number {\r\n return Math.min(max, Math.max(min, value));\r\n}\r\n\r\nexport function clampOpacity(value: number): number {\r\n return clampNumber(value, 0, 1);\r\n}\r\n\r\nexport function isPolygonLayer(layerType?: string, geometryType?: string): boolean {\r\n const candidate = (layerType ?? geometryType ?? '').toLowerCase();\r\n return candidate === 'polygon' || candidate === 'multipolygon';\r\n}\r\n\r\nexport function getZoomOpacityFactor(zoom: number, options?: ZoomOpacityOptions): number {\r\n const settings = { ...DEFAULT_OPTIONS, ...options };\r\n const { minZoom, maxZoom, minFactor, maxFactor } = settings;\r\n\r\n if (maxZoom <= minZoom) return clampNumber(maxFactor, minFactor, maxFactor);\r\n\r\n const t = clampNumber((zoom - minZoom) / (maxZoom - minZoom), 0, 1);\r\n const factor = maxFactor + (minFactor - maxFactor) * t;\r\n return clampNumber(factor, minFactor, maxFactor);\r\n}\r\n\r\nexport function getLayerZoomOpacityFactor(\r\n zoom: number,\r\n layerType?: string,\r\n geometryType?: string,\r\n options?: ZoomOpacityOptions,\r\n): number {\r\n if (!isPolygonLayer(layerType, geometryType)) return 1;\r\n return getZoomOpacityFactor(zoom, options);\r\n}\r\n\r\nexport function getEffectiveLayerOpacity(\r\n baseOpacity: number,\r\n zoom: number,\r\n layerType?: string,\r\n geometryType?: string,\r\n options?: ZoomOpacityOptions,\r\n): number {\r\n if (!isPolygonLayer(layerType, geometryType)) {\r\n return clampOpacity(baseOpacity);\r\n }\r\n\r\n const settings = { ...DEFAULT_OPTIONS, ...options };\r\n const factor = getZoomOpacityFactor(zoom, options);\r\n const effective = clampOpacity(baseOpacity) * factor;\r\n return clampNumber(effective, settings.minOpacity, settings.maxOpacity);\r\n}\r\n","import React, { useEffect, useMemo, useRef } from 'react';\r\nimport { GeoJSON } from 'react-leaflet';\r\nimport L, { PathOptions } from 'leaflet';\r\nimport type { GeoJsonFeatureCollection } from '../../layers/types';\r\nimport { sanitizeGeoJson } from './geojson-sanitize';\r\n\r\nconst POINT_GEOMETRY_TYPES = new Set(['Point', 'MultiPoint']);\r\nconst DEV_MODE = typeof process !== 'undefined' && process.env.NODE_ENV !== 'production';\r\n\r\ntype AnyGeoJsonFeature = {\r\n geometry?: { type?: unknown } | null;\r\n};\r\n\r\n\r\ntype BboxTuple = [number, number, number, number];\r\n\r\ntype FeatureWithProperties = {\r\n id?: unknown;\r\n properties?: {\r\n featureId?: unknown;\r\n } | null;\r\n};\r\n\r\nfunction normalizeBboxFromData(data: GeoJsonFeatureCollection): BboxTuple | null {\r\n const bboxCandidate = (data as { bbox?: unknown }).bbox;\r\n if (!Array.isArray(bboxCandidate) || bboxCandidate.length < 4) return null;\r\n\r\n const [minLon, minLat, maxLon, maxLat] = bboxCandidate;\r\n const values = [minLon, minLat, maxLon, maxLat].map((value) => Number(value));\r\n if (values.every((value) => Number.isFinite(value))) {\r\n return values as BboxTuple;\r\n }\r\n return null;\r\n}\r\n\r\nfunction buildIdsSample(features: unknown[]): string {\r\n return features\r\n .slice(0, 10)\r\n .map((feature) => {\r\n const typedFeature = feature as FeatureWithProperties;\r\n if (typedFeature.id !== undefined && typedFeature.id !== null) {\r\n return String(typedFeature.id);\r\n }\r\n const featureId = typedFeature.properties?.featureId;\r\n return featureId !== undefined && featureId !== null ? String(featureId) : '';\r\n })\r\n .join(',');\r\n}\r\n\r\nfunction getGeometryType(feature: unknown): string | null {\r\n const t = (feature as AnyGeoJsonFeature | null | undefined)?.geometry?.type;\r\n return typeof t === 'string' ? t : null;\r\n}\r\n\r\nfunction isPointGeometry(feature: unknown): boolean {\r\n const geometryType = getGeometryType(feature);\r\n return geometryType !== null && POINT_GEOMETRY_TYPES.has(geometryType);\r\n}\r\n\r\nfunction isNonPointGeometry(feature: unknown): boolean {\r\n const geometryType = getGeometryType(feature);\r\n return geometryType !== null && !POINT_GEOMETRY_TYPES.has(geometryType);\r\n}\r\n\r\nfunction isValidLatLng(latlng: unknown): latlng is { lat: number; lng: number } {\r\n const candidate = latlng as { lat?: unknown; lng?: unknown } | null | undefined;\r\n return Boolean(\r\n candidate &&\r\n Number.isFinite(candidate.lat) &&\r\n Number.isFinite(candidate.lng),\r\n );\r\n}\r\n\r\nfunction createInvisibleFallbackMarker(latlng?: L.LatLngExpression): L.CircleMarker {\r\n return L.circleMarker(latlng ?? [0, 0], {\r\n radius: 0,\r\n opacity: 0,\r\n fillOpacity: 0,\r\n interactive: false,\r\n });\r\n}\r\n\r\nfunction createInvisibleFallbackClusterMarker(latlng?: L.LatLngExpression): L.Marker {\r\n return L.marker(latlng ?? [0, 0], {\r\n opacity: 0,\r\n interactive: false,\r\n });\r\n}\r\n\r\n\r\nfunction ensurePaneName(mapInstance: L.Map | null, paneName: string, fallbackPaneName: string): string {\r\n if (!mapInstance) return fallbackPaneName;\r\n const existingPane = mapInstance.getPane(paneName) ?? mapInstance.createPane(paneName);\r\n if (!existingPane && DEV_MODE) {\r\n console.warn('[LayerGeoJson] pane unavailable, using fallback', { paneName, fallbackPaneName });\r\n }\r\n return mapInstance.getPane(paneName) ? paneName : fallbackPaneName;\r\n}\r\n\r\nfunction createPointDivIcon(style: PathOptions, isMobile: boolean): L.DivIcon {\r\n const size = isMobile ? 18 : 14;\r\n const backgroundColor = style.fillColor ?? style.color ?? '#3388ff';\r\n const borderColor = style.color ?? style.fillColor ?? '#3388ff';\r\n\r\n return L.divIcon({\r\n className: 'zenit-point-marker',\r\n html: `<div style=\"width:${size}px;height:${size}px;border-radius:50%;background:${backgroundColor};border:2px solid ${borderColor};\"></div>`,\r\n iconSize: [size, size],\r\n iconAnchor: [size / 2, size / 2],\r\n });\r\n}\r\n\r\nfunction buildFeatureCollection(features: any[]): GeoJsonFeatureCollection {\r\n return {\r\n type: 'FeatureCollection',\r\n features,\r\n } as GeoJsonFeatureCollection;\r\n}\r\n\r\nexport type LayerGeoJsonProps = {\r\n layerId: number | string;\r\n data: GeoJsonFeatureCollection;\r\n baseOpacity: number;\r\n isMobile: boolean;\r\n panesReady: boolean;\r\n mapInstance: L.Map | null;\r\n fillPaneName: string;\r\n pointsPaneName: string;\r\n layerType?: string;\r\n styleFn: (feature: any, layerType?: string, baseOpacity?: number) => PathOptions;\r\n onEachFeature: (feature: any, layer: any) => void;\r\n onPolygonLabel?: (feature: any, layer: any) => void;\r\n};\r\n\r\nexport const LayerGeoJson: React.FC<LayerGeoJsonProps> = ({\r\n layerId,\r\n data,\r\n baseOpacity,\r\n isMobile,\r\n panesReady,\r\n mapInstance,\r\n fillPaneName,\r\n pointsPaneName,\r\n layerType,\r\n styleFn,\r\n onEachFeature,\r\n onPolygonLabel,\r\n}) => {\r\n const styleFnRef = useRef(styleFn);\r\n const onEachFeatureRef = useRef(onEachFeature);\r\n\r\n useEffect(() => {\r\n styleFnRef.current = styleFn;\r\n }, [styleFn]);\r\n\r\n useEffect(() => {\r\n onEachFeatureRef.current = onEachFeature;\r\n }, [onEachFeature]);\r\n\r\n const safeData = useMemo(() => sanitizeGeoJson(data, String(layerId)), [data, layerId]);\r\n const features = useMemo(() => safeData.features ?? [], [safeData]);\r\n const fillFeatures = useMemo(() => features.filter(isNonPointGeometry), [features]);\r\n const pointFeatures = useMemo(() => features.filter(isPointGeometry), [features]);\r\n\r\n // Track data version to force GeoJSON component remount when data changes.\r\n // react-leaflet's GeoJSON updateGeoJSON only handles style changes,\r\n // so changing the key is the only way to get new data rendered.\r\n // Use a content signature instead of reference equality so that in-place\r\n // mutations (same object, different contents) also trigger a remount.\r\n const dataVersionRef = useRef(0);\r\n const prevSignatureRef = useRef('');\r\n const firstId = features.length > 0 ? String((features[0] as FeatureWithProperties | undefined)?.id ?? '') : '';\r\n const lastId =\r\n features.length > 0\r\n ? String((features[features.length - 1] as FeatureWithProperties | undefined)?.id ?? '')\r\n : '';\r\n const bbox = normalizeBboxFromData(safeData);\r\n const idsSample = buildIdsSample(features);\r\n const signature = bbox\r\n ? `${layerId}|${features.length}|${firstId}|${lastId}|${idsSample}|${bbox[0]}|${bbox[1]}|${bbox[2]}|${bbox[3]}`\r\n : `${layerId}|${features.length}|${firstId}|${lastId}|${idsSample}`;\r\n const signatureToken = signature.replace(/[^a-zA-Z0-9_-]/g, '_');\r\n if (prevSignatureRef.current !== signature) {\r\n dataVersionRef.current += 1;\r\n prevSignatureRef.current = signature;\r\n }\r\n\r\n const fillData = useMemo(() => (fillFeatures.length > 0 ? buildFeatureCollection(fillFeatures) : null), [fillFeatures]);\r\n const pointsData = useMemo(() => (pointFeatures.length > 0 ? buildFeatureCollection(pointFeatures) : null), [pointFeatures]);\r\n const clusterLayerRef = useRef<L.LayerGroup | null>(null);\r\n\r\n const canCluster =\r\n typeof (L as { markerClusterGroup?: () => L.LayerGroup }).markerClusterGroup === 'function';\r\n\r\n const resolvedFillPane = useMemo(\r\n () => ensurePaneName(mapInstance, fillPaneName, 'overlayPane'),\r\n [fillPaneName, mapInstance],\r\n );\r\n const resolvedPointsPane = useMemo(\r\n () => ensurePaneName(mapInstance, pointsPaneName, 'markerPane'),\r\n [mapInstance, pointsPaneName],\r\n );\r\n\r\n useEffect(() => {\r\n if (!mapInstance || !panesReady || !pointsData || !canCluster) return;\r\n\r\n const markerClusterGroup = (\r\n L as {\r\n markerClusterGroup: (options?: { pane?: string; clusterPane?: string }) => L.LayerGroup;\r\n }\r\n ).markerClusterGroup;\r\n const clusterPaneName = resolvedPointsPane;\r\n const clusterLayer = clusterLayerRef.current ?? markerClusterGroup({ pane: clusterPaneName, clusterPane: clusterPaneName });\r\n clusterLayerRef.current = clusterLayer;\r\n\r\n if (!mapInstance.hasLayer(clusterLayer)) {\r\n mapInstance.addLayer(clusterLayer);\r\n }\r\n\r\n clusterLayer.clearLayers();\r\n\r\n const geoJsonLayer = L.geoJSON(pointsData, {\r\n pointToLayer: (feature, latlng) => {\r\n if (!isValidLatLng(latlng)) {\r\n return createInvisibleFallbackClusterMarker();\r\n }\r\n\r\n const style = styleFnRef.current(feature, layerType, baseOpacity);\r\n\r\n return L.marker(latlng, {\r\n icon: createPointDivIcon(style, isMobile),\r\n pane: clusterPaneName,\r\n interactive: true,\r\n });\r\n },\r\n onEachFeature: (feature, layer) => onEachFeatureRef.current(feature, layer),\r\n });\r\n\r\n clusterLayer.addLayer(geoJsonLayer);\r\n\r\n return () => {\r\n clusterLayer.clearLayers();\r\n if (mapInstance.hasLayer(clusterLayer)) {\r\n mapInstance.removeLayer(clusterLayer);\r\n }\r\n };\r\n }, [\r\n baseOpacity,\r\n canCluster,\r\n isMobile,\r\n layerType,\r\n mapInstance,\r\n panesReady,\r\n pointsData,\r\n resolvedPointsPane,\r\n ]);\r\n\r\n return (\r\n <>\r\n {fillData && (\r\n <GeoJSON\r\n key={`fill-${layerId}-${signatureToken}-v${dataVersionRef.current}`}\r\n data={fillData}\r\n pane={resolvedFillPane}\r\n style={(feature) => styleFn(feature, layerType, baseOpacity)}\r\n onEachFeature={(feature, layer) => {\r\n onEachFeature(feature, layer);\r\n onPolygonLabel?.(feature, layer);\r\n }}\r\n />\r\n )}\r\n {pointsData && !canCluster && (\r\n <GeoJSON\r\n key={`points-${layerId}-${signatureToken}-v${dataVersionRef.current}`}\r\n data={pointsData}\r\n pane={resolvedPointsPane}\r\n pointToLayer={(feature, latlng) => {\r\n if (!isValidLatLng(latlng)) {\r\n return createInvisibleFallbackMarker();\r\n }\r\n\r\n return L.circleMarker(latlng, {\r\n radius: isMobile ? 8 : 6,\r\n ...styleFn(feature, layerType, baseOpacity),\r\n });\r\n }}\r\n onEachFeature={onEachFeature}\r\n />\r\n )}\r\n </>\r\n );\r\n};\r\n","import type { GeoJsonFeatureCollection } from '../../layers/types';\r\n\r\ntype GeoJsonGeometry = {\r\n type?: unknown;\r\n coordinates?: unknown;\r\n};\r\n\r\ntype GeoJsonFeature = {\r\n type?: unknown;\r\n geometry?: GeoJsonGeometry | null;\r\n [key: string]: unknown;\r\n};\r\n\r\ntype GeoJsonInput =\r\n | GeoJsonFeatureCollection\r\n | GeoJsonFeature\r\n | { data?: GeoJsonFeatureCollection | GeoJsonFeature | null }\r\n | null\r\n | undefined;\r\n\r\ntype SanitizeStats = {\r\n droppedFeatures: number;\r\n droppedPointsFromMultiPoint: number;\r\n};\r\n\r\nconst warnedKeys = new Set<string>();\r\n\r\nexport function isFiniteNumber(value: unknown): boolean {\r\n if (typeof value === 'number') return Number.isFinite(value);\r\n if (typeof value === 'string') return Number.isFinite(Number(value));\r\n return false;\r\n}\r\n\r\nexport function isValidLonLat(lon: unknown, lat: unknown): boolean {\r\n const lonN = typeof lon === 'string' ? Number(lon) : lon;\r\n const latN = typeof lat === 'string' ? Number(lat) : lat;\r\n\r\n if (!isFiniteNumber(lonN) || !isFiniteNumber(latN)) return false;\r\n\r\n if (typeof lonN !== 'number' || typeof latN !== 'number') return false;\r\n\r\n return lonN >= -180 && lonN <= 180 && latN >= -90 && latN <= 90;\r\n}\r\n\r\nfunction asFeatureCollection(input: GeoJsonInput): GeoJsonFeatureCollection {\r\n const raw = input && typeof input === 'object' && 'data' in input ? input.data : input;\r\n\r\n if (!raw || typeof raw !== 'object') {\r\n return { type: 'FeatureCollection', features: [] } as GeoJsonFeatureCollection;\r\n }\r\n\r\n if ((raw as { type?: unknown }).type === 'FeatureCollection') {\r\n const collection = raw as GeoJsonFeatureCollection;\r\n const features = Array.isArray(collection.features) ? collection.features : [];\r\n return { ...collection, features };\r\n }\r\n\r\n if ((raw as { type?: unknown }).type === 'Feature') {\r\n return {\r\n type: 'FeatureCollection',\r\n features: [raw as GeoJsonFeature],\r\n } as GeoJsonFeatureCollection;\r\n }\r\n\r\n return { type: 'FeatureCollection', features: [] } as GeoJsonFeatureCollection;\r\n}\r\n\r\nexport function sanitizeFeature(feature: GeoJsonFeature): GeoJsonFeature | null {\r\n if (!feature || typeof feature !== 'object') return null;\r\n\r\n const geometry = feature.geometry;\r\n if (!geometry || typeof geometry !== 'object') return null;\r\n\r\n const geometryType = geometry.type;\r\n const coordinates = geometry.coordinates;\r\n\r\n if (geometryType === 'Point') {\r\n if (!Array.isArray(coordinates) || coordinates.length < 2) return null;\r\n return isValidLonLat(coordinates[0], coordinates[1]) ? feature : null;\r\n }\r\n\r\n if (geometryType === 'MultiPoint') {\r\n if (!Array.isArray(coordinates)) return null;\r\n\r\n const validCoordinates = coordinates.filter((coordinate) => {\r\n if (!Array.isArray(coordinate) || coordinate.length < 2) return false;\r\n return isValidLonLat(coordinate[0], coordinate[1]);\r\n });\r\n\r\n if (validCoordinates.length === 0) return null;\r\n\r\n if (validCoordinates.length === coordinates.length) {\r\n return feature;\r\n }\r\n\r\n return {\r\n ...feature,\r\n geometry: {\r\n ...geometry,\r\n coordinates: validCoordinates,\r\n },\r\n };\r\n }\r\n\r\n if (\r\n geometryType === 'LineString' ||\r\n geometryType === 'Polygon' ||\r\n geometryType === 'MultiPolygon' ||\r\n geometryType === 'MultiLineString'\r\n ) {\r\n return Array.isArray(coordinates) && coordinates.length > 0 ? feature : null;\r\n }\r\n\r\n return feature;\r\n}\r\n\r\nfunction logSanitizeStats(stats: SanitizeStats, debugKey?: string): void {\r\n if (process.env.NODE_ENV === 'production') return;\r\n if (stats.droppedFeatures === 0 && stats.droppedPointsFromMultiPoint === 0) return;\r\n\r\n const resolvedKey = debugKey ?? '__default__';\r\n if (warnedKeys.has(resolvedKey)) return;\r\n\r\n warnedKeys.add(resolvedKey);\r\n console.warn('[zenit-sdk] GeoJSON sanitization dropped invalid geometries.', {\r\n layerId: debugKey,\r\n ...stats,\r\n });\r\n}\r\n\r\nexport function sanitizeGeoJson(input: GeoJsonInput, debugKey?: string): GeoJsonFeatureCollection {\r\n const featureCollection = asFeatureCollection(input);\r\n const safeFeatures: GeoJsonFeature[] = [];\r\n const stats: SanitizeStats = {\r\n droppedFeatures: 0,\r\n droppedPointsFromMultiPoint: 0,\r\n };\r\n\r\n const rawFeatures = Array.isArray(featureCollection.features) ? featureCollection.features : [];\r\n rawFeatures.forEach((rawFeature) => {\r\n const feature = rawFeature as GeoJsonFeature;\r\n const geometryType = feature?.geometry?.type;\r\n const originalCoords = feature?.geometry?.coordinates;\r\n\r\n const sanitized = sanitizeFeature(feature);\r\n if (!sanitized) {\r\n stats.droppedFeatures += 1;\r\n if (geometryType === 'MultiPoint' && Array.isArray(originalCoords)) {\r\n stats.droppedPointsFromMultiPoint += originalCoords.length;\r\n }\r\n return;\r\n }\r\n\r\n if (geometryType === 'MultiPoint' && Array.isArray(originalCoords)) {\r\n const safeCoords = sanitized.geometry?.coordinates;\r\n const safeCount = Array.isArray(safeCoords) ? safeCoords.length : 0;\r\n stats.droppedPointsFromMultiPoint += Math.max(0, originalCoords.length - safeCount);\r\n }\r\n\r\n safeFeatures.push(sanitized);\r\n });\r\n\r\n logSanitizeStats(stats, debugKey);\r\n\r\n return {\r\n ...featureCollection,\r\n type: 'FeatureCollection',\r\n features: safeFeatures as GeoJsonFeatureCollection['features'],\r\n };\r\n}\r\n","import React, { useEffect, useMemo, useRef } from 'react';\r\nimport { createPortal } from 'react-dom';\r\nimport { Circle, Marker, useMap } from 'react-leaflet';\r\nimport L from 'leaflet';\r\nimport { useGeolocation } from '../hooks/use-geolocation';\r\nimport { createLocationIcon } from './map-utils';\r\n\r\nconst LOCATION_STYLE_ID = 'zenit-location-control-styles';\r\n\r\nconst LOCATION_STYLES = `\r\n.zenit-location-control {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 8px;\r\n}\r\n\r\n.zenit-location-button {\r\n width: 42px;\r\n height: 42px;\r\n border-radius: 12px;\r\n border: none;\r\n background: #ffffff;\r\n color: #0f172a;\r\n box-shadow: 0 8px 18px rgba(15, 23, 42, 0.2);\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n cursor: pointer;\r\n position: relative;\r\n}\r\n\r\n.zenit-location-button.zenit-location-button--tracking {\r\n animation: zenitLocationPulse 1.8s infinite;\r\n}\r\n\r\n.zenit-location-button:hover {\r\n background: #f8fafc;\r\n}\r\n\r\n.zenit-location-badge {\r\n position: absolute;\r\n top: -6px;\r\n right: -6px;\r\n width: 18px;\r\n height: 18px;\r\n border-radius: 999px;\r\n background: #ef4444;\r\n color: #fff;\r\n font-size: 11px;\r\n font-weight: 700;\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n box-shadow: 0 4px 10px rgba(239, 68, 68, 0.35);\r\n}\r\n\r\n.zenit-location-error {\r\n background: rgba(15, 23, 42, 0.92);\r\n color: #f8fafc;\r\n border-radius: 10px;\r\n padding: 8px 10px;\r\n font-size: 12px;\r\n max-width: 200px;\r\n box-shadow: 0 10px 24px rgba(15, 23, 42, 0.3);\r\n}\r\n\r\n@keyframes zenitLocationPulse {\r\n 0% { box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.35); }\r\n 70% { box-shadow: 0 0 0 12px rgba(16, 185, 129, 0); }\r\n 100% { box-shadow: 0 0 0 0 rgba(16, 185, 129, 0); }\r\n}\r\n`;\r\n\r\nconst LocateIcon = () => (\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\r\n <line x1=\"12\" y1=\"2\" x2=\"12\" y2=\"5\" />\r\n <line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"22\" />\r\n <line x1=\"2\" y1=\"12\" x2=\"5\" y2=\"12\" />\r\n <line x1=\"19\" y1=\"12\" x2=\"22\" y2=\"12\" />\r\n </svg>\r\n);\r\n\r\nexport type LocationControlProps = {\r\n position?: L.ControlPosition;\r\n zoom?: number;\r\n};\r\n\r\nexport const LocationControl: React.FC<LocationControlProps> = ({ position = 'bottomleft', zoom = 16 }) => {\r\n const map = useMap();\r\n const controlRef = useRef<HTMLDivElement | null>(null);\r\n const hasCenteredRef = useRef(false);\r\n const { isTracking, location, error, toggleTracking, clearError } = useGeolocation();\r\n\r\n useEffect(() => {\r\n if (typeof document === 'undefined') return;\r\n if (document.getElementById(LOCATION_STYLE_ID)) return;\r\n const styleTag = document.createElement('style');\r\n styleTag.id = LOCATION_STYLE_ID;\r\n styleTag.textContent = LOCATION_STYLES;\r\n document.head.appendChild(styleTag);\r\n }, []);\r\n\r\n useEffect(() => {\r\n const control = L.control({ position });\r\n control.onAdd = () => {\r\n const container = L.DomUtil.create('div', 'zenit-location-control');\r\n L.DomEvent.disableClickPropagation(container);\r\n controlRef.current = container;\r\n return container;\r\n };\r\n control.addTo(map);\r\n\r\n return () => {\r\n control.remove();\r\n controlRef.current = null;\r\n };\r\n }, [map, position]);\r\n\r\n useEffect(() => {\r\n if (!location || !isTracking) return;\r\n if (hasCenteredRef.current) return;\r\n hasCenteredRef.current = true;\r\n map.flyTo([location.lat, location.lon], zoom, { animate: true });\r\n }, [isTracking, location, map, zoom]);\r\n\r\n const markerIcon = useMemo(() => createLocationIcon(), []);\r\n\r\n return (\r\n <>\r\n {controlRef.current &&\r\n createPortal(\r\n <div>\r\n <button\r\n type=\"button\"\r\n className={`zenit-location-button${isTracking ? ' zenit-location-button--tracking' : ''}`}\r\n onClick={() => {\r\n if (error) {\r\n clearError();\r\n }\r\n toggleTracking();\r\n }}\r\n aria-label={isTracking ? 'Detener ubicación' : 'Mostrar mi ubicación'}\r\n >\r\n <LocateIcon />\r\n {error && <span className=\"zenit-location-badge\">!</span>}\r\n </button>\r\n {error && (\r\n <div className=\"zenit-location-error\">\r\n {error.message || 'No se pudo acceder a tu ubicación.'}\r\n </div>\r\n )}\r\n </div>,\r\n controlRef.current\r\n )}\r\n\r\n {location && (\r\n <>\r\n <Marker position={[location.lat, location.lon]} icon={markerIcon} />\r\n <Circle\r\n center={[location.lat, location.lon]}\r\n radius={location.accuracy}\r\n pathOptions={{ color: '#2563eb', fillColor: '#2563eb', fillOpacity: 0.15 }}\r\n />\r\n </>\r\n )}\r\n </>\r\n );\r\n};\r\n","import { useCallback, useEffect, useRef, useState } from 'react';\r\n\r\ntype GeoLocationState = {\r\n lat: number;\r\n lon: number;\r\n accuracy: number;\r\n};\r\n\r\ntype GeoLocationOptions = {\r\n enableHighAccuracy?: boolean;\r\n timeout?: number;\r\n maximumAge?: number;\r\n};\r\n\r\nexport type GeolocationError = {\r\n code: number;\r\n message: string;\r\n};\r\n\r\nexport function useGeolocation(options?: GeoLocationOptions) {\r\n const [isTracking, setIsTracking] = useState(false);\r\n const [location, setLocation] = useState<GeoLocationState | null>(null);\r\n const [error, setError] = useState<GeolocationError | null>(null);\r\n const watchIdRef = useRef<number | null>(null);\r\n\r\n const stopTracking = useCallback(() => {\r\n if (watchIdRef.current !== null && typeof navigator !== 'undefined' && navigator.geolocation) {\r\n navigator.geolocation.clearWatch(watchIdRef.current);\r\n }\r\n watchIdRef.current = null;\r\n setIsTracking(false);\r\n }, []);\r\n\r\n const startTracking = useCallback(() => {\r\n if (typeof navigator === 'undefined' || !navigator.geolocation) {\r\n setError({ code: 0, message: 'La geolocalización no está disponible en este navegador.' });\r\n return;\r\n }\r\n\r\n setError(null);\r\n\r\n watchIdRef.current = navigator.geolocation.watchPosition(\r\n (position) => {\r\n setLocation({\r\n lat: position.coords.latitude,\r\n lon: position.coords.longitude,\r\n accuracy: position.coords.accuracy,\r\n });\r\n setIsTracking(true);\r\n },\r\n (err) => {\r\n setError({ code: err.code, message: err.message });\r\n stopTracking();\r\n },\r\n {\r\n enableHighAccuracy: options?.enableHighAccuracy ?? true,\r\n timeout: options?.timeout ?? 12000,\r\n maximumAge: options?.maximumAge ?? 0,\r\n }\r\n );\r\n }, [options?.enableHighAccuracy, options?.maximumAge, options?.timeout, stopTracking]);\r\n\r\n const toggleTracking = useCallback(() => {\r\n if (isTracking) {\r\n stopTracking();\r\n } else {\r\n startTracking();\r\n }\r\n }, [isTracking, startTracking, stopTracking]);\r\n\r\n const clearError = useCallback(() => setError(null), []);\r\n\r\n useEffect(() => {\r\n return () => {\r\n stopTracking();\r\n };\r\n }, [stopTracking]);\r\n\r\n return {\r\n isTracking,\r\n location,\r\n error,\r\n startTracking,\r\n stopTracking,\r\n toggleTracking,\r\n clearError,\r\n };\r\n}\r\n","import L, { PathOptions } from 'leaflet';\r\nimport type { LayerStyle } from '../layerStyleHelpers';\r\nimport {\r\n applyModalWhitelist,\r\n CLIENTE_MODAL_WHITELIST,\r\n type ModalWhitelistItem,\r\n normalizeKey,\r\n SECTOR_MODAL_WHITELIST,\r\n} from '../../config/modalWhitelist';\r\n\r\nconst POPUP_STYLE_ID = 'zenit-leaflet-popup-styles';\r\n\r\nconst POPUP_EXCLUDED_KEYS = new Set(['geom', 'geometry', '_private']);\r\nconst POPUP_TITLE_KEYS = ['id', 'nombre', 'name', 'title', 'titulo', 'cluster'];\r\nconst POPUP_BADGE_KEYS = ['tipo', 'type', 'category', 'categoria', 'estado', 'status'];\r\nconst POPUP_DESCRIPTION_KEYS = ['descripcion', 'description', 'desc'];\r\nconst CURRENCY_KEYWORDS = [\r\n 'capital',\r\n 'monto',\r\n 'precio',\r\n 'costo',\r\n 'valor',\r\n 'ingreso',\r\n 'egreso',\r\n 'saldo',\r\n 'subtotal',\r\n 'venta',\r\n 'compra',\r\n];\r\n\r\nconst DESKTOP_POPUP_DIMENSIONS = { maxWidth: 360, minWidth: 280, maxHeight: 520 };\r\nconst MOBILE_POPUP_DIMENSIONS = { maxWidth: 300, minWidth: 240, maxHeight: 420 };\r\n\r\nconst ZENIT_LEAFLET_POPUP_STYLES = `\r\n.custom-leaflet-popup .leaflet-popup-content-wrapper {\r\n border-radius: 12px;\r\n padding: 0;\r\n background: #ffffff;\r\n box-shadow: 0 12px 24px rgba(15, 23, 42, 0.18);\r\n border: 1px solid rgba(15, 23, 42, 0.08);\r\n}\r\n\r\n.custom-leaflet-popup .leaflet-popup-content {\r\n margin: 0;\r\n padding: 12px 14px;\r\n font-size: 13px;\r\n line-height: 1.4;\r\n color: #0f172a;\r\n max-height: min(70vh, 520px);\r\n overflow: auto;\r\n scrollbar-width: thin;\r\n scrollbar-color: rgba(148, 163, 184, 0.6) transparent;\r\n}\r\n\r\n.custom-leaflet-popup .leaflet-popup-close-button {\r\n color: #64748b;\r\n font-size: 16px;\r\n padding: 6px 8px;\r\n border-radius: 8px;\r\n transition: background-color 0.15s ease, color 0.15s ease;\r\n}\r\n\r\n.custom-leaflet-popup .leaflet-popup-close-button:hover {\r\n color: #0f172a;\r\n background: rgba(148, 163, 184, 0.2);\r\n}\r\n\r\n.custom-leaflet-popup .leaflet-popup-content::-webkit-scrollbar {\r\n width: 6px;\r\n}\r\n\r\n.custom-leaflet-popup .leaflet-popup-content::-webkit-scrollbar-thumb {\r\n background: rgba(148, 163, 184, 0.5);\r\n border-radius: 999px;\r\n}\r\n\r\n.custom-leaflet-popup .leaflet-popup-content::-webkit-scrollbar-track {\r\n background: transparent;\r\n}\r\n\r\n@media (max-width: 640px) {\r\n .custom-leaflet-popup .leaflet-popup-content {\r\n font-size: 12px;\r\n padding: 10px 12px;\r\n max-height: min(65vh, 420px);\r\n }\r\n\r\n .custom-leaflet-popup .leaflet-popup-close-button {\r\n font-size: 14px;\r\n padding: 4px 6px;\r\n }\r\n}\r\n\r\n.zenit-map-tooltip {\r\n background-color: rgba(31, 41, 55, 0.95);\r\n border: none;\r\n border-radius: 6px;\r\n color: #ffffff;\r\n font-size: 12px;\r\n font-weight: 500;\r\n padding: 6px 10px;\r\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\r\n}\r\n\r\n.zenit-map-tooltip::before {\r\n border-top-color: rgba(31, 41, 55, 0.95);\r\n}\r\n\r\n.polygon-label-tooltip {\r\n background: rgba(15, 23, 42, 0.92);\r\n border: none;\r\n border-radius: 6px;\r\n color: #f8fafc;\r\n font-weight: 600;\r\n font-size: 12px;\r\n padding: 4px 8px;\r\n}\r\n`;\r\n\r\nfunction clampNumber(value: number, min: number, max: number): number {\r\n return Math.min(max, Math.max(min, value));\r\n}\r\n\r\nexport function clampOpacity(value: number): number {\r\n return clampNumber(value, 0, 1);\r\n}\r\n\r\nexport function ensurePopupStyles(): void {\r\n if (typeof document === 'undefined') return;\r\n if (document.getElementById(POPUP_STYLE_ID)) return;\r\n const styleTag = document.createElement('style');\r\n styleTag.id = POPUP_STYLE_ID;\r\n styleTag.textContent = ZENIT_LEAFLET_POPUP_STYLES;\r\n document.head.appendChild(styleTag);\r\n}\r\n\r\nexport function getPopupDimensions(): { maxWidth: number; minWidth: number; maxHeight: number } {\r\n if (typeof window === 'undefined') {\r\n return DESKTOP_POPUP_DIMENSIONS;\r\n }\r\n\r\n const isSmallWidth = window.innerWidth < 640;\r\n const isShortHeight = window.innerHeight < 768;\r\n const base = isSmallWidth ? MOBILE_POPUP_DIMENSIONS : DESKTOP_POPUP_DIMENSIONS;\r\n const maxHeight = isShortHeight ? Math.min(base.maxHeight, 360) : base.maxHeight;\r\n return { ...base, maxHeight };\r\n}\r\n\r\nfunction escapeHtml(value: string): string {\r\n return value\r\n .replace(/&/g, '&amp;')\r\n .replace(/</g, '&lt;')\r\n .replace(/>/g, '&gt;')\r\n .replace(/\"/g, '&quot;')\r\n .replace(/'/g, '&#39;');\r\n}\r\n\r\nfunction formatLabel(key: string): string {\r\n return key\r\n .replace(/_/g, ' ')\r\n .replace(/([a-z])([A-Z])/g, '$1 $2')\r\n .trim();\r\n}\r\n\r\nfunction isHexColor(value: string): boolean {\r\n return /^#([0-9A-F]{3}){1,2}$/i.test(value.trim());\r\n}\r\n\r\nexport function isCurrencyField(key: string): boolean {\r\n const normalized = key.trim().toLowerCase();\r\n return CURRENCY_KEYWORDS.some((keyword) => normalized.includes(keyword));\r\n}\r\n\r\nexport function formatCurrency(value: number): string {\r\n return new Intl.NumberFormat('es-GT', { style: 'currency', currency: 'GTQ' }).format(value);\r\n}\r\n\r\ntype PopupBadge = { label: string; bg: string; color: string; border: string };\r\n\r\nexport function getBadgeForProperty(key: string, value: unknown): PopupBadge | null {\r\n if (value === null || value === undefined) return null;\r\n const normalizedKey = key.trim().toLowerCase();\r\n const normalizedValue = String(value).trim().toLowerCase();\r\n\r\n const byType: Record<string, PopupBadge> = {\r\n mora: { label: 'Mora', bg: '#fee2e2', color: '#b91c1c', border: '#fecaca' },\r\n castigo: { label: 'Castigo', bg: '#ffedd5', color: '#c2410c', border: '#fed7aa' },\r\n colocacion: { label: 'Colocación', bg: '#dbeafe', color: '#1d4ed8', border: '#bfdbfe' },\r\n sano: { label: 'Sano', bg: '#dcfce7', color: '#15803d', border: '#bbf7d0' },\r\n };\r\n\r\n const byStatus: Record<string, PopupBadge> = {\r\n activo: { label: 'Activo', bg: '#dcfce7', color: '#15803d', border: '#bbf7d0' },\r\n inactivo: { label: 'Inactivo', bg: '#fef9c3', color: '#a16207', border: '#fde68a' },\r\n pendiente: { label: 'Pendiente', bg: '#fef9c3', color: '#a16207', border: '#fde68a' },\r\n cancelado: { label: 'Cancelado', bg: '#fee2e2', color: '#b91c1c', border: '#fecaca' },\r\n rechazado: { label: 'Rechazado', bg: '#fee2e2', color: '#b91c1c', border: '#fecaca' },\r\n };\r\n\r\n if (['tipo', 'type', 'category', 'categoria'].includes(normalizedKey)) {\r\n return byType[normalizedValue] ?? {\r\n label: String(value),\r\n bg: '#e0e7ff',\r\n color: '#4338ca',\r\n border: '#c7d2fe',\r\n };\r\n }\r\n\r\n if (['estado', 'status'].includes(normalizedKey)) {\r\n return byStatus[normalizedValue] ?? {\r\n label: String(value),\r\n bg: '#f1f5f9',\r\n color: '#475569',\r\n border: '#cbd5e1',\r\n };\r\n }\r\n\r\n return null;\r\n}\r\n\r\nfunction findHeaderProperties(properties: Record<string, unknown>): {\r\n title?: { key: string; value: string };\r\n badge?: { key: string; value: unknown };\r\n description?: { key: string; value: string };\r\n} {\r\n const entries = Object.entries(properties);\r\n const titleEntry = entries.find(([key, value]) =>\r\n POPUP_TITLE_KEYS.includes(key.trim().toLowerCase()) && String(value ?? '').trim().length > 0\r\n );\r\n const badgeEntry = entries.find(([key, value]) =>\r\n POPUP_BADGE_KEYS.includes(key.trim().toLowerCase()) && String(value ?? '').trim().length > 0\r\n );\r\n const descriptionEntry = entries.find(([key, value]) =>\r\n POPUP_DESCRIPTION_KEYS.includes(key.trim().toLowerCase()) && String(value ?? '').trim().length > 0\r\n );\r\n\r\n return {\r\n title: titleEntry ? { key: titleEntry[0], value: String(titleEntry[1]).trim() } : undefined,\r\n badge: badgeEntry ? { key: badgeEntry[0], value: badgeEntry[1] } : undefined,\r\n description: descriptionEntry\r\n ? { key: descriptionEntry[0], value: String(descriptionEntry[1]).trim() }\r\n : undefined,\r\n };\r\n}\r\n\r\nfunction renderPopupValue(value: unknown): string {\r\n if (value === null || value === undefined) return '<span style=\"color:#94a3b8;\">Sin datos</span>';\r\n if (value instanceof Date) {\r\n return escapeHtml(value.toLocaleDateString('es-GT'));\r\n }\r\n if (typeof value === 'number') {\r\n return escapeHtml(value.toLocaleString('es-GT'));\r\n }\r\n if (typeof value === 'string') {\r\n const trimmed = value.trim();\r\n if (!trimmed) return '<span style=\"color:#94a3b8;\">Sin datos</span>';\r\n return escapeHtml(trimmed);\r\n }\r\n if (typeof value === 'object') {\r\n try {\r\n return `<pre style=\"margin:0; white-space:pre-wrap; font-size:11px; background:#f8fafc; border:1px solid #e2e8f0; padding:6px 8px; border-radius:6px;\">${escapeHtml(\r\n JSON.stringify(value, null, 2)\r\n )}</pre>`;\r\n } catch {\r\n return escapeHtml(String(value));\r\n }\r\n }\r\n return escapeHtml(String(value));\r\n}\r\n\r\nfunction extractPopupHeader(properties: Record<string, unknown>): string | null {\r\n const header = findHeaderProperties(properties);\r\n return header.title?.value ?? null;\r\n}\r\n\r\nfunction shouldIncludePopupEntry(key: string, value: unknown): boolean {\r\n if (!key) return false;\r\n const normalized = key.trim().toLowerCase();\r\n if (!normalized) return false;\r\n if (normalized.startsWith('_')) return false;\r\n if (POPUP_EXCLUDED_KEYS.has(normalized)) return false;\r\n if (value === null || value === undefined) return false;\r\n if (typeof value === 'string' && !value.trim()) return false;\r\n return true;\r\n}\r\n\r\nexport function createPopupContent(properties: Record<string, unknown>): string {\r\n const header = findHeaderProperties(properties);\r\n const headerText = header.title?.value ?? extractPopupHeader(properties);\r\n const usedKeys = new Set([header.title?.key, header.badge?.key, header.description?.key].filter(Boolean));\r\n const badge = header.badge ? getBadgeForProperty(header.badge.key, header.badge.value) : null;\r\n const colorValue = properties.color;\r\n const colorBar =\r\n typeof colorValue === 'string' && isHexColor(colorValue)\r\n ? `<div style=\"height:6px; border-radius:8px; margin:-2px -2px 10px; background:linear-gradient(90deg, ${colorValue}, rgba(255,255,255,0.95));\"></div>`\r\n : '';\r\n const entries = Object.entries(properties).filter(([key, value]) => {\r\n if (!shouldIncludePopupEntry(key, value)) return false;\r\n if (usedKeys.has(key)) return false;\r\n return true;\r\n });\r\n\r\n if (entries.length === 0) {\r\n return '<div style=\"padding:8px 0; color:#64748b; text-align:center;\">Sin datos disponibles</div>';\r\n }\r\n\r\n const headerHtml =\r\n headerText || badge\r\n ? `<div style=\"display:flex; justify-content:space-between; gap:8px; align-items:flex-start; margin-bottom:8px;\">\r\n <div style=\"font-weight:700; font-size:14px; color:#0f172a;\">${escapeHtml(headerText ?? 'Detalle')}</div>\r\n ${\r\n badge\r\n ? `<span style=\"display:inline-flex; padding:2px 8px; border-radius:999px; font-size:11px; font-weight:700; background:${badge.bg}; color:${badge.color}; border:1px solid ${badge.border}; white-space:nowrap;\">${escapeHtml(\r\n badge.label\r\n )}</span>`\r\n : ''\r\n }\r\n </div>`\r\n : '';\r\n\r\n const descriptionHtml = header.description\r\n ? `<div style=\"margin-bottom:10px; padding:8px 10px; background:#f8fafc; border-left:3px solid #38bdf8; border-radius:6px; color:#334155; font-size:12px;\">${escapeHtml(\r\n header.description.value\r\n )}</div>`\r\n : '';\r\n const whitelistedRows = buildWhitelistedRows(properties, { colorBar, headerHtml, descriptionHtml });\r\n if (whitelistedRows) {\r\n return whitelistedRows;\r\n }\r\n\r\n const rowsHtml = entries\r\n .map(([key, value]) => {\r\n const label = escapeHtml(formatLabel(key));\r\n const normalizedKey = key.trim().toLowerCase();\r\n let valueHtml = renderPopupValue(value);\r\n if (typeof value === 'number') {\r\n valueHtml = isCurrencyField(normalizedKey)\r\n ? `<span style=\"color:#15803d; font-weight:700;\">${escapeHtml(formatCurrency(value))}</span>`\r\n : `<span style=\"color:#0369a1; font-weight:600;\">${escapeHtml(value.toLocaleString('es-GT'))}</span>`;\r\n }\r\n return `\r\n <div style=\"display:grid; grid-template-columns:minmax(90px, 35%) 1fr; gap:8px; padding:6px 0; border-bottom:1px solid #e2e8f0;\">\r\n <div style=\"font-size:11px; font-weight:600; text-transform:uppercase; letter-spacing:0.04em; color:#64748b;\">${label}</div>\r\n <div style=\"font-size:13px; color:#0f172a; word-break:break-word;\">${valueHtml}</div>\r\n </div>\r\n `;\r\n })\r\n .join('');\r\n\r\n return `<div>${colorBar}${headerHtml}${descriptionHtml}${rowsHtml}</div>`;\r\n}\r\n\r\nfunction buildWhitelistedRows(\r\n properties: Record<string, unknown>,\r\n headerSections: { colorBar: string; headerHtml: string; descriptionHtml: string }\r\n): string | null {\r\n const selection = selectModalWhitelist(properties);\r\n if (!selection) {\r\n logModalWhitelistDebug({\r\n modalType: 'generic',\r\n properties,\r\n entries: [],\r\n whitelist: null,\r\n fallbackToGeneric: true,\r\n });\r\n return null;\r\n }\r\n\r\n const { whitelist, modalType } = selection;\r\n const entries = applyModalWhitelist(properties, whitelist);\r\n if (entries.length === 0) {\r\n logModalWhitelistDebug({\r\n modalType,\r\n properties,\r\n entries,\r\n whitelist,\r\n fallbackToGeneric: true,\r\n });\r\n return null;\r\n }\r\n\r\n logModalWhitelistDebug({\r\n modalType,\r\n properties,\r\n entries,\r\n whitelist,\r\n fallbackToGeneric: false,\r\n });\r\n\r\n const rowsHtml = entries\r\n .map(({ label, value }) => {\r\n const valueHtml = renderPopupValue(value);\r\n return `\r\n <div style=\"display:grid; grid-template-columns:minmax(90px, 35%) 1fr; gap:8px; padding:6px 0; border-bottom:1px solid #e2e8f0;\">\r\n <div style=\"font-size:11px; font-weight:600; text-transform:uppercase; letter-spacing:0.04em; color:#64748b;\">${escapeHtml(label)}</div>\r\n <div style=\"font-size:13px; color:#0f172a; word-break:break-word;\">${valueHtml}</div>\r\n </div>\r\n `;\r\n })\r\n .join('');\r\n\r\n return `<div>${headerSections.colorBar}${headerSections.headerHtml}${headerSections.descriptionHtml}${rowsHtml}</div>`;\r\n}\r\n\r\nfunction hasAnyKey(properties: Record<string, unknown>, candidates: string[]): boolean {\r\n const normalizedKeys = new Set(Object.keys(properties).map((key) => normalizeKey(key)));\r\n return candidates.some((candidate) => normalizedKeys.has(normalizeKey(candidate)));\r\n}\r\n\r\ntype ModalType = 'cliente' | 'sector' | 'generic';\r\n\r\nfunction selectModalWhitelist(\r\n properties: Record<string, unknown>\r\n): { modalType: Exclude<ModalType, 'generic'>; whitelist: ModalWhitelistItem[] } | null {\r\n if (hasAnyKey(properties, ['nombre_del_cliente', 'dpi', 'capital_concedido', 'kpi'])) {\r\n return { modalType: 'cliente', whitelist: CLIENTE_MODAL_WHITELIST };\r\n }\r\n\r\n if (hasAnyKey(properties, ['nom_sector', 'NOM_SECTOR', 'total_clientes_sector', 'capital_total', 'impacto_sector'])) {\r\n return { modalType: 'sector', whitelist: SECTOR_MODAL_WHITELIST };\r\n }\r\n\r\n return null;\r\n}\r\n\r\nfunction logModalWhitelistDebug(options: {\r\n modalType: ModalType;\r\n properties: Record<string, unknown>;\r\n entries: Array<{ id: string; matchedKey: string }>;\r\n whitelist: ModalWhitelistItem[] | null;\r\n fallbackToGeneric: boolean;\r\n}): void {\r\n if (process.env.NODE_ENV === 'production') return;\r\n\r\n const { modalType, properties, entries, whitelist, fallbackToGeneric } = options;\r\n const matchedIds = new Set(entries.map((entry) => entry.id));\r\n const missingFields = (whitelist ?? []).filter((item) => !matchedIds.has(item.id)).map((item) => item.id);\r\n\r\n console.info('[modal-whitelist]', {\r\n modalType,\r\n keys: Object.keys(properties),\r\n matchedFields: entries.map((entry) => ({ id: entry.id, matchedKey: entry.matchedKey })),\r\n missingFields,\r\n fallbackToGeneric,\r\n });\r\n}\r\n\r\nfunction isPolygonType(layerType?: string, geometryType?: string): boolean {\r\n const candidate = (layerType ?? geometryType ?? '').toLowerCase();\r\n return candidate === 'polygon' || candidate === 'multipolygon';\r\n}\r\n\r\nexport function calculateZoomBasedOpacity(\r\n zoom: number,\r\n baseOpacity: number,\r\n layerType?: string,\r\n geometryType?: string\r\n): number {\r\n if (!isPolygonType(layerType, geometryType)) return clampOpacity(baseOpacity);\r\n\r\n const minZoom = 11;\r\n const maxZoom = 15;\r\n const minFactor = 0.5;\r\n\r\n if (maxZoom <= minZoom) return clampOpacity(baseOpacity * minFactor);\r\n\r\n const t = clampNumber((zoom - minZoom) / (maxZoom - minZoom), 0, 1);\r\n const factor = 1 - (1 - minFactor) * t;\r\n return clampOpacity(baseOpacity * factor);\r\n}\r\n\r\nexport function layerStyleToLeaflet(options: {\r\n baseOpacity: number;\r\n zoom: number;\r\n layerStyle?: LayerStyle | null;\r\n geometryType?: string;\r\n layerType?: string;\r\n properties?: Record<string, unknown>;\r\n}): PathOptions {\r\n const { baseOpacity, zoom, layerStyle, geometryType, layerType, properties } = options;\r\n const sanitizedOpacity = clampOpacity(baseOpacity);\r\n const zoomOpacity = calculateZoomBasedOpacity(zoom, sanitizedOpacity, layerType, geometryType);\r\n const badgeForType = getBadgeForProperty('type', properties?.type ?? properties?.tipo ?? properties?.category ?? properties?.categoria);\r\n const badgeForStatus = getBadgeForProperty('status', properties?.status ?? properties?.estado);\r\n const featureColor =\r\n (typeof properties?.color === 'string' && properties.color.trim().length > 0 ? properties.color : undefined) ??\r\n badgeForType?.color ??\r\n badgeForStatus?.color;\r\n const styleFillOpacity =\r\n typeof layerStyle?.fillOpacity === 'number'\r\n ? clampOpacity(layerStyle.fillOpacity)\r\n : 0.65;\r\n\r\n const fallbackColor = '#2563eb';\r\n const resolvedColor = featureColor ?? layerStyle?.color ?? layerStyle?.fillColor ?? fallbackColor;\r\n const resolvedFillColor = featureColor ?? layerStyle?.fillColor ?? layerStyle?.color ?? fallbackColor;\r\n\r\n return {\r\n color: resolvedColor,\r\n weight: layerStyle?.weight ?? 2,\r\n fillColor: resolvedFillColor,\r\n opacity: clampOpacity(Math.max(0.35, zoomOpacity * 0.9)),\r\n fillOpacity: clampOpacity(zoomOpacity * styleFillOpacity),\r\n };\r\n}\r\n\r\nfunction getRgbFromColor(color: string): { r: number; g: number; b: number } | null {\r\n const trimmed = color.trim();\r\n if (trimmed.startsWith('#')) {\r\n const hex = trimmed.replace('#', '');\r\n const expanded =\r\n hex.length === 3\r\n ? hex\r\n .split('')\r\n .map((char) => `${char}${char}`)\r\n .join('')\r\n : hex;\r\n if (expanded.length === 6) {\r\n const r = parseInt(expanded.slice(0, 2), 16);\r\n const g = parseInt(expanded.slice(2, 4), 16);\r\n const b = parseInt(expanded.slice(4, 6), 16);\r\n return { r, g, b };\r\n }\r\n }\r\n\r\n const rgbMatch = trimmed.match(/rgba?\\(([^)]+)\\)/i);\r\n if (rgbMatch) {\r\n const [r, g, b] = rgbMatch[1]\r\n .split(',')\r\n .map((value) => parseFloat(value.trim()))\r\n .slice(0, 3);\r\n if ([r, g, b].every((value) => Number.isFinite(value))) {\r\n return { r, g, b };\r\n }\r\n }\r\n\r\n return null;\r\n}\r\n\r\nfunction getLabelTextStyles(color: string): { color: string; shadow: string } {\r\n const rgb = getRgbFromColor(color);\r\n if (!rgb) {\r\n return { color: '#0f172a', shadow: '0 1px 2px rgba(255, 255, 255, 0.6)' };\r\n }\r\n\r\n const luminance = (0.2126 * rgb.r + 0.7152 * rgb.g + 0.0722 * rgb.b) / 255;\r\n if (luminance > 0.6) {\r\n return { color: '#0f172a', shadow: '0 1px 2px rgba(255, 255, 255, 0.7)' };\r\n }\r\n\r\n return { color: '#ffffff', shadow: '0 1px 2px rgba(0, 0, 0, 0.4)' };\r\n}\r\n\r\nfunction withAlpha(color: string, alpha: number): string {\r\n const trimmed = color.trim();\r\n if (trimmed.startsWith('#')) {\r\n const hex = trimmed.replace('#', '');\r\n const expanded =\r\n hex.length === 3\r\n ? hex\r\n .split('')\r\n .map((char) => `${char}${char}`)\r\n .join('')\r\n : hex;\r\n if (expanded.length === 6) {\r\n const r = parseInt(expanded.slice(0, 2), 16);\r\n const g = parseInt(expanded.slice(2, 4), 16);\r\n const b = parseInt(expanded.slice(4, 6), 16);\r\n return `rgba(${r}, ${g}, ${b}, ${alpha})`;\r\n }\r\n }\r\n\r\n if (trimmed.startsWith('rgb(')) {\r\n const inner = trimmed.slice(4, -1);\r\n return `rgba(${inner}, ${alpha})`;\r\n }\r\n\r\n if (trimmed.startsWith('rgba(')) {\r\n const inner = trimmed.slice(5, -1).split(',').slice(0, 3).map((value) => value.trim());\r\n return `rgba(${inner.join(', ')}, ${alpha})`;\r\n }\r\n\r\n return color;\r\n}\r\n\r\nexport function createCustomIcon(label: string, opacity: number, color: string): L.DivIcon {\r\n const size = 60;\r\n const innerSize = 44;\r\n const textStyles = getLabelTextStyles(color);\r\n const safeLabel = escapeHtml(label);\r\n const clampedOpacity = Math.min(1, Math.max(0.92, opacity));\r\n const innerBackground = withAlpha(color, 0.9);\r\n\r\n return L.divIcon({\r\n className: 'zenit-label-marker',\r\n iconSize: [size, size],\r\n iconAnchor: [size / 2, size / 2],\r\n html: `\r\n <div\r\n title=\"${safeLabel}\"\r\n style=\"\r\n width:${size}px;\r\n height:${size}px;\r\n border-radius:9999px;\r\n background:rgba(255, 255, 255, 0.95);\r\n border:3px solid rgba(255, 255, 255, 1);\r\n display:flex;\r\n align-items:center;\r\n justify-content:center;\r\n opacity:${clampedOpacity};\r\n box-shadow:0 2px 6px rgba(0, 0, 0, 0.25);\r\n pointer-events:none;\r\n \"\r\n >\r\n <div\r\n style=\"\r\n width:${innerSize}px;\r\n height:${innerSize}px;\r\n border-radius:9999px;\r\n background:${innerBackground};\r\n display:flex;\r\n align-items:center;\r\n justify-content:center;\r\n box-shadow:inset 0 0 0 1px rgba(15, 23, 42, 0.12);\r\n \"\r\n >\r\n <span\r\n style=\"\r\n color:${textStyles.color};\r\n font-size:20px;\r\n font-weight:800;\r\n text-shadow:${textStyles.shadow};\r\n \"\r\n >\r\n ${safeLabel}\r\n </span>\r\n </div>\r\n </div>\r\n `,\r\n });\r\n}\r\n\r\nexport function createLocationIcon(): L.DivIcon {\r\n return L.divIcon({\r\n className: 'zenit-location-marker',\r\n iconSize: [18, 18],\r\n iconAnchor: [9, 9],\r\n html: `\r\n <div style=\"width:18px;height:18px;border-radius:9999px;background:#2563eb;border:2px solid #fff;box-shadow:0 0 0 4px rgba(37, 99, 235, 0.25);\"></div>\r\n `,\r\n });\r\n}\r\n","export type ModalWhitelistItem = {\r\n id: string;\r\n label: string;\r\n aliases: string[];\r\n hint?: 'trend_icon' | 'collapsible' | 'kpi_badge' | 'phone_link' | 'mora_alert';\r\n};\r\n\r\nexport type WhitelistedModalField = {\r\n id: string;\r\n label: string;\r\n value: unknown;\r\n hint: ModalWhitelistItem['hint'] | null;\r\n matchedKey: string;\r\n};\r\n\r\nexport function normalizeKey(value: string): string {\r\n return value\r\n .normalize('NFD')\r\n .replace(/\\p{Diacritic}/gu, '')\r\n .replace(/[_\\s-]+/g, '')\r\n .toLowerCase()\r\n .trim();\r\n}\r\n\r\n// ─── MODAL DE CLIENTE ───────────────────────────────────────────\r\nexport const CLIENTE_MODAL_WHITELIST: ModalWhitelistItem[] = [\r\n {\r\n id: 'nombre_cliente',\r\n label: 'Nombre del Cliente',\r\n aliases: ['nombre_del_cliente', 'nombre cliente', 'nombre_del_cliente ', 'NOMBRE_CLIENTE'],\r\n },\r\n {\r\n id: 'dpi',\r\n label: 'DPI',\r\n aliases: ['dpi', 'DPI'],\r\n },\r\n {\r\n id: 'kpi',\r\n label: 'Estado',\r\n aliases: ['kpi', 'KPI'],\r\n hint: 'kpi_badge',\r\n },\r\n {\r\n id: 'tel_principal',\r\n label: 'Teléfono',\r\n aliases: ['tel_principal', 'tel principal', 'telefono', 'telefono_principal', 'TEL_PRINCIPAL'],\r\n hint: 'phone_link',\r\n },\r\n {\r\n id: 'capital_concedido',\r\n label: 'Capital Concedido',\r\n aliases: ['capital_concedido', 'capital concedido', 'CAPITAL_CONCEDIDO'],\r\n },\r\n {\r\n id: 'mora',\r\n label: 'Monto en Mora',\r\n aliases: ['mora', 'MORA'],\r\n hint: 'mora_alert',\r\n },\r\n {\r\n id: 'etapa',\r\n label: 'Etapa del Crédito',\r\n aliases: ['etapa', 'ETAPA'],\r\n },\r\n {\r\n id: 'prestamo',\r\n label: 'No. de Préstamo',\r\n aliases: ['prestamo', 'prestamo_id', 'no_prestamo', 'numero_prestamo', 'PRESTAMO'],\r\n },\r\n {\r\n id: 'sucursal',\r\n label: 'Sucursal',\r\n aliases: ['sucursal', 'nombre_sucursal', 'nombre sucursal', 'SUCURSAL'],\r\n },\r\n];\r\n\r\n// ─── MODAL DE SECTOR ───────────────────────────────────────────\r\nexport const SECTOR_MODAL_WHITELIST: ModalWhitelistItem[] = [\r\n { id: 'sector', label: 'Sector', aliases: ['nom_sector', 'NOM_SECTOR', 'sector', 'SECTOR'] },\r\n { id: 'promotor', label: 'Promotor', aliases: ['promotor', 'PROMOTOR'] },\r\n { id: 'capital_total', label: 'Capital Total', aliases: ['capital_total', 'capital total', 'CAPITAL_TOTAL'] },\r\n {\r\n id: 'total_capital_mora',\r\n label: 'Total Capital Mora',\r\n aliases: ['total_capital_mora', 'total capital mora', 'TOTAL_CAPITAL_MORA'],\r\n },\r\n {\r\n id: 'tendencia_mora',\r\n label: 'Tendencia Mora',\r\n aliases: ['tendencia_mora', 'tendencia mora', 'TENDENCIA_MORA'],\r\n hint: 'trend_icon',\r\n },\r\n {\r\n id: 'tendencia_capital',\r\n label: 'Tendencia Capital',\r\n aliases: ['tendencia_capital', 'tendencia capital', 'TENDENCIA_CAPITAL'],\r\n hint: 'trend_icon',\r\n },\r\n {\r\n id: 'tendencia_castigos',\r\n label: 'Tendencia Castigos',\r\n aliases: ['tendencia_castigos', 'tendencia castigos', 'TENDENCIA_CASTIGOS'],\r\n hint: 'trend_icon',\r\n },\r\n {\r\n id: 'impacto_sector',\r\n label: 'Impacto Sector',\r\n aliases: ['impacto_sector', 'impacto sector', 'IMPACTO_SECTOR'],\r\n },\r\n {\r\n id: 'total_clientes_sector',\r\n label: 'Total Clientes Sector',\r\n aliases: ['total_clientes_sector', 'total clientes sector', 'TOTAL_CLIENTES_SECTOR'],\r\n },\r\n {\r\n id: 'total_clientes_sanos',\r\n label: 'Total Clientes Sanos',\r\n aliases: ['total_clientes_sanos', 'total clientes sanos', 'TOTAL_CLIENTES_SANOS'],\r\n },\r\n {\r\n id: 'total_clientes_morosos',\r\n label: 'Total Clientes Morosos',\r\n aliases: ['total_clientes_morosos', 'total clientes morosos', 'TOTAL_CLIENTES_MOROSOS'],\r\n },\r\n {\r\n id: 'total_clientes_castigados',\r\n label: 'Total Clientes Castigados',\r\n aliases: ['total_clientes_castigados', 'total clientes castigados', 'TOTAL_CLIENTES_CASTIGADOS'],\r\n },\r\n {\r\n id: 'total_clientes_nuevos',\r\n label: 'Total Clientes Nuevos',\r\n aliases: ['total_clientes_nuevos', 'total clientes nuevos', 'TOTAL_CLIENTES_NUEVOS'],\r\n },\r\n {\r\n id: 'total_clientes_salidos',\r\n label: 'Total Clientes Salidos',\r\n aliases: ['total_clientes_salidos', 'total clientes salidos', 'TOTAL_CLIENTES_SALIDOS'],\r\n },\r\n { id: 'insights', label: 'Insights', aliases: ['insights', 'INSIGHTS'], hint: 'collapsible' },\r\n {\r\n id: 'recomendaciones',\r\n label: 'Recomendaciones',\r\n aliases: ['recomendaciones', 'RECOMENDACIONES'],\r\n hint: 'collapsible',\r\n },\r\n];\r\n\r\n/**\r\n * Filtra y ordena los datos de un modal según la whitelist.\r\n * @param rawData - Todos los campos que vienen del backend\r\n * @param whitelist - SECTOR_MODAL_WHITELIST o CLIENTE_MODAL_WHITELIST\r\n * @returns [{ id, label, value, hint, matchedKey }] listos para renderizar\r\n */\r\nexport function applyModalWhitelist(\r\n rawData: Record<string, unknown>,\r\n whitelist: ModalWhitelistItem[]\r\n): WhitelistedModalField[] {\r\n const keyByNormalized = new Map<string, string>();\r\n\r\n Object.keys(rawData ?? {}).forEach((rawKey) => {\r\n const normalized = normalizeKey(rawKey);\r\n if (!normalized || keyByNormalized.has(normalized)) return;\r\n keyByNormalized.set(normalized, rawKey);\r\n });\r\n\r\n return whitelist\r\n .map(({ id, label, hint, aliases }) => {\r\n const candidates = [...aliases, id];\r\n\r\n for (const candidate of candidates) {\r\n const matchedKey = keyByNormalized.get(normalizeKey(candidate));\r\n if (!matchedKey) continue;\r\n const value = rawData[matchedKey];\r\n if (value === null || value === undefined) continue;\r\n\r\n return { id, label, value, hint: hint ?? null, matchedKey };\r\n }\r\n\r\n return null;\r\n })\r\n .filter((entry): entry is WhitelistedModalField => Boolean(entry));\r\n}\r\n","import React, { useEffect, useRef } from 'react';\r\nimport { useMap } from 'react-leaflet';\r\nimport type { LatLngBoundsExpression, Map as LeafletMap } from 'leaflet';\r\nimport type { Bbox, GeoJsonFeatureCollection } from '../../layers/types';\r\n\r\ntype MapInvalidatorProps = {\r\n trigger?: unknown;\r\n};\r\n\r\nexport const MapInvalidator: React.FC<MapInvalidatorProps> = ({ trigger }) => {\r\n const map = useMap();\r\n const lastTrigger = useRef<unknown>(undefined);\r\n\r\n useEffect(() => {\r\n if (lastTrigger.current === trigger) return;\r\n lastTrigger.current = trigger;\r\n requestAnimationFrame(() => {\r\n map.invalidateSize();\r\n });\r\n }, [map, trigger]);\r\n\r\n return null;\r\n};\r\n\r\nfunction computeBBoxFromGeojson(geojson?: GeoJsonFeatureCollection | null): Bbox | null {\r\n if (!geojson || !Array.isArray(geojson.features)) return null;\r\n const coords: Array<[number, number]> = [];\r\n\r\n const collect = (candidate: unknown) => {\r\n if (!Array.isArray(candidate)) return;\r\n if (\r\n candidate.length === 2 &&\r\n typeof candidate[0] === 'number' &&\r\n typeof candidate[1] === 'number' &&\r\n Number.isFinite(candidate[0]) &&\r\n Number.isFinite(candidate[1])\r\n ) {\r\n coords.push([candidate[0], candidate[1]]);\r\n return;\r\n }\r\n\r\n candidate.forEach((item) => collect(item));\r\n };\r\n\r\n geojson.features.forEach((feature) => {\r\n collect((feature as { geometry?: { coordinates?: unknown } }).geometry?.coordinates);\r\n });\r\n\r\n if (coords.length === 0) return null;\r\n\r\n const [firstLon, firstLat] = coords[0];\r\n const bbox: Bbox = { minLon: firstLon, minLat: firstLat, maxLon: firstLon, maxLat: firstLat };\r\n\r\n coords.forEach(([lon, lat]) => {\r\n bbox.minLon = Math.min(bbox.minLon, lon);\r\n bbox.minLat = Math.min(bbox.minLat, lat);\r\n bbox.maxLon = Math.max(bbox.maxLon, lon);\r\n bbox.maxLat = Math.max(bbox.maxLat, lat);\r\n });\r\n\r\n return bbox;\r\n}\r\n\r\nfunction mergeBBoxes(bboxes: Array<Bbox | null>): Bbox | null {\r\n const valid = bboxes.filter((bbox): bbox is Bbox => !!bbox);\r\n if (valid.length === 0) return null;\r\n\r\n const first = valid[0];\r\n return valid.slice(1).reduce(\r\n (acc, bbox) => ({\r\n minLon: Math.min(acc.minLon, bbox.minLon),\r\n minLat: Math.min(acc.minLat, bbox.minLat),\r\n maxLon: Math.max(acc.maxLon, bbox.maxLon),\r\n maxLat: Math.max(acc.maxLat, bbox.maxLat),\r\n }),\r\n { ...first }\r\n );\r\n}\r\n\r\ntype BBoxZoomHandlerProps = {\r\n bbox?: Bbox | null;\r\n geojson?: GeoJsonFeatureCollection | null;\r\n autoGeojson?: GeoJsonFeatureCollection[];\r\n enabled?: boolean;\r\n};\r\n\r\nexport const BBoxZoomHandler: React.FC<BBoxZoomHandlerProps> = ({\r\n bbox,\r\n geojson,\r\n autoGeojson = [],\r\n enabled = true,\r\n}) => {\r\n const map = useMap();\r\n const lastAppliedBBox = useRef<string | null>(null);\r\n const lastUserInteracted = useRef(false);\r\n\r\n useEffect(() => {\r\n const handleInteraction = () => {\r\n lastUserInteracted.current = true;\r\n };\r\n\r\n map.on('dragstart', handleInteraction);\r\n map.on('zoomstart', handleInteraction);\r\n\r\n return () => {\r\n map.off('dragstart', handleInteraction);\r\n map.off('zoomstart', handleInteraction);\r\n };\r\n }, [map]);\r\n\r\n useEffect(() => {\r\n if (!enabled) return;\r\n\r\n let resolvedBBox = bbox ?? null;\r\n\r\n if (!resolvedBBox && geojson) {\r\n resolvedBBox = computeBBoxFromGeojson(geojson);\r\n }\r\n\r\n if (!resolvedBBox && autoGeojson.length > 0) {\r\n const bboxes = autoGeojson.map((collection) => computeBBoxFromGeojson(collection));\r\n resolvedBBox = mergeBBoxes(bboxes);\r\n }\r\n\r\n if (!resolvedBBox) return;\r\n\r\n const serialized = JSON.stringify(resolvedBBox);\r\n if (lastAppliedBBox.current === serialized) return;\r\n\r\n if (lastUserInteracted.current && !bbox && !geojson) {\r\n lastUserInteracted.current = false;\r\n return;\r\n }\r\n\r\n const bounds: LatLngBoundsExpression = [\r\n [resolvedBBox.minLat, resolvedBBox.minLon],\r\n [resolvedBBox.maxLat, resolvedBBox.maxLon],\r\n ];\r\n map.fitBounds(bounds, { padding: [12, 12] });\r\n lastAppliedBBox.current = serialized;\r\n }, [autoGeojson, bbox, enabled, geojson, map]);\r\n\r\n return null;\r\n};\r\n\r\ntype ZoomBasedOpacityHandlerProps = {\r\n onZoomChange: (zoom: number) => void;\r\n};\r\n\r\nexport const ZoomBasedOpacityHandler: React.FC<ZoomBasedOpacityHandlerProps> = ({ onZoomChange }) => {\r\n const map = useMap();\r\n\r\n useEffect(() => {\r\n const handleZoom = () => {\r\n onZoomChange(map.getZoom());\r\n };\r\n\r\n map.on('zoomend', handleZoom);\r\n handleZoom();\r\n\r\n return () => {\r\n map.off('zoomend', handleZoom);\r\n };\r\n }, [map, onZoomChange]);\r\n\r\n return null;\r\n};\r\n\r\ntype MapInstanceBridgeProps = {\r\n onReady: (mapInstance: LeafletMap) => void;\r\n};\r\n\r\nexport const MapInstanceBridge: React.FC<MapInstanceBridgeProps> = ({ onReady }) => {\r\n const map = useMap();\r\n\r\n useEffect(() => {\r\n onReady(map);\r\n }, [map, onReady]);\r\n\r\n return null;\r\n};\r\n","import React, { useEffect, useMemo, useRef, useState } from 'react';\r\nimport type { ZenitClient } from '../config/ZenitSdkConfig';\r\nimport type { GeoJsonPolygon, LayerDto } from '../layers/types';\r\nimport type { MapDto, MapLayerConfig } from '../maps/types';\r\nimport { extractMapDto, normalizeMapCenter, normalizeMapLayers } from '../maps/helpers';\r\nimport type { EffectiveLayerState, LayerOverrideState } from '../engine/LayerStateEngine';\r\nimport { applyLayerOverrides, initLayerStates } from '../engine/LayerStateEngine';\r\nimport { Eye, EyeOff, Layers, Upload } from './icons';\r\nimport { ZenitSelect } from './ui/ZenitSelect';\r\nimport { ZenitCombobox } from './ui/ZenitCombobox';\r\nimport { getEffectiveLayerOpacity } from './zoomOpacity';\r\n\r\nexport interface LayerStyle {\r\n color?: string;\r\n weight?: number;\r\n fillColor?: string;\r\n fillOpacity?: number;\r\n}\r\n\r\nexport interface ZenitLayerManagerProps {\r\n client: ZenitClient;\r\n mapId: number | string;\r\n side?: 'left' | 'right';\r\n className?: string;\r\n style?: React.CSSProperties;\r\n height?: string;\r\n layerStates?: EffectiveLayerState[];\r\n onLayerStatesChange?: (states: EffectiveLayerState[]) => void;\r\n mapZoom?: number;\r\n autoOpacityOnZoom?: boolean;\r\n autoOpacityConfig?: {\r\n minZoom?: number;\r\n maxZoom?: number;\r\n minOpacity?: number;\r\n maxOpacity?: number;\r\n };\r\n showUploadTab?: boolean;\r\n showLayerVisibilityIcon?: boolean;\r\n layerFeatureCounts?: Record<string | number, number | null | undefined>;\r\n mapLayers?: Array<{\r\n layerId: number | string;\r\n geometryType?: string | null;\r\n layerType?: string | null;\r\n name?: string | null;\r\n style?: LayerStyle | null;\r\n bboxGeometry?: GeoJsonPolygon | null;\r\n displayOrder?: number | null;\r\n }>;\r\n onZoomToLayer?: (layerId: number | string, bboxGeometry?: GeoJsonPolygon | null) => void;\r\n onApplyLayerFilter?: (params: {\r\n layerId: number | string;\r\n field: string;\r\n value: string;\r\n }) => Promise<void> | void;\r\n onClearLayerFilter?: (params: { layerId: number | string; field?: string }) => Promise<void> | void;\r\n availableFilterLayers?: Array<number | string>;\r\n filterFieldWhitelist?: string[];\r\n}\r\n\r\ntype MapLayerWithId = MapLayerConfig & { layerId: number | string; layer?: LayerDto };\r\n\r\ninterface ManagedLayerState {\r\n mapLayer: MapLayerWithId;\r\n layer?: LayerDto;\r\n effective?: EffectiveLayerState;\r\n visible?: boolean;\r\n opacity?: number;\r\n displayOrder?: number;\r\n initialIndex?: number;\r\n featureCount?: number | null;\r\n layerName?: string;\r\n}\r\n\r\nconst FLOAT_TOLERANCE = 0.001;\r\n\r\nconst CATALOG_FIELD_BLACKLIST = new Set([\r\n 'mapids', 'mapId', 'mapIDs', 'mapId',\r\n 'field', 'Field',\r\n 'objectid', 'OBJECTID', 'objectId',\r\n 'gforms', 'GFORMS',\r\n 'nomina', 'NOMINA',\r\n 'shape_area', 'SHAPE_AREA',\r\n 'shape_leng', 'SHAPE_LENG',\r\n 'fid', 'FID', 'gid', 'GID',\r\n 'created_at', 'updated_at',\r\n 'created_user', 'last_edited_user',\r\n 'globalid', 'GLOBALID',\r\n]);\r\n\r\nfunction isFieldVisible(key: string): boolean {\r\n return (\r\n !CATALOG_FIELD_BLACKLIST.has(key) &&\r\n !key.startsWith('_') &&\r\n !key.startsWith('__')\r\n );\r\n}\r\n\r\nconst matchesWhitelist = (key: string, whitelist: string[]) =>\r\n whitelist.some((w) => w.toUpperCase() === key.toUpperCase());\r\n\r\nfunction areEffectiveStatesEqual(a: EffectiveLayerState[], b: EffectiveLayerState[]): boolean {\r\n if (a.length !== b.length) return false;\r\n return a.every((state, index) => {\r\n const other = b[index];\r\n if (!other) return false;\r\n const opacityDiff = Math.abs((state.opacity ?? 1) - (other.opacity ?? 1));\r\n return (\r\n String(state.layerId) === String(other.layerId) &&\r\n (state.visible ?? false) === (other.visible ?? false) &&\r\n opacityDiff <= FLOAT_TOLERANCE\r\n );\r\n });\r\n}\r\n\r\nfunction getLayerColor(style?: LayerStyle | null): string {\r\n if (!style) return '#94a3b8';\r\n\r\n return style.fillColor ?? style.color ?? '#94a3b8';\r\n}\r\n\r\nfunction resolveDisplayOrder(value?: number | string | null): number {\r\n if (typeof value === 'number' && Number.isFinite(value)) return value;\r\n if (typeof value === 'string') {\r\n const parsed = Number.parseFloat(value);\r\n if (Number.isFinite(parsed)) return parsed;\r\n }\r\n return 0;\r\n}\r\n\r\nexport const ZenitLayerManager: React.FC<ZenitLayerManagerProps> = ({\r\n client,\r\n mapId,\r\n side = 'right',\r\n className,\r\n style,\r\n height,\r\n layerStates,\r\n onLayerStatesChange,\r\n mapZoom,\r\n autoOpacityOnZoom = false,\r\n autoOpacityConfig,\r\n showUploadTab = true,\r\n showLayerVisibilityIcon = true,\r\n layerFeatureCounts,\r\n mapLayers,\r\n onApplyLayerFilter,\r\n onClearLayerFilter,\r\n availableFilterLayers = [],\r\n filterFieldWhitelist = [],\r\n}) => {\r\n const [map, setMap] = useState<MapDto | null>(null);\r\n const [loadingMap, setLoadingMap] = useState(false);\r\n const [mapError, setMapError] = useState<string | null>(null);\r\n const [layers, setLayers] = useState<ManagedLayerState[]>([]);\r\n const [activeTab, setActiveTab] = useState<'layers' | 'filters' | 'upload'>('layers');\r\n const [panelVisible, setPanelVisible] = useState(true);\r\n const [selectedFilterLayerId, setSelectedFilterLayerId] = useState<string>('');\r\n const [selectedFilterField, setSelectedFilterField] = useState<string>('');\r\n const [selectedFilterValue, setSelectedFilterValue] = useState<string>('');\r\n const [catalogByLayerField, setCatalogByLayerField] = useState<Record<string, string[]>>({});\r\n const [catalogFieldsByLayer, setCatalogFieldsByLayer] = useState<Record<string, string[]>>({});\r\n const [loadingCatalog, setLoadingCatalog] = useState(false);\r\n const [applyingFilter, setApplyingFilter] = useState(false);\r\n const [filterError, setFilterError] = useState<string | null>(null);\r\n const [appliedFilter, setAppliedFilter] = useState<{\r\n layerId: number | string;\r\n field: string;\r\n value: string;\r\n } | null>(null);\r\n const catalogAbortRef = useRef<AbortController | null>(null);\r\n const lastEmittedStatesRef = useRef<EffectiveLayerState[] | null>(null);\r\n // Controlled mode: emit changes to parent instead of mutating local layer state.\r\n const isControlled = Array.isArray(layerStates) && typeof onLayerStatesChange === 'function';\r\n\r\n const baseStates = useMemo(\r\n () =>\r\n initLayerStates(\r\n layers.map((entry) => ({\r\n ...entry.mapLayer,\r\n layerId: entry.mapLayer.layerId,\r\n isVisible: entry.visible,\r\n opacity: entry.opacity,\r\n })) as MapLayerWithId[]\r\n ),\r\n [layers]\r\n );\r\n\r\n const overrideStates = useMemo(\r\n () =>\r\n layers.map(\r\n (entry): LayerOverrideState => ({\r\n layerId: entry.mapLayer.layerId,\r\n overrideVisible: entry.visible,\r\n overrideOpacity: entry.opacity,\r\n })\r\n ),\r\n [layers]\r\n );\r\n\r\n const effectiveStates = useMemo(\r\n () => layerStates ?? applyLayerOverrides(baseStates, overrideStates),\r\n [baseStates, layerStates, overrideStates]\r\n );\r\n\r\n const layerMetaIndex = useMemo(() => {\r\n const index = new Map<string, { layerType?: string; geometryType?: string }>();\r\n mapLayers?.forEach((entry) => {\r\n const key = String(entry.layerId);\r\n index.set(key, { layerType: entry.layerType ?? undefined, geometryType: entry.geometryType ?? undefined });\r\n });\r\n map?.mapLayers?.forEach((entry) => {\r\n const key = String(entry.layerId);\r\n if (!index.has(key)) {\r\n index.set(key, { layerType: entry.layerType ?? undefined, geometryType: entry.geometryType ?? undefined });\r\n }\r\n });\r\n return index;\r\n }, [map, mapLayers]);\r\n\r\n const resolveUserOpacity = React.useCallback((state: EffectiveLayerState): number => {\r\n if (typeof state.overrideOpacity === 'number') return state.overrideOpacity;\r\n if (typeof state.overrideOpacity === 'string') {\r\n const parsed = Number.parseFloat(state.overrideOpacity);\r\n if (Number.isFinite(parsed)) return parsed;\r\n }\r\n return state.opacity ?? 1;\r\n }, []);\r\n\r\n const resolveEffectiveOpacity = React.useCallback(\r\n (layerId: number | string, userOpacity: number): number => {\r\n if (!autoOpacityOnZoom || typeof mapZoom !== 'number') {\r\n return userOpacity;\r\n }\r\n const meta = layerMetaIndex.get(String(layerId));\r\n return getEffectiveLayerOpacity(\r\n userOpacity,\r\n mapZoom,\r\n meta?.layerType,\r\n meta?.geometryType,\r\n autoOpacityConfig\r\n );\r\n },\r\n [autoOpacityConfig, autoOpacityOnZoom, layerMetaIndex, mapZoom]\r\n );\r\n\r\n const effectiveStatesWithZoom = useMemo(() => {\r\n if (!autoOpacityOnZoom || typeof mapZoom !== 'number') {\r\n return effectiveStates;\r\n }\r\n\r\n return effectiveStates.map((state) => {\r\n const userOpacity = resolveUserOpacity(state);\r\n const adjustedOpacity = resolveEffectiveOpacity(state.layerId, userOpacity);\r\n return {\r\n ...state,\r\n opacity: adjustedOpacity,\r\n overrideOpacity: userOpacity,\r\n };\r\n });\r\n }, [autoOpacityOnZoom, effectiveStates, mapZoom, resolveEffectiveOpacity, resolveUserOpacity]);\r\n\r\n useEffect(() => {\r\n let cancelled = false;\r\n setLoadingMap(true);\r\n setMapError(null);\r\n setLayers([]);\r\n client.maps\r\n .getMap(mapId, true)\r\n .then((mapResponse) => {\r\n if (cancelled) return;\r\n const extractedMap = extractMapDto(mapResponse);\r\n const resolvedMap = extractedMap ? normalizeMapCenter(extractedMap) : null;\r\n setMap(resolvedMap);\r\n const normalizedLayers = normalizeMapLayers(resolvedMap);\r\n setLayers(\r\n normalizedLayers.map((entry, index) => ({\r\n mapLayer: { ...(entry.mapLayer as MapLayerConfig & { layer?: LayerDto }), layerId: entry.layerId } as MapLayerWithId,\r\n layer: entry.layer,\r\n visible: entry.isVisible,\r\n opacity: entry.opacity,\r\n displayOrder: entry.displayOrder,\r\n initialIndex: index,\r\n }))\r\n );\r\n })\r\n .catch((err: unknown) => {\r\n if (cancelled) return;\r\n const message = err instanceof Error ? err.message : 'No se pudo cargar el mapa';\r\n setMapError(message);\r\n })\r\n .finally(() => {\r\n if (!cancelled) setLoadingMap(false);\r\n });\r\n\r\n return () => {\r\n cancelled = true;\r\n };\r\n }, [client.maps, mapId]);\r\n\r\n useEffect(() => {\r\n if (!showUploadTab && activeTab === 'upload') {\r\n setActiveTab('layers');\r\n }\r\n }, [activeTab, showUploadTab]);\r\n\r\n useEffect(() => {\r\n if (isControlled) return;\r\n if (!onLayerStatesChange) return;\r\n const emitStates =\r\n autoOpacityOnZoom && typeof mapZoom === 'number' ? effectiveStatesWithZoom : effectiveStates;\r\n const previous = lastEmittedStatesRef.current;\r\n if (previous && areEffectiveStatesEqual(previous, emitStates)) {\r\n return;\r\n }\r\n lastEmittedStatesRef.current = emitStates;\r\n onLayerStatesChange(emitStates);\r\n }, [\r\n autoOpacityOnZoom,\r\n effectiveStates,\r\n effectiveStatesWithZoom,\r\n isControlled,\r\n mapZoom,\r\n onLayerStatesChange,\r\n ]);\r\n\r\n const updateLayerVisible = React.useCallback(\r\n (layerId: number | string, visible: boolean) => {\r\n if (!onLayerStatesChange) return;\r\n const next = effectiveStates.map((state) =>\r\n state.layerId === layerId\r\n ? { ...state, visible, overrideVisible: visible }\r\n : state\r\n );\r\n onLayerStatesChange(next);\r\n },\r\n [effectiveStates, onLayerStatesChange]\r\n );\r\n\r\n const updateLayerOpacity = React.useCallback(\r\n (layerId: number | string, opacity: number) => {\r\n if (!onLayerStatesChange) return;\r\n const adjustedOpacity = resolveEffectiveOpacity(layerId, opacity);\r\n const next = effectiveStates.map((state) =>\r\n state.layerId === layerId\r\n ? { ...state, opacity: adjustedOpacity, overrideOpacity: opacity }\r\n : state\r\n );\r\n onLayerStatesChange(next);\r\n },\r\n [effectiveStates, onLayerStatesChange, resolveEffectiveOpacity]\r\n );\r\n\r\n const resolveFeatureCount = React.useCallback(\r\n (layerId: number | string, layer?: LayerDto) => {\r\n const resolvedFeatureCount =\r\n layerFeatureCounts?.[layerId] ?? layerFeatureCounts?.[String(layerId)];\r\n if (typeof resolvedFeatureCount === 'number') return resolvedFeatureCount;\r\n\r\n const featureCount =\r\n (layer as { featuresCount?: number } | undefined)?.featuresCount ??\r\n (layer as { featureCount?: number } | undefined)?.featureCount ??\r\n (layer as { totalFeatures?: number } | undefined)?.totalFeatures;\r\n\r\n return typeof featureCount === 'number' ? featureCount : null;\r\n },\r\n [layerFeatureCounts]\r\n );\r\n\r\n const decoratedLayers = useMemo(() => {\r\n return layers\r\n .map((entry) => ({\r\n ...entry,\r\n effective: effectiveStates.find((state) => state.layerId === entry.mapLayer.layerId),\r\n featureCount: resolveFeatureCount(entry.mapLayer.layerId, entry.layer),\r\n layerName: entry.layer?.name ?? entry.mapLayer.name ?? `Capa ${entry.mapLayer.layerId}`,\r\n }))\r\n .sort((a, b) => {\r\n const aOrder = resolveDisplayOrder(\r\n a.displayOrder ?? a.mapLayer.displayOrder ?? a.mapLayer.order\r\n );\r\n const bOrder = resolveDisplayOrder(\r\n b.displayOrder ?? b.mapLayer.displayOrder ?? b.mapLayer.order\r\n );\r\n const aHasOrder =\r\n a.displayOrder ?? a.mapLayer.displayOrder ?? a.mapLayer.order ?? null;\r\n const bHasOrder =\r\n b.displayOrder ?? b.mapLayer.displayOrder ?? b.mapLayer.order ?? null;\r\n if (aHasOrder !== null && bHasOrder !== null) {\r\n const orderCompare = aOrder - bOrder;\r\n if (orderCompare !== 0) return orderCompare;\r\n }\r\n\r\n const aInitial = a.initialIndex ?? 0;\r\n const bInitial = b.initialIndex ?? 0;\r\n if (aInitial !== bInitial) return aInitial - bInitial;\r\n\r\n const aName = a.layerName ?? String(a.mapLayer.layerId);\r\n const bName = b.layerName ?? String(b.mapLayer.layerId);\r\n const nameCompare = aName.localeCompare(bName, undefined, { sensitivity: 'base' });\r\n if (nameCompare !== 0) return nameCompare;\r\n\r\n return String(a.mapLayer.layerId).localeCompare(String(b.mapLayer.layerId));\r\n });\r\n }, [effectiveStates, layers, resolveFeatureCount]);\r\n\r\n const hasPrefilters = useMemo(() => {\r\n const candidates = [...(mapLayers ?? []), ...(map?.mapLayers ?? [])];\r\n return candidates.some((layer) => {\r\n const record = layer as Record<string, unknown>;\r\n const applied =\r\n record.appliedFilters ??\r\n record.prefilters ??\r\n record.initialFilters ??\r\n record.filters ??\r\n ((record.layerConfig as Record<string, unknown> | undefined)?.appliedFilters ??\r\n (record.layerConfig as Record<string, unknown> | undefined)?.prefilters);\r\n return !!applied && typeof applied === 'object' && Object.keys(applied as Record<string, unknown>).length > 0;\r\n });\r\n }, [map?.mapLayers, mapLayers]);\r\n\r\n const filterableLayers = useMemo(() => {\r\n const forcedLayerIds = new Set(availableFilterLayers.map((layerId) => String(layerId)));\r\n return decoratedLayers.filter((entry) => {\r\n const prefilters = (entry.mapLayer.layerConfig as { prefilters?: Record<string, unknown> } | undefined)?.prefilters;\r\n if (prefilters && Object.keys(prefilters).length > 0) return true;\r\n if (forcedLayerIds.has(String(entry.mapLayer.layerId))) return true;\r\n const layerType = (entry.mapLayer.layerType ?? entry.layer?.layerType ?? '').toString().toLowerCase();\r\n return layerType === 'multipolygon';\r\n });\r\n }, [availableFilterLayers, decoratedLayers]);\r\n\r\n const selectedFilterLayer = useMemo(\r\n () => filterableLayers.find((layer) => String(layer.mapLayer.layerId) === selectedFilterLayerId) ?? null,\r\n [filterableLayers, selectedFilterLayerId]\r\n );\r\n\r\n const filterFields = useMemo(() => {\r\n if (!selectedFilterLayer) return [];\r\n const prefilters = (selectedFilterLayer.mapLayer.layerConfig as { prefilters?: Record<string, unknown> } | undefined)?.prefilters;\r\n if (prefilters) {\r\n const keys = Object.keys(prefilters);\r\n if (keys.length > 0) return keys;\r\n }\r\n return catalogFieldsByLayer[String(selectedFilterLayer.mapLayer.layerId)] ?? [];\r\n }, [catalogFieldsByLayer, selectedFilterLayer]);\r\n\r\n const activeCatalogKey = selectedFilterLayer ? `${selectedFilterLayer.mapLayer.layerId}:${selectedFilterField}` : null;\r\n const activeCatalogValues = activeCatalogKey ? catalogByLayerField[activeCatalogKey] ?? [] : [];\r\n\r\n const extractCatalogValues = React.useCallback((catalogData: unknown, field: string): string[] => {\r\n const values = new Set<string>();\r\n\r\n const pushValue = (value: unknown) => {\r\n if (value === null || value === undefined) return;\r\n const normalized = String(value).trim();\r\n if (normalized) values.add(normalized);\r\n };\r\n\r\n if (catalogData && typeof catalogData === 'object') {\r\n const maybeRecord = catalogData as Record<string, unknown>;\r\n const directField = maybeRecord[field];\r\n if (Array.isArray(directField)) {\r\n directField.forEach(pushValue);\r\n }\r\n\r\n const items = maybeRecord.items;\r\n if (Array.isArray(items)) {\r\n items.forEach((item) => {\r\n if (!item || typeof item !== 'object') return;\r\n const row = item as Record<string, unknown>;\r\n const rowField = row.field;\r\n if (String(rowField ?? '').toUpperCase() === field.toUpperCase() && Array.isArray(row.values)) {\r\n row.values.forEach(pushValue);\r\n }\r\n });\r\n }\r\n\r\n const features = maybeRecord.features;\r\n if (Array.isArray(features)) {\r\n features.forEach((feature) => {\r\n if (!feature || typeof feature !== 'object') return;\r\n const properties = (feature as { properties?: Record<string, unknown> }).properties;\r\n if (properties && field in properties) {\r\n pushValue(properties[field]);\r\n }\r\n });\r\n }\r\n }\r\n\r\n return [...values].sort((a, b) => a.localeCompare(b, undefined, { sensitivity: 'base' }));\r\n }, []);\r\n\r\n const extractCatalogFieldMap = React.useCallback((catalogData: unknown, whitelist?: string[]): Record<string, string[]> => {\r\n if (!catalogData || typeof catalogData !== 'object') return {};\r\n const maybeRecord = catalogData as Record<string, unknown>;\r\n const fieldNames = new Set<string>();\r\n\r\n Object.entries(maybeRecord).forEach(([key, value]) => {\r\n if (Array.isArray(value) && key !== 'items' && key !== 'features') {\r\n if (isFieldVisible(key)) fieldNames.add(key);\r\n }\r\n });\r\n\r\n const items = maybeRecord.items;\r\n if (Array.isArray(items)) {\r\n items.forEach((item) => {\r\n if (!item || typeof item !== 'object') return;\r\n const row = item as Record<string, unknown>;\r\n if (row.field !== null && row.field !== undefined) {\r\n const fieldName = String(row.field).trim();\r\n if (fieldName && isFieldVisible(fieldName)) fieldNames.add(fieldName);\r\n }\r\n });\r\n }\r\n\r\n const features = maybeRecord.features;\r\n if (Array.isArray(features)) {\r\n features.forEach((feature) => {\r\n if (!feature || typeof feature !== 'object') return;\r\n const properties = (feature as { properties?: Record<string, unknown> }).properties;\r\n if (!properties || typeof properties !== 'object') return;\r\n Object.keys(properties).forEach((key) => {\r\n if (isFieldVisible(key)) fieldNames.add(key);\r\n });\r\n });\r\n }\r\n\r\n const normalizedWhitelist = (whitelist ?? []).map((item) => String(item).trim()).filter(Boolean);\r\n const resolvedFieldNames =\r\n normalizedWhitelist.length > 0\r\n ? [...fieldNames].filter((field) => matchesWhitelist(field, normalizedWhitelist))\r\n : [...fieldNames];\r\n\r\n const next: Record<string, string[]> = {};\r\n resolvedFieldNames.forEach((field) => {\r\n next[field] = extractCatalogValues(catalogData, field);\r\n });\r\n return next;\r\n }, [extractCatalogValues]);\r\n\r\n\r\n useEffect(() => {\r\n if (!filterableLayers.length) {\r\n setSelectedFilterLayerId('');\r\n return;\r\n }\r\n\r\n if (!selectedFilterLayerId || !filterableLayers.some((layer) => String(layer.mapLayer.layerId) === selectedFilterLayerId)) {\r\n setSelectedFilterLayerId(String(filterableLayers[0].mapLayer.layerId));\r\n }\r\n }, [filterableLayers, selectedFilterLayerId]);\r\n\r\n useEffect(() => {\r\n if (!filterFields.length) {\r\n setSelectedFilterField('');\r\n return;\r\n }\r\n if (!selectedFilterField || !filterFields.includes(selectedFilterField)) {\r\n setSelectedFilterField(filterFields[0]);\r\n setSelectedFilterValue('');\r\n }\r\n }, [filterFields, selectedFilterField]);\r\n\r\n useEffect(() => {\r\n if (hasPrefilters && activeTab === 'filters') {\r\n setActiveTab('layers');\r\n }\r\n }, [activeTab, hasPrefilters]);\r\n\r\n useEffect(() => {\r\n if (activeTab !== 'filters') return;\r\n if (!selectedFilterLayer) return;\r\n\r\n const layerId = selectedFilterLayer.mapLayer.layerId;\r\n const layerKey = String(layerId);\r\n const prefilters = (selectedFilterLayer.mapLayer.layerConfig as { prefilters?: Record<string, unknown> } | undefined)?.prefilters;\r\n const requiresCatalogForFields = !prefilters || Object.keys(prefilters).length === 0;\r\n const hasFieldsLoaded = (catalogFieldsByLayer[layerKey]?.length ?? 0) > 0;\r\n const needsLayerCatalog = requiresCatalogForFields && !hasFieldsLoaded;\r\n const needsFieldCatalog = Boolean(activeCatalogKey && selectedFilterField && !catalogByLayerField[activeCatalogKey]);\r\n\r\n if (!needsLayerCatalog && !needsFieldCatalog) return;\r\n\r\n catalogAbortRef.current?.abort();\r\n const controller = new AbortController();\r\n catalogAbortRef.current = controller;\r\n setLoadingCatalog(true);\r\n setFilterError(null);\r\n\r\n client.layers\r\n .getLayerFeaturesCatalog(layerId)\r\n .then((response) => {\r\n if (controller.signal.aborted) return;\r\n const fieldMap = extractCatalogFieldMap(response.data, filterFieldWhitelist);\r\n const fields = Object.keys(fieldMap);\r\n setCatalogFieldsByLayer((prev) => ({ ...prev, [layerKey]: fields }));\r\n setCatalogByLayerField((prev) => {\r\n const next = { ...prev };\r\n fields.forEach((field) => {\r\n const key = `${layerKey}:${field}`;\r\n if (!next[key]) {\r\n next[key] = fieldMap[field] ?? [];\r\n }\r\n });\r\n return next;\r\n });\r\n })\r\n .catch((error: unknown) => {\r\n if (controller.signal.aborted) return;\r\n const message = error instanceof Error ? error.message : 'No se pudo cargar el catálogo';\r\n setFilterError(message);\r\n })\r\n .finally(() => {\r\n if (!controller.signal.aborted) setLoadingCatalog(false);\r\n });\r\n\r\n return () => {\r\n controller.abort();\r\n };\r\n }, [activeCatalogKey, activeTab, catalogByLayerField, catalogFieldsByLayer, client.layers, extractCatalogFieldMap, filterFieldWhitelist, selectedFilterField, selectedFilterLayer]);\r\n\r\n const handleApplyFilter = React.useCallback(async () => {\r\n if (!selectedFilterLayer || !selectedFilterField || !selectedFilterValue || !onApplyLayerFilter) return;\r\n setApplyingFilter(true);\r\n setFilterError(null);\r\n try {\r\n await onApplyLayerFilter({\r\n layerId: selectedFilterLayer.mapLayer.layerId,\r\n field: selectedFilterField,\r\n value: selectedFilterValue,\r\n });\r\n setAppliedFilter({\r\n layerId: selectedFilterLayer.mapLayer.layerId,\r\n field: selectedFilterField,\r\n value: selectedFilterValue,\r\n });\r\n } catch (error: unknown) {\r\n const message = error instanceof Error ? error.message : 'No se pudo aplicar el filtro';\r\n setFilterError(message);\r\n } finally {\r\n setApplyingFilter(false);\r\n }\r\n }, [onApplyLayerFilter, selectedFilterField, selectedFilterLayer, selectedFilterValue]);\r\n\r\n const handleClearFilter = React.useCallback(async () => {\r\n if (!selectedFilterLayer) return;\r\n setApplyingFilter(true);\r\n setFilterError(null);\r\n try {\r\n await onClearLayerFilter?.({ layerId: selectedFilterLayer.mapLayer.layerId, field: selectedFilterField || undefined });\r\n setSelectedFilterValue('');\r\n setAppliedFilter(null);\r\n } catch (error: unknown) {\r\n const message = error instanceof Error ? error.message : 'No se pudo limpiar el filtro';\r\n setFilterError(message);\r\n } finally {\r\n setApplyingFilter(false);\r\n }\r\n }, [onClearLayerFilter, selectedFilterField, selectedFilterLayer]);\r\n\r\n const resolveLayerStyle = React.useCallback(\r\n (layerId: number | string): LayerStyle | undefined => {\r\n const layerKey = String(layerId);\r\n\r\n const fromProp = mapLayers?.find((entry) => String(entry.layerId) === layerKey)?.style;\r\n if (fromProp) return fromProp;\r\n\r\n const fromMapDto = map?.mapLayers?.find((entry) => String(entry.layerId) === layerKey);\r\n if (fromMapDto?.layer) {\r\n const layer = fromMapDto.layer as LayerDto & { style?: LayerStyle };\r\n if (layer.style) return layer.style;\r\n }\r\n\r\n return undefined;\r\n },\r\n [map, mapLayers]\r\n );\r\n\r\n const allVisible = decoratedLayers.every(\r\n (entry) => entry.effective?.visible ?? false\r\n );\r\n const anyVisible = decoratedLayers.some(\r\n (entry) => entry.effective?.visible ?? false\r\n );\r\n\r\n const handleToggleAllLayers = React.useCallback(() => {\r\n if (!onLayerStatesChange) return;\r\n // Si al menos una está visible → ocultar todas\r\n // Si todas están ocultas → mostrar todas\r\n const nextVisible = !anyVisible;\r\n const next = effectiveStates.map((state) => ({\r\n ...state,\r\n visible: nextVisible,\r\n overrideVisible: nextVisible,\r\n }));\r\n onLayerStatesChange(next);\r\n }, [anyVisible, effectiveStates, onLayerStatesChange]);\r\n\r\n const panelStyle: React.CSSProperties = {\r\n width: 360,\r\n borderLeft: side === 'right' ? '1px solid #e2e8f0' : undefined,\r\n borderRight: side === 'left' ? '1px solid #e2e8f0' : undefined,\r\n background: '#f1f5f9',\r\n fontFamily: 'system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif',\r\n fontSize: 14,\r\n boxSizing: 'border-box',\r\n height: height ?? '100%',\r\n display: 'flex',\r\n flexDirection: 'column',\r\n boxShadow: '0 12px 28px rgba(15, 23, 42, 0.08)',\r\n ...style,\r\n ...(height ? { height } : {}),\r\n };\r\n\r\n if (loadingMap) {\r\n return <div className={className} style={panelStyle}>Cargando capas…</div>;\r\n }\r\n\r\n if (mapError) {\r\n return (\r\n <div className={className} style={{ ...panelStyle, color: '#c53030' }}>\r\n Error al cargar mapa: {mapError}\r\n </div>\r\n );\r\n }\r\n\r\n if (!map) {\r\n return null;\r\n }\r\n\r\n const headerStyle: React.CSSProperties = {\r\n padding: '14px 16px',\r\n borderBottom: '1px solid #e2e8f0',\r\n background: '#fff',\r\n position: 'sticky',\r\n top: 0,\r\n zIndex: 2,\r\n boxShadow: '0 1px 0 rgba(148, 163, 184, 0.25)',\r\n };\r\n\r\n const renderLayerCards = () => {\r\n return (\r\n <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>\r\n {decoratedLayers.map((layerState) => {\r\n const layerId = layerState.mapLayer.layerId;\r\n const layerName = layerState.layerName ?? `Capa ${layerId}`;\r\n const visible = layerState.effective?.visible ?? false;\r\n const userOpacity = layerState.effective ? resolveUserOpacity(layerState.effective) : 1;\r\n const featureCount = layerState.featureCount;\r\n const layerColor = getLayerColor(resolveLayerStyle(layerId));\r\n const muted = !visible;\r\n const opacityPercent = Math.round(userOpacity * 100);\r\n const sliderBackground = `linear-gradient(to right, ${layerColor} 0%, ${layerColor} ${opacityPercent}%, #e5e7eb ${opacityPercent}%, #e5e7eb 100%)`;\r\n\r\n return (\r\n <div\r\n key={layerId.toString()}\r\n className={`zlm-card${muted ? ' is-muted' : ''}`}\r\n style={{\r\n border: '1px solid #e2e8f0',\r\n borderRadius: 12,\r\n padding: 12,\r\n background: '#fff',\r\n display: 'flex',\r\n flexDirection: 'column',\r\n gap: 10,\r\n width: '100%',\r\n }}\r\n >\r\n <div style={{ display: 'flex', justifyContent: 'space-between', gap: 12 }}>\r\n <div style={{ display: 'flex', gap: 10, alignItems: 'flex-start', minWidth: 0, flex: 1 }}>\r\n <div\r\n style={{\r\n width: 14,\r\n height: 14,\r\n borderRadius: '50%',\r\n backgroundColor: layerColor,\r\n border: '2px solid #e2e8f0',\r\n flexShrink: 0,\r\n marginTop: 4,\r\n }}\r\n title=\"Color de la capa\"\r\n />\r\n {showLayerVisibilityIcon && (\r\n <button\r\n type=\"button\"\r\n className={`zlm-icon-button${visible ? ' is-active' : ''}`}\r\n onClick={() =>\r\n isControlled\r\n ? updateLayerVisible(layerId, !visible)\r\n : setLayers((prev) =>\r\n prev.map((entry) =>\r\n entry.mapLayer.layerId === layerId ? { ...entry, visible: !visible } : entry\r\n )\r\n )\r\n }\r\n aria-label={visible ? 'Ocultar capa' : 'Mostrar capa'}\r\n >\r\n {visible ? <Eye size={16} /> : <EyeOff size={16} />}\r\n </button>\r\n )}\r\n <div style={{ minWidth: 0, flex: 1 }}>\r\n <div\r\n className=\"zlm-layer-name\"\r\n style={{\r\n fontWeight: 700,\r\n display: '-webkit-box',\r\n WebkitLineClamp: 2,\r\n WebkitBoxOrient: 'vertical',\r\n overflow: 'hidden',\r\n overflowWrap: 'anywhere',\r\n lineHeight: 1.2,\r\n color: muted ? '#64748b' : '#0f172a',\r\n }}\r\n title={layerName}\r\n >\r\n {layerName}\r\n </div>\r\n <div style={{ color: muted ? '#94a3b8' : '#64748b', fontSize: 12 }}>ID {layerId}</div>\r\n </div>\r\n </div>\r\n <div style={{ display: 'flex', alignItems: 'flex-start', gap: 6, flexShrink: 0 }}>\r\n {typeof featureCount === 'number' && (\r\n <span className=\"zlm-badge\">\r\n {featureCount.toLocaleString()} features\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n\r\n <div style={{ display: 'flex', gap: 10, alignItems: 'center' }}>\r\n <div style={{ flex: 1 }}>\r\n <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 6, color: '#64748b', fontSize: 12 }}>\r\n <span>Opacidad</span>\r\n <span>{opacityPercent}%</span>\r\n </div>\r\n <input\r\n className=\"zlm-range\"\r\n type=\"range\"\r\n min={0}\r\n max={1}\r\n step={0.05}\r\n value={userOpacity}\r\n style={{\r\n width: '100%',\r\n accentColor: layerColor,\r\n background: sliderBackground,\r\n height: 6,\r\n borderRadius: 999,\r\n }}\r\n onChange={(e) => {\r\n const value = Number(e.target.value);\r\n if (isControlled) {\r\n updateLayerOpacity(layerId, value);\r\n return;\r\n }\r\n setLayers((prev) =>\r\n prev.map((entry) =>\r\n entry.mapLayer.layerId === layerId ? { ...entry, opacity: value } : entry\r\n )\r\n );\r\n }}\r\n aria-label={`Opacidad de la capa ${layerName}`}\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n );\r\n };\r\n\r\n return (\r\n <div className={['zenit-layer-manager', className].filter(Boolean).join(' ')} style={panelStyle}>\r\n <style>\r\n {`\r\n .zenit-layer-manager .zlm-card {\r\n transition: box-shadow 0.2s ease, transform 0.2s ease, opacity 0.2s ease;\r\n box-shadow: 0 6px 16px rgba(15, 23, 42, 0.08);\r\n }\r\n .zenit-layer-manager .zlm-card.is-muted {\r\n opacity: 0.7;\r\n }\r\n .zenit-layer-manager .zlm-badge {\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 4px;\r\n margin-top: 6px;\r\n padding: 2px 8px;\r\n border-radius: 999px;\r\n background: #f1f5f9;\r\n color: #475569;\r\n font-size: 11px;\r\n font-weight: 600;\r\n }\r\n .zenit-layer-manager .zlm-icon-button {\r\n border: 1px solid #e2e8f0;\r\n background: #f8fafc;\r\n color: #475569;\r\n border-radius: 8px;\r\n width: 34px;\r\n height: 34px;\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n cursor: pointer;\r\n transition: all 0.15s ease;\r\n }\r\n .zenit-layer-manager .zlm-icon-button.is-active {\r\n background: #0f172a;\r\n color: #fff;\r\n border-color: #0f172a;\r\n }\r\n .zenit-layer-manager .zlm-icon-button:hover {\r\n box-shadow: 0 4px 10px rgba(15, 23, 42, 0.12);\r\n }\r\n .zenit-layer-manager .zlm-icon-button:focus-visible {\r\n outline: 2px solid #60a5fa;\r\n outline-offset: 2px;\r\n }\r\n .zenit-layer-manager .zlm-range {\r\n width: 100%;\r\n accent-color: #0f172a;\r\n }\r\n .zenit-layer-manager .zlm-tab {\r\n flex: 1;\r\n padding: 8px 12px;\r\n border: none;\r\n background: transparent;\r\n color: #475569;\r\n font-weight: 600;\r\n cursor: pointer;\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 6px;\r\n font-size: 13px;\r\n }\r\n .zenit-layer-manager .zlm-tab.is-active {\r\n background: #fff;\r\n color: #0f172a;\r\n box-shadow: 0 4px 10px rgba(15, 23, 42, 0.08);\r\n border-radius: 10px;\r\n }\r\n .zenit-layer-manager .zlm-tab:focus-visible {\r\n outline: 2px solid #60a5fa;\r\n outline-offset: 2px;\r\n }\r\n .zenit-layer-manager .zlm-panel-toggle {\r\n border: 1px solid #e2e8f0;\r\n background: #fff;\r\n color: #0f172a;\r\n border-radius: 10px;\r\n padding: 6px 10px;\r\n display: inline-flex;\r\n align-items: center;\r\n gap: 6px;\r\n font-size: 12px;\r\n font-weight: 600;\r\n cursor: pointer;\r\n transition: all 0.15s ease;\r\n }\r\n .zenit-layer-manager .zlm-panel-toggle:hover {\r\n box-shadow: 0 4px 10px rgba(15, 23, 42, 0.12);\r\n }\r\n .zenit-layer-manager .zlm-panel-toggle:focus-visible {\r\n outline: 2px solid #60a5fa;\r\n outline-offset: 2px;\r\n }\r\n `}\r\n </style>\r\n <div style={headerStyle}>\r\n <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>\r\n <div>\r\n <div style={{ fontWeight: 800, fontSize: 16, color: '#0f172a' }}>Gestión de Capas</div>\r\n <div style={{ color: '#64748b', fontSize: 12 }}>Mapa #{map.id}</div>\r\n </div>\r\n <button\r\n type=\"button\"\r\n onClick={() => setPanelVisible((prev) => !prev)}\r\n className=\"zlm-panel-toggle\"\r\n aria-label={panelVisible ? 'Ocultar panel de capas' : 'Mostrar panel de capas'}\r\n >\r\n {panelVisible ? <Eye size={16} /> : <EyeOff size={16} />}\r\n {panelVisible ? 'Ocultar' : 'Mostrar'}\r\n </button>\r\n </div>\r\n <div\r\n style={{\r\n display: 'flex',\r\n gap: 6,\r\n marginTop: 12,\r\n padding: 4,\r\n border: '1px solid #e2e8f0',\r\n borderRadius: 12,\r\n background: '#f1f5f9',\r\n }}\r\n >\r\n <button\r\n type=\"button\"\r\n className={`zlm-tab${activeTab === 'layers' ? ' is-active' : ''}`}\r\n onClick={() => setActiveTab('layers')}\r\n >\r\n <Layers size={16} />\r\n Capas\r\n </button>\r\n {showUploadTab && (\r\n <button\r\n type=\"button\"\r\n className={`zlm-tab${activeTab === 'upload' ? ' is-active' : ''}`}\r\n onClick={() => setActiveTab('upload')}\r\n >\r\n <Upload size={16} />\r\n Subir\r\n </button>\r\n )}\r\n {!hasPrefilters && (\r\n <button\r\n type=\"button\"\r\n className={`zlm-tab${activeTab === 'filters' ? ' is-active' : ''}`}\r\n onClick={() => setActiveTab('filters')}\r\n >\r\n <Layers size={16} />\r\n Filtros\r\n </button>\r\n )}\r\n </div>\r\n </div>\r\n\r\n {panelVisible && (\r\n <div style={{ padding: '12px 10px 18px', overflowY: 'auto', flex: 1, minHeight: 0 }}>\r\n {hasPrefilters && (\r\n <div className=\"zlm-badge\" style={{ marginBottom: 10 }}>\r\n Este mapa ya incluye filtros preaplicados\r\n </div>\r\n )}\r\n {activeTab === 'layers' && (\r\n <>\r\n <div style={{ marginBottom: 10 }}>\r\n <button\r\n type=\"button\"\r\n className=\"zlm-panel-toggle\"\r\n onClick={handleToggleAllLayers}\r\n disabled={decoratedLayers.length === 0}\r\n aria-label={anyVisible ? 'Ocultar todas las capas' : 'Mostrar todas las capas'}\r\n >\r\n {anyVisible ? <EyeOff size={14} /> : <Eye size={14} />}\r\n {anyVisible ? 'Ocultar todas' : 'Mostrar todas'}\r\n </button>\r\n </div>\r\n {renderLayerCards()}\r\n </>\r\n )}\r\n {!hasPrefilters && activeTab === 'filters' && (\r\n <div className=\"zlm-filter-panel\" style={{ display: 'flex', flexDirection: 'column', gap: 12, background: '#fff', border: '1px solid #e2e8f0', borderRadius: 12, padding: 12 }}>\r\n {!filterableLayers.length ? (\r\n <div style={{ color: '#64748b', fontSize: 13 }}>No hay filtros disponibles para las capas de este mapa.</div>\r\n ) : (\r\n <>\r\n {filterableLayers.length > 1 && (\r\n <label style={{ display: 'flex', flexDirection: 'column', gap: 6, fontSize: 12, color: '#475569' }}>\r\n Capa\r\n <ZenitSelect\r\n ariaLabel=\"Seleccionar capa para filtrar\"\r\n value={selectedFilterLayerId}\r\n onValueChange={setSelectedFilterLayerId}\r\n options={filterableLayers.map((layer) => ({\r\n value: String(layer.mapLayer.layerId),\r\n label: layer.layerName ?? `Capa ${layer.mapLayer.layerId}`,\r\n }))}\r\n />\r\n </label>\r\n )}\r\n <label style={{ display: 'flex', flexDirection: 'column', gap: 6, fontSize: 12, color: '#475569' }}>\r\n Campo\r\n <ZenitSelect\r\n ariaLabel=\"Seleccionar campo de filtrado\"\r\n value={selectedFilterField}\r\n onValueChange={(nextField) => {\r\n setSelectedFilterField(nextField);\r\n setSelectedFilterValue('');\r\n }}\r\n options={filterFields.map((field) => ({ value: field, label: field }))}\r\n />\r\n </label>\r\n <label style={{ display: 'flex', flexDirection: 'column', gap: 6, fontSize: 12, color: '#475569' }}>\r\n Valor\r\n <ZenitCombobox\r\n value={selectedFilterValue}\r\n placeholder=\"Seleccionar…\"\r\n searchPlaceholder=\"Buscar valor…\"\r\n onChange={(nextValue) => setSelectedFilterValue(nextValue)}\r\n options={activeCatalogValues}\r\n disabled={loadingCatalog || activeCatalogValues.length === 0}\r\n />\r\n </label>\r\n {loadingCatalog && <div style={{ color: '#64748b', fontSize: 12 }}>Cargando catálogo…</div>}\r\n {!loadingCatalog && selectedFilterField && activeCatalogValues.length === 0 && (\r\n <div style={{ color: '#64748b', fontSize: 12 }}>No hay catálogo disponible para este filtro.</div>\r\n )}\r\n {filterError && <div style={{ color: '#b91c1c', fontSize: 12 }}>{filterError}</div>}\r\n {appliedFilter && (\r\n <div className=\"zlm-badge\" style={{ alignSelf: 'flex-start' }}>\r\n Activo: {appliedFilter.field} = {appliedFilter.value}\r\n </div>\r\n )}\r\n <div className=\"zlm-filter-actions\" style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>\r\n <button\r\n type=\"button\"\r\n className=\"zlm-panel-toggle\"\r\n disabled={!selectedFilterValue || applyingFilter || !onApplyLayerFilter}\r\n onClick={handleApplyFilter}\r\n >\r\n {applyingFilter ? 'Aplicando…' : 'Aplicar'}\r\n </button>\r\n <button\r\n type=\"button\"\r\n className=\"zlm-panel-toggle\"\r\n disabled={applyingFilter}\r\n onClick={handleClearFilter}\r\n >\r\n Limpiar\r\n </button>\r\n </div>\r\n </>\r\n )}\r\n </div>\r\n )}\r\n {showUploadTab && activeTab === 'upload' && (\r\n <div style={{ color: '#475569', fontSize: 13 }}>\r\n Próximamente podrás subir capas desde este panel.\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n};\r\n","export { Eye, EyeOff, ChevronDown, ChevronLeft, ChevronRight, Layers, Upload, X, ZoomIn } from 'lucide-react';\r\n","import React from 'react';\r\nimport { createPortal } from 'react-dom';\r\nimport { ChevronDown } from '../icons';\r\n\r\nexport interface ZenitSelectOption {\r\n value: string;\r\n label: string;\r\n disabled?: boolean;\r\n}\r\n\r\nexport interface ZenitSelectProps {\r\n id?: string;\r\n value?: string;\r\n placeholder?: string;\r\n options: ZenitSelectOption[];\r\n onValueChange?: (value: string) => void;\r\n disabled?: boolean;\r\n className?: string;\r\n menuZIndex?: number;\r\n maxMenuHeight?: number;\r\n ariaLabel?: string;\r\n useNativeOnMobile?: boolean;\r\n}\r\n\r\nconst DEFAULT_SAFE_MENU_Z_INDEX = 4000;\r\n\r\nfunction readCssMenuZIndex(): number | null {\r\n if (typeof document === 'undefined') return null;\r\n const rootStyles = getComputedStyle(document.documentElement);\r\n const configuredValue =\r\n rootStyles.getPropertyValue('--zenit-select-z-index').trim() ||\r\n rootStyles.getPropertyValue('--zenit-overlay-z-index').trim();\r\n\r\n if (!configuredValue) return null;\r\n const parsed = Number.parseInt(configuredValue, 10);\r\n return Number.isFinite(parsed) ? parsed : null;\r\n}\r\n\r\nfunction shouldUseNativeSelect(): boolean {\r\n if (typeof window === 'undefined' || typeof navigator === 'undefined') return false;\r\n\r\n const hasCoarsePointer = typeof window.matchMedia === 'function'\r\n ? window.matchMedia('(pointer: coarse)').matches\r\n : false;\r\n\r\n return hasCoarsePointer || navigator.maxTouchPoints > 0;\r\n}\r\n\r\nexport const ZenitSelect: React.FC<ZenitSelectProps> = ({\r\n id,\r\n value,\r\n placeholder = 'Seleccionar…',\r\n options,\r\n onValueChange,\r\n disabled = false,\r\n className,\r\n menuZIndex,\r\n maxMenuHeight = 384,\r\n ariaLabel,\r\n useNativeOnMobile = true,\r\n}) => {\r\n const rootRef = React.useRef<HTMLDivElement | null>(null);\r\n const triggerRef = React.useRef<HTMLButtonElement | null>(null);\r\n const menuRef = React.useRef<HTMLDivElement | null>(null);\r\n\r\n // evita dobles triggers touch -> synthetic mouse\r\n const lastTouchTsRef = React.useRef<number>(0);\r\n\r\n const [isOpen, setIsOpen] = React.useState(false);\r\n const [menuPosition, setMenuPosition] = React.useState({ top: 0, left: 0, width: 0 });\r\n\r\n const selectedOption = React.useMemo(\r\n () => options.find((option) => option.value === value),\r\n [options, value]\r\n );\r\n\r\n const effectiveMenuZIndex = React.useMemo(\r\n () => menuZIndex ?? readCssMenuZIndex() ?? DEFAULT_SAFE_MENU_Z_INDEX,\r\n [menuZIndex]\r\n );\r\n\r\n const useNative = React.useMemo(\r\n () => useNativeOnMobile && shouldUseNativeSelect(),\r\n [useNativeOnMobile]\r\n );\r\n\r\n const updateMenuPosition = React.useCallback(() => {\r\n const trigger = triggerRef.current;\r\n if (!trigger) return;\r\n\r\n const rect = trigger.getBoundingClientRect();\r\n const viewportPadding = 8;\r\n const minWidth = 200;\r\n const width = Math.max(rect.width, minWidth);\r\n\r\n const maxLeft = window.innerWidth - width - viewportPadding;\r\n const nextLeft = Math.max(viewportPadding, Math.min(rect.left, maxLeft));\r\n const nextTop = rect.bottom + 4;\r\n\r\n setMenuPosition({ top: nextTop, left: nextLeft, width });\r\n }, []);\r\n\r\n const getEffectiveMaxHeight = React.useCallback(() => {\r\n // Evita que el menú “se salga” en pantallas pequeñas\r\n const available = Math.max(160, window.innerHeight - menuPosition.top - 12);\r\n return Math.min(maxMenuHeight, available);\r\n }, [maxMenuHeight, menuPosition.top]);\r\n\r\n React.useEffect(() => {\r\n if (!isOpen) return;\r\n\r\n updateMenuPosition();\r\n\r\n const isEventInsideSelect = (targetNode: Node) =>\r\n Boolean(rootRef.current?.contains(targetNode) || menuRef.current?.contains(targetNode));\r\n\r\n const handleOutsideTouchStart = (event: TouchEvent) => {\r\n lastTouchTsRef.current = Date.now();\r\n const targetNode = event.target as Node;\r\n if (isEventInsideSelect(targetNode)) return;\r\n setIsOpen(false);\r\n };\r\n\r\n const handleOutsideMouseDown = (event: MouseEvent) => {\r\n if (Date.now() - lastTouchTsRef.current < 500) return;\r\n const targetNode = event.target as Node;\r\n if (isEventInsideSelect(targetNode)) return;\r\n setIsOpen(false);\r\n };\r\n\r\n const handleEscape = (event: KeyboardEvent) => {\r\n if (event.key === 'Escape') {\r\n setIsOpen(false);\r\n triggerRef.current?.focus();\r\n }\r\n };\r\n\r\n const handleWindowChanges = () => updateMenuPosition();\r\n\r\n document.addEventListener('touchstart', handleOutsideTouchStart, { capture: true });\r\n document.addEventListener('mousedown', handleOutsideMouseDown, true);\r\n document.addEventListener('keydown', handleEscape);\r\n window.addEventListener('resize', handleWindowChanges);\r\n window.addEventListener('scroll', handleWindowChanges, true);\r\n\r\n return () => {\r\n document.removeEventListener('touchstart', handleOutsideTouchStart, true);\r\n document.removeEventListener('mousedown', handleOutsideMouseDown, true);\r\n document.removeEventListener('keydown', handleEscape);\r\n window.removeEventListener('resize', handleWindowChanges);\r\n window.removeEventListener('scroll', handleWindowChanges, true);\r\n };\r\n }, [isOpen, updateMenuPosition]);\r\n\r\n const handleTriggerDown = (\r\n event: React.TouchEvent<HTMLButtonElement> | React.MouseEvent<HTMLButtonElement>\r\n ) => {\r\n if (event.type === 'touchstart') {\r\n lastTouchTsRef.current = Date.now();\r\n }\r\n if (event.type === 'mousedown' && Date.now() - lastTouchTsRef.current < 500) {\r\n return;\r\n }\r\n\r\n // prevenir ghost click / cierres raros\r\n event.preventDefault();\r\n event.stopPropagation();\r\n\r\n if (disabled) return;\r\n if (!isOpen) updateMenuPosition();\r\n setIsOpen((prev) => !prev);\r\n };\r\n\r\n const handleTriggerClick = (event: React.MouseEvent<HTMLButtonElement>) => {\r\n // solo teclado\r\n if (event.detail !== 0) return;\r\n event.preventDefault();\r\n event.stopPropagation();\r\n if (disabled) return;\r\n if (!isOpen) updateMenuPosition();\r\n setIsOpen((prev) => !prev);\r\n };\r\n\r\n const selectValue = (nextValue: string, isDisabled?: boolean) => {\r\n if (isDisabled) return;\r\n onValueChange?.(nextValue);\r\n setIsOpen(false);\r\n triggerRef.current?.focus();\r\n };\r\n\r\n if (useNative) {\r\n return (\r\n <div ref={rootRef} className={[className, 'zenit-select-root'].filter(Boolean).join(' ')}>\r\n <style>\r\n {`\r\n .zenit-select-native {\r\n width: 100%;\r\n min-height: 40px;\r\n height: 40px;\r\n border: 1px solid #cbd5e1;\r\n border-radius: 6px;\r\n background: #ffffff;\r\n color: #0f172a;\r\n padding: 0 12px;\r\n font-size: 14px;\r\n line-height: 1.25;\r\n cursor: pointer;\r\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\r\n appearance: none;\r\n -webkit-appearance: none;\r\n }\r\n .zenit-select-native:disabled {\r\n opacity: 0.6;\r\n cursor: not-allowed;\r\n }\r\n .zenit-select-native:focus-visible {\r\n outline: none;\r\n border-color: #60a5fa;\r\n box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.35);\r\n }\r\n\r\n @media (max-width: 640px) {\r\n .zenit-select-native {\r\n min-height: 38px;\r\n height: 38px;\r\n }\r\n }\r\n `}\r\n </style>\r\n\r\n <select\r\n id={id}\r\n className=\"zenit-select-native\"\r\n value={value ?? ''}\r\n aria-label={ariaLabel}\r\n disabled={disabled}\r\n onChange={(event) => {\r\n onValueChange?.(event.target.value);\r\n }}\r\n >\r\n <option value=\"\" disabled hidden>\r\n {placeholder}\r\n </option>\r\n {options.map((option) => (\r\n <option key={option.value} value={option.value} disabled={option.disabled}>\r\n {option.label}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div ref={rootRef} className={[className, 'zenit-select-root'].filter(Boolean).join(' ')}>\r\n <style>\r\n {`\r\n .zenit-select-trigger {\r\n width: 100%;\r\n min-height: 40px;\r\n height: 40px;\r\n border: 1px solid #cbd5e1;\r\n border-radius: 6px;\r\n background: #ffffff;\r\n color: #0f172a;\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n gap: 8px;\r\n padding: 0 12px;\r\n font-size: 14px;\r\n line-height: 1.25;\r\n cursor: pointer;\r\n text-align: left;\r\n transition: border-color 0.15s ease, box-shadow 0.15s ease;\r\n touch-action: manipulation;\r\n -webkit-tap-highlight-color: transparent;\r\n }\r\n .zenit-select-trigger.is-disabled {\r\n opacity: 0.6;\r\n cursor: not-allowed;\r\n }\r\n .zenit-select-trigger:focus-visible {\r\n outline: none;\r\n border-color: #60a5fa;\r\n box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.35);\r\n }\r\n .zenit-select-label {\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n .zenit-select-label.is-placeholder {\r\n color: #64748b;\r\n }\r\n .zenit-select-chevron {\r\n opacity: 0.5;\r\n flex-shrink: 0;\r\n }\r\n\r\n /* Contenedor: aquí debe GANAR el scroll en móvil */\r\n .zenit-select-content {\r\n position: fixed;\r\n border: 1px solid #cbd5e1;\r\n border-radius: 6px;\r\n background: #ffffff;\r\n box-shadow: 0 10px 25px rgba(15, 23, 42, 0.18);\r\n overflow-y: auto;\r\n padding: 4px;\r\n pointer-events: auto;\r\n\r\n /* Lo importante: permitir pan vertical dentro del menú */\r\n touch-action: pan-y;\r\n overscroll-behavior: contain;\r\n -webkit-overflow-scrolling: touch;\r\n }\r\n\r\n /* Items NO son button: evitamos que WebView “secuestré” el gesto */\r\n .zenit-select-item {\r\n width: 100%;\r\n border-radius: 4px;\r\n text-align: left;\r\n color: #0f172a;\r\n font-size: 14px;\r\n min-height: 34px;\r\n padding: 8px 10px;\r\n cursor: pointer;\r\n -webkit-tap-highlight-color: transparent;\r\n user-select: none;\r\n }\r\n .zenit-select-item:hover {\r\n background: #f1f5f9;\r\n }\r\n .zenit-select-item.is-selected {\r\n background: #e2e8f0;\r\n font-weight: 600;\r\n }\r\n .zenit-select-item.is-disabled {\r\n color: #94a3b8;\r\n cursor: not-allowed;\r\n }\r\n .zenit-select-item:focus-visible {\r\n outline: none;\r\n box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.35);\r\n }\r\n\r\n @media (max-width: 640px) {\r\n .zenit-select-trigger {\r\n height: 38px;\r\n min-height: 38px;\r\n }\r\n .zenit-select-content {\r\n max-width: calc(100vw - 16px);\r\n }\r\n }\r\n `}\r\n </style>\r\n\r\n <button\r\n id={id}\r\n ref={triggerRef}\r\n type=\"button\"\r\n className={`zenit-select-trigger${disabled ? ' is-disabled' : ''}`}\r\n onTouchStart={handleTriggerDown}\r\n onMouseDown={handleTriggerDown}\r\n onClick={handleTriggerClick}\r\n aria-haspopup=\"listbox\"\r\n aria-expanded={isOpen}\r\n aria-label={ariaLabel}\r\n disabled={disabled}\r\n >\r\n <span className={`zenit-select-label${selectedOption ? '' : ' is-placeholder'}`}>\r\n {selectedOption?.label ?? placeholder}\r\n </span>\r\n <ChevronDown className=\"zenit-select-chevron\" size={16} aria-hidden=\"true\" />\r\n </button>\r\n\r\n {isOpen &&\r\n typeof document !== 'undefined' &&\r\n createPortal(\r\n <div\r\n ref={menuRef}\r\n className=\"zenit-select-content\"\r\n role=\"listbox\"\r\n style={{\r\n top: menuPosition.top,\r\n left: menuPosition.left,\r\n width: menuPosition.width,\r\n zIndex: effectiveMenuZIndex,\r\n maxHeight: getEffectiveMaxHeight(),\r\n }}\r\n >\r\n {options.map((option) => {\r\n const isSelected = option.value === value;\r\n\r\n return (\r\n <div\r\n key={option.value}\r\n role=\"option\"\r\n aria-selected={isSelected}\r\n tabIndex={option.disabled ? -1 : 0}\r\n className={`zenit-select-item${isSelected ? ' is-selected' : ''}${\r\n option.disabled ? ' is-disabled' : ''\r\n }`}\r\n // Selección por click (tap). Sin handlers touch para no romper scroll.\r\n onClick={(event) => {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n if (option.disabled) return;\r\n selectValue(option.value, option.disabled);\r\n }}\r\n // teclado\r\n onKeyDown={(event) => {\r\n if (option.disabled) return;\r\n if (event.key === 'Enter' || event.key === ' ') {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n selectValue(option.value, option.disabled);\r\n }\r\n }}\r\n >\r\n {option.label}\r\n </div>\r\n );\r\n })}\r\n </div>,\r\n document.body\r\n )}\r\n </div>\r\n );\r\n};\r\n","import React from 'react';\r\n\r\nexport interface ZenitComboboxProps {\r\n options: string[];\r\n value: string;\r\n onChange: (value: string) => void;\r\n placeholder?: string;\r\n searchPlaceholder?: string;\r\n disabled?: boolean;\r\n}\r\n\r\nexport const ZenitCombobox: React.FC<ZenitComboboxProps> = ({\r\n options,\r\n value,\r\n onChange,\r\n placeholder = 'Seleccionar…',\r\n searchPlaceholder = 'Buscar…',\r\n disabled = false,\r\n}) => {\r\n const rootRef = React.useRef<HTMLDivElement | null>(null);\r\n const [isOpen, setIsOpen] = React.useState(false);\r\n const [query, setQuery] = React.useState('');\r\n\r\n const filteredOptions = React.useMemo(() => {\r\n const normalized = query.trim().toLowerCase();\r\n if (!normalized) return options;\r\n return options.filter((option) => option.toLowerCase().includes(normalized));\r\n }, [options, query]);\r\n\r\n React.useEffect(() => {\r\n if (!isOpen) return;\r\n const onClickOutside = (event: MouseEvent) => {\r\n if (!rootRef.current?.contains(event.target as Node)) {\r\n setIsOpen(false);\r\n }\r\n };\r\n const onEscape = (event: KeyboardEvent) => {\r\n if (event.key === 'Escape') {\r\n setIsOpen(false);\r\n }\r\n };\r\n document.addEventListener('mousedown', onClickOutside);\r\n document.addEventListener('keydown', onEscape);\r\n return () => {\r\n document.removeEventListener('mousedown', onClickOutside);\r\n document.removeEventListener('keydown', onEscape);\r\n };\r\n }, [isOpen]);\r\n\r\n React.useEffect(() => {\r\n if (!isOpen) {\r\n setQuery('');\r\n }\r\n }, [isOpen]);\r\n\r\n return (\r\n <div ref={rootRef} className=\"zenit-combobox-root\" style={{ position: 'relative' }}>\r\n <style>\r\n {`\r\n .zenit-combobox-trigger {\r\n width: 100%;\r\n min-height: 40px;\r\n height: 40px;\r\n border: 1px solid #cbd5e1;\r\n border-radius: 6px;\r\n background: #ffffff;\r\n color: #0f172a;\r\n display: inline-flex;\r\n align-items: center;\r\n padding: 0 12px;\r\n font-size: 14px;\r\n line-height: 1.25;\r\n cursor: pointer;\r\n text-align: left;\r\n }\r\n .zenit-combobox-trigger.is-placeholder {\r\n color: #64748b;\r\n }\r\n .zenit-combobox-trigger:disabled {\r\n opacity: 0.6;\r\n cursor: not-allowed;\r\n }\r\n .zenit-combobox-content {\r\n position: absolute;\r\n top: calc(100% + 6px);\r\n left: 0;\r\n right: 0;\r\n border: 1px solid #cbd5e1;\r\n border-radius: 6px;\r\n background: #ffffff;\r\n box-shadow: 0 10px 25px rgba(15, 23, 42, 0.18);\r\n padding: 8px;\r\n z-index: 4000;\r\n }\r\n .zenit-combobox-search {\r\n width: 100%;\r\n min-height: 36px;\r\n border: 1px solid #cbd5e1;\r\n border-radius: 6px;\r\n background: #ffffff;\r\n color: #0f172a;\r\n padding: 0 10px;\r\n font-size: 14px;\r\n margin-bottom: 8px;\r\n box-sizing: border-box;\r\n }\r\n .zenit-combobox-list {\r\n max-height: 220px;\r\n overflow-y: auto;\r\n }\r\n .zenit-combobox-item {\r\n width: 100%;\r\n border-radius: 4px;\r\n color: #0f172a;\r\n font-size: 14px;\r\n min-height: 34px;\r\n padding: 8px 10px;\r\n cursor: pointer;\r\n user-select: none;\r\n }\r\n .zenit-combobox-item:hover { background: #f1f5f9; }\r\n .zenit-combobox-item.is-selected { background: #e2e8f0; font-weight: 600; }\r\n `}\r\n </style>\r\n <button\r\n type=\"button\"\r\n className={`zenit-combobox-trigger${!value ? ' is-placeholder' : ''}`}\r\n disabled={disabled}\r\n onClick={() => !disabled && setIsOpen((prev) => !prev)}\r\n >\r\n {value || placeholder}\r\n </button>\r\n {isOpen && (\r\n <div className=\"zenit-combobox-content\">\r\n <input\r\n className=\"zenit-combobox-search\"\r\n value={query}\r\n onChange={(event) => setQuery(event.target.value)}\r\n placeholder={searchPlaceholder}\r\n autoFocus\r\n />\r\n <div className=\"zenit-combobox-list\">\r\n {filteredOptions.length === 0 && (\r\n <div className=\"zenit-combobox-item\" style={{ color: '#64748b', cursor: 'default' }}>\r\n Sin coincidencias\r\n </div>\r\n )}\r\n {filteredOptions.map((option) => (\r\n <div\r\n key={option}\r\n className={`zenit-combobox-item${option === value ? ' is-selected' : ''}`}\r\n onClick={() => {\r\n onChange(option);\r\n setIsOpen(false);\r\n }}\r\n >\r\n {option}\r\n </div>\r\n ))}\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n};\r\n","import React from 'react';\r\nimport type { LayerFilters } from '../layers/types';\r\n\r\nexport interface ZenitFeatureFilterPanelProps {\r\n title?: string;\r\n description?: string;\r\n className?: string;\r\n style?: React.CSSProperties;\r\n filters?: LayerFilters;\r\n onChange?: (filters: LayerFilters) => void;\r\n children?: React.ReactNode;\r\n}\r\n\r\nexport const ZenitFeatureFilterPanel: React.FC<ZenitFeatureFilterPanelProps> = ({\r\n title = 'Filtros',\r\n description,\r\n className,\r\n style,\r\n children,\r\n}) => {\r\n return (\r\n <section\r\n className={className}\r\n style={{\r\n border: '1px solid #e2e8f0',\r\n borderRadius: 12,\r\n padding: 16,\r\n background: '#fff',\r\n fontFamily: 'system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif',\r\n ...style,\r\n }}\r\n >\r\n <header style={{ marginBottom: 12 }}>\r\n <h3 style={{ margin: 0, fontSize: 16 }}>{title}</h3>\r\n {description && (\r\n <p style={{ margin: '6px 0 0', color: '#475569', fontSize: 13 }}>{description}</p>\r\n )}\r\n </header>\r\n <div>{children}</div>\r\n </section>\r\n );\r\n};\r\n","import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\r\nimport { createPortal } from 'react-dom';\r\nimport type { ChatRequestDto, ChatResponseDto, SuggestedAction } from '../../ai/types';\r\nimport { useSendMessageStream } from '../hooks/use-chat';\r\nimport type { ChatServiceConfig } from '../../ai/chat.service';\r\nimport { MarkdownRenderer } from '../components/MarkdownRenderer';\r\n\r\ninterface ChatMessage {\r\n id: string;\r\n role: 'user' | 'assistant';\r\n content: string;\r\n response?: ChatResponseDto;\r\n}\r\n\r\nexport interface FloatingChatBoxProps {\r\n mapId?: number;\r\n filteredLayerIds?: number[];\r\n filters?: Record<string, unknown>;\r\n userId?: number | null;\r\n baseUrl?: string;\r\n accessToken?: string;\r\n getAccessToken?: () => string | Promise<string>;\r\n onActionClick?: (action: SuggestedAction) => void;\r\n /** Called when the chat panel opens or closes. */\r\n onOpenChange?: (isOpen: boolean) => void;\r\n /** When true, the floating action button is hidden (panel can still be open). */\r\n hideButton?: boolean;\r\n /**\r\n * Controlled open state. When provided, the component uses this as the source of truth.\r\n * Use with `onOpenChange` to control the chat panel externally.\r\n */\r\n open?: boolean;\r\n}\r\n\r\n// SVG Icons as inline components (no external dependencies)\r\nconst ChatIcon = () => (\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\" />\r\n </svg>\r\n);\r\n\r\nconst CloseIcon = () => (\r\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\r\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\r\n </svg>\r\n);\r\n\r\nconst ExpandIcon = () => (\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <polyline points=\"15 3 21 3 21 9\" />\r\n <polyline points=\"9 21 3 21 3 15\" />\r\n <line x1=\"21\" y1=\"3\" x2=\"14\" y2=\"10\" />\r\n <line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\" />\r\n </svg>\r\n);\r\n\r\nconst CollapseIcon = () => (\r\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <polyline points=\"4 14 10 14 10 20\" />\r\n <polyline points=\"20 10 14 10 14 4\" />\r\n <line x1=\"14\" y1=\"10\" x2=\"21\" y2=\"3\" />\r\n <line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\" />\r\n </svg>\r\n);\r\n\r\nconst SendIcon = () => (\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\" />\r\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\" />\r\n </svg>\r\n);\r\n\r\nconst LayersIcon = () => (\r\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <polygon points=\"12 2 2 7 12 12 22 7 12 2\" />\r\n <polyline points=\"2 17 12 22 22 17\" />\r\n <polyline points=\"2 12 12 17 22 12\" />\r\n </svg>\r\n);\r\n\r\nconst styles = {\r\n root: {\r\n fontFamily: 'system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\r\n } as React.CSSProperties,\r\n\r\n // Floating button (closed state - wide with text, open state - circular with X)\r\n floatingButton: {\r\n position: 'fixed',\r\n bottom: 16,\r\n right: 16,\r\n borderRadius: '999px',\r\n border: 'none',\r\n cursor: 'pointer',\r\n background: 'linear-gradient(135deg, #10b981, #059669)',\r\n color: '#fff',\r\n boxShadow: '0 12px 28px rgba(16, 185, 129, 0.4)',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n fontSize: 14,\r\n fontWeight: 600,\r\n zIndex: 99999,\r\n transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)',\r\n } as React.CSSProperties,\r\n\r\n floatingButtonClosed: {\r\n padding: '12px 20px',\r\n gap: 8,\r\n } as React.CSSProperties,\r\n\r\n floatingButtonOpen: {\r\n width: 52,\r\n height: 52,\r\n padding: 0,\r\n } as React.CSSProperties,\r\n\r\n floatingButtonMobile: {\r\n width: 52,\r\n height: 52,\r\n padding: 0,\r\n } as React.CSSProperties,\r\n\r\n // Panel (expandable)\r\n panel: {\r\n position: 'fixed',\r\n bottom: 80,\r\n right: 16,\r\n background: '#fff',\r\n borderRadius: 16,\r\n boxShadow: '0 20px 60px rgba(15, 23, 42, 0.3), 0 0 0 1px rgba(15, 23, 42, 0.05)',\r\n display: 'flex',\r\n flexDirection: 'column',\r\n overflow: 'hidden',\r\n zIndex: 99999,\r\n transition: 'all 0.3s cubic-bezier(0.4, 0, 0.2, 1)',\r\n } as React.CSSProperties,\r\n\r\n panelNormal: {\r\n width: 360,\r\n height: 520,\r\n } as React.CSSProperties,\r\n\r\n panelExpanded: {\r\n width: 480,\r\n height: 640,\r\n } as React.CSSProperties,\r\n\r\n panelMobileFullscreen: {\r\n position: 'fixed',\r\n top: 0,\r\n left: 0,\r\n right: 0,\r\n bottom: 0,\r\n width: '100%',\r\n height: '100%',\r\n borderRadius: 0,\r\n margin: 0,\r\n } as React.CSSProperties,\r\n\r\n // Header with green gradient\r\n header: {\r\n padding: '14px 16px',\r\n background: 'linear-gradient(135deg, #10b981, #059669)',\r\n color: '#fff',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'space-between',\r\n } as React.CSSProperties,\r\n\r\n title: {\r\n margin: 0,\r\n fontSize: 15,\r\n fontWeight: 600,\r\n letterSpacing: '-0.01em',\r\n } as React.CSSProperties,\r\n\r\n headerButtons: {\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: 8,\r\n } as React.CSSProperties,\r\n\r\n headerButton: {\r\n border: 'none',\r\n background: 'rgba(255, 255, 255, 0.15)',\r\n color: '#fff',\r\n width: 30,\r\n height: 30,\r\n borderRadius: 8,\r\n cursor: 'pointer',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n transition: 'background 0.2s',\r\n } as React.CSSProperties,\r\n\r\n // Messages area\r\n messages: {\r\n flex: 1,\r\n padding: '16px',\r\n overflowY: 'auto',\r\n background: '#f8fafc',\r\n display: 'flex',\r\n flexDirection: 'column',\r\n gap: 16,\r\n } as React.CSSProperties,\r\n\r\n // Message bubbles\r\n messageWrapper: {\r\n display: 'flex',\r\n flexDirection: 'column',\r\n gap: 8,\r\n } as React.CSSProperties,\r\n\r\n messageBubble: {\r\n maxWidth: '85%',\r\n padding: '10px 12px',\r\n borderRadius: 16,\r\n lineHeight: 1.5,\r\n fontSize: 13,\r\n whiteSpace: 'pre-wrap',\r\n wordBreak: 'break-word',\r\n } as React.CSSProperties,\r\n\r\n userMessage: {\r\n alignSelf: 'flex-end',\r\n background: 'linear-gradient(135deg, #10b981, #059669)',\r\n color: '#fff',\r\n borderBottomRightRadius: 4,\r\n } as React.CSSProperties,\r\n\r\n assistantMessage: {\r\n alignSelf: 'flex-start',\r\n background: '#e2e8f0',\r\n color: '#0f172a',\r\n borderBottomLeftRadius: 4,\r\n } as React.CSSProperties,\r\n\r\n // Streaming cursor\r\n cursor: {\r\n display: 'inline-block',\r\n width: 2,\r\n height: 16,\r\n background: '#0f172a',\r\n marginLeft: 2,\r\n animation: 'zenitBlink 1s infinite',\r\n verticalAlign: 'text-bottom',\r\n } as React.CSSProperties,\r\n\r\n thinkingText: {\r\n fontStyle: 'italic',\r\n opacity: 0.7,\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: 8,\r\n } as React.CSSProperties,\r\n\r\n typingIndicator: {\r\n display: 'flex',\r\n gap: 4,\r\n alignItems: 'center',\r\n } as React.CSSProperties,\r\n\r\n typingDot: {\r\n width: 8,\r\n height: 8,\r\n borderRadius: '50%',\r\n backgroundColor: '#059669',\r\n animation: 'typingDotBounce 1.4s infinite ease-in-out',\r\n } as React.CSSProperties,\r\n\r\n // Metadata section (Referenced Layers)\r\n metadataSection: {\r\n marginTop: 12,\r\n padding: '10px 12px',\r\n background: 'rgba(255, 255, 255, 0.5)',\r\n borderRadius: 10,\r\n fontSize: 12,\r\n } as React.CSSProperties,\r\n\r\n metadataTitle: {\r\n fontWeight: 600,\r\n color: '#059669',\r\n marginBottom: 6,\r\n display: 'flex',\r\n alignItems: 'center',\r\n gap: 6,\r\n } as React.CSSProperties,\r\n\r\n metadataList: {\r\n margin: 0,\r\n paddingLeft: 18,\r\n color: '#475569',\r\n } as React.CSSProperties,\r\n\r\n metadataItem: {\r\n marginBottom: 2,\r\n } as React.CSSProperties,\r\n\r\n // Suggested actions\r\n actionsSection: {\r\n marginTop: 12,\r\n } as React.CSSProperties,\r\n\r\n sectionLabel: {\r\n fontSize: 11,\r\n fontWeight: 600,\r\n color: '#64748b',\r\n marginBottom: 8,\r\n textTransform: 'uppercase',\r\n letterSpacing: '0.05em',\r\n } as React.CSSProperties,\r\n\r\n actionsGrid: {\r\n display: 'flex',\r\n flexWrap: 'wrap',\r\n gap: 6,\r\n } as React.CSSProperties,\r\n\r\n actionButton: {\r\n border: '1px solid #d1fae5',\r\n background: '#d1fae5',\r\n color: '#065f46',\r\n borderRadius: 999,\r\n padding: '6px 12px',\r\n fontSize: 12,\r\n fontWeight: 500,\r\n cursor: 'pointer',\r\n transition: 'all 0.2s',\r\n } as React.CSSProperties,\r\n\r\n // Follow-up questions\r\n followUpButton: {\r\n border: '1px solid #cbd5e1',\r\n background: '#fff',\r\n color: '#475569',\r\n borderRadius: 10,\r\n padding: '8px 12px',\r\n fontSize: 12,\r\n fontWeight: 500,\r\n cursor: 'pointer',\r\n textAlign: 'left',\r\n width: '100%',\r\n transition: 'all 0.2s',\r\n } as React.CSSProperties,\r\n\r\n // Input area\r\n inputWrapper: {\r\n borderTop: '1px solid #e2e8f0',\r\n padding: '10px 14px',\r\n display: 'flex',\r\n gap: 10,\r\n alignItems: 'flex-end',\r\n background: '#fff',\r\n } as React.CSSProperties,\r\n\r\n textarea: {\r\n flex: 1,\r\n resize: 'none',\r\n borderRadius: 12,\r\n border: '1.5px solid #cbd5e1',\r\n padding: '8px 10px',\r\n fontSize: 13,\r\n fontFamily: 'inherit',\r\n lineHeight: 1.4,\r\n transition: 'border-color 0.2s',\r\n } as React.CSSProperties,\r\n\r\n textareaFocus: {\r\n borderColor: '#10b981',\r\n outline: 'none',\r\n } as React.CSSProperties,\r\n\r\n sendButton: {\r\n borderRadius: 12,\r\n border: 'none',\r\n padding: '8px 12px',\r\n background: 'linear-gradient(135deg, #10b981, #059669)',\r\n color: '#fff',\r\n cursor: 'pointer',\r\n fontSize: 13,\r\n fontWeight: 600,\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n transition: 'opacity 0.2s, transform 0.2s',\r\n minWidth: 40,\r\n height: 40,\r\n } as React.CSSProperties,\r\n\r\n // Status messages\r\n statusNote: {\r\n padding: '0 16px 14px',\r\n fontSize: 12,\r\n color: '#64748b',\r\n textAlign: 'center',\r\n } as React.CSSProperties,\r\n\r\n errorText: {\r\n padding: '0 16px 14px',\r\n fontSize: 12,\r\n color: '#dc2626',\r\n textAlign: 'center',\r\n } as React.CSSProperties,\r\n};\r\n\r\nexport const FloatingChatBox: React.FC<FloatingChatBoxProps> = ({\r\n mapId,\r\n filteredLayerIds,\r\n filters,\r\n userId,\r\n baseUrl,\r\n accessToken,\r\n getAccessToken,\r\n onActionClick,\r\n onOpenChange,\r\n hideButton,\r\n open: openProp,\r\n}) => {\r\n // Controlled vs uncontrolled mode\r\n const isControlled = openProp !== undefined;\r\n const [internalOpen, setInternalOpen] = useState(false);\r\n const open = isControlled ? openProp : internalOpen;\r\n\r\n const setOpen = useCallback((value: boolean | ((prev: boolean) => boolean)) => {\r\n const newValue = typeof value === 'function' ? value(open) : value;\r\n if (!isControlled) {\r\n setInternalOpen(newValue);\r\n }\r\n // Always notify parent so they can update their state\r\n onOpenChange?.(newValue);\r\n }, [isControlled, open, onOpenChange]);\r\n const [expanded, setExpanded] = useState(false);\r\n const [messages, setMessages] = useState<ChatMessage[]>([]);\r\n const [inputValue, setInputValue] = useState('');\r\n const [conversationId, setConversationId] = useState<number | undefined>();\r\n const [errorMessage, setErrorMessage] = useState<string | null>(null);\r\n const [isFocused, setIsFocused] = useState(false);\r\n const [isMobile, setIsMobile] = useState(false);\r\n const messagesEndRef = useRef<HTMLDivElement | null>(null);\r\n const messagesContainerRef = useRef<HTMLDivElement | null>(null);\r\n const chatBoxRef = useRef<HTMLDivElement | null>(null);\r\n\r\n const chatConfig = useMemo<ChatServiceConfig | undefined>(() => {\r\n if (!baseUrl) return undefined;\r\n return { baseUrl, accessToken, getAccessToken };\r\n }, [accessToken, baseUrl, getAccessToken]);\r\n\r\n const { sendMessage, isStreaming, streamingText, completeResponse } = useSendMessageStream(chatConfig);\r\n\r\n const canSend = Boolean(mapId) && Boolean(baseUrl) && inputValue.trim().length > 0 && !isStreaming;\r\n\r\n\r\n // Auto-expand to fullscreen on mobile when opening\r\n useEffect(() => {\r\n if (open && isMobile) {\r\n setExpanded(true);\r\n }\r\n }, [open, isMobile]);\r\n\r\n // Auto-scroll to bottom\r\n const scrollToBottom = useCallback(() => {\r\n if (messagesEndRef.current) {\r\n messagesEndRef.current.scrollIntoView({ behavior: 'smooth' });\r\n }\r\n }, []);\r\n\r\n // Initial welcome message\r\n useEffect(() => {\r\n if (open && messages.length === 0) {\r\n setMessages([\r\n {\r\n id: 'welcome',\r\n role: 'assistant',\r\n content: 'Hola, soy el asistente de IA de ZENIT. Estoy aquí para ayudarte a analizar tu mapa y responder tus preguntas sobre las capas y datos. ¿En qué puedo ayudarte hoy?',\r\n },\r\n ]);\r\n }\r\n }, [open, messages.length]);\r\n\r\n // Auto-scroll on new messages or streaming\r\n useEffect(() => {\r\n scrollToBottom();\r\n }, [messages, streamingText, scrollToBottom]);\r\n\r\n // Close chat when clicking outside (skip on mobile fullscreen — use header close button)\r\n useEffect(() => {\r\n if (!open) return;\r\n if (isMobile && expanded) return;\r\n\r\n const handleClickOutside = (event: MouseEvent) => {\r\n if (\r\n chatBoxRef.current &&\r\n !chatBoxRef.current.contains(event.target as Node)\r\n ) {\r\n setOpen(false);\r\n }\r\n };\r\n\r\n document.addEventListener('mousedown', handleClickOutside);\r\n return () => {\r\n document.removeEventListener('mousedown', handleClickOutside);\r\n };\r\n }, [open, isMobile, expanded]);\r\n\r\n useEffect(() => {\r\n if (typeof window === 'undefined') return;\r\n const mediaQuery = window.matchMedia('(max-width: 768px)');\r\n const updateMobile = () => setIsMobile(mediaQuery.matches);\r\n updateMobile();\r\n if (mediaQuery.addEventListener) {\r\n mediaQuery.addEventListener('change', updateMobile);\r\n } else {\r\n mediaQuery.addListener(updateMobile);\r\n }\r\n return () => {\r\n if (mediaQuery.removeEventListener) {\r\n mediaQuery.removeEventListener('change', updateMobile);\r\n } else {\r\n mediaQuery.removeListener(updateMobile);\r\n }\r\n };\r\n }, []);\r\n\r\n // Lock body scroll when chat is fullscreen on mobile\r\n useEffect(() => {\r\n if (typeof document === 'undefined') return;\r\n if (!open || !isMobile) return;\r\n document.body.style.overflow = 'hidden';\r\n return () => {\r\n document.body.style.overflow = '';\r\n };\r\n }, [open, isMobile]);\r\n\r\n const addMessage = useCallback((message: ChatMessage) => {\r\n setMessages((prev) => [...prev, message]);\r\n }, []);\r\n\r\n const handleSend = useCallback(async () => {\r\n if (!mapId) {\r\n setErrorMessage('Selecciona un mapa para usar el asistente.');\r\n return;\r\n }\r\n if (!baseUrl) {\r\n setErrorMessage('Configura la baseUrl del SDK para usar Zenit AI.');\r\n return;\r\n }\r\n if (!inputValue.trim()) return;\r\n\r\n const messageText = inputValue.trim();\r\n setInputValue('');\r\n setErrorMessage(null);\r\n\r\n addMessage({\r\n id: `user-${Date.now()}`,\r\n role: 'user',\r\n content: messageText,\r\n });\r\n\r\n const request: ChatRequestDto = {\r\n message: messageText,\r\n conversationId,\r\n filteredLayerIds,\r\n filters,\r\n userId,\r\n };\r\n\r\n try {\r\n const response = await sendMessage(mapId, request);\r\n setConversationId(response.conversationId ?? conversationId);\r\n addMessage({\r\n id: `assistant-${Date.now()}`,\r\n role: 'assistant',\r\n content: response.answer,\r\n response,\r\n });\r\n } catch (error) {\r\n setErrorMessage('Ocurrió un error al generar la respuesta.');\r\n addMessage({\r\n id: `error-${Date.now()}`,\r\n role: 'assistant',\r\n content: '❌ Ocurrió un error al generar la respuesta.',\r\n });\r\n }\r\n }, [\r\n addMessage,\r\n baseUrl,\r\n conversationId,\r\n filteredLayerIds,\r\n filters,\r\n inputValue,\r\n mapId,\r\n sendMessage,\r\n userId,\r\n ]);\r\n\r\n const handleKeyDown = useCallback(\r\n (event: React.KeyboardEvent<HTMLTextAreaElement>) => {\r\n if (event.key === 'Enter' && !event.shiftKey) {\r\n event.preventDefault();\r\n if (canSend) {\r\n void handleSend();\r\n }\r\n }\r\n },\r\n [canSend, handleSend]\r\n );\r\n\r\n const handleFollowUpClick = useCallback((question: string) => {\r\n setInputValue(question);\r\n }, []);\r\n\r\n // Render metadata (Referenced Layers)\r\n const renderMetadata = (response?: ChatResponseDto) => {\r\n if (!response?.metadata) return null;\r\n\r\n const referencedLayers = response.metadata.referencedLayers as Array<{ layerName: string; featureCount: number }> | undefined;\r\n if (!referencedLayers || referencedLayers.length === 0) return null;\r\n\r\n return (\r\n <div style={styles.metadataSection}>\r\n <div style={styles.metadataTitle}>\r\n <LayersIcon />\r\n Capas Analizadas\r\n </div>\r\n <ul style={styles.metadataList}>\r\n {referencedLayers.map((layer, index) => (\r\n <li key={index} style={styles.metadataItem}>\r\n <strong>{layer.layerName}</strong> ({layer.featureCount} {layer.featureCount === 1 ? 'elemento' : 'elementos'})\r\n </li>\r\n ))}\r\n </ul>\r\n </div>\r\n );\r\n };\r\n\r\n // Handle suggested action click: close chat first, then execute action\r\n const handleActionClick = useCallback((action: SuggestedAction) => {\r\n if (isStreaming) return;\r\n // Close chat immediately so map is visible\r\n setOpen(false);\r\n // Execute action in next frame after chat closes\r\n requestAnimationFrame(() => {\r\n onActionClick?.(action);\r\n });\r\n }, [isStreaming, setOpen, onActionClick]);\r\n\r\n // Render suggested actions\r\n const renderActions = (response?: ChatResponseDto) => {\r\n if (!response?.suggestedActions?.length) return null;\r\n\r\n return (\r\n <div style={styles.actionsSection}>\r\n <div style={styles.sectionLabel}>Acciones Sugeridas</div>\r\n <div style={styles.actionsGrid}>\r\n {response.suggestedActions.map((action, index) => (\r\n <button\r\n key={`${action.label ?? action.action ?? 'action'}-${index}`}\r\n type=\"button\"\r\n style={{\r\n ...styles.actionButton,\r\n opacity: isStreaming ? 0.5 : 1,\r\n cursor: isStreaming ? 'not-allowed' : 'pointer',\r\n }}\r\n onClick={() => handleActionClick(action)}\r\n disabled={isStreaming}\r\n onMouseEnter={(e) => {\r\n if (!isStreaming) {\r\n e.currentTarget.style.background = '#a7f3d0';\r\n e.currentTarget.style.borderColor = '#a7f3d0';\r\n }\r\n }}\r\n onMouseLeave={(e) => {\r\n if (!isStreaming) {\r\n e.currentTarget.style.background = '#d1fae5';\r\n e.currentTarget.style.borderColor = '#d1fae5';\r\n }\r\n }}\r\n >\r\n {action.label ?? action.action ?? 'Acción'}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n );\r\n };\r\n\r\n // Render follow-up questions\r\n const renderFollowUps = (response?: ChatResponseDto) => {\r\n if (!response?.followUpQuestions?.length) return null;\r\n\r\n return (\r\n <div style={styles.actionsSection}>\r\n <div style={styles.sectionLabel}>Preguntas Relacionadas</div>\r\n <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>\r\n {response.followUpQuestions.map((question, index) => (\r\n <button\r\n key={`followup-${index}`}\r\n type=\"button\"\r\n style={{\r\n ...styles.followUpButton,\r\n opacity: isStreaming ? 0.5 : 1,\r\n cursor: isStreaming ? 'not-allowed' : 'pointer',\r\n }}\r\n onClick={() => !isStreaming && handleFollowUpClick(question)}\r\n disabled={isStreaming}\r\n onMouseEnter={(e) => {\r\n if (!isStreaming) {\r\n e.currentTarget.style.background = '#f8fafc';\r\n e.currentTarget.style.borderColor = '#10b981';\r\n }\r\n }}\r\n onMouseLeave={(e) => {\r\n if (!isStreaming) {\r\n e.currentTarget.style.background = '#fff';\r\n e.currentTarget.style.borderColor = '#cbd5e1';\r\n }\r\n }}\r\n >\r\n {question}\r\n </button>\r\n ))}\r\n </div>\r\n </div>\r\n );\r\n };\r\n\r\n const chatContent = (\r\n <div style={styles.root}>\r\n <style>{`\r\n @keyframes zenitBlink {\r\n 0%, 49% { opacity: 1; }\r\n 50%, 100% { opacity: 0; }\r\n }\r\n @keyframes zenitPulse {\r\n 0% { box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.7); }\r\n 70% { box-shadow: 0 0 0 14px rgba(16, 185, 129, 0); }\r\n 100% { box-shadow: 0 0 0 0 rgba(16, 185, 129, 0); }\r\n }\r\n @keyframes typingDotBounce {\r\n 0%, 60%, 100% { transform: translateY(0); }\r\n 30% { transform: translateY(-8px); }\r\n }\r\n .zenit-typing-dot:nth-child(1) { animation-delay: 0s; }\r\n .zenit-typing-dot:nth-child(2) { animation-delay: 0.2s; }\r\n .zenit-typing-dot:nth-child(3) { animation-delay: 0.4s; }\r\n .zenit-ai-button:not(.open) {\r\n animation: zenitPulse 2.5s infinite;\r\n }\r\n .zenit-ai-button:hover {\r\n transform: scale(1.05);\r\n }\r\n .zenit-ai-button:active {\r\n transform: scale(0.95);\r\n }\r\n .zenit-send-button:disabled {\r\n opacity: 0.5;\r\n cursor: not-allowed;\r\n }\r\n .zenit-send-button:not(:disabled):hover {\r\n opacity: 0.9;\r\n transform: translateY(-1px);\r\n }\r\n .zenit-send-button:not(:disabled):active {\r\n transform: translateY(0);\r\n }\r\n .zenit-chat-panel {\r\n box-sizing: border-box;\r\n }\r\n @media (max-width: 768px) {\r\n .zenit-chat-panel.zenit-chat-panel--fullscreen .zenit-ai-body {\r\n flex: 1;\r\n min-height: 0;\r\n overflow-y: auto;\r\n -webkit-overflow-scrolling: touch;\r\n }\r\n .zenit-chat-panel.zenit-chat-panel--fullscreen .zenit-ai-input-area {\r\n flex-shrink: 0;\r\n padding-bottom: max(14px, env(safe-area-inset-bottom));\r\n }\r\n .zenit-ai-button.zenit-ai-button--hidden-mobile {\r\n display: none !important;\r\n }\r\n }\r\n `}</style>\r\n\r\n {open && (\r\n <div\r\n ref={chatBoxRef}\r\n className={`zenit-chat-panel${expanded && !isMobile ? ' zenit-chat-panel--expanded' : ''}${\r\n isMobile ? ' zenit-chat-panel--fullscreen' : ''\r\n }`}\r\n style={(() => {\r\n // Split desktop vs mobile styles to prevent fullscreen from being overridden by desktop sizing.\r\n const desktopStyle = expanded ? styles.panelExpanded : styles.panelNormal;\r\n const mobileStyle = styles.panelMobileFullscreen;\r\n return {\r\n ...styles.panel,\r\n ...(isMobile ? mobileStyle : desktopStyle),\r\n };\r\n })()}\r\n >\r\n <header style={styles.header}>\r\n <h3 style={styles.title}>Asistente Zenit AI</h3>\r\n <div style={styles.headerButtons}>\r\n {!isMobile && (\r\n <button\r\n type=\"button\"\r\n style={styles.headerButton}\r\n onClick={() => setExpanded(!expanded)}\r\n onMouseEnter={(e) => {\r\n e.currentTarget.style.background = 'rgba(255, 255, 255, 0.25)';\r\n }}\r\n onMouseLeave={(e) => {\r\n e.currentTarget.style.background = 'rgba(255, 255, 255, 0.15)';\r\n }}\r\n aria-label={expanded ? 'Contraer' : 'Expandir'}\r\n >\r\n {expanded ? <CollapseIcon /> : <ExpandIcon />}\r\n </button>\r\n )}\r\n <button\r\n type=\"button\"\r\n style={styles.headerButton}\r\n onClick={() => setOpen(false)}\r\n onMouseEnter={(e) => {\r\n e.currentTarget.style.background = 'rgba(255, 255, 255, 0.25)';\r\n }}\r\n onMouseLeave={(e) => {\r\n e.currentTarget.style.background = 'rgba(255, 255, 255, 0.15)';\r\n }}\r\n aria-label=\"Cerrar\"\r\n >\r\n <CloseIcon />\r\n </button>\r\n </div>\r\n </header>\r\n\r\n <div ref={messagesContainerRef} className=\"zenit-ai-body\" style={styles.messages}>\r\n {messages.map((message) => (\r\n <div\r\n key={message.id}\r\n style={{\r\n ...styles.messageWrapper,\r\n alignItems: message.role === 'user' ? 'flex-end' : 'flex-start',\r\n }}\r\n >\r\n <div\r\n style={{\r\n ...styles.messageBubble,\r\n ...(message.role === 'user' ? styles.userMessage : styles.assistantMessage),\r\n }}\r\n >\r\n {message.role === 'assistant' ? (\r\n <MarkdownRenderer content={message.content} />\r\n ) : (\r\n message.content\r\n )}\r\n {message.role === 'assistant' && renderMetadata(message.response)}\r\n {message.role === 'assistant' && renderActions(message.response)}\r\n {message.role === 'assistant' && renderFollowUps(message.response)}\r\n </div>\r\n </div>\r\n ))}\r\n\r\n {isStreaming && (\r\n <div\r\n style={{\r\n ...styles.messageWrapper,\r\n alignItems: 'flex-start',\r\n }}\r\n >\r\n <div\r\n style={{\r\n ...styles.messageBubble,\r\n ...styles.assistantMessage,\r\n }}\r\n >\r\n {streamingText ? (\r\n <>\r\n <MarkdownRenderer content={streamingText} />\r\n <span style={styles.cursor} />\r\n </>\r\n ) : (\r\n <div style={styles.thinkingText}>\r\n <span>Pensando</span>\r\n <div style={styles.typingIndicator}>\r\n <div className=\"zenit-typing-dot\" style={styles.typingDot} />\r\n <div className=\"zenit-typing-dot\" style={styles.typingDot} />\r\n <div className=\"zenit-typing-dot\" style={styles.typingDot} />\r\n </div>\r\n </div>\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n\r\n <div ref={messagesEndRef} />\r\n </div>\r\n\r\n <div className=\"zenit-ai-input-area\" style={styles.inputWrapper}>\r\n <textarea\r\n style={{\r\n ...styles.textarea,\r\n ...(isFocused ? styles.textareaFocus : {}),\r\n }}\r\n rows={2}\r\n value={inputValue}\r\n onChange={(event) => setInputValue(event.target.value)}\r\n onKeyDown={handleKeyDown}\r\n onFocus={() => setIsFocused(true)}\r\n onBlur={() => setIsFocused(false)}\r\n placeholder={\r\n !mapId\r\n ? 'Selecciona un mapa para comenzar'\r\n : isStreaming\r\n ? 'Esperando respuesta...'\r\n : 'Escribe tu pregunta...'\r\n }\r\n disabled={!mapId || !baseUrl || isStreaming}\r\n />\r\n <button\r\n type=\"button\"\r\n className=\"zenit-send-button\"\r\n style={styles.sendButton}\r\n onClick={() => void handleSend()}\r\n disabled={!canSend}\r\n aria-label=\"Enviar mensaje\"\r\n >\r\n <SendIcon />\r\n </button>\r\n </div>\r\n\r\n {errorMessage && (\r\n <div style={styles.errorText}>\r\n {errorMessage}\r\n </div>\r\n )}\r\n\r\n {isStreaming && !errorMessage && (\r\n <div style={styles.statusNote}>\r\n Generando sugerencias...\r\n </div>\r\n )}\r\n\r\n {!mapId && !errorMessage && (\r\n <div style={styles.statusNote}>\r\n Selecciona un mapa para usar el asistente\r\n </div>\r\n )}\r\n\r\n {!baseUrl && !errorMessage && (\r\n <div style={styles.statusNote}>\r\n Configura la baseUrl del SDK\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n\r\n {/* Hide FAB when hideButton is true and chat is closed; always show when chat is open so user can close */}\r\n {!(hideButton && !open) && (\r\n <button\r\n type=\"button\"\r\n className={`zenit-ai-button ${open ? 'open' : ''}${\r\n open && isMobile ? ' zenit-ai-button--hidden-mobile' : ''\r\n }`}\r\n style={{\r\n ...styles.floatingButton,\r\n ...(open\r\n ? styles.floatingButtonOpen\r\n : isMobile\r\n ? styles.floatingButtonMobile\r\n : styles.floatingButtonClosed),\r\n zIndex: open ? 100001 : 99999,\r\n }}\r\n onClick={() => setOpen((prev) => !prev)}\r\n aria-label={open ? 'Cerrar asistente' : 'Abrir asistente Zenit AI'}\r\n >\r\n {open ? (\r\n <CloseIcon />\r\n ) : (\r\n <>\r\n <ChatIcon />\r\n {!isMobile && <span>Asistente IA</span>}\r\n </>\r\n )}\r\n </button>\r\n )}\r\n </div>\r\n );\r\n\r\n // Use portal to render at document.body for proper z-index\r\n if (typeof document !== 'undefined') {\r\n return createPortal(chatContent, document.body);\r\n }\r\n\r\n // Fallback for SSR\r\n return chatContent;\r\n};\r\n","import { useCallback, useRef, useState } from 'react';\r\nimport type { ChatRequestDto, ChatResponseDto } from '../../ai/types';\r\nimport type { ChatRequestOptions, ChatServiceConfig } from '../../ai/chat.service';\r\nimport { sendMessage, sendMessageStream } from '../../ai/chat.service';\r\n\r\nexport const useSendMessage = (config?: ChatServiceConfig) => {\r\n const [isLoading, setIsLoading] = useState(false);\r\n const [error, setError] = useState<unknown>(null);\r\n\r\n const send = useCallback(\r\n async (mapId: number, request: ChatRequestDto, options?: ChatRequestOptions) => {\r\n setIsLoading(true);\r\n setError(null);\r\n try {\r\n return await sendMessage(mapId, request, options, config);\r\n } catch (err) {\r\n setError(err);\r\n throw err;\r\n } finally {\r\n setIsLoading(false);\r\n }\r\n },\r\n [config]\r\n );\r\n\r\n return { sendMessage: send, isLoading, error };\r\n};\r\n\r\nexport const useSendMessageStream = (config?: ChatServiceConfig) => {\r\n const [isStreaming, setIsStreaming] = useState(false);\r\n const [streamingText, setStreamingText] = useState('');\r\n const [completeResponse, setCompleteResponse] = useState<ChatResponseDto | null>(null);\r\n const [error, setError] = useState<unknown>(null);\r\n const requestIdRef = useRef(0);\r\n\r\n const reset = useCallback(() => {\r\n setIsStreaming(false);\r\n setStreamingText('');\r\n setCompleteResponse(null);\r\n setError(null);\r\n }, []);\r\n\r\n const send = useCallback(\r\n async (mapId: number, request: ChatRequestDto, options?: ChatRequestOptions) => {\r\n const requestId = requestIdRef.current + 1;\r\n requestIdRef.current = requestId;\r\n\r\n setIsStreaming(true);\r\n setStreamingText('');\r\n setCompleteResponse(null);\r\n setError(null);\r\n\r\n try {\r\n const response = await sendMessageStream(\r\n mapId,\r\n request,\r\n {\r\n onChunk: (_chunk, aggregated) => {\r\n if (requestIdRef.current !== requestId) return;\r\n setStreamingText(aggregated);\r\n },\r\n onError: (err) => {\r\n if (requestIdRef.current !== requestId) return;\r\n setError(err);\r\n },\r\n onComplete: (finalResponse) => {\r\n if (requestIdRef.current !== requestId) return;\r\n setCompleteResponse(finalResponse);\r\n },\r\n },\r\n options,\r\n config\r\n );\r\n return response;\r\n } catch (err) {\r\n setError(err);\r\n throw err;\r\n } finally {\r\n if (requestIdRef.current === requestId) {\r\n setIsStreaming(false);\r\n }\r\n }\r\n },\r\n [config]\r\n );\r\n\r\n return {\r\n sendMessage: send,\r\n isStreaming,\r\n streamingText,\r\n completeResponse,\r\n error,\r\n reset,\r\n };\r\n};\r\n","import type { ChatRequestDto, ChatResponseDto } from './types';\r\n\r\nexport interface ChatServiceConfig {\r\n baseUrl: string;\r\n accessToken?: string;\r\n getAccessToken?: () => string | Promise<string>;\r\n}\r\n\r\nexport interface ChatRequestOptions {\r\n baseUrl?: string;\r\n accessToken?: string;\r\n getAccessToken?: () => string | Promise<string>;\r\n signal?: AbortSignal;\r\n}\r\n\r\nexport interface ChatStreamCallbacks {\r\n onChunk?: (chunk: ChatResponseDto, aggregatedText: string) => void;\r\n onComplete?: (response: ChatResponseDto) => void;\r\n onError?: (error: unknown) => void;\r\n}\r\n\r\nconst DEFAULT_ERROR_MESSAGE = 'No fue posible completar la solicitud al asistente.';\r\n\r\nconst normalizeBaseUrl = (baseUrl: string) => baseUrl.replace(/\\/$/, '');\r\n\r\nconst resolveBaseUrl = (config?: ChatServiceConfig, options?: ChatRequestOptions): string => {\r\n const baseUrl = options?.baseUrl ?? config?.baseUrl;\r\n if (!baseUrl) {\r\n throw new Error('baseUrl es requerido para usar el chat de Zenit AI.');\r\n }\r\n return normalizeBaseUrl(baseUrl);\r\n};\r\n\r\nconst resolveAccessToken = async (\r\n config?: ChatServiceConfig,\r\n options?: ChatRequestOptions\r\n): Promise<string | undefined> => {\r\n if (options?.accessToken) return options.accessToken;\r\n if (config?.accessToken) return config.accessToken;\r\n\r\n if (options?.getAccessToken) return await options.getAccessToken();\r\n if (config?.getAccessToken) return await config.getAccessToken();\r\n\r\n return undefined;\r\n};\r\n\r\nconst buildAuthHeaders = (token?: string): Record<string, string> => {\r\n if (!token) return {};\r\n return { Authorization: `Bearer ${token}` };\r\n};\r\n\r\nconst parseError = async (response: Response): Promise<Error> => {\r\n try {\r\n const contentType = response.headers.get('content-type') ?? '';\r\n if (contentType.includes('application/json')) {\r\n const payload = await response.json();\r\n const message = payload?.message ?? DEFAULT_ERROR_MESSAGE;\r\n return new Error(message);\r\n }\r\n\r\n const text = await response.text();\r\n return new Error(text || DEFAULT_ERROR_MESSAGE);\r\n } catch (error) {\r\n return error instanceof Error ? error : new Error(DEFAULT_ERROR_MESSAGE);\r\n }\r\n};\r\n\r\nexport const sendMessage = async (\r\n mapId: number,\r\n request: ChatRequestDto,\r\n options?: ChatRequestOptions,\r\n config?: ChatServiceConfig\r\n): Promise<ChatResponseDto> => {\r\n const baseUrl = resolveBaseUrl(config, options);\r\n const token = await resolveAccessToken(config, options);\r\n const response = await fetch(`${baseUrl}/ai/maps/chat/${mapId}`, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n ...buildAuthHeaders(token),\r\n },\r\n body: JSON.stringify(request),\r\n signal: options?.signal,\r\n });\r\n\r\n if (!response.ok) {\r\n throw await parseError(response);\r\n }\r\n\r\n return (await response.json()) as ChatResponseDto;\r\n};\r\n\r\nconst mergeResponse = (\r\n previous: ChatResponseDto | null,\r\n chunk: ChatResponseDto,\r\n aggregatedAnswer: string\r\n): ChatResponseDto => ({\r\n ...(previous ?? chunk),\r\n ...chunk,\r\n answer: aggregatedAnswer,\r\n});\r\n\r\nconst resolveAggregatedAnswer = (current: string, incoming: string): string => {\r\n if (!incoming) return current;\r\n if (incoming.startsWith(current)) return incoming;\r\n return current + incoming;\r\n};\r\n\r\nexport const sendMessageStream = async (\r\n mapId: number,\r\n request: ChatRequestDto,\r\n callbacks: ChatStreamCallbacks = {},\r\n options?: ChatRequestOptions,\r\n config?: ChatServiceConfig\r\n): Promise<ChatResponseDto> => {\r\n const baseUrl = resolveBaseUrl(config, options);\r\n const token = await resolveAccessToken(config, options);\r\n\r\n const response = await fetch(`${baseUrl}/ai/maps/chat/${mapId}/stream`, {\r\n method: 'POST',\r\n headers: {\r\n Accept: 'text/event-stream',\r\n 'Content-Type': 'application/json',\r\n ...buildAuthHeaders(token),\r\n },\r\n body: JSON.stringify(request),\r\n signal: options?.signal,\r\n });\r\n\r\n if (!response.ok) {\r\n const error = await parseError(response);\r\n callbacks.onError?.(error);\r\n throw error;\r\n }\r\n\r\n const reader = response.body?.getReader();\r\n if (!reader) {\r\n const error = new Error('No se pudo iniciar el streaming de Zenit AI.');\r\n callbacks.onError?.(error);\r\n throw error;\r\n }\r\n\r\n const decoder = new TextDecoder('utf-8');\r\n let buffer = '';\r\n let aggregated = '';\r\n let latestResponse: ChatResponseDto | null = null;\r\n\r\n try {\r\n while (true) {\r\n const { value, done } = await reader.read();\r\n if (done) break;\r\n\r\n buffer += decoder.decode(value, { stream: true });\r\n const lines = buffer.split(/\\r?\\n/);\r\n buffer = lines.pop() ?? '';\r\n\r\n for (const line of lines) {\r\n const trimmed = line.trim();\r\n if (!trimmed || trimmed.startsWith('event:')) continue;\r\n if (!trimmed.startsWith('data:')) continue;\r\n\r\n const payload = trimmed.replace(/^data:\\s*/, '');\r\n if (!payload || payload === '[DONE]') continue;\r\n\r\n try {\r\n const parsed = JSON.parse(payload) as ChatResponseDto;\r\n aggregated = resolveAggregatedAnswer(aggregated, parsed.answer ?? '');\r\n latestResponse = mergeResponse(latestResponse, parsed, aggregated);\r\n if (latestResponse) {\r\n callbacks.onChunk?.(latestResponse, aggregated);\r\n }\r\n } catch (error) {\r\n callbacks.onError?.(error);\r\n }\r\n }\r\n }\r\n } catch (error) {\r\n callbacks.onError?.(error);\r\n throw error;\r\n }\r\n\r\n if (!latestResponse) {\r\n const error = new Error(DEFAULT_ERROR_MESSAGE);\r\n callbacks.onError?.(error);\r\n throw error;\r\n }\r\n\r\n callbacks.onComplete?.(latestResponse);\r\n return latestResponse;\r\n};\r\n\r\nexport const createChatService = (config: ChatServiceConfig) => ({\r\n sendMessage: (mapId: number, request: ChatRequestDto, options?: ChatRequestOptions) =>\r\n sendMessage(mapId, request, options, config),\r\n sendMessageStream: (\r\n mapId: number,\r\n request: ChatRequestDto,\r\n callbacks?: ChatStreamCallbacks,\r\n options?: ChatRequestOptions\r\n ) => sendMessageStream(mapId, request, callbacks, options, config),\r\n});\r\n","import React from 'react';\r\nimport ReactMarkdown from 'react-markdown';\r\nimport remarkGfm from 'remark-gfm';\r\n\r\ninterface MarkdownRendererProps {\r\n content: string;\r\n className?: string;\r\n}\r\n\r\n/**\r\n * Normalizes assistant markdown by removing artifacts and cleaning up formatting\r\n */\r\nfunction normalizeAssistantMarkdown(text: string): string {\r\n if (!text || typeof text !== 'string') return '';\r\n\r\n let normalized = text;\r\n\r\n // 1. Normalize line endings\r\n normalized = normalized.replace(/\\r\\n/g, '\\n');\r\n\r\n // 2. Remove standalone header symbols (lines that are ONLY # symbols with optional whitespace)\r\n normalized = normalized.replace(/^\\s*#{1,6}\\s*$/gm, '');\r\n\r\n // 3. Remove excessive blank lines (more than 2 consecutive newlines)\r\n normalized = normalized.replace(/\\n{3,}/g, '\\n\\n');\r\n\r\n // 4. Trim trailing whitespace from each line\r\n normalized = normalized\r\n .split('\\n')\r\n .map((line) => line.trimEnd())\r\n .join('\\n');\r\n\r\n // 5. Trim the entire string\r\n normalized = normalized.trim();\r\n\r\n return normalized;\r\n}\r\n\r\n/**\r\n * Renders markdown content with GFM support and normalization\r\n */\r\nexport const MarkdownRenderer: React.FC<MarkdownRendererProps> = ({ content, className }) => {\r\n const normalizedContent = normalizeAssistantMarkdown(content);\r\n\r\n if (!normalizedContent) {\r\n return null;\r\n }\r\n\r\n return (\r\n <div className={className} style={{ wordBreak: 'break-word' }}>\r\n <ReactMarkdown\r\n remarkPlugins={[remarkGfm]}\r\n components={{\r\n // Headings with proper spacing\r\n h1: ({ children, ...props }) => (\r\n <h1 style={{ fontSize: '1.5em', fontWeight: 700, marginTop: '1em', marginBottom: '0.5em' }} {...props}>\r\n {children}\r\n </h1>\r\n ),\r\n h2: ({ children, ...props }) => (\r\n <h2 style={{ fontSize: '1.3em', fontWeight: 700, marginTop: '0.9em', marginBottom: '0.45em' }} {...props}>\r\n {children}\r\n </h2>\r\n ),\r\n h3: ({ children, ...props }) => (\r\n <h3 style={{ fontSize: '1.15em', fontWeight: 600, marginTop: '0.75em', marginBottom: '0.4em' }} {...props}>\r\n {children}\r\n </h3>\r\n ),\r\n h4: ({ children, ...props }) => (\r\n <h4 style={{ fontSize: '1.05em', fontWeight: 600, marginTop: '0.6em', marginBottom: '0.35em' }} {...props}>\r\n {children}\r\n </h4>\r\n ),\r\n h5: ({ children, ...props }) => (\r\n <h5 style={{ fontSize: '1em', fontWeight: 600, marginTop: '0.5em', marginBottom: '0.3em' }} {...props}>\r\n {children}\r\n </h5>\r\n ),\r\n h6: ({ children, ...props }) => (\r\n <h6 style={{ fontSize: '0.95em', fontWeight: 600, marginTop: '0.5em', marginBottom: '0.3em' }} {...props}>\r\n {children}\r\n </h6>\r\n ),\r\n // Paragraphs with comfortable line height\r\n p: ({ children, ...props }) => (\r\n <p style={{ marginTop: '0.5em', marginBottom: '0.5em', lineHeight: 1.6 }} {...props}>\r\n {children}\r\n </p>\r\n ),\r\n // Lists with proper indentation\r\n ul: ({ children, ...props }) => (\r\n <ul style={{ paddingLeft: '1.5em', marginTop: '0.5em', marginBottom: '0.5em' }} {...props}>\r\n {children}\r\n </ul>\r\n ),\r\n ol: ({ children, ...props }) => (\r\n <ol style={{ paddingLeft: '1.5em', marginTop: '0.5em', marginBottom: '0.5em' }} {...props}>\r\n {children}\r\n </ol>\r\n ),\r\n li: ({ children, ...props }) => (\r\n <li style={{ marginTop: '0.25em', marginBottom: '0.25em' }} {...props}>\r\n {children}\r\n </li>\r\n ),\r\n // Code blocks\r\n code: ({ inline, children, ...props }: any) => {\r\n if (inline) {\r\n return (\r\n <code\r\n style={{\r\n backgroundColor: 'rgba(0, 0, 0, 0.08)',\r\n padding: '0.15em 0.4em',\r\n borderRadius: '4px',\r\n fontSize: '0.9em',\r\n fontFamily: 'monospace',\r\n }}\r\n {...props}\r\n >\r\n {children}\r\n </code>\r\n );\r\n }\r\n return (\r\n <code\r\n style={{\r\n display: 'block',\r\n backgroundColor: 'rgba(0, 0, 0, 0.08)',\r\n padding: '0.75em',\r\n borderRadius: '6px',\r\n fontSize: '0.9em',\r\n fontFamily: 'monospace',\r\n overflowX: 'auto',\r\n marginTop: '0.5em',\r\n marginBottom: '0.5em',\r\n }}\r\n {...props}\r\n >\r\n {children}\r\n </code>\r\n );\r\n },\r\n // Pre (code block wrapper)\r\n pre: ({ children, ...props }) => (\r\n <pre style={{ margin: 0 }} {...props}>\r\n {children}\r\n </pre>\r\n ),\r\n // Blockquotes\r\n blockquote: ({ children, ...props }) => (\r\n <blockquote\r\n style={{\r\n borderLeft: '4px solid rgba(0, 0, 0, 0.2)',\r\n paddingLeft: '1em',\r\n marginLeft: 0,\r\n marginTop: '0.5em',\r\n marginBottom: '0.5em',\r\n color: 'rgba(0, 0, 0, 0.7)',\r\n }}\r\n {...props}\r\n >\r\n {children}\r\n </blockquote>\r\n ),\r\n // Strong/bold\r\n strong: ({ children, ...props }) => (\r\n <strong style={{ fontWeight: 600 }} {...props}>\r\n {children}\r\n </strong>\r\n ),\r\n // Emphasis/italic\r\n em: ({ children, ...props }) => (\r\n <em style={{ fontStyle: 'italic' }} {...props}>\r\n {children}\r\n </em>\r\n ),\r\n // Horizontal rule\r\n hr: (props) => (\r\n <hr\r\n style={{\r\n border: 'none',\r\n borderTop: '1px solid rgba(0, 0, 0, 0.1)',\r\n marginTop: '1em',\r\n marginBottom: '1em',\r\n }}\r\n {...props}\r\n />\r\n ),\r\n // Tables (GFM)\r\n table: ({ children, ...props }) => (\r\n <div style={{ overflowX: 'auto', marginTop: '0.5em', marginBottom: '0.5em' }}>\r\n <table\r\n style={{\r\n borderCollapse: 'collapse',\r\n width: '100%',\r\n fontSize: '0.9em',\r\n }}\r\n {...props}\r\n >\r\n {children}\r\n </table>\r\n </div>\r\n ),\r\n th: ({ children, ...props }) => (\r\n <th\r\n style={{\r\n border: '1px solid rgba(0, 0, 0, 0.2)',\r\n padding: '0.5em',\r\n backgroundColor: 'rgba(0, 0, 0, 0.05)',\r\n fontWeight: 600,\r\n textAlign: 'left',\r\n }}\r\n {...props}\r\n >\r\n {children}\r\n </th>\r\n ),\r\n td: ({ children, ...props }) => (\r\n <td\r\n style={{\r\n border: '1px solid rgba(0, 0, 0, 0.2)',\r\n padding: '0.5em',\r\n }}\r\n {...props}\r\n >\r\n {children}\r\n </td>\r\n ),\r\n }}\r\n >\r\n {normalizedContent}\r\n </ReactMarkdown>\r\n </div>\r\n );\r\n};\r\n"],"mappings":"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","names":["React","useCallback","useEffect","useMemo","useRef","useState","Marker","L","clampOpacity","clampOpacity","useEffect","useMemo","useRef","L","useEffect","useRef","L","clampNumber","clampOpacity","L","Fragment","jsx","jsxs","useRef","useEffect","L","useMemo","useEffect","useRef","useMap","jsx","jsxs","DEV_MODE","POINT_GEOMETRY_TYPES","L","useState","useRef","useMemo","useEffect","useCallback","clampOpacity","zoom","React","layerType","baseOpacity","Marker","React","useEffect","useMemo","useRef","useState","React","createPortal","jsx","jsxs","React","createPortal","React","jsx","jsxs","Fragment","jsx","jsxs","getLayerColor","useState","useRef","useMemo","React","useEffect","jsx","jsxs","useCallback","useEffect","useMemo","useRef","useState","createPortal","useCallback","useRef","useState","useState","useCallback","useRef","jsx","Fragment","jsx","jsxs","useState","useCallback","useRef","useMemo","sendMessage","useEffect","createPortal"]}