zenit-sdk 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-R73LRYVJ.mjs +3060 -0
- package/dist/chunk-R73LRYVJ.mjs.map +1 -0
- package/dist/{chat.service-Dr9qCnuT.d.mts → index-Da0hFqDL.d.mts} +187 -1
- package/dist/{chat.service-Dr9qCnuT.d.ts → index-Da0hFqDL.d.ts} +187 -1
- package/dist/index.d.mts +5 -2
- package/dist/index.d.ts +5 -2
- package/dist/index.js +2764 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +51 -3
- package/dist/index.mjs.map +1 -1
- package/dist/react/index.d.mts +3 -183
- package/dist/react/index.d.ts +3 -183
- package/dist/react/index.js +38 -35
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +25 -2712
- package/dist/react/index.mjs.map +1 -1
- package/package.json +27 -7
- package/dist/chunk-4Y7JCMGR.mjs +0 -330
- package/dist/chunk-4Y7JCMGR.mjs.map +0 -1
package/dist/react/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/react/index.ts","../../src/react/ZenitMap.tsx","../../src/maps/helpers.ts","../../src/engine/LayerStateEngine.ts","../../src/react/layerStyleHelpers.ts","../../src/react/zoomOpacity.ts","../../src/react/ZenitLayerManager.tsx","../../src/react/icons.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":["export { ZenitMap } from './ZenitMap';\r\nexport type { ZenitMapRef, LayerSnapshot, ZenitMapProps } from './ZenitMap';\r\nexport { ZenitLayerManager } from './ZenitLayerManager';\r\nexport { ZenitFeatureFilterPanel } from './ZenitFeatureFilterPanel';\r\nexport { FloatingChatBox } from './ai/FloatingChatBox';\r\nexport type { FloatingChatBoxProps } from './ai/FloatingChatBox';\r\nexport * from './hooks/use-chat';\r\nexport * from './icons';\r\nexport * from './layerStyleHelpers';\r\nexport * from './zoomOpacity';\r\n","import React, { useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState, forwardRef } from 'react';\r\nimport { GeoJSON, MapContainer, Marker, TileLayer, ZoomControl, useMap } 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 {\r\n clampOpacity,\r\n getEffectiveLayerOpacity,\r\n getLayerZoomOpacityFactor,\r\n} from './zoomOpacity';\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 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 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\n\r\nfunction computeBBoxFromGeojson(geojson?: GeoJsonFeatureCollection | null): Bbox | null {\r\n if (!geojson) return null;\r\n if (!Array.isArray(geojson.features) || geojson.features.length === 0) 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 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\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\nfunction escapeHtml(value: string): string {\r\n return value\r\n .replace(/&/g, '&')\r\n .replace(/</g, '<')\r\n .replace(/>/g, '>')\r\n .replace(/\"/g, '"')\r\n .replace(/'/g, ''');\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\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 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 layerName =\r\n (properties.layerName as string | undefined) ??\r\n (properties.layer_name as string | undefined) ??\r\n (properties.name as string | undefined);\r\n const descripcion =\r\n (properties.descripcion as string | undefined) ??\r\n (properties.description as string | undefined);\r\n\r\n const reservedKeys = new Set([\r\n '_style',\r\n 'layerId',\r\n 'layer_id',\r\n '__zenit_layerId',\r\n 'layerName',\r\n 'layer_name',\r\n 'name',\r\n 'descripcion',\r\n 'description',\r\n ]);\r\n\r\n const extraEntries = Object.entries(properties)\r\n .filter(([key, value]) => {\r\n if (reservedKeys.has(key)) return false;\r\n return ['string', 'number', 'boolean'].includes(typeof value);\r\n })\r\n .slice(0, 5);\r\n\r\n if (!layerName && !descripcion && extraEntries.length === 0) return null;\r\n\r\n const parts: string[] = [];\r\n if (layerName) {\r\n parts.push(`<div style=\"font-weight:600;margin-bottom:4px;\">${escapeHtml(layerName)}</div>`);\r\n }\r\n if (descripcion) {\r\n parts.push(`<div style=\"margin-bottom:6px;\">${escapeHtml(descripcion)}</div>`);\r\n }\r\n if (extraEntries.length > 0) {\r\n const rows = extraEntries\r\n .map(([key, value]) => {\r\n const label = escapeHtml(key.replace(/_/g, ' '));\r\n const val = escapeHtml(String(value));\r\n return `<div><strong>${label}:</strong> ${val}</div>`;\r\n })\r\n .join('');\r\n parts.push(`<div style=\"font-size:12px;line-height:1.4;\">${rows}</div>`);\r\n }\r\n\r\n return `<div>${parts.join('')}</div>`;\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\nconst FitToBounds: React.FC<{ bbox?: Bbox | null }> = ({ bbox }) => {\r\n const mapInstance = useMap();\r\n const lastAppliedBBox = useRef<string | null>(null);\r\n\r\n useEffect(() => {\r\n const targetBBox = bbox;\r\n if (!targetBBox) return;\r\n\r\n const serialized = JSON.stringify(targetBBox);\r\n if (lastAppliedBBox.current === serialized) return;\r\n\r\n const bounds: LatLngBoundsExpression = [\r\n [targetBBox.minLat, targetBBox.minLon],\r\n [targetBBox.maxLat, targetBBox.maxLon],\r\n ];\r\n mapInstance.fitBounds(bounds, { padding: [12, 12] });\r\n lastAppliedBBox.current = serialized;\r\n }, [bbox, mapInstance]);\r\n\r\n return null;\r\n};\r\n\r\nconst AutoFitToBounds: React.FC<{ bbox?: Bbox | null; enabled?: boolean }> = ({\r\n bbox,\r\n enabled = true,\r\n}) => {\r\n const mapInstance = useMap();\r\n const lastAutoBBoxApplied = useRef<string | null>(null);\r\n const lastUserInteracted = useRef(false);\r\n\r\n useEffect(() => {\r\n if (!enabled) return;\r\n\r\n const handleInteraction = () => {\r\n lastUserInteracted.current = true;\r\n };\r\n\r\n mapInstance.on('dragstart', handleInteraction);\r\n mapInstance.on('zoomstart', handleInteraction);\r\n\r\n return () => {\r\n mapInstance.off('dragstart', handleInteraction);\r\n mapInstance.off('zoomstart', handleInteraction);\r\n };\r\n }, [enabled, mapInstance]);\r\n\r\n useEffect(() => {\r\n if (!enabled) return;\r\n if (!bbox) return;\r\n\r\n const serialized = JSON.stringify(bbox);\r\n if (lastAutoBBoxApplied.current === serialized) return;\r\n\r\n if (lastUserInteracted.current) {\r\n lastUserInteracted.current = false;\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 mapInstance.fitBounds(bounds, { padding: [12, 12] });\r\n lastAutoBBoxApplied.current = serialized;\r\n }, [bbox, enabled, mapInstance]);\r\n\r\n return null;\r\n};\r\n\r\ninterface ZoomBasedOpacityHandlerProps {\r\n onZoomChange: (zoom: number) => void;\r\n}\r\n\r\nconst ZoomBasedOpacityHandler: React.FC<ZoomBasedOpacityHandlerProps> = ({ onZoomChange }) => {\r\n const mapInstance = useMap();\r\n\r\n useEffect(() => {\r\n const handleZoom = () => {\r\n onZoomChange(mapInstance.getZoom());\r\n };\r\n\r\n mapInstance.on('zoomend', handleZoom);\r\n handleZoom();\r\n\r\n return () => {\r\n mapInstance.off('zoomend', handleZoom);\r\n };\r\n }, [mapInstance, onZoomChange]);\r\n\r\n return null;\r\n};\r\n\r\ninterface MapInstanceBridgeProps {\r\n onReady: (mapInstance: L.Map) => void;\r\n}\r\n\r\nconst MapInstanceBridge: React.FC<MapInstanceBridgeProps> = ({ onReady }) => {\r\n const mapInstance = useMap();\r\n\r\n useEffect(() => {\r\n onReady(mapInstance);\r\n }, [mapInstance, onReady]);\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 [currentZoom, setCurrentZoom] = useState<number>(initialZoom ?? DEFAULT_ZOOM);\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 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 [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 zoomFactor = getLayerZoomOpacityFactor(\r\n currentZoom,\r\n meta?.layerType,\r\n meta?.geometryType\r\n );\r\n const baseOpacity = clampOpacity(uiOpacity / zoomFactor);\r\n const effectiveOpacity = getEffectiveLayerOpacity(\r\n baseOpacity,\r\n currentZoom,\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 const decoratedLayers = useMemo(() => {\r\n return layers.map((layer) => ({\r\n ...layer,\r\n effective: effectiveStates.find((state) => state.layerId === layer.mapLayer.layerId),\r\n data:\r\n layerGeojson?.[layer.mapLayer.layerId] ??\r\n layerGeojson?.[String(layer.mapLayer.layerId)] ??\r\n null,\r\n }));\r\n }, [effectiveStates, layerGeojson, 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 explicitZoomBBox = useMemo(() => {\r\n if (zoomToBbox) return zoomToBbox;\r\n if (zoomToGeojson) return computeBBoxFromGeojson(zoomToGeojson);\r\n return null;\r\n }, [zoomToBbox, zoomToGeojson]);\r\n\r\n const autoZoomBBox = useMemo(() => {\r\n if (explicitZoomBBox) return null;\r\n const visibleBBoxes = orderedLayers.map((layer) => computeBBoxFromGeojson(layer.data));\r\n return mergeBBoxes(visibleBBoxes);\r\n }, [explicitZoomBBox, orderedLayers]);\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 opacity = layerState.effective?.opacity ?? 1;\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 }, [decoratedLayers, labelKeyIndex, resolveLayerStyle]);\r\n\r\n const ensureLayerPanes = useCallback(\r\n (targetMap: L.Map, targetLayers: Array<{ layerId: number | string; displayOrder: number }>) => {\r\n const baseZIndex = 400;\r\n\r\n targetLayers.forEach((layer) => {\r\n const paneName = `zenit-layer-${layer.layerId}`;\r\n const pane = targetMap.getPane(paneName) ?? targetMap.createPane(paneName);\r\n const order = Number.isFinite(layer.displayOrder) ? layer.displayOrder : 0;\r\n pane.style.zIndex = String(baseZIndex + order);\r\n });\r\n },\r\n []\r\n );\r\n\r\n const handleMapReady = useCallback(\r\n (instance: L.Map) => {\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, solo salir sin resetear panesReady\r\n if (!mapInstance) {\r\n return;\r\n }\r\n\r\n // Si no hay capas ordenadas, solo salir sin resetear panesReady\r\n if (orderedLayers.length === 0) {\r\n return; // ← CAMBIO CRÍTICO: NO hacer setPanesReady(false) aquí\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\r\n ensureLayerPanes(mapInstance, layerTargets);\r\n }, [mapInstance, orderedLayers, ensureLayerPanes]);\r\n\r\n const overlayOnEachFeature = useMemo(() => {\r\n return (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 isPointFeature =\r\n geometryType === 'Point' ||\r\n geometryType === 'MultiPoint' ||\r\n layer instanceof L.CircleMarker;\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 layer.bindPopup(content, { maxWidth: 320 });\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', () => onFeatureClick?.(feature, layerId));\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 };\r\n }, [featureInfoMode, onFeatureClick, onFeatureHover]);\r\n\r\n const buildLayerStyle = (\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 const sanitizedBaseOpacity = clampOpacity(baseOpacity);\r\n const normalizedStyleFill =\r\n typeof resolvedStyle?.fillOpacity === 'number'\r\n ? clampOpacity(resolvedStyle.fillOpacity)\r\n : 0.8;\r\n const effectiveOpacity = getEffectiveLayerOpacity(\r\n sanitizedBaseOpacity,\r\n currentZoom,\r\n resolvedLayerType,\r\n geometryType\r\n );\r\n const fillOpacity = clampOpacity(effectiveOpacity * normalizedStyleFill);\r\n const strokeOpacity = clampOpacity(Math.max(0.35, effectiveOpacity * 0.9));\r\n\r\n return {\r\n color: resolvedStyle?.color ?? resolvedStyle?.fillColor ?? '#2563eb',\r\n weight: resolvedStyle?.weight ?? 2,\r\n fillColor: resolvedStyle?.fillColor ?? resolvedStyle?.color ?? '#2563eb',\r\n opacity: strokeOpacity,\r\n fillOpacity,\r\n };\r\n };\r\n\r\n const buildLabelIcon = useCallback((label: string, opacity: number, color: string) => {\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\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 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 getMapInstance: () => mapInstance,\r\n }), [effectiveStates, 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 style={{ flex: 1, position: 'relative' }}>\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=\"© OpenStreetMap contributors\"\r\n />\r\n <ZoomControl position=\"topright\" />\r\n <MapInstanceBridge onReady={handleMapReady} />\r\n <FitToBounds bbox={explicitZoomBBox ?? undefined} />\r\n <AutoFitToBounds bbox={autoZoomBBox ?? undefined} enabled={!explicitZoomBBox} />\r\n <ZoomBasedOpacityHandler onZoomChange={handleZoomChange} />\r\n {orderedLayers.map((layerState) => {\r\n const baseOpacity =\r\n layerState.effective?.baseOpacity ?? layerState.effective?.opacity ?? 1;\r\n const paneName = `zenit-layer-${layerState.mapLayer.layerId}`;\r\n const layerType =\r\n layerState.layer?.layerType ??\r\n (layerState.mapLayer as { layerType?: string }).layerType ??\r\n undefined;\r\n\r\n return (\r\n <GeoJSON\r\n key={layerState.mapLayer.layerId.toString()}\r\n data={layerState.data as GeoJsonFeatureCollection}\r\n pane={mapInstance?.getPane(paneName) ? paneName : undefined}\r\n style={(feature) =>\r\n buildLayerStyle(layerState.mapLayer.layerId, baseOpacity, feature, layerType)\r\n }\r\n pointToLayer={(feature, latlng) =>\r\n L.circleMarker(latlng, {\r\n radius: isMobile ? 8 : 6,\r\n ...buildLayerStyle(layerState.mapLayer.layerId, baseOpacity, feature, layerType),\r\n })\r\n }\r\n onEachFeature={overlayOnEachFeature}\r\n />\r\n );\r\n })}\r\n {overlayGeojson && (\r\n <GeoJSON\r\n key=\"zenit-overlay-geojson\"\r\n data={overlayGeojson as GeoJsonFeatureCollection}\r\n style={overlayStyleFunction}\r\n onEachFeature={overlayOnEachFeature}\r\n />\r\n )}\r\n {labelMarkers.map((marker) => (\r\n <Marker\r\n key={marker.key}\r\n position={marker.position}\r\n icon={buildLabelIcon(marker.label, marker.opacity, marker.color)}\r\n interactive={false}\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 && (\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: 10,\r\n maxZoom: 17,\r\n minFactor: 0.6,\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, 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 { 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}\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\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}) => {\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' | 'upload'>('layers');\r\n const [panelVisible, setPanelVisible] = useState(true);\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 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 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 </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 {activeTab === 'layers' && renderLayerCards()}\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, ChevronLeft, ChevronRight, Layers, Upload, X, ZoomIn } from 'lucide-react';\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}\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: 24,\r\n right: 24,\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: 15,\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: '14px 24px',\r\n gap: 8,\r\n } as React.CSSProperties,\r\n\r\n floatingButtonOpen: {\r\n width: 56,\r\n height: 56,\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: 92,\r\n right: 24,\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: 400,\r\n height: 550,\r\n } as React.CSSProperties,\r\n\r\n panelExpanded: {\r\n width: 520,\r\n height: 700,\r\n } as React.CSSProperties,\r\n\r\n // Header with green gradient\r\n header: {\r\n padding: '16px 18px',\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: 16,\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: 32,\r\n height: 32,\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: '20px 18px',\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: '12px 14px',\r\n borderRadius: 16,\r\n lineHeight: 1.5,\r\n fontSize: 14,\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: '14px 16px',\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: '10px 12px',\r\n fontSize: 14,\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: '10px 14px',\r\n background: 'linear-gradient(135deg, #10b981, #059669)',\r\n color: '#fff',\r\n cursor: 'pointer',\r\n fontSize: 14,\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: 44,\r\n height: 44,\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}) => {\r\n const [open, setOpen] = useState(false);\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 // 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\r\n useEffect(() => {\r\n if (!open) return;\r\n\r\n const handleClickOutside = (event: MouseEvent) => {\r\n if (\r\n open &&\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]);\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 useEffect(() => {\r\n if (typeof window === 'undefined' || typeof document === 'undefined') return;\r\n\r\n const mediaQuery = window.matchMedia('(max-width: 768px)');\r\n const originalOverflow = document.body.style.overflow;\r\n\r\n const updateOverflow = () => {\r\n if (open && expanded && mediaQuery.matches) {\r\n document.body.style.overflow = 'hidden';\r\n } else {\r\n document.body.style.overflow = originalOverflow;\r\n }\r\n };\r\n\r\n updateOverflow();\r\n if (mediaQuery.addEventListener) {\r\n mediaQuery.addEventListener('change', updateOverflow);\r\n } else {\r\n mediaQuery.addListener(updateOverflow);\r\n }\r\n\r\n return () => {\r\n if (mediaQuery.removeEventListener) {\r\n mediaQuery.removeEventListener('change', updateOverflow);\r\n } else {\r\n mediaQuery.removeListener(updateOverflow);\r\n }\r\n document.body.style.overflow = originalOverflow;\r\n };\r\n }, [open, expanded]);\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(error instanceof Error ? error.message : 'Ocurrió un error inesperado.');\r\n addMessage({\r\n id: `error-${Date.now()}`,\r\n role: 'assistant',\r\n content: `❌ Error: ${error instanceof Error ? error.message : 'Ocurrió un error inesperado.'}`,\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 // 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={() => !isStreaming && onActionClick?.(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 {\r\n position: fixed !important;\r\n inset: 0 !important;\r\n width: 100vw !important;\r\n max-width: 100vw !important;\r\n height: 100vh !important;\r\n height: 100dvh !important;\r\n border-radius: 0 !important;\r\n display: flex !important;\r\n flex-direction: column !important;\r\n overflow: hidden !important;\r\n z-index: 3000 !important;\r\n padding-top: env(safe-area-inset-top);\r\n padding-bottom: env(safe-area-inset-bottom);\r\n }\r\n .zenit-chat-panel.zenit-chat-panel--fullscreen .zenit-ai-body {\r\n flex: 1;\r\n overflow: auto;\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 ? ' zenit-chat-panel--expanded' : ''}${\r\n expanded && isMobile ? ' zenit-chat-panel--fullscreen' : ''\r\n }`}\r\n style={{\r\n ...styles.panel,\r\n ...(expanded ? styles.panelExpanded : styles.panelNormal),\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 <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 <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>Analizando</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 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 {!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 <button\r\n type=\"button\"\r\n className={`zenit-ai-button ${open ? 'open' : ''}${\r\n open && expanded && isMobile ? ' zenit-ai-button--hidden-mobile' : ''\r\n }`}\r\n style={{\r\n ...styles.floatingButton,\r\n ...(open ? styles.floatingButtonOpen : styles.floatingButtonClosed),\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 <span>Asistente IA</span>\r\n </>\r\n )}\r\n </button>\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":["clampOpacity","clampOpacity","clampOpacity","clampOpacity","L","zoom","import_react","import_jsx_runtime","getLayerColor","React","import_jsx_runtime","import_react","import_react","import_jsx_runtime","ReactMarkdown","remarkGfm","import_jsx_runtime","sendMessage"]}
|
|
1
|
+
{"version":3,"sources":["../../src/react/index.ts","../../src/react/ZenitMap.tsx","../../src/maps/helpers.ts","../../src/engine/LayerStateEngine.ts","../../src/react/layerStyleHelpers.ts","../../src/react/zoomOpacity.ts","../../src/react/ZenitLayerManager.tsx","../../src/react/icons.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":["export { ZenitMap } from './ZenitMap';\r\nexport type { ZenitMapRef, LayerSnapshot, ZenitMapProps } from './ZenitMap';\r\nexport { ZenitLayerManager } from './ZenitLayerManager';\r\nexport { ZenitFeatureFilterPanel } from './ZenitFeatureFilterPanel';\r\nexport { FloatingChatBox } from './ai/FloatingChatBox';\r\nexport type { FloatingChatBoxProps } from './ai/FloatingChatBox';\r\nexport * from './hooks/use-chat';\r\nexport * from './icons';\r\nexport * from './layerStyleHelpers';\r\nexport * from './zoomOpacity';\r\n","import React, { useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState, forwardRef } from 'react';\r\nimport { GeoJSON, MapContainer, Marker, TileLayer, ZoomControl, useMap } 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 {\r\n clampOpacity,\r\n getEffectiveLayerOpacity,\r\n getLayerZoomOpacityFactor,\r\n} from './zoomOpacity';\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 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 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\n\r\nfunction computeBBoxFromGeojson(geojson?: GeoJsonFeatureCollection | null): Bbox | null {\r\n if (!geojson) return null;\r\n if (!Array.isArray(geojson.features) || geojson.features.length === 0) 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 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\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\nfunction escapeHtml(value: string): string {\r\n return value\r\n .replace(/&/g, '&')\r\n .replace(/</g, '<')\r\n .replace(/>/g, '>')\r\n .replace(/\"/g, '"')\r\n .replace(/'/g, ''');\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\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 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 layerName =\r\n (properties.layerName as string | undefined) ??\r\n (properties.layer_name as string | undefined) ??\r\n (properties.name as string | undefined);\r\n const descripcion =\r\n (properties.descripcion as string | undefined) ??\r\n (properties.description as string | undefined);\r\n\r\n const reservedKeys = new Set([\r\n '_style',\r\n 'layerId',\r\n 'layer_id',\r\n '__zenit_layerId',\r\n 'layerName',\r\n 'layer_name',\r\n 'name',\r\n 'descripcion',\r\n 'description',\r\n ]);\r\n\r\n const extraEntries = Object.entries(properties)\r\n .filter(([key, value]) => {\r\n if (reservedKeys.has(key)) return false;\r\n return ['string', 'number', 'boolean'].includes(typeof value);\r\n })\r\n .slice(0, 5);\r\n\r\n if (!layerName && !descripcion && extraEntries.length === 0) return null;\r\n\r\n const parts: string[] = [];\r\n if (layerName) {\r\n parts.push(`<div style=\"font-weight:600;margin-bottom:4px;\">${escapeHtml(layerName)}</div>`);\r\n }\r\n if (descripcion) {\r\n parts.push(`<div style=\"margin-bottom:6px;\">${escapeHtml(descripcion)}</div>`);\r\n }\r\n if (extraEntries.length > 0) {\r\n const rows = extraEntries\r\n .map(([key, value]) => {\r\n const label = escapeHtml(key.replace(/_/g, ' '));\r\n const val = escapeHtml(String(value));\r\n return `<div><strong>${label}:</strong> ${val}</div>`;\r\n })\r\n .join('');\r\n parts.push(`<div style=\"font-size:12px;line-height:1.4;\">${rows}</div>`);\r\n }\r\n\r\n return `<div>${parts.join('')}</div>`;\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\nconst FitToBounds: React.FC<{ bbox?: Bbox | null }> = ({ bbox }) => {\r\n const mapInstance = useMap();\r\n const lastAppliedBBox = useRef<string | null>(null);\r\n\r\n useEffect(() => {\r\n const targetBBox = bbox;\r\n if (!targetBBox) return;\r\n\r\n const serialized = JSON.stringify(targetBBox);\r\n if (lastAppliedBBox.current === serialized) return;\r\n\r\n const bounds: LatLngBoundsExpression = [\r\n [targetBBox.minLat, targetBBox.minLon],\r\n [targetBBox.maxLat, targetBBox.maxLon],\r\n ];\r\n mapInstance.fitBounds(bounds, { padding: [12, 12] });\r\n lastAppliedBBox.current = serialized;\r\n }, [bbox, mapInstance]);\r\n\r\n return null;\r\n};\r\n\r\nconst AutoFitToBounds: React.FC<{ bbox?: Bbox | null; enabled?: boolean }> = ({\r\n bbox,\r\n enabled = true,\r\n}) => {\r\n const mapInstance = useMap();\r\n const lastAutoBBoxApplied = useRef<string | null>(null);\r\n const lastUserInteracted = useRef(false);\r\n\r\n useEffect(() => {\r\n if (!enabled) return;\r\n\r\n const handleInteraction = () => {\r\n lastUserInteracted.current = true;\r\n };\r\n\r\n mapInstance.on('dragstart', handleInteraction);\r\n mapInstance.on('zoomstart', handleInteraction);\r\n\r\n return () => {\r\n mapInstance.off('dragstart', handleInteraction);\r\n mapInstance.off('zoomstart', handleInteraction);\r\n };\r\n }, [enabled, mapInstance]);\r\n\r\n useEffect(() => {\r\n if (!enabled) return;\r\n if (!bbox) return;\r\n\r\n const serialized = JSON.stringify(bbox);\r\n if (lastAutoBBoxApplied.current === serialized) return;\r\n\r\n if (lastUserInteracted.current) {\r\n lastUserInteracted.current = false;\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 mapInstance.fitBounds(bounds, { padding: [12, 12] });\r\n lastAutoBBoxApplied.current = serialized;\r\n }, [bbox, enabled, mapInstance]);\r\n\r\n return null;\r\n};\r\n\r\ninterface ZoomBasedOpacityHandlerProps {\r\n onZoomChange: (zoom: number) => void;\r\n}\r\n\r\nconst ZoomBasedOpacityHandler: React.FC<ZoomBasedOpacityHandlerProps> = ({ onZoomChange }) => {\r\n const mapInstance = useMap();\r\n\r\n useEffect(() => {\r\n const handleZoom = () => {\r\n onZoomChange(mapInstance.getZoom());\r\n };\r\n\r\n mapInstance.on('zoomend', handleZoom);\r\n handleZoom();\r\n\r\n return () => {\r\n mapInstance.off('zoomend', handleZoom);\r\n };\r\n }, [mapInstance, onZoomChange]);\r\n\r\n return null;\r\n};\r\n\r\ninterface MapInstanceBridgeProps {\r\n onReady: (mapInstance: L.Map) => void;\r\n}\r\n\r\nconst MapInstanceBridge: React.FC<MapInstanceBridgeProps> = ({ onReady }) => {\r\n const mapInstance = useMap();\r\n\r\n useEffect(() => {\r\n onReady(mapInstance);\r\n }, [mapInstance, onReady]);\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 [currentZoom, setCurrentZoom] = useState<number>(initialZoom ?? DEFAULT_ZOOM);\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 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 [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 zoomFactor = getLayerZoomOpacityFactor(\r\n currentZoom,\r\n meta?.layerType,\r\n meta?.geometryType\r\n );\r\n const baseOpacity = clampOpacity(uiOpacity / zoomFactor);\r\n const effectiveOpacity = getEffectiveLayerOpacity(\r\n baseOpacity,\r\n currentZoom,\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 const decoratedLayers = useMemo(() => {\r\n return layers.map((layer) => ({\r\n ...layer,\r\n effective: effectiveStates.find((state) => state.layerId === layer.mapLayer.layerId),\r\n data:\r\n layerGeojson?.[layer.mapLayer.layerId] ??\r\n layerGeojson?.[String(layer.mapLayer.layerId)] ??\r\n null,\r\n }));\r\n }, [effectiveStates, layerGeojson, 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 explicitZoomBBox = useMemo(() => {\r\n if (zoomToBbox) return zoomToBbox;\r\n if (zoomToGeojson) return computeBBoxFromGeojson(zoomToGeojson);\r\n return null;\r\n }, [zoomToBbox, zoomToGeojson]);\r\n\r\n const autoZoomBBox = useMemo(() => {\r\n if (explicitZoomBBox) return null;\r\n const visibleBBoxes = orderedLayers.map((layer) => computeBBoxFromGeojson(layer.data));\r\n return mergeBBoxes(visibleBBoxes);\r\n }, [explicitZoomBBox, orderedLayers]);\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 opacity = layerState.effective?.opacity ?? 1;\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 }, [decoratedLayers, labelKeyIndex, resolveLayerStyle]);\r\n\r\n const ensureLayerPanes = useCallback(\r\n (targetMap: L.Map, targetLayers: Array<{ layerId: number | string; displayOrder: number }>) => {\r\n const baseZIndex = 400;\r\n\r\n targetLayers.forEach((layer) => {\r\n const paneName = `zenit-layer-${layer.layerId}`;\r\n const pane = targetMap.getPane(paneName) ?? targetMap.createPane(paneName);\r\n const order = Number.isFinite(layer.displayOrder) ? layer.displayOrder : 0;\r\n pane.style.zIndex = String(baseZIndex + order);\r\n });\r\n },\r\n []\r\n );\r\n\r\n const handleMapReady = useCallback(\r\n (instance: L.Map) => {\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, solo salir sin resetear panesReady\r\n if (!mapInstance) {\r\n return;\r\n }\r\n\r\n // Si no hay capas ordenadas, solo salir sin resetear panesReady\r\n if (orderedLayers.length === 0) {\r\n return; // ← CAMBIO CRÍTICO: NO hacer setPanesReady(false) aquí\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\r\n ensureLayerPanes(mapInstance, layerTargets);\r\n }, [mapInstance, orderedLayers, ensureLayerPanes]);\r\n\r\n const overlayOnEachFeature = useMemo(() => {\r\n return (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 isPointFeature =\r\n geometryType === 'Point' ||\r\n geometryType === 'MultiPoint' ||\r\n layer instanceof L.CircleMarker;\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 layer.bindPopup(content, { maxWidth: 320 });\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', () => onFeatureClick?.(feature, layerId));\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 };\r\n }, [featureInfoMode, onFeatureClick, onFeatureHover]);\r\n\r\n const buildLayerStyle = (\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 const sanitizedBaseOpacity = clampOpacity(baseOpacity);\r\n const normalizedStyleFill =\r\n typeof resolvedStyle?.fillOpacity === 'number'\r\n ? clampOpacity(resolvedStyle.fillOpacity)\r\n : 0.8;\r\n const effectiveOpacity = getEffectiveLayerOpacity(\r\n sanitizedBaseOpacity,\r\n currentZoom,\r\n resolvedLayerType,\r\n geometryType\r\n );\r\n const fillOpacity = clampOpacity(effectiveOpacity * normalizedStyleFill);\r\n const strokeOpacity = clampOpacity(Math.max(0.35, effectiveOpacity * 0.9));\r\n\r\n return {\r\n color: resolvedStyle?.color ?? resolvedStyle?.fillColor ?? '#2563eb',\r\n weight: resolvedStyle?.weight ?? 2,\r\n fillColor: resolvedStyle?.fillColor ?? resolvedStyle?.color ?? '#2563eb',\r\n opacity: strokeOpacity,\r\n fillOpacity,\r\n };\r\n };\r\n\r\n const buildLabelIcon = useCallback((label: string, opacity: number, color: string) => {\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\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 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 getMapInstance: () => mapInstance,\r\n }), [effectiveStates, 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 style={{ flex: 1, position: 'relative' }}>\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=\"© OpenStreetMap contributors\"\r\n />\r\n <ZoomControl position=\"topright\" />\r\n <MapInstanceBridge onReady={handleMapReady} />\r\n <FitToBounds bbox={explicitZoomBBox ?? undefined} />\r\n <AutoFitToBounds bbox={autoZoomBBox ?? undefined} enabled={!explicitZoomBBox} />\r\n <ZoomBasedOpacityHandler onZoomChange={handleZoomChange} />\r\n {orderedLayers.map((layerState) => {\r\n const baseOpacity =\r\n layerState.effective?.baseOpacity ?? layerState.effective?.opacity ?? 1;\r\n const paneName = `zenit-layer-${layerState.mapLayer.layerId}`;\r\n const layerType =\r\n layerState.layer?.layerType ??\r\n (layerState.mapLayer as { layerType?: string }).layerType ??\r\n undefined;\r\n\r\n return (\r\n <GeoJSON\r\n key={layerState.mapLayer.layerId.toString()}\r\n data={layerState.data as GeoJsonFeatureCollection}\r\n pane={mapInstance?.getPane(paneName) ? paneName : undefined}\r\n style={(feature) =>\r\n buildLayerStyle(layerState.mapLayer.layerId, baseOpacity, feature, layerType)\r\n }\r\n pointToLayer={(feature, latlng) =>\r\n L.circleMarker(latlng, {\r\n radius: isMobile ? 8 : 6,\r\n ...buildLayerStyle(layerState.mapLayer.layerId, baseOpacity, feature, layerType),\r\n })\r\n }\r\n onEachFeature={overlayOnEachFeature}\r\n />\r\n );\r\n })}\r\n {overlayGeojson && (\r\n <GeoJSON\r\n key=\"zenit-overlay-geojson\"\r\n data={overlayGeojson as GeoJsonFeatureCollection}\r\n style={overlayStyleFunction}\r\n onEachFeature={overlayOnEachFeature}\r\n />\r\n )}\r\n {labelMarkers.map((marker) => (\r\n <Marker\r\n key={marker.key}\r\n position={marker.position}\r\n icon={buildLabelIcon(marker.label, marker.opacity, marker.color)}\r\n interactive={false}\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 && (\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: 10,\r\n maxZoom: 17,\r\n minFactor: 0.6,\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, 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 { 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}\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\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}) => {\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' | 'upload'>('layers');\r\n const [panelVisible, setPanelVisible] = useState(true);\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 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 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 </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 {activeTab === 'layers' && renderLayerCards()}\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, ChevronLeft, ChevronRight, Layers, Upload, X, ZoomIn } from 'lucide-react';\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\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: 24,\r\n right: 24,\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: 15,\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: '14px 24px',\r\n gap: 8,\r\n } as React.CSSProperties,\r\n\r\n floatingButtonOpen: {\r\n width: 56,\r\n height: 56,\r\n padding: 0,\r\n } as React.CSSProperties,\r\n\r\n floatingButtonMobile: {\r\n width: 56,\r\n height: 56,\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: 92,\r\n right: 24,\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: 400,\r\n height: 550,\r\n } as React.CSSProperties,\r\n\r\n panelExpanded: {\r\n width: 520,\r\n height: 700,\r\n } as React.CSSProperties,\r\n\r\n // Header with green gradient\r\n header: {\r\n padding: '16px 18px',\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: 16,\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: 32,\r\n height: 32,\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: '20px 18px',\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: '12px 14px',\r\n borderRadius: 16,\r\n lineHeight: 1.5,\r\n fontSize: 14,\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: '14px 16px',\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: '10px 12px',\r\n fontSize: 14,\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: '10px 14px',\r\n background: 'linear-gradient(135deg, #10b981, #059669)',\r\n color: '#fff',\r\n cursor: 'pointer',\r\n fontSize: 14,\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: 44,\r\n height: 44,\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}) => {\r\n const [open, setOpen] = useState(false);\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 // Notify parent when open state changes\r\n useEffect(() => {\r\n onOpenChange?.(open);\r\n }, [open, onOpenChange]);\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(error instanceof Error ? error.message : 'Ocurrió un error inesperado.');\r\n addMessage({\r\n id: `error-${Date.now()}`,\r\n role: 'assistant',\r\n content: `❌ Error: ${error instanceof Error ? error.message : 'Ocurrió un error inesperado.'}`,\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 // 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={() => !isStreaming && onActionClick?.(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 {\r\n position: fixed !important;\r\n inset: 0 !important;\r\n width: 100vw !important;\r\n max-width: 100vw !important;\r\n height: 100vh !important;\r\n height: 100dvh !important;\r\n border-radius: 0 !important;\r\n display: flex !important;\r\n flex-direction: column !important;\r\n overflow: hidden !important;\r\n z-index: 100000 !important;\r\n padding-top: env(safe-area-inset-top);\r\n }\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 ? ' zenit-chat-panel--expanded' : ''}${\r\n isMobile ? ' zenit-chat-panel--fullscreen' : ''\r\n }`}\r\n style={{\r\n ...styles.panel,\r\n ...(expanded ? styles.panelExpanded : styles.panelNormal),\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 <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 <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>Analizando</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 {!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 }}\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":["clampOpacity","clampOpacity","clampOpacity","clampOpacity","L","zoom","import_react","import_jsx_runtime","getLayerColor","React","import_jsx_runtime","import_react","import_react","import_jsx_runtime","ReactMarkdown","remarkGfm","import_jsx_runtime","sendMessage"]}
|