zenit-sdk 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/http/HttpClient.ts","../src/auth/ZenitAuthClient.ts","../src/sdkAuth/ZenitSdkAuthClient.ts","../src/maps/ZenitMapsClient.ts","../src/layers/catalogSupport.ts","../src/engine/PrefilterEngine.ts","../src/layers/ZenitLayersClient.ts","../src/config/ZenitSdkConfig.ts","../src/maps/helpers.ts","../src/engine/FilterEngine.ts","../src/engine/LayerStateEngine.ts","../src/ai/chat.service.ts","../src/ai/normalize.ts","../src/react/ZenitMap.tsx","../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/react/components/MarkdownRenderer.tsx"],"sourcesContent":["export * from './core';\r\nexport * from './react';\r\n","export interface ZenitSdkError {\r\n success: false;\r\n statusCode: number;\r\n timestamp?: string;\r\n path?: string;\r\n method?: string;\r\n error?: string;\r\n message: string;\r\n}\r\n\r\ntype TokenResolver = () => { accessToken?: string; sdkToken?: string };\r\ntype AuthorizationHeaderResolver = () => Record<string, string>;\r\n\r\nexport interface HttpClientOptions {\r\n baseUrl: string;\r\n resolveTokens?: TokenResolver;\r\n resolveAuthorizationHeader?: AuthorizationHeaderResolver;\r\n}\r\n\r\n/**\r\n * Minimal fetch-based HTTP client for the Zenit SDK.\r\n * Responsible for setting base URL, auth headers and error normalization.\r\n *\r\n * - El header `Authorization` se usa para JWT de usuario o JWT obtenido vía `/sdk-auth/exchange`.\r\n * - El header `X-SDK-Token` se usa para enviar el token SDK crudo a endpoints como\r\n * `/sdk-auth/validate` y `/sdk-auth/exchange`.\r\n */\r\nexport class HttpClient {\r\n private readonly baseUrl: string;\r\n private readonly resolveTokens?: TokenResolver;\r\n private readonly resolveAuthorizationHeader: AuthorizationHeaderResolver;\r\n\r\n constructor(options: HttpClientOptions) {\r\n this.baseUrl = options.baseUrl.replace(/\\/$/, '');\r\n this.resolveTokens = options.resolveTokens;\r\n this.resolveAuthorizationHeader = options.resolveAuthorizationHeader ?? (() => ({}));\r\n }\r\n\r\n async get<T>(path: string, options: RequestInit = {}): Promise<T> {\r\n const headers = {\r\n ...(options.headers as Record<string, string> | undefined),\r\n ...this.resolveAuthorizationHeader(),\r\n };\r\n\r\n return this.request<T>(path, { ...options, method: 'GET', headers });\r\n }\r\n\r\n async post<T>(path: string, body?: unknown, options: RequestInit = {}): Promise<T> {\r\n const headers: Record<string, string> = {\r\n 'Content-Type': 'application/json',\r\n ...(options.headers as Record<string, string> | undefined),\r\n ...this.resolveAuthorizationHeader(),\r\n };\r\n\r\n return this.request<T>(path, {\r\n ...options,\r\n method: 'POST',\r\n headers,\r\n body: body !== undefined ? JSON.stringify(body) : undefined,\r\n });\r\n }\r\n\r\n async put<T>(path: string, body?: unknown, options: RequestInit = {}): Promise<T> {\r\n const headers: Record<string, string> = {\r\n 'Content-Type': 'application/json',\r\n ...(options.headers as Record<string, string> | undefined),\r\n ...this.resolveAuthorizationHeader(),\r\n };\r\n\r\n return this.request<T>(path, {\r\n ...options,\r\n method: 'PUT',\r\n headers,\r\n body: body !== undefined ? JSON.stringify(body) : undefined,\r\n });\r\n }\r\n\r\n async patch<T>(path: string, body?: unknown, options: RequestInit = {}): Promise<T> {\r\n const headers: Record<string, string> = {\r\n 'Content-Type': 'application/json',\r\n ...(options.headers as Record<string, string> | undefined),\r\n ...this.resolveAuthorizationHeader(),\r\n };\r\n\r\n return this.request<T>(path, {\r\n ...options,\r\n method: 'PATCH',\r\n headers,\r\n body: body !== undefined ? JSON.stringify(body) : undefined,\r\n });\r\n }\r\n\r\n async delete<T>(path: string, options: RequestInit = {}): Promise<T> {\r\n const headers = {\r\n ...(options.headers as Record<string, string> | undefined),\r\n ...this.resolveAuthorizationHeader(),\r\n };\r\n\r\n return this.request<T>(path, { ...options, method: 'DELETE', headers });\r\n }\r\n\r\n private async request<T>(path: string, options: RequestInit): Promise<T> {\r\n const url = `${this.baseUrl}${path}`;\r\n const tokenState = this.resolveTokens?.();\r\n\r\n // Usamos Record<string, string> para que TypeScript permita indexar con 'Authorization' y 'X-SDK-Token'\r\n const headers: Record<string, string> = {\r\n ...(options.headers as Record<string, string> | undefined),\r\n };\r\n\r\n if (!headers['Authorization'] && tokenState?.accessToken) {\r\n headers['Authorization'] = `Bearer ${tokenState.accessToken}`;\r\n }\r\n\r\n if (tokenState?.sdkToken) {\r\n headers['X-SDK-Token'] = tokenState.sdkToken;\r\n }\r\n\r\n const response = await fetch(url, {\r\n ...options,\r\n headers,\r\n });\r\n\r\n const contentType = response.headers.get('content-type');\r\n const isJson = contentType?.includes('application/json');\r\n const payload = isJson ? await response.json() : await response.text();\r\n\r\n if (!response.ok) {\r\n const normalizedError: ZenitSdkError = {\r\n success: false,\r\n statusCode: response.status,\r\n message: typeof payload === 'string' ? payload : payload?.message || 'Unknown error',\r\n timestamp: typeof payload === 'object' ? payload.timestamp : undefined,\r\n path: typeof payload === 'object' ? payload.path : undefined,\r\n method: typeof payload === 'object' ? payload.method : undefined,\r\n error: typeof payload === 'object' ? payload.error : undefined,\r\n };\r\n throw normalizedError;\r\n }\r\n\r\n return payload as T;\r\n }\r\n}\r\n","import { HttpClient } from '../http/HttpClient';\r\nimport type {\r\n LoginRequest,\r\n LoginResponse,\r\n MeResponse,\r\n RefreshResponse,\r\n ValidateResponse\r\n} from './AuthTypes';\r\nimport type { ZenitSdkConfig } from '../config/ZenitSdkConfig';\r\n\r\n/**\r\n * Client to manage user authentication endpoints.\r\n */\r\nexport class ZenitAuthClient {\r\n constructor(\r\n private readonly http: HttpClient,\r\n private readonly updateTokens: (tokens: { accessToken?: string; refreshToken?: string }) => void,\r\n private readonly config: ZenitSdkConfig\r\n ) {}\r\n\r\n async login(credentials: LoginRequest): Promise<LoginResponse> {\r\n try {\r\n const response = await this.http.post<LoginResponse>('/auth/login', credentials);\r\n const accessToken = (response as any)?.accessToken ?? (response as any)?.data?.accessToken;\r\n const refreshToken = (response as any)?.refreshToken ?? (response as any)?.data?.refreshToken;\r\n this.updateTokens({ accessToken, refreshToken });\r\n return response;\r\n } catch (error) {\r\n this.config.onAuthError?.(error as any);\r\n throw error;\r\n }\r\n }\r\n\r\n async refresh(refreshToken?: string): Promise<RefreshResponse> {\r\n // Zenit allows refresh via httpOnly cookie or Authorization header; the SDK uses the header when a token is available.\r\n const tokenToUse = refreshToken || this.config.refreshToken;\r\n const headers = tokenToUse ? { Authorization: `Bearer ${tokenToUse}` } : undefined;\r\n const response = await this.http.post<RefreshResponse>('/auth/refresh', undefined, { headers });\r\n const accessToken = (response as any)?.accessToken ?? (response as any)?.data?.accessToken;\r\n const nextRefreshToken = (response as any)?.refreshToken ?? (response as any)?.data?.refreshToken;\r\n this.updateTokens({ accessToken, refreshToken: nextRefreshToken });\r\n return response;\r\n }\r\n\r\n async me(): Promise<MeResponse> {\r\n return this.http.get<MeResponse>('/auth/me');\r\n }\r\n\r\n async validate(): Promise<ValidateResponse> {\r\n return this.http.get<ValidateResponse>('/auth/validate');\r\n }\r\n}\r\n","import { HttpClient } from '../http/HttpClient';\r\nimport type { ZenitSdkConfig } from '../config/ZenitSdkConfig';\r\nimport type { SdkTokenExchangeResponse, SdkTokenValidateResponse } from './SdkAuthTypes';\r\n\r\n/**\r\n * Client to manage SDK token validation and exchange endpoints.\r\n */\r\nexport class ZenitSdkAuthClient {\r\n constructor(\r\n private readonly http: HttpClient,\r\n private readonly updateAccessToken: (token?: string) => void,\r\n private readonly config: ZenitSdkConfig\r\n ) {}\r\n\r\n /**\r\n * Validate an SDK token. If no token argument is provided, it falls back to config.sdkToken.\r\n */\r\n async validateSdkToken(token?: string): Promise<SdkTokenValidateResponse> {\r\n const sdkToken = token || this.config.sdkToken;\r\n return this.http.post<SdkTokenValidateResponse>('/sdk-auth/validate', { token: sdkToken });\r\n }\r\n\r\n /**\r\n * Exchange an SDK token for an access token. Token can come from method args or config.sdkToken.\r\n */\r\n async exchangeSdkToken(token?: string): Promise<SdkTokenExchangeResponse> {\r\n const sdkToken = token || this.config.sdkToken;\r\n const response = await this.http.post<SdkTokenExchangeResponse>('/sdk-auth/exchange', { token: sdkToken });\r\n const accessToken = (response as any)?.accessToken ?? (response as any)?.data?.accessToken;\r\n this.updateAccessToken(accessToken);\r\n return response;\r\n }\r\n}\r\n","import { HttpClient } from '../http/HttpClient';\r\nimport type { MapDto } from './types';\r\n\r\nexport class ZenitMapsClient {\r\n constructor(private readonly httpClient: HttpClient) {}\r\n\r\n async getMap(mapId: number | string, includeLayers = true): Promise<MapDto> {\r\n const include = includeLayers ? '?includeLayers=true' : '';\r\n return this.httpClient.get<MapDto>(`/maps/${mapId}${include}`);\r\n }\r\n}\r\n","export type CatalogSupportReason =\r\n | 'supported'\r\n | 'unsupported-geometry'\r\n | 'unknown-geometry';\r\n\r\nexport type CatalogSupport = {\r\n supported: boolean;\r\n reason: CatalogSupportReason;\r\n layerType?: string;\r\n geometryType?: string;\r\n};\r\n\r\nfunction isPolygonLike(value?: string): boolean {\r\n if (!value) {\r\n return false;\r\n }\r\n\r\n const normalized = value.toLowerCase();\r\n return normalized === 'polygon' || normalized === 'multipolygon';\r\n}\r\n\r\nexport function getCatalogSupport(args: {\r\n layerType?: string;\r\n geometryType?: string;\r\n}): CatalogSupport {\r\n const { layerType, geometryType } = args;\r\n\r\n if (layerType !== undefined) {\r\n const supported = isPolygonLike(layerType);\r\n return {\r\n supported,\r\n reason: supported ? 'supported' : 'unsupported-geometry',\r\n layerType,\r\n geometryType,\r\n };\r\n }\r\n\r\n if (geometryType !== undefined) {\r\n const supported = isPolygonLike(geometryType);\r\n return {\r\n supported,\r\n reason: supported ? 'supported' : 'unsupported-geometry',\r\n geometryType,\r\n };\r\n }\r\n\r\n return {\r\n supported: false,\r\n reason: 'unknown-geometry',\r\n };\r\n}\r\n\r\nexport class ZenitCatalogNotSupportedError extends Error {\r\n name = 'ZenitCatalogNotSupportedError';\r\n support: CatalogSupport;\r\n\r\n constructor(support: CatalogSupport, message?: string) {\r\n super(message ?? 'Catalog is not supported for this layer geometry');\r\n this.support = support;\r\n Object.setPrototypeOf(this, new.target.prototype);\r\n }\r\n}\r\n","import type { GeoJsonFeature, GeoJsonFeatureCollection } from '../layers/types';\r\n\r\ntype PrefilterValue = string | number | boolean;\r\nexport type Prefilters = Record<string, unknown> | null | undefined;\r\n\r\nconst normalizeString = (value: string): string => value.trim().toLowerCase();\r\n\r\nconst isPrefilterValue = (value: unknown): value is PrefilterValue =>\r\n typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean';\r\n\r\nconst matchesPrefilterValue = (candidate: unknown, expected: PrefilterValue): boolean => {\r\n if (typeof expected === 'string') {\r\n if (candidate === null || candidate === undefined) return false;\r\n return normalizeString(String(candidate)) === normalizeString(expected);\r\n }\r\n\r\n return candidate === expected;\r\n};\r\n\r\nconst shouldApplyPrefilters = (prefilters: Prefilters): prefilters is Record<string, unknown> =>\r\n !!prefilters && Object.keys(prefilters).length > 0;\r\n\r\nconst featureMatchesPrefilters = (\r\n feature: GeoJsonFeature,\r\n prefilters: Record<string, unknown>\r\n): boolean => {\r\n const properties = (feature.properties ?? {}) as Record<string, unknown>;\r\n\r\n return Object.entries(prefilters).every(([key, expected]) => {\r\n if (!isPrefilterValue(expected)) return true;\r\n return matchesPrefilterValue(properties[key], expected);\r\n });\r\n};\r\n\r\nexport const applyPrefiltersToFeatureCollection = (\r\n featureCollection: GeoJsonFeatureCollection,\r\n prefilters: Prefilters\r\n): GeoJsonFeatureCollection => {\r\n if (!shouldApplyPrefilters(prefilters)) return featureCollection;\r\n\r\n const nextFeatures = featureCollection.features.filter((feature) =>\r\n featureMatchesPrefilters(feature, prefilters)\r\n );\r\n\r\n return {\r\n ...featureCollection,\r\n features: nextFeatures,\r\n };\r\n};\r\n\r\nexport const decorateFeaturesWithLayerId = (\r\n featureCollection: GeoJsonFeatureCollection,\r\n layerId: number | string\r\n): GeoJsonFeatureCollection => {\r\n let shouldClone = false;\r\n\r\n featureCollection.features.forEach((feature) => {\r\n const existing = (feature.properties as { __zenit_layerId?: number | string } | undefined)\r\n ?.__zenit_layerId;\r\n if (existing !== layerId) {\r\n shouldClone = true;\r\n }\r\n });\r\n\r\n if (!shouldClone) {\r\n return featureCollection;\r\n }\r\n\r\n return {\r\n ...featureCollection,\r\n features: featureCollection.features.map((feature) => ({\r\n ...feature,\r\n properties: {\r\n ...(feature.properties ?? {}),\r\n __zenit_layerId: layerId,\r\n },\r\n })),\r\n };\r\n};\r\n","import { HttpClient } from '../http/HttpClient';\r\nimport {\r\n ZenitCatalogNotSupportedError,\r\n getCatalogSupport,\r\n} from './catalogSupport';\r\nimport { decorateFeaturesWithLayerId } from '../engine/PrefilterEngine';\r\nimport type {\r\n ApiResponseData,\r\n FilterMultipleMetadata,\r\n FilterMultipleLayerMeta,\r\n FilterMultipleWithFallbackResult,\r\n GeoJsonBBoxRequest,\r\n GeoJsonFeatureCollection,\r\n GeoJsonGeometryCollection,\r\n GeoJsonIntersectRequest,\r\n GeoJsonRequestOptions,\r\n LayerAoi,\r\n LayerDto,\r\n LayerMetadata,\r\n LayerFeaturesCatalogDto,\r\n LayerFilters,\r\n LoadLayerDataParams,\r\n LoadLayerDataResult,\r\n ResolveLayerStrategyParams,\r\n ResolveLayerStrategyResult,\r\n} from './types';\r\n\r\nfunction parseQueryParams(options: GeoJsonRequestOptions = {}): URLSearchParams {\r\n const params = new URLSearchParams();\r\n if (options.maxFeatures !== undefined) {\r\n params.set('maxFeatures', String(options.maxFeatures));\r\n }\r\n if (options.simplify !== undefined) {\r\n params.set('simplify', String(options.simplify));\r\n }\r\n return params;\r\n}\r\n\r\nfunction serializeFilterValue(value: unknown): string | undefined {\r\n if (Array.isArray(value)) {\r\n const serialized = value.map(String).filter((item) => item.trim().length > 0).join(',');\r\n return serialized.length > 0 ? serialized : undefined;\r\n }\r\n\r\n if (value === undefined || value === null) {\r\n return undefined;\r\n }\r\n\r\n const serialized = String(value);\r\n return serialized.trim().length > 0 ? serialized : undefined;\r\n}\r\n\r\nexport function buildLayerFilters(filters?: LayerFilters): URLSearchParams {\r\n const query = new URLSearchParams();\r\n\r\n if (!filters) {\r\n return query;\r\n }\r\n\r\n Object.entries(filters).forEach(([key, value]) => {\r\n const serialized = serializeFilterValue(value);\r\n if (serialized !== undefined) {\r\n query.set(key, serialized);\r\n }\r\n });\r\n\r\n return query;\r\n}\r\n\r\nexport function buildFilterMultipleParams(params: {\r\n layerIds: Array<number | string>;\r\n filters?: LayerFilters;\r\n}): URLSearchParams {\r\n const query = buildLayerFilters(params.filters);\r\n\r\n if (!Array.isArray(params.layerIds) || params.layerIds.length === 0) {\r\n throw new Error('layerIds is required and cannot be empty');\r\n }\r\n\r\n query.set('layerIds', params.layerIds.map((id) => String(id)).join(','));\r\n return query;\r\n\r\n}\r\n\r\nfunction asOptionalNumber(value: unknown): number | undefined {\r\n return typeof value === 'number' && Number.isFinite(value)\r\n ? value\r\n : undefined;\r\n}\r\n\r\nfunction createEmptyFeatureCollection(): GeoJsonFeatureCollection {\r\n return { type: 'FeatureCollection', features: [] };\r\n}\r\n\r\nfunction hasFilters(filters?: LayerFilters): boolean {\r\n return buildLayerFilters(filters).size > 0;\r\n}\r\n\r\nfunction mergeLayerFilters(\r\n base?: LayerFilters,\r\n extra?: LayerFilters\r\n): LayerFilters | undefined {\r\n if (!base && !extra) return undefined;\r\n const merged: LayerFilters = { ...(base ?? {}), ...(extra ?? {}) };\r\n return hasFilters(merged) ? merged : undefined;\r\n}\r\n\r\nexport const DEFAULT_MAX_FEATURES_FULL_GEOJSON = 50000;\r\n\r\nfunction normalizeLayerType(layerType?: string): string | undefined {\r\n return typeof layerType === 'string' ? layerType.toLowerCase() : undefined;\r\n}\r\n\r\nexport function shouldUseFilterMultiple(layerType?: string): boolean {\r\n return normalizeLayerType(layerType) === 'multipolygon';\r\n}\r\n\r\nexport function shouldSkipGeojsonDownload(\r\n layerType?: string,\r\n totalFeatures?: number,\r\n thresholds: { maxFeatures: number; allowLargeGeojson?: boolean } = {\r\n maxFeatures: DEFAULT_MAX_FEATURES_FULL_GEOJSON,\r\n }\r\n): boolean {\r\n if (thresholds.allowLargeGeojson) {\r\n return false;\r\n }\r\n const normalizedType = normalizeLayerType(layerType);\r\n if (normalizedType === 'mixed') {\r\n return true;\r\n }\r\n\r\n if (typeof totalFeatures === 'number' && totalFeatures > thresholds.maxFeatures) {\r\n return true;\r\n }\r\n\r\n return false;\r\n}\r\n\r\nfunction parseBbox(value: unknown): GeoJsonBBoxRequest['bbox'] | undefined {\r\n if (!value || typeof value !== 'object') {\r\n return undefined;\r\n }\r\n const candidate = value as Partial<GeoJsonBBoxRequest['bbox']>;\r\n if (\r\n typeof candidate.minLon === 'number' &&\r\n typeof candidate.minLat === 'number' &&\r\n typeof candidate.maxLon === 'number' &&\r\n typeof candidate.maxLat === 'number'\r\n ) {\r\n return {\r\n minLon: candidate.minLon,\r\n minLat: candidate.minLat,\r\n maxLon: candidate.maxLon,\r\n maxLat: candidate.maxLat,\r\n };\r\n }\r\n\r\n if (Array.isArray(value) && value.length === 4) {\r\n const [minLon, minLat, maxLon, maxLat] = value;\r\n if (\r\n typeof minLon === 'number' &&\r\n typeof minLat === 'number' &&\r\n typeof maxLon === 'number' &&\r\n typeof maxLat === 'number'\r\n ) {\r\n return { minLon, minLat, maxLon, maxLat };\r\n }\r\n }\r\n\r\n return undefined;\r\n}\r\n\r\nfunction buildBboxFromFeatureCollection(\r\n featureCollection: GeoJsonFeatureCollection\r\n): GeoJsonBBoxRequest['bbox'] | undefined {\r\n const coords: Array<[number, number]> = [];\r\n\r\n const collect = (candidate: unknown) => {\r\n if (!Array.isArray(candidate)) return;\r\n if (\r\n candidate.length === 2 &&\r\n typeof candidate[0] === 'number' &&\r\n typeof candidate[1] === 'number' &&\r\n Number.isFinite(candidate[0]) &&\r\n Number.isFinite(candidate[1])\r\n ) {\r\n coords.push([candidate[0], candidate[1]]);\r\n return;\r\n }\r\n\r\n candidate.forEach((item) => collect(item));\r\n };\r\n\r\n featureCollection.features.forEach((feature) => {\r\n collect((feature as { geometry?: { coordinates?: unknown } }).geometry?.coordinates);\r\n });\r\n\r\n if (coords.length === 0) return undefined;\r\n\r\n const [firstLon, firstLat] = coords[0];\r\n const 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 buildGeometryCollectionFromFeatureCollection(\r\n featureCollection: GeoJsonFeatureCollection\r\n): GeoJsonGeometryCollection {\r\n return {\r\n type: 'GeometryCollection',\r\n geometries: featureCollection.features\r\n .map((feature) => feature.geometry)\r\n .filter((geometry) => geometry !== undefined && geometry !== null),\r\n };\r\n}\r\n\r\nexport function buildAoiFromFeatureCollection(\r\n featureCollection: GeoJsonFeatureCollection,\r\n metadata?: FilterMultipleMetadata\r\n): LayerAoi | null {\r\n const metadataBbox = parseBbox(metadata?.bbox);\r\n const derivedBbox = metadataBbox ?? buildBboxFromFeatureCollection(featureCollection);\r\n const hasFeatures = featureCollection.features.length > 0;\r\n\r\n const geometry = hasFeatures\r\n ? buildGeometryCollectionFromFeatureCollection(featureCollection)\r\n : undefined;\r\n\r\n if (!derivedBbox && !geometry) {\r\n return null;\r\n }\r\n\r\n return { bbox: derivedBbox, geometry };\r\n}\r\n\r\nfunction splitFeatureCollectionByLayerId(\r\n featureCollection: GeoJsonFeatureCollection,\r\n layerIds: Array<number | string>\r\n): Record<string, GeoJsonFeatureCollection> {\r\n const grouped: Record<string, GeoJsonFeatureCollection> = {};\r\n layerIds.forEach((layerId) => {\r\n grouped[String(layerId)] = createEmptyFeatureCollection();\r\n });\r\n\r\n featureCollection.features.forEach((feature) => {\r\n const properties = feature.properties as Record<string, unknown> | undefined;\r\n const layerId =\r\n (properties?.layerId as number | string | undefined) ??\r\n (properties?.layer_id as number | string | undefined) ??\r\n (properties?.__zenit_layerId as number | string | undefined);\r\n if (layerId === undefined || layerId === null) {\r\n return;\r\n }\r\n\r\n const key = String(layerId);\r\n if (!grouped[key]) {\r\n grouped[key] = createEmptyFeatureCollection();\r\n }\r\n grouped[key] = {\r\n ...grouped[key],\r\n features: [...grouped[key].features, feature],\r\n };\r\n });\r\n\r\n return grouped;\r\n}\r\n\r\nexport function resolveLayerStrategy(\r\n params: ResolveLayerStrategyParams\r\n): ResolveLayerStrategyResult {\r\n const {\r\n layerDetail,\r\n bbox,\r\n filterBBox,\r\n filteredGeoJSON,\r\n isVisible = true,\r\n maxFeaturesFullGeojson,\r\n allowLargeGeojson,\r\n } = params;\r\n\r\n if (!isVisible) {\r\n return { strategy: 'geojson', effectiveBBox: bbox };\r\n }\r\n\r\n if (filteredGeoJSON && layerDetail.layerType !== 'multipolygon') {\r\n return {\r\n strategy: 'intersect',\r\n intersectionGeometry: buildGeometryCollectionFromFeatureCollection(filteredGeoJSON),\r\n };\r\n }\r\n\r\n const shouldSkipGeojson = shouldSkipGeojsonDownload(layerDetail.layerType, layerDetail.totalFeatures, {\r\n maxFeatures: maxFeaturesFullGeojson ?? DEFAULT_MAX_FEATURES_FULL_GEOJSON,\r\n allowLargeGeojson,\r\n });\r\n\r\n if (shouldSkipGeojson && (filterBBox ?? bbox)) {\r\n return { strategy: 'bbox', effectiveBBox: filterBBox ?? bbox };\r\n }\r\n\r\n if ((layerDetail.totalFeatures ?? 0) > 5000 && (filterBBox ?? bbox)) {\r\n return { strategy: 'bbox', effectiveBBox: filterBBox ?? bbox };\r\n }\r\n\r\n return { strategy: 'geojson', effectiveBBox: bbox };\r\n}\r\n\r\nexport function buildLimitedMessage(metadata?: LayerMetadata): string | undefined {\r\n if (!metadata) {\r\n return undefined;\r\n }\r\n\r\n const explicit = metadata.limitedMessage;\r\n if (typeof explicit === 'string' && explicit.trim().length > 0) {\r\n return explicit;\r\n }\r\n\r\n const limit = typeof metadata.limit === 'number' ? metadata.limit : undefined;\r\n const total =\r\n typeof metadata.totalFeatures === 'number'\r\n ? metadata.totalFeatures\r\n : undefined;\r\n\r\n if (limit !== undefined && total !== undefined && total > limit) {\r\n return `Mostrando ${limit.toLocaleString()} de ${total.toLocaleString()} elementos por límite de capa.`;\r\n }\r\n\r\n if (metadata.limited && limit !== undefined) {\r\n return `Mostrando un máximo de ${limit.toLocaleString()} elementos por límite de capa.`;\r\n }\r\n\r\n return undefined;\r\n}\r\n\r\nexport class ZenitLayersClient {\r\n constructor(private readonly httpClient: HttpClient) {}\r\n\r\n async getLayer(layerId: number | string): Promise<ApiResponseData<LayerDto>> {\r\n const response = await this.httpClient.get<ApiResponseData<LayerDto>>(\r\n `/layers/${layerId}`\r\n );\r\n return this.unwrapResponse(response);\r\n }\r\n\r\n async getLayerGeoJson(\r\n layerId: number | string,\r\n options: GeoJsonRequestOptions = {}\r\n ): Promise<ApiResponseData<GeoJsonFeatureCollection>> {\r\n const params = parseQueryParams(options);\r\n const suffix = params.size > 0 ? `?${params.toString()}` : '';\r\n\r\n const response = await this.httpClient.get<ApiResponseData<GeoJsonFeatureCollection>>(\r\n `/layers/${layerId}/geojson${suffix}`\r\n );\r\n return this.unwrapResponse(response);\r\n }\r\n\r\n async getLayerFeaturesCatalog(\r\n layerId: number | string,\r\n options?: { layerType?: string; geometryType?: string; strict?: boolean }\r\n ): Promise<ApiResponseData<LayerFeaturesCatalogDto>> {\r\n if (options?.strict) {\r\n const support = getCatalogSupport({\r\n layerType: options.layerType,\r\n geometryType: options.geometryType,\r\n });\r\n\r\n if (!support.supported) {\r\n throw new ZenitCatalogNotSupportedError(\r\n support,\r\n support.reason === 'unknown-geometry'\r\n ? 'Catalog support cannot be determined without a geometry type'\r\n : 'Catalog is only supported for polygon or multipolygon geometries'\r\n );\r\n }\r\n }\r\n\r\n const response = await this.httpClient.get<ApiResponseData<LayerFeaturesCatalogDto>>(\r\n `/layers/${layerId}/features/catalog`\r\n );\r\n return this.unwrapResponse(response);\r\n }\r\n\r\n async getLayerFeatures(\r\n layerId: number | string,\r\n featureIds: Array<number | string>\r\n ): Promise<ApiResponseData<GeoJsonFeatureCollection>> {\r\n if (!Array.isArray(featureIds) || featureIds.length === 0) {\r\n throw new Error('featureIds is required and cannot be empty');\r\n }\r\n\r\n const query = featureIds.map(String).join(',');\r\n const response = await this.httpClient.get<ApiResponseData<GeoJsonFeatureCollection>>(\r\n `/layers/${layerId}/features?featureIds=${encodeURIComponent(query)}`\r\n );\r\n\r\n return this.unwrapResponse(response);\r\n }\r\n\r\n async filterLayerFeatures(\r\n layerId: number | string,\r\n filters: LayerFilters\r\n ): Promise<ApiResponseData<GeoJsonFeatureCollection>> {\r\n const query = buildLayerFilters(filters);\r\n\r\n const suffix = query.toString();\r\n const response = await this.httpClient.get<ApiResponseData<GeoJsonFeatureCollection>>(\r\n `/layers/${layerId}/features/filter${suffix ? `?${suffix}` : ''}`\r\n );\r\n\r\n return this.unwrapResponse(response);\r\n }\r\n\r\n async filterMultipleLayersFeatures(params: {\r\n layerIds: Array<number | string>;\r\n filters?: LayerFilters;\r\n }): Promise<ApiResponseData<GeoJsonFeatureCollection, FilterMultipleMetadata>> {\r\n const query = buildFilterMultipleParams(params);\r\n\r\n const suffix = query.toString();\r\n const response = await this.httpClient.get<\r\n ApiResponseData<GeoJsonFeatureCollection, FilterMultipleMetadata>\r\n >(`/layers/features/filter-multiple${suffix ? `?${suffix}` : ''}`);\r\n\r\n return this.unwrapResponse(response);\r\n }\r\n\r\n async filterMultiple(params: {\r\n layerIds: Array<number | string>;\r\n filters?: LayerFilters;\r\n }): Promise<ApiResponseData<GeoJsonFeatureCollection, FilterMultipleMetadata>> {\r\n return this.filterMultipleLayersFeatures(params);\r\n }\r\n\r\n /**\r\n * Resilient filter-multiple helper:\r\n * - Usa filter-multiple SOLO en capas multipolygon.\r\n * - Para otras capas aplica filterLayerFeatures o getLayerGeoJson según haya filtros.\r\n * - Nunca falla toda la operación por una capa inválida.\r\n *\r\n * Para mejor detección de layerType, pasa layerMetas con el layerType de cada capa.\r\n */\r\n async filterMultipleWithFallback(params: {\r\n layerIds: Array<number | string>;\r\n filters?: LayerFilters;\r\n layerMetas?: FilterMultipleLayerMeta[];\r\n maxFeaturesFullGeojson?: number;\r\n allowLargeGeojson?: boolean;\r\n }): Promise<FilterMultipleWithFallbackResult> {\r\n const layerIds = params.layerIds ?? [];\r\n const perLayer: Record<string, GeoJsonFeatureCollection> = {};\r\n const warnings: string[] = [];\r\n const hasLayerMetas = (params.layerMetas ?? []).length > 0;\r\n const maxFeaturesFullGeojson =\r\n params.maxFeaturesFullGeojson ?? DEFAULT_MAX_FEATURES_FULL_GEOJSON;\r\n const allowLargeGeojson = params.allowLargeGeojson ?? false;\r\n\r\n layerIds.forEach((layerId) => {\r\n perLayer[String(layerId)] = createEmptyFeatureCollection();\r\n });\r\n\r\n if (layerIds.length === 0) {\r\n return { perLayer };\r\n }\r\n\r\n const globalFilters = hasFilters(params.filters) ? params.filters : undefined;\r\n const metaIndex = new Map<string, FilterMultipleLayerMeta>();\r\n (params.layerMetas ?? []).forEach((meta) => {\r\n metaIndex.set(String(meta.layerId), meta);\r\n });\r\n\r\n let multipolygonIds: Array<number | string> = [];\r\n let otherIds: Array<number | string> = [];\r\n const layerIdsWithData = new Set<string>();\r\n let aoi: LayerAoi | null = null;\r\n\r\n const pushWarning = (message: string) => {\r\n warnings.push(message);\r\n console.warn(message);\r\n };\r\n\r\n const buildSkipWarning = (\r\n layerId: number | string,\r\n layerType?: string,\r\n totalFeatures?: number,\r\n reason?: string\r\n ) => {\r\n const typeLabel = layerType ?? 'unknown';\r\n const totalLabel =\r\n typeof totalFeatures === 'number' ? ` totalFeatures=${totalFeatures}` : '';\r\n const reasonLabel = reason ? ` ${reason}` : '';\r\n return `Layer ${layerId} skipped: layerType=${typeLabel}${totalLabel}${reasonLabel}`;\r\n };\r\n\r\n if (hasLayerMetas) {\r\n layerIds.forEach((layerId) => {\r\n const meta = metaIndex.get(String(layerId));\r\n if (shouldUseFilterMultiple(meta?.layerType)) {\r\n multipolygonIds.push(layerId);\r\n } else {\r\n otherIds.push(layerId);\r\n }\r\n });\r\n } else {\r\n multipolygonIds = [...layerIds];\r\n }\r\n\r\n let metadata: FilterMultipleMetadata | undefined;\r\n\r\n if (multipolygonIds.length > 0) {\r\n try {\r\n const response = await this.filterMultipleLayersFeatures({\r\n layerIds: multipolygonIds,\r\n filters: globalFilters,\r\n });\r\n metadata = response.metadata;\r\n const geojson = response.data ?? createEmptyFeatureCollection();\r\n if (globalFilters) {\r\n aoi = buildAoiFromFeatureCollection(geojson, metadata);\r\n }\r\n const perLayerFromMultiple = splitFeatureCollectionByLayerId(geojson, layerIds);\r\n\r\n Object.entries(perLayerFromMultiple).forEach(([layerKey, collection]) => {\r\n if (collection.features.length === 0) {\r\n return;\r\n }\r\n perLayer[layerKey] = decorateFeaturesWithLayerId(collection, layerKey);\r\n layerIdsWithData.add(layerKey);\r\n });\r\n } catch {\r\n if (hasLayerMetas) {\r\n otherIds = [...new Set([...otherIds, ...multipolygonIds])];\r\n } else {\r\n otherIds = [...layerIds];\r\n }\r\n multipolygonIds = [];\r\n }\r\n }\r\n\r\n if (otherIds.length > 0) {\r\n const pendingIds = otherIds.filter(\r\n (layerId) => !layerIdsWithData.has(String(layerId))\r\n );\r\n const resolved = await Promise.all(\r\n pendingIds.map(async (layerId) => {\r\n const meta = metaIndex.get(String(layerId));\r\n const layerType = meta?.layerType;\r\n const totalFeatures = meta?.totalFeatures;\r\n const layerFilters = mergeLayerFilters(globalFilters, meta?.prefilters);\r\n const canUseIntersect =\r\n !!globalFilters && !shouldUseFilterMultiple(layerType) && !!aoi?.geometry;\r\n\r\n if (canUseIntersect) {\r\n const intersectionGeometry = aoi?.geometry;\r\n if (!intersectionGeometry) {\r\n pushWarning(\r\n buildSkipWarning(\r\n layerId,\r\n layerType,\r\n totalFeatures,\r\n 'no AOI geometry available'\r\n )\r\n );\r\n return { layerId, geojson: createEmptyFeatureCollection() };\r\n }\r\n\r\n try {\r\n const response = await this.getLayerGeoJsonIntersect({\r\n id: layerId,\r\n geometry: intersectionGeometry,\r\n });\r\n if (aoi?.bbox) {\r\n console.debug(\r\n `Layer ${layerId} fetched by intersect using AOI bbox=${JSON.stringify(\r\n aoi.bbox\r\n )}`\r\n );\r\n } else {\r\n console.debug(`Layer ${layerId} fetched by intersect using AOI geometry`);\r\n }\r\n const geojson = response.data ?? createEmptyFeatureCollection();\r\n return {\r\n layerId,\r\n geojson: decorateFeaturesWithLayerId(geojson, layerId),\r\n };\r\n } catch (error) {\r\n const message =\r\n error instanceof Error ? error.message : 'Unknown error';\r\n pushWarning(\r\n buildSkipWarning(\r\n layerId,\r\n layerType,\r\n totalFeatures,\r\n `intersect failed: ${message}`\r\n )\r\n );\r\n return { layerId, geojson: createEmptyFeatureCollection() };\r\n }\r\n }\r\n\r\n if (layerFilters && (hasLayerMetas ? shouldUseFilterMultiple(layerType) : true)) {\r\n try {\r\n const response = await this.filterLayerFeatures(layerId, layerFilters);\r\n const geojson = response.data ?? createEmptyFeatureCollection();\r\n return {\r\n layerId,\r\n geojson: decorateFeaturesWithLayerId(geojson, layerId),\r\n };\r\n } catch (error) {\r\n const message =\r\n error instanceof Error ? error.message : 'Unknown error';\r\n pushWarning(\r\n `Layer ${layerId} filter failed: ${message}`\r\n );\r\n return { layerId, geojson: createEmptyFeatureCollection() };\r\n }\r\n }\r\n\r\n if (\r\n shouldSkipGeojsonDownload(layerType, totalFeatures, {\r\n maxFeatures: maxFeaturesFullGeojson,\r\n allowLargeGeojson,\r\n })\r\n ) {\r\n pushWarning(\r\n buildSkipWarning(\r\n layerId,\r\n layerType,\r\n totalFeatures,\r\n 'not supported by filter endpoint and too large for /geojson; use intersect with AOI'\r\n )\r\n );\r\n return { layerId, geojson: createEmptyFeatureCollection() };\r\n }\r\n\r\n try {\r\n const response = await this.getLayerGeoJson(layerId);\r\n const geojson = response.data ?? createEmptyFeatureCollection();\r\n return {\r\n layerId,\r\n geojson: decorateFeaturesWithLayerId(geojson, layerId),\r\n };\r\n } catch (error) {\r\n const message =\r\n error instanceof Error ? error.message : 'Unknown error';\r\n pushWarning(\r\n buildSkipWarning(layerId, layerType, totalFeatures, `error=${message}`)\r\n );\r\n return { layerId, geojson: createEmptyFeatureCollection() };\r\n }\r\n })\r\n );\r\n\r\n resolved.forEach(({ layerId, geojson }) => {\r\n perLayer[String(layerId)] = geojson;\r\n });\r\n }\r\n\r\n const mergedMetadata =\r\n warnings.length > 0\r\n ? {\r\n ...(metadata ?? {}),\r\n warnings: [...(metadata?.warnings ?? []), ...warnings],\r\n }\r\n : metadata;\r\n\r\n return { perLayer, metadata: mergedMetadata, aoi };\r\n }\r\n\r\n async getLayerGeoJsonBBox(\r\n request: GeoJsonBBoxRequest\r\n ): Promise<ApiResponseData<GeoJsonFeatureCollection>> {\r\n const params = new URLSearchParams({\r\n minLon: String(request.bbox.minLon),\r\n minLat: String(request.bbox.minLat),\r\n maxLon: String(request.bbox.maxLon),\r\n maxLat: String(request.bbox.maxLat),\r\n });\r\n\r\n parseQueryParams(request).forEach((value, key) => params.set(key, value));\r\n\r\n const response = await this.httpClient.get<ApiResponseData<GeoJsonFeatureCollection>>(\r\n `/layers/${request.id}/geojson/bbox?${params.toString()}`\r\n );\r\n return this.unwrapResponse(response);\r\n }\r\n\r\n async getLayerGeoJsonIntersect(\r\n request: GeoJsonIntersectRequest\r\n ): Promise<ApiResponseData<GeoJsonFeatureCollection>> {\r\n const params = parseQueryParams(request);\r\n const suffix = params.size > 0 ? `?${params.toString()}` : '';\r\n\r\n const response = await this.httpClient.post<ApiResponseData<GeoJsonFeatureCollection>>(\r\n `/layers/${request.id}/geojson/intersects${suffix}`,\r\n { geometry: request.geometry }\r\n );\r\n return this.unwrapResponse(response);\r\n }\r\n\r\n async getLayerTileTemplate(layerId: number | string): Promise<string> {\r\n const response = await this.httpClient.get<ApiResponseData<string | { template: string }>>(\r\n `/layers/${layerId}/tiles/template`\r\n );\r\n const unwrapped = this.unwrapResponse(response);\r\n if (typeof unwrapped.data === 'string') {\r\n return unwrapped.data;\r\n }\r\n if (unwrapped.data && typeof (unwrapped.data as { template?: string }).template === 'string') {\r\n return (unwrapped.data as { template: string }).template;\r\n }\r\n throw new Error('Invalid tile template response');\r\n }\r\n\r\n async loadLayerData(\r\n params: LoadLayerDataParams\r\n ): Promise<LoadLayerDataResult> {\r\n const { id, layerDetail, bbox, filterBBox, filteredGeoJSON, isVisible = true, ...options } = params;\r\n const resolution = resolveLayerStrategy({\r\n layerDetail,\r\n bbox,\r\n filterBBox,\r\n filteredGeoJSON,\r\n isVisible,\r\n maxFeaturesFullGeojson: params.maxFeaturesFullGeojson,\r\n allowLargeGeojson: params.allowLargeGeojson,\r\n });\r\n\r\n const response = await this.fetchByStrategy(id, resolution, options);\r\n\r\n const totalFeatures =\r\n asOptionalNumber(response.totalFeatures) ??\r\n asOptionalNumber(response.metadata?.totalFeatures) ??\r\n asOptionalNumber(layerDetail.totalFeatures);\r\n\r\n const limitedMessage =\r\n response.limitedMessage ?? buildLimitedMessage(response.metadata as LayerMetadata | undefined);\r\n\r\n return {\r\n geojson: response.data,\r\n strategy: resolution.strategy,\r\n limitedMessage,\r\n totalFeatures,\r\n metadata: response.metadata as LayerMetadata | undefined,\r\n };\r\n }\r\n\r\n async loadFilteredFeatures(params: {\r\n layerIds: Array<number | string>;\r\n filters: LayerFilters;\r\n }): Promise<{\r\n geojson: GeoJsonFeatureCollection;\r\n metadata?: FilterMultipleMetadata;\r\n totalFeatures?: number;\r\n }> {\r\n const response = await this.filterMultipleLayersFeatures(params);\r\n return {\r\n geojson: response.data,\r\n metadata: response.metadata,\r\n totalFeatures: response.metadata?.totalFeatures ?? response.totalFeatures,\r\n };\r\n }\r\n\r\n private async fetchByStrategy(\r\n layerId: number | string,\r\n resolution: ResolveLayerStrategyResult,\r\n options: GeoJsonRequestOptions\r\n ): Promise<ApiResponseData<GeoJsonFeatureCollection, LayerMetadata>> {\r\n switch (resolution.strategy) {\r\n case 'bbox': {\r\n if (!resolution.effectiveBBox) {\r\n throw new Error('Bounding box is required for bbox strategy');\r\n }\r\n return this.getLayerGeoJsonBBox({ id: layerId, bbox: resolution.effectiveBBox, ...options });\r\n }\r\n case 'intersect': {\r\n if (!resolution.intersectionGeometry) {\r\n throw new Error('Geometry is required for intersect strategy');\r\n }\r\n return this.getLayerGeoJsonIntersect({\r\n id: layerId,\r\n geometry: resolution.intersectionGeometry,\r\n ...options,\r\n });\r\n }\r\n case 'geojson':\r\n default:\r\n return this.getLayerGeoJson(layerId, options);\r\n }\r\n }\r\n\r\n private unwrapResponse<TData, TMetadata = LayerMetadata>(\r\n response: ApiResponseData<TData, TMetadata>\r\n ): ApiResponseData<TData, TMetadata> {\r\n if (!response || typeof response !== 'object' || !('data' in response)) {\r\n throw new Error('Invalid API response: missing data field');\r\n }\r\n if ('success' in response && response.success === false) {\r\n throw new Error(response.message ?? 'Request was not successful');\r\n }\r\n return response;\r\n }\r\n}\r\n","import { HttpClient, ZenitSdkError } from '../http/HttpClient';\r\nimport { ZenitAuthClient } from '../auth/ZenitAuthClient';\r\nimport { ZenitSdkAuthClient } from '../sdkAuth/ZenitSdkAuthClient';\r\nimport { ZenitMapsClient } from '../maps/ZenitMapsClient';\r\nimport { ZenitLayersClient } from '../layers/ZenitLayersClient';\r\n\r\nexport interface ZenitSdkConfig {\r\n // baseUrl: debe apuntar al prefijo de API de Zenit (ej: https://api.mi-zenit.com/api/v1).\r\n baseUrl: string;\r\n // sdkToken: token SDK que se puede validar o intercambiar por JWT.\r\n sdkToken?: string;\r\n // accessToken y refreshToken: tokens de usuario en caso de que el integrador ya los tenga (opcional).\r\n accessToken?: string;\r\n refreshToken?: string;\r\n // onAuthError: callback para manejar errores de login.\r\n onAuthError?(error: ZenitSdkError): void;\r\n // onTokenRefreshed: callback para actualizar tokens en el cliente que consuma el SDK.\r\n onTokenRefreshed?(tokens: { accessToken: string; refreshToken?: string }): void;\r\n}\r\n\r\nexport class ZenitClient {\r\n private accessToken?: string;\r\n private refreshToken?: string;\r\n private sdkToken?: string;\r\n private readonly httpClient: HttpClient;\r\n\r\n readonly auth: ZenitAuthClient;\r\n readonly sdkAuth: ZenitSdkAuthClient;\r\n readonly maps: ZenitMapsClient;\r\n readonly layers: ZenitLayersClient;\r\n\r\n constructor(private readonly config: ZenitSdkConfig) {\r\n this.accessToken = config.accessToken;\r\n this.refreshToken = config.refreshToken;\r\n this.sdkToken = config.sdkToken;\r\n this.httpClient = new HttpClient({\r\n baseUrl: config.baseUrl,\r\n resolveTokens: () => ({ accessToken: this.accessToken, sdkToken: this.sdkToken }),\r\n resolveAuthorizationHeader: this.getAuthorizationHeader.bind(this)\r\n });\r\n\r\n this.auth = new ZenitAuthClient(this.httpClient, this.updateTokens.bind(this), config);\r\n this.sdkAuth = new ZenitSdkAuthClient(\r\n this.httpClient,\r\n this.updateAccessTokenFromSdkExchange.bind(this),\r\n config\r\n );\r\n this.maps = new ZenitMapsClient(this.httpClient);\r\n this.layers = new ZenitLayersClient(this.httpClient);\r\n }\r\n\r\n /**\r\n * Update tokens in memory and propagate to config callbacks.\r\n */\r\n private updateTokens(tokens: { accessToken?: string; refreshToken?: string }) {\r\n if (tokens.accessToken) {\r\n this.setAccessToken(tokens.accessToken);\r\n }\r\n if (tokens.refreshToken) {\r\n this.setRefreshToken(tokens.refreshToken);\r\n }\r\n this.config.onTokenRefreshed?.({\r\n accessToken: this.accessToken || '',\r\n refreshToken: this.refreshToken\r\n });\r\n }\r\n\r\n // Se usa cuando /sdk-auth/exchange devuelve un accessToken; pasa a ser el accessToken principal del SDK.\r\n private updateAccessTokenFromSdkExchange(token?: string) {\r\n if (token) {\r\n this.setAccessToken(token);\r\n }\r\n }\r\n\r\n setAccessToken(token: string) {\r\n this.accessToken = token;\r\n this.config.accessToken = token;\r\n }\r\n\r\n setRefreshToken(token: string) {\r\n this.refreshToken = token;\r\n this.config.refreshToken = token;\r\n }\r\n\r\n getAuthorizationHeader(): Record<string, string> {\r\n const header: Record<string, string> = {};\r\n\r\n if (this.accessToken) {\r\n header.Authorization = `Bearer ${this.accessToken}`;\r\n }\r\n\r\n return header;\r\n }\r\n\r\n getHttpClient(): HttpClient {\r\n return this.httpClient;\r\n }\r\n}\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 { Bbox, GeoJsonPolygon, GeoJsonRequestOptions, LayerFilters } from '../layers/types';\r\n\r\nexport type FilterEngineRequest =\r\n | {\r\n type: 'filter-multiple';\r\n layerIds: Array<number | string>;\r\n filters: LayerFilters;\r\n }\r\n | {\r\n type: 'filter-layer';\r\n layerId: number | string;\r\n filters: LayerFilters;\r\n }\r\n | {\r\n type: 'geojson';\r\n layerId: number | string;\r\n options?: GeoJsonRequestOptions;\r\n }\r\n | {\r\n type: 'bbox';\r\n layerId: number | string;\r\n bbox: Bbox;\r\n options?: GeoJsonRequestOptions;\r\n }\r\n | {\r\n type: 'intersect';\r\n layerId: number | string;\r\n geometry: GeoJsonPolygon;\r\n options?: GeoJsonRequestOptions;\r\n };\r\n\r\nexport interface FilterEngineDecision {\r\n nextRequest: FilterEngineRequest;\r\n reason?: string;\r\n}\r\n\r\nexport interface FilterEngineParams {\r\n layerIds?: Array<number | string>;\r\n layerId?: number | string;\r\n filters?: LayerFilters;\r\n bbox?: Bbox;\r\n geometry?: GeoJsonPolygon;\r\n options?: GeoJsonRequestOptions;\r\n request?: FilterEngineRequest;\r\n}\r\n\r\nexport class FilterEngine {\r\n decide(params: FilterEngineParams): FilterEngineDecision {\r\n if (params.request) {\r\n return { nextRequest: params.request };\r\n }\r\n\r\n if (params.filters && params.layerIds && params.layerIds.length > 1) {\r\n return {\r\n nextRequest: {\r\n type: 'filter-multiple',\r\n layerIds: params.layerIds,\r\n filters: params.filters,\r\n },\r\n reason: 'filters+layerIds',\r\n };\r\n }\r\n\r\n if (params.filters && params.layerId !== undefined) {\r\n return {\r\n nextRequest: {\r\n type: 'filter-layer',\r\n layerId: params.layerId,\r\n filters: params.filters,\r\n },\r\n reason: 'filters+layerId',\r\n };\r\n }\r\n\r\n if (params.bbox && params.layerId !== undefined) {\r\n return {\r\n nextRequest: {\r\n type: 'bbox',\r\n layerId: params.layerId,\r\n bbox: params.bbox,\r\n options: params.options,\r\n },\r\n reason: 'bbox+layerId',\r\n };\r\n }\r\n\r\n if (params.geometry && params.layerId !== undefined) {\r\n return {\r\n nextRequest: {\r\n type: 'intersect',\r\n layerId: params.layerId,\r\n geometry: params.geometry,\r\n options: params.options,\r\n },\r\n reason: 'geometry+layerId',\r\n };\r\n }\r\n\r\n if (params.layerId !== undefined) {\r\n return {\r\n nextRequest: {\r\n type: 'geojson',\r\n layerId: params.layerId,\r\n options: params.options,\r\n },\r\n reason: 'layerId',\r\n };\r\n }\r\n\r\n throw new Error('FilterEngine could not resolve a next request');\r\n }\r\n}\r\n\r\nexport const filterEngine = new FilterEngine();\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","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 type { Bbox } from '../layers/types';\r\n\r\n/**\r\n * Normalizes a bbox input to a standard Bbox object format.\r\n *\r\n * Accepts:\r\n * - Array tuple: [minLon, minLat, maxLon, maxLat]\r\n * - Object: { minLon, minLat, maxLon, maxLat }\r\n *\r\n * Returns:\r\n * - A valid Bbox object with { minLon, minLat, maxLon, maxLat }\r\n * - null if the input is invalid or contains non-finite numbers\r\n *\r\n * @param input - The bbox to normalize (can be array or object)\r\n * @returns A normalized Bbox object or null if invalid\r\n */\r\nexport function normalizeBbox(\r\n input: unknown\r\n): Bbox | null {\r\n if (!input) return null;\r\n\r\n // Case 1: Array tuple [minLon, minLat, maxLon, maxLat]\r\n if (Array.isArray(input)) {\r\n if (input.length !== 4) {\r\n console.warn('[normalizeBbox] Array must have exactly 4 elements, got:', input.length);\r\n return null;\r\n }\r\n\r\n const [minLon, minLat, maxLon, maxLat] = input;\r\n\r\n // Validate all are finite numbers\r\n if (\r\n typeof minLon !== 'number' ||\r\n typeof minLat !== 'number' ||\r\n typeof maxLon !== 'number' ||\r\n typeof maxLat !== 'number' ||\r\n !Number.isFinite(minLon) ||\r\n !Number.isFinite(minLat) ||\r\n !Number.isFinite(maxLon) ||\r\n !Number.isFinite(maxLat)\r\n ) {\r\n console.warn('[normalizeBbox] Array contains non-finite numbers:', input);\r\n return null;\r\n }\r\n\r\n // Validate min < max\r\n if (minLon >= maxLon || minLat >= maxLat) {\r\n console.warn('[normalizeBbox] Invalid bbox: min must be < max', {\r\n minLon,\r\n maxLon,\r\n minLat,\r\n maxLat,\r\n });\r\n return null;\r\n }\r\n\r\n return { minLon, minLat, maxLon, maxLat };\r\n }\r\n\r\n // Case 2: Object with keys { minLon, minLat, maxLon, maxLat }\r\n if (typeof input === 'object') {\r\n const candidate = input as Partial<Bbox>;\r\n\r\n const { minLon, minLat, maxLon, maxLat } = candidate;\r\n\r\n // Validate all keys exist and are finite numbers\r\n if (\r\n typeof minLon !== 'number' ||\r\n typeof minLat !== 'number' ||\r\n typeof maxLon !== 'number' ||\r\n typeof maxLat !== 'number' ||\r\n !Number.isFinite(minLon) ||\r\n !Number.isFinite(minLat) ||\r\n !Number.isFinite(maxLon) ||\r\n !Number.isFinite(maxLat)\r\n ) {\r\n console.warn('[normalizeBbox] Object missing valid bbox keys or contains non-finite numbers:', input);\r\n return null;\r\n }\r\n\r\n // Validate min < max\r\n if (minLon >= maxLon || minLat >= maxLat) {\r\n console.warn('[normalizeBbox] Invalid bbox: min must be < max', {\r\n minLon,\r\n maxLon,\r\n minLat,\r\n maxLat,\r\n });\r\n return null;\r\n }\r\n\r\n return { minLon, minLat, maxLon, maxLat };\r\n }\r\n\r\n console.warn('[normalizeBbox] Unsupported bbox format:', typeof input);\r\n return null;\r\n}\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, '&amp;')\r\n .replace(/</g, '&lt;')\r\n .replace(/>/g, '&gt;')\r\n .replace(/\"/g, '&quot;')\r\n .replace(/'/g, '&#39;');\r\n}\r\n\r\nfunction 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=\"&copy; 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","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 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","serialized","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"]}