@json_1013/core-geografico-isa-mapa 0.1.0-poc
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +90 -0
- package/dist-lib/estilos.css +3 -0
- package/dist-lib/index.js +7722 -0
- package/dist-lib/index.js.map +1 -0
- package/dist-lib/standalone.js +16810 -0
- package/dist-lib/standalone.js.map +1 -0
- package/dist-lib/tipos/features/maps/components/ArbolCapas.d.ts +20 -0
- package/dist-lib/tipos/features/maps/components/BarraHerramientas.d.ts +17 -0
- package/dist-lib/tipos/features/maps/components/BotonTridimensional.d.ts +10 -0
- package/dist-lib/tipos/features/maps/components/ComboBuscable.d.ts +23 -0
- package/dist-lib/tipos/features/maps/components/ControlesEscritorio.d.ts +80 -0
- package/dist-lib/tipos/features/maps/components/ControlesResponsive.d.ts +37 -0
- package/dist-lib/tipos/features/maps/components/LecturaCoordenadas.d.ts +9 -0
- package/dist-lib/tipos/features/maps/components/LeyendaCapa.d.ts +5 -0
- package/dist-lib/tipos/features/maps/components/ListaMapasBase.d.ts +11 -0
- package/dist-lib/tipos/features/maps/components/ListadoOpciones.d.ts +25 -0
- package/dist-lib/tipos/features/maps/components/MapaView.d.ts +19 -0
- package/dist-lib/tipos/features/maps/components/MenuOpcionesServicio.d.ts +13 -0
- package/dist-lib/tipos/features/maps/components/MiniaturaBasemap.d.ts +9 -0
- package/dist-lib/tipos/features/maps/components/ModalAlerta.d.ts +22 -0
- package/dist-lib/tipos/features/maps/components/ModalConsulta.d.ts +34 -0
- package/dist-lib/tipos/features/maps/components/ModalCoordenadas.d.ts +10 -0
- package/dist-lib/tipos/features/maps/components/ModalMedicion.d.ts +25 -0
- package/dist-lib/tipos/features/maps/components/ModalProyeccion.d.ts +16 -0
- package/dist-lib/tipos/features/maps/components/PanelCapas.d.ts +18 -0
- package/dist-lib/tipos/features/maps/components/PanelInferior.d.ts +12 -0
- package/dist-lib/tipos/features/maps/components/PanelMetadata.d.ts +10 -0
- package/dist-lib/tipos/features/maps/components/SelectorBasemap.d.ts +17 -0
- package/dist-lib/tipos/features/maps/components/SelectorDesplegable.d.ts +33 -0
- package/dist-lib/tipos/features/maps/components/TablaResultadosConsulta.d.ts +29 -0
- package/dist-lib/tipos/features/maps/components/Tooltip.d.ts +32 -0
- package/dist-lib/tipos/features/maps/components/VisorMapa.d.ts +18 -0
- package/dist-lib/tipos/features/maps/components/VisorMapaSkeleton.d.ts +4 -0
- package/dist-lib/tipos/features/maps/components/iconos.d.ts +51 -0
- package/dist-lib/tipos/features/maps/context/alertas.context.d.ts +32 -0
- package/dist-lib/tipos/features/maps/context/configuracion.context.d.ts +6 -0
- package/dist-lib/tipos/features/maps/hooks/useCoordenadasPuntero.d.ts +11 -0
- package/dist-lib/tipos/features/maps/hooks/useCoordenadasSeleccion.d.ts +4 -0
- package/dist-lib/tipos/features/maps/hooks/useElevarSuperficies.d.ts +10 -0
- package/dist-lib/tipos/features/maps/hooks/useEstadosCapas.d.ts +16 -0
- package/dist-lib/tipos/features/maps/hooks/useGestorCapas.d.ts +16 -0
- package/dist-lib/tipos/features/maps/hooks/useHerramientaActiva.d.ts +14 -0
- package/dist-lib/tipos/features/maps/hooks/useListbox.d.ts +53 -0
- package/dist-lib/tipos/features/maps/hooks/useMarcadorPunto.d.ts +15 -0
- package/dist-lib/tipos/features/maps/hooks/useModalArrastrable.d.ts +33 -0
- package/dist-lib/tipos/features/maps/hooks/useModoResponsive.d.ts +14 -0
- package/dist-lib/tipos/features/maps/hooks/usePanelesInferiores.d.ts +10 -0
- package/dist-lib/tipos/features/maps/hooks/useRenovacionToken.d.ts +3 -0
- package/dist-lib/tipos/features/maps/hooks/useResaltadoConsulta.d.ts +19 -0
- package/dist-lib/tipos/features/maps/hooks/useResultadosConsulta.d.ts +31 -0
- package/dist-lib/tipos/features/maps/hooks/useVistaArcgis.d.ts +17 -0
- package/dist-lib/tipos/features/maps/providers/ProveedorAlertas.d.ts +3 -0
- package/dist-lib/tipos/features/maps/providers/ProveedorConfiguracion.d.ts +14 -0
- package/dist-lib/tipos/features/maps/services/configuracion-aplicacion.d.ts +10 -0
- package/dist-lib/tipos/features/maps/services/entorno.d.ts +8 -0
- package/dist-lib/tipos/features/maps/services/formato-coordenadas.d.ts +4 -0
- package/dist-lib/tipos/features/maps/services/layers/arcgis.factory.d.ts +8 -0
- package/dist-lib/tipos/features/maps/services/layers/consulta-arcgis.d.ts +20 -0
- package/dist-lib/tipos/features/maps/services/layers/consulta-capa-activa.d.ts +56 -0
- package/dist-lib/tipos/features/maps/services/layers/consulta-wfs.d.ts +20 -0
- package/dist-lib/tipos/features/maps/services/layers/consulta.constantes.d.ts +5 -0
- package/dist-lib/tipos/features/maps/services/layers/descarga-capa.d.ts +46 -0
- package/dist-lib/tipos/features/maps/services/layers/error-servicio.d.ts +2 -0
- package/dist-lib/tipos/features/maps/services/layers/geoserver.d.ts +5 -0
- package/dist-lib/tipos/features/maps/services/layers/gestor-capas.d.ts +62 -0
- package/dist-lib/tipos/features/maps/services/layers/identity-manager.d.ts +5 -0
- package/dist-lib/tipos/features/maps/services/layers/leyenda.d.ts +25 -0
- package/dist-lib/tipos/features/maps/services/layers/simbolos-consulta.d.ts +19 -0
- package/dist-lib/tipos/features/maps/services/layers/types.d.ts +19 -0
- package/dist-lib/tipos/features/maps/services/layers/url-sin-query.d.ts +2 -0
- package/dist-lib/tipos/features/maps/services/layers/wms.factory.d.ts +4 -0
- package/dist-lib/tipos/features/maps/services/layers/xml-utils.d.ts +4 -0
- package/dist-lib/tipos/features/maps/services/parametros-generales.d.ts +12 -0
- package/dist-lib/tipos/features/maps/services/proveedor-token.d.ts +20 -0
- package/dist-lib/tipos/features/maps/services/proyeccion.d.ts +37 -0
- package/dist-lib/tipos/features/maps/services/tools/acciones.registry.d.ts +25 -0
- package/dist-lib/tipos/features/maps/services/tools/agrupar-herramientas.d.ts +3 -0
- package/dist-lib/tipos/features/maps/services/tools/grupos-barra.d.ts +13 -0
- package/dist-lib/tipos/features/maps/services/tools/herramientas.registry.d.ts +8 -0
- package/dist-lib/tipos/features/maps/services/tools/identify.tool.d.ts +27 -0
- package/dist-lib/tipos/features/maps/services/tools/medicion.tool.d.ts +69 -0
- package/dist-lib/tipos/features/maps/services/tools/types.d.ts +24 -0
- package/dist-lib/tipos/features/maps/styles/alertas.estilos.d.ts +15 -0
- package/dist-lib/tipos/features/maps/styles/controles.estilos.d.ts +20 -0
- package/dist-lib/tipos/features/maps/styles/modales.estilos.d.ts +11 -0
- package/dist-lib/tipos/features/maps/styles/raiz.estilos.d.ts +6 -0
- package/dist-lib/tipos/features/maps/types/aplicacion.types.d.ts +7 -0
- package/dist-lib/tipos/features/maps/types/capas.types.d.ts +14 -0
- package/dist-lib/tipos/features/maps/types/configuracion-aplicacion.types.d.ts +14 -0
- package/dist-lib/tipos/features/maps/types/consulta.types.d.ts +57 -0
- package/dist-lib/tipos/features/maps/types/galeria.types.d.ts +7 -0
- package/dist-lib/tipos/features/maps/types/herramienta.types.d.ts +20 -0
- package/dist-lib/tipos/features/maps/types/index.d.ts +11 -0
- package/dist-lib/tipos/features/maps/types/leyenda.types.d.ts +10 -0
- package/dist-lib/tipos/features/maps/types/mapa.types.d.ts +33 -0
- package/dist-lib/tipos/features/maps/types/parametros-generales.types.d.ts +51 -0
- package/dist-lib/tipos/features/maps/types/responsive.types.d.ts +6 -0
- package/dist-lib/tipos/features/maps/types/servicio.types.d.ts +63 -0
- package/dist-lib/tipos/features/maps/utils/basemap-imagenes.d.ts +2 -0
- package/dist-lib/tipos/features/maps/utils/capas-activas.d.ts +6 -0
- package/dist-lib/tipos/features/maps/utils/filtrar-barra.d.ts +6 -0
- package/dist-lib/tipos/features/maps/utils/mapa-helpers.d.ts +5 -0
- package/dist-lib/tipos/features/maps/utils/resolver-servicios.d.ts +5 -0
- package/dist-lib/tipos/lib/MapaCoreIsa.d.ts +31 -0
- package/dist-lib/tipos/lib/index.d.ts +15 -0
- package/dist-lib/tipos/lib/standalone.d.ts +20 -0
- package/dist-lib/tipos/shared/components/MensajeError.d.ts +8 -0
- package/dist-lib/tipos/shared/components/Skeleton.d.ts +4 -0
- package/dist-lib/tipos/shared/entorno.d.ts +19 -0
- package/dist-lib/tipos/shared/helpers/descargar-archivo.d.ts +2 -0
- package/dist-lib/tipos/shared/helpers/formato-duracion.d.ts +2 -0
- package/dist-lib/tipos/shared/helpers/http.d.ts +7 -0
- package/dist-lib/tipos/shared/hooks/useCerrarAlClicFuera.d.ts +3 -0
- package/dist-lib/tipos/shared/hooks/useDesbordado.d.ts +2 -0
- package/dist-lib/tipos/shared/hooks/useHojaInferiorArrastrable.d.ts +21 -0
- package/dist-lib/tipos/shared/hooks/useObservadorTamano.d.ts +11 -0
- package/dist-lib/tipos/shared/hooks/useRecursoAsync.d.ts +12 -0
- package/dist-lib/tipos/shared/hooks/useTamanoContenedor.d.ts +2 -0
- package/dist-lib/tipos/shared/lib/cn.d.ts +2 -0
- package/dist-lib/tipos/shared/types.d.ts +5 -0
- package/package.json +89 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../node_modules/tailwind-merge/dist/bundle-mjs.mjs","../src/shared/lib/cn.ts","../src/shared/components/MensajeError.tsx","../src/features/maps/context/configuracion.context.ts","../src/features/maps/services/proveedor-token.ts","../src/features/maps/types/mapa.types.ts","../src/features/maps/types/servicio.types.ts","../src/shared/helpers/descargar-archivo.ts","../src/shared/helpers/formato-duracion.ts","../src/features/maps/context/alertas.context.ts","../src/features/maps/hooks/useCoordenadasPuntero.ts","../src/features/maps/hooks/useMarcadorPunto.ts","../src/features/maps/hooks/useCoordenadasSeleccion.ts","../src/features/maps/hooks/useElevarSuperficies.ts","../src/features/maps/hooks/useEstadosCapas.ts","../src/features/maps/services/layers/arcgis.factory.ts","../src/features/maps/services/layers/consulta.constantes.ts","../src/features/maps/services/layers/consulta-arcgis.ts","../src/features/maps/services/layers/geoserver.ts","../src/features/maps/services/layers/xml-utils.ts","../src/features/maps/services/layers/consulta-wfs.ts","../src/features/maps/services/layers/url-sin-query.ts","../src/features/maps/services/layers/descarga-capa.ts","../src/features/maps/services/layers/leyenda.ts","../src/features/maps/services/layers/consulta-capa-activa.ts","../src/features/maps/services/layers/identity-manager.ts","../src/features/maps/services/layers/wms.factory.ts","../src/features/maps/services/layers/gestor-capas.ts","../src/features/maps/hooks/useGestorCapas.ts","../src/shared/entorno.ts","../src/shared/helpers/http.ts","../src/features/maps/services/parametros-generales.ts","../src/features/maps/services/tools/identify.tool.ts","../src/features/maps/services/tools/medicion.tool.ts","../src/features/maps/services/tools/herramientas.registry.ts","../src/features/maps/hooks/useHerramientaActiva.ts","../src/shared/hooks/useObservadorTamano.ts","../src/shared/hooks/useTamanoContenedor.ts","../src/features/maps/styles/controles.estilos.ts","../src/features/maps/hooks/useModoResponsive.ts","../src/features/maps/hooks/usePanelesInferiores.ts","../src/features/maps/services/layers/simbolos-consulta.ts","../src/features/maps/hooks/useResaltadoConsulta.ts","../src/features/maps/utils/mapa-helpers.ts","../src/features/maps/hooks/useResultadosConsulta.ts","../src/features/maps/hooks/useVistaArcgis.ts","../src/features/maps/services/layers/error-servicio.ts","../src/features/maps/services/tools/agrupar-herramientas.ts","../src/features/maps/services/tools/acciones.registry.ts","../src/features/maps/utils/capas-activas.ts","../src/features/maps/services/tools/grupos-barra.ts","../src/features/maps/utils/filtrar-barra.ts","../src/features/maps/utils/resolver-servicios.ts","../src/assets/icons/3DActivo.svg?url","../src/assets/icons/3DInactivo.svg?url","../src/assets/icons/Alerta.svg?url","../src/assets/icons/Arrastrar.svg?url","../src/assets/icons/CapaActiva.svg?url","../src/assets/icons/CapasYServicios.svg?url","../src/assets/icons/Cerrar.svg?url","../src/assets/icons/Consultar.svg?url","../src/assets/icons/Descargar.svg?url","../src/assets/icons/FuenteInformacion.svg?url","../src/assets/icons/Identificar.svg?url","../src/assets/icons/Intercambiar.svg?url","../src/assets/icons/Limpiar.svg?url","../src/assets/icons/Medir.svg?url","../src/assets/icons/MedirArea.svg?url","../src/assets/icons/MedirDistancia.svg?url","../src/assets/icons/ObtenerCoordenadas.svg?url","../src/assets/icons/Opacidad.svg?url","../src/assets/icons/OpcionesCapa.svg?url","../src/assets/icons/Proyectar.svg?url","../src/assets/icons/Regresar.svg?url","../src/assets/icons/RestablecerMedida.svg?url","../src/assets/icons/VerTabla.svg?url","../src/assets/icons/ZoomALaCapa.svg?url","../src/assets/icons/ZoomIn.svg?url","../src/assets/icons/ZoomInicial.svg?url","../src/assets/icons/ZoomOut.svg?url","../src/features/maps/components/iconos.tsx","../src/features/maps/styles/raiz.estilos.ts","../src/features/maps/components/Tooltip.tsx","../src/features/maps/components/BarraHerramientas.tsx","../src/features/maps/components/BotonTridimensional.tsx","../src/features/maps/services/formato-coordenadas.ts","../src/features/maps/components/LecturaCoordenadas.tsx","../src/features/maps/hooks/useModalArrastrable.ts","../src/features/maps/styles/modales.estilos.ts","../src/shared/hooks/useCerrarAlClicFuera.ts","../src/features/maps/hooks/useListbox.ts","../src/features/maps/components/ListadoOpciones.tsx","../src/features/maps/components/ComboBuscable.tsx","../src/features/maps/components/SelectorDesplegable.tsx","../src/features/maps/components/TablaResultadosConsulta.tsx","../src/features/maps/components/ModalConsulta.tsx","../src/features/maps/components/ModalCoordenadas.tsx","../src/features/maps/components/ModalMedicion.tsx","../src/features/maps/services/proyeccion.ts","../src/features/maps/components/ModalProyeccion.tsx","../src/shared/hooks/useDesbordado.ts","../src/features/maps/components/LeyendaCapa.tsx","../src/features/maps/components/MenuOpcionesServicio.tsx","../src/features/maps/components/ArbolCapas.tsx","../src/features/maps/components/PanelCapas.tsx","../src/features/maps/components/PanelMetadata.tsx","../src/assets/imagenes/calle_con_relieve.png?url","../src/assets/imagenes/calles.png?url","../src/assets/imagenes/calles_nocturno.png?url","../src/assets/imagenes/gris_claro.png?url","../src/assets/imagenes/gris_oscuro.png?url","../src/assets/imagenes/hibrido.png?url","../src/assets/imagenes/imagenes_satelitales.png?url","../src/assets/imagenes/navegacion.png?url","../src/assets/imagenes/oceanos.png?url","../src/assets/imagenes/openStreetMap.png?url","../src/assets/imagenes/terreno.png?url","../src/assets/imagenes/topografico.png?url","../src/features/maps/utils/basemap-imagenes.ts","../src/features/maps/components/MiniaturaBasemap.tsx","../src/features/maps/components/ListaMapasBase.tsx","../src/features/maps/components/SelectorBasemap.tsx","../src/features/maps/components/ControlesEscritorio.tsx","../src/shared/hooks/useHojaInferiorArrastrable.ts","../src/features/maps/components/PanelInferior.tsx","../src/features/maps/components/ControlesResponsive.tsx","../src/shared/components/Skeleton.tsx","../src/features/maps/components/VisorMapaSkeleton.tsx","../src/features/maps/components/MapaView.tsx","../src/features/maps/components/VisorMapa.tsx","../src/features/maps/styles/alertas.estilos.ts","../src/features/maps/components/ModalAlerta.tsx","../src/features/maps/providers/ProveedorAlertas.tsx","../src/shared/hooks/useRecursoAsync.ts","../src/features/maps/services/configuracion-aplicacion.ts","../src/features/maps/hooks/useRenovacionToken.ts","../src/features/maps/providers/ProveedorConfiguracion.tsx","../src/features/maps/services/entorno.ts","../src/lib/MapaCoreIsa.tsx"],"sourcesContent":["/**\n * Concatenates two arrays faster than the array spread operator.\n */\nconst concatArrays = (array1, array2) => {\n // Pre-allocate for better V8 optimization\n const combinedArray = new Array(array1.length + array2.length);\n for (let i = 0; i < array1.length; i++) {\n combinedArray[i] = array1[i];\n }\n for (let i = 0; i < array2.length; i++) {\n combinedArray[array1.length + i] = array2[i];\n }\n return combinedArray;\n};\n\n// Factory function ensures consistent object shapes\nconst createClassValidatorObject = (classGroupId, validator) => ({\n classGroupId,\n validator\n});\n// Factory ensures consistent ClassPartObject shape\nconst createClassPartObject = (nextPart = new Map(), validators = null, classGroupId) => ({\n nextPart,\n validators,\n classGroupId\n});\nconst CLASS_PART_SEPARATOR = '-';\nconst EMPTY_CONFLICTS = [];\n// I use two dots here because one dot is used as prefix for class groups in plugins\nconst ARBITRARY_PROPERTY_PREFIX = 'arbitrary..';\nconst createClassGroupUtils = config => {\n const classMap = createClassMap(config);\n const {\n conflictingClassGroups,\n conflictingClassGroupModifiers\n } = config;\n const getClassGroupId = className => {\n if (className.startsWith('[') && className.endsWith(']')) {\n return getGroupIdForArbitraryProperty(className);\n }\n const classParts = className.split(CLASS_PART_SEPARATOR);\n // Classes like `-inset-1` produce an empty string as first classPart. We assume that classes for negative values are used correctly and skip it.\n const startIndex = classParts[0] === '' && classParts.length > 1 ? 1 : 0;\n return getGroupRecursive(classParts, startIndex, classMap);\n };\n const getConflictingClassGroupIds = (classGroupId, hasPostfixModifier) => {\n if (hasPostfixModifier) {\n const modifierConflicts = conflictingClassGroupModifiers[classGroupId];\n const baseConflicts = conflictingClassGroups[classGroupId];\n if (modifierConflicts) {\n if (baseConflicts) {\n // Merge base conflicts with modifier conflicts\n return concatArrays(baseConflicts, modifierConflicts);\n }\n // Only modifier conflicts\n return modifierConflicts;\n }\n // Fall back to without postfix if no modifier conflicts\n return baseConflicts || EMPTY_CONFLICTS;\n }\n return conflictingClassGroups[classGroupId] || EMPTY_CONFLICTS;\n };\n return {\n getClassGroupId,\n getConflictingClassGroupIds\n };\n};\nconst getGroupRecursive = (classParts, startIndex, classPartObject) => {\n const classPathsLength = classParts.length - startIndex;\n if (classPathsLength === 0) {\n return classPartObject.classGroupId;\n }\n const currentClassPart = classParts[startIndex];\n const nextClassPartObject = classPartObject.nextPart.get(currentClassPart);\n if (nextClassPartObject) {\n const result = getGroupRecursive(classParts, startIndex + 1, nextClassPartObject);\n if (result) return result;\n }\n const validators = classPartObject.validators;\n if (validators === null) {\n return undefined;\n }\n // Build classRest string efficiently by joining from startIndex onwards\n const classRest = startIndex === 0 ? classParts.join(CLASS_PART_SEPARATOR) : classParts.slice(startIndex).join(CLASS_PART_SEPARATOR);\n const validatorsLength = validators.length;\n for (let i = 0; i < validatorsLength; i++) {\n const validatorObj = validators[i];\n if (validatorObj.validator(classRest)) {\n return validatorObj.classGroupId;\n }\n }\n return undefined;\n};\n/**\n * Get the class group ID for an arbitrary property.\n *\n * @param className - The class name to get the group ID for. Is expected to be string starting with `[` and ending with `]`.\n */\nconst getGroupIdForArbitraryProperty = className => className.slice(1, -1).indexOf(':') === -1 ? undefined : (() => {\n const content = className.slice(1, -1);\n const colonIndex = content.indexOf(':');\n const property = content.slice(0, colonIndex);\n return property ? ARBITRARY_PROPERTY_PREFIX + property : undefined;\n})();\n/**\n * Exported for testing only\n */\nconst createClassMap = config => {\n const {\n theme,\n classGroups\n } = config;\n return processClassGroups(classGroups, theme);\n};\n// Split into separate functions to maintain monomorphic call sites\nconst processClassGroups = (classGroups, theme) => {\n const classMap = createClassPartObject();\n for (const classGroupId in classGroups) {\n const group = classGroups[classGroupId];\n processClassesRecursively(group, classMap, classGroupId, theme);\n }\n return classMap;\n};\nconst processClassesRecursively = (classGroup, classPartObject, classGroupId, theme) => {\n const len = classGroup.length;\n for (let i = 0; i < len; i++) {\n const classDefinition = classGroup[i];\n processClassDefinition(classDefinition, classPartObject, classGroupId, theme);\n }\n};\n// Split into separate functions for each type to maintain monomorphic call sites\nconst processClassDefinition = (classDefinition, classPartObject, classGroupId, theme) => {\n if (typeof classDefinition === 'string') {\n processStringDefinition(classDefinition, classPartObject, classGroupId);\n return;\n }\n if (typeof classDefinition === 'function') {\n processFunctionDefinition(classDefinition, classPartObject, classGroupId, theme);\n return;\n }\n processObjectDefinition(classDefinition, classPartObject, classGroupId, theme);\n};\nconst processStringDefinition = (classDefinition, classPartObject, classGroupId) => {\n const classPartObjectToEdit = classDefinition === '' ? classPartObject : getPart(classPartObject, classDefinition);\n classPartObjectToEdit.classGroupId = classGroupId;\n};\nconst processFunctionDefinition = (classDefinition, classPartObject, classGroupId, theme) => {\n if (isThemeGetter(classDefinition)) {\n processClassesRecursively(classDefinition(theme), classPartObject, classGroupId, theme);\n return;\n }\n if (classPartObject.validators === null) {\n classPartObject.validators = [];\n }\n classPartObject.validators.push(createClassValidatorObject(classGroupId, classDefinition));\n};\nconst processObjectDefinition = (classDefinition, classPartObject, classGroupId, theme) => {\n const entries = Object.entries(classDefinition);\n const len = entries.length;\n for (let i = 0; i < len; i++) {\n const [key, value] = entries[i];\n processClassesRecursively(value, getPart(classPartObject, key), classGroupId, theme);\n }\n};\nconst getPart = (classPartObject, path) => {\n let current = classPartObject;\n const parts = path.split(CLASS_PART_SEPARATOR);\n const len = parts.length;\n for (let i = 0; i < len; i++) {\n const part = parts[i];\n let next = current.nextPart.get(part);\n if (!next) {\n next = createClassPartObject();\n current.nextPart.set(part, next);\n }\n current = next;\n }\n return current;\n};\n// Type guard maintains monomorphic check\nconst isThemeGetter = func => 'isThemeGetter' in func && func.isThemeGetter === true;\n\n// LRU cache implementation using plain objects for simplicity\nconst createLruCache = maxCacheSize => {\n if (maxCacheSize < 1) {\n return {\n get: () => undefined,\n set: () => {}\n };\n }\n let cacheSize = 0;\n let cache = Object.create(null);\n let previousCache = Object.create(null);\n const update = (key, value) => {\n cache[key] = value;\n cacheSize++;\n if (cacheSize > maxCacheSize) {\n cacheSize = 0;\n previousCache = cache;\n cache = Object.create(null);\n }\n };\n return {\n get(key) {\n let value = cache[key];\n if (value !== undefined) {\n return value;\n }\n if ((value = previousCache[key]) !== undefined) {\n update(key, value);\n return value;\n }\n },\n set(key, value) {\n if (key in cache) {\n cache[key] = value;\n } else {\n update(key, value);\n }\n }\n };\n};\nconst IMPORTANT_MODIFIER = '!';\nconst MODIFIER_SEPARATOR = ':';\nconst EMPTY_MODIFIERS = [];\n// Pre-allocated result object shape for consistency\nconst createResultObject = (modifiers, hasImportantModifier, baseClassName, maybePostfixModifierPosition, isExternal) => ({\n modifiers,\n hasImportantModifier,\n baseClassName,\n maybePostfixModifierPosition,\n isExternal\n});\nconst createParseClassName = config => {\n const {\n prefix,\n experimentalParseClassName\n } = config;\n /**\n * Parse class name into parts.\n *\n * Inspired by `splitAtTopLevelOnly` used in Tailwind CSS\n * @see https://github.com/tailwindlabs/tailwindcss/blob/v3.2.2/src/util/splitAtTopLevelOnly.js\n */\n let parseClassName = className => {\n // Use simple array with push for better performance\n const modifiers = [];\n let bracketDepth = 0;\n let parenDepth = 0;\n let modifierStart = 0;\n let postfixModifierPosition;\n const len = className.length;\n for (let index = 0; index < len; index++) {\n const currentCharacter = className[index];\n if (bracketDepth === 0 && parenDepth === 0) {\n if (currentCharacter === MODIFIER_SEPARATOR) {\n modifiers.push(className.slice(modifierStart, index));\n modifierStart = index + 1;\n continue;\n }\n if (currentCharacter === '/') {\n postfixModifierPosition = index;\n continue;\n }\n }\n if (currentCharacter === '[') bracketDepth++;else if (currentCharacter === ']') bracketDepth--;else if (currentCharacter === '(') parenDepth++;else if (currentCharacter === ')') parenDepth--;\n }\n const baseClassNameWithImportantModifier = modifiers.length === 0 ? className : className.slice(modifierStart);\n // Inline important modifier check\n let baseClassName = baseClassNameWithImportantModifier;\n let hasImportantModifier = false;\n if (baseClassNameWithImportantModifier.endsWith(IMPORTANT_MODIFIER)) {\n baseClassName = baseClassNameWithImportantModifier.slice(0, -1);\n hasImportantModifier = true;\n } else if (\n /**\n * In Tailwind CSS v3 the important modifier was at the start of the base class name. This is still supported for legacy reasons.\n * @see https://github.com/dcastil/tailwind-merge/issues/513#issuecomment-2614029864\n */\n baseClassNameWithImportantModifier.startsWith(IMPORTANT_MODIFIER)) {\n baseClassName = baseClassNameWithImportantModifier.slice(1);\n hasImportantModifier = true;\n }\n const maybePostfixModifierPosition = postfixModifierPosition && postfixModifierPosition > modifierStart ? postfixModifierPosition - modifierStart : undefined;\n return createResultObject(modifiers, hasImportantModifier, baseClassName, maybePostfixModifierPosition);\n };\n if (prefix) {\n const fullPrefix = prefix + MODIFIER_SEPARATOR;\n const parseClassNameOriginal = parseClassName;\n parseClassName = className => className.startsWith(fullPrefix) ? parseClassNameOriginal(className.slice(fullPrefix.length)) : createResultObject(EMPTY_MODIFIERS, false, className, undefined, true);\n }\n if (experimentalParseClassName) {\n const parseClassNameOriginal = parseClassName;\n parseClassName = className => experimentalParseClassName({\n className,\n parseClassName: parseClassNameOriginal\n });\n }\n return parseClassName;\n};\n\n/**\n * Sorts modifiers according to following schema:\n * - Predefined modifiers are sorted alphabetically\n * - When an arbitrary variant appears, it must be preserved which modifiers are before and after it\n */\nconst createSortModifiers = config => {\n // Pre-compute weights for all known modifiers for O(1) comparison\n const modifierWeights = new Map();\n // Assign weights to sensitive modifiers (highest priority, but preserve order)\n config.orderSensitiveModifiers.forEach((mod, index) => {\n modifierWeights.set(mod, 1000000 + index); // High weights for sensitive mods\n });\n return modifiers => {\n const result = [];\n let currentSegment = [];\n // Process modifiers in one pass\n for (let i = 0; i < modifiers.length; i++) {\n const modifier = modifiers[i];\n // Check if modifier is sensitive (starts with '[' or in orderSensitiveModifiers)\n const isArbitrary = modifier[0] === '[';\n const isOrderSensitive = modifierWeights.has(modifier);\n if (isArbitrary || isOrderSensitive) {\n // Sort and flush current segment alphabetically\n if (currentSegment.length > 0) {\n currentSegment.sort();\n result.push(...currentSegment);\n currentSegment = [];\n }\n result.push(modifier);\n } else {\n // Regular modifier - add to current segment for batch sorting\n currentSegment.push(modifier);\n }\n }\n // Sort and add any remaining segment items\n if (currentSegment.length > 0) {\n currentSegment.sort();\n result.push(...currentSegment);\n }\n return result;\n };\n};\nconst createConfigUtils = config => ({\n cache: createLruCache(config.cacheSize),\n parseClassName: createParseClassName(config),\n sortModifiers: createSortModifiers(config),\n postfixLookupClassGroupIds: createPostfixLookupClassGroupIds(config),\n ...createClassGroupUtils(config)\n});\nconst createPostfixLookupClassGroupIds = config => {\n const lookup = Object.create(null);\n const classGroupIds = config.postfixLookupClassGroups;\n if (classGroupIds) {\n for (let i = 0; i < classGroupIds.length; i++) {\n lookup[classGroupIds[i]] = true;\n }\n }\n return lookup;\n};\nconst SPLIT_CLASSES_REGEX = /\\s+/;\nconst mergeClassList = (classList, configUtils) => {\n const {\n parseClassName,\n getClassGroupId,\n getConflictingClassGroupIds,\n sortModifiers,\n postfixLookupClassGroupIds\n } = configUtils;\n /**\n * Set of classGroupIds in following format:\n * `{importantModifier}{variantModifiers}{classGroupId}`\n * @example 'float'\n * @example 'hover:focus:bg-color'\n * @example 'md:!pr'\n */\n const classGroupsInConflict = [];\n const classNames = classList.trim().split(SPLIT_CLASSES_REGEX);\n let result = '';\n for (let index = classNames.length - 1; index >= 0; index -= 1) {\n const originalClassName = classNames[index];\n const {\n isExternal,\n modifiers,\n hasImportantModifier,\n baseClassName,\n maybePostfixModifierPosition\n } = parseClassName(originalClassName);\n if (isExternal) {\n result = originalClassName + (result.length > 0 ? ' ' + result : result);\n continue;\n }\n let hasPostfixModifier = !!maybePostfixModifierPosition;\n let classGroupId;\n if (hasPostfixModifier) {\n const baseClassNameWithoutPostfix = baseClassName.substring(0, maybePostfixModifierPosition);\n classGroupId = getClassGroupId(baseClassNameWithoutPostfix);\n const classGroupIdWithPostfix = classGroupId && postfixLookupClassGroupIds[classGroupId] ? getClassGroupId(baseClassName) : undefined;\n if (classGroupIdWithPostfix && classGroupIdWithPostfix !== classGroupId) {\n classGroupId = classGroupIdWithPostfix;\n hasPostfixModifier = false;\n }\n } else {\n classGroupId = getClassGroupId(baseClassName);\n }\n if (!classGroupId) {\n if (!hasPostfixModifier) {\n // Not a Tailwind class\n result = originalClassName + (result.length > 0 ? ' ' + result : result);\n continue;\n }\n classGroupId = getClassGroupId(baseClassName);\n if (!classGroupId) {\n // Not a Tailwind class\n result = originalClassName + (result.length > 0 ? ' ' + result : result);\n continue;\n }\n hasPostfixModifier = false;\n }\n // Fast path: skip sorting for empty or single modifier\n const variantModifier = modifiers.length === 0 ? '' : modifiers.length === 1 ? modifiers[0] : sortModifiers(modifiers).join(':');\n const modifierId = hasImportantModifier ? variantModifier + IMPORTANT_MODIFIER : variantModifier;\n const classId = modifierId + classGroupId;\n if (classGroupsInConflict.indexOf(classId) > -1) {\n // Tailwind class omitted due to conflict\n continue;\n }\n classGroupsInConflict.push(classId);\n const conflictGroups = getConflictingClassGroupIds(classGroupId, hasPostfixModifier);\n for (let i = 0; i < conflictGroups.length; ++i) {\n const group = conflictGroups[i];\n classGroupsInConflict.push(modifierId + group);\n }\n // Tailwind class not in conflict\n result = originalClassName + (result.length > 0 ? ' ' + result : result);\n }\n return result;\n};\n\n/**\n * The code in this file is copied from https://github.com/lukeed/clsx and modified to suit the needs of tailwind-merge better.\n *\n * Specifically:\n * - Runtime code from https://github.com/lukeed/clsx/blob/v1.2.1/src/index.js\n * - TypeScript types from https://github.com/lukeed/clsx/blob/v1.2.1/clsx.d.ts\n *\n * Original code has MIT license: Copyright (c) Luke Edwards <luke.edwards05@gmail.com> (lukeed.com)\n */\nconst twJoin = (...classLists) => {\n let index = 0;\n let argument;\n let resolvedValue;\n let string = '';\n while (index < classLists.length) {\n if (argument = classLists[index++]) {\n if (resolvedValue = toValue(argument)) {\n string && (string += ' ');\n string += resolvedValue;\n }\n }\n }\n return string;\n};\nconst toValue = mix => {\n // Fast path for strings\n if (typeof mix === 'string') {\n return mix;\n }\n let resolvedValue;\n let string = '';\n for (let k = 0; k < mix.length; k++) {\n if (mix[k]) {\n if (resolvedValue = toValue(mix[k])) {\n string && (string += ' ');\n string += resolvedValue;\n }\n }\n }\n return string;\n};\nconst createTailwindMerge = (createConfigFirst, ...createConfigRest) => {\n let configUtils;\n let cacheGet;\n let cacheSet;\n let functionToCall;\n const initTailwindMerge = classList => {\n const config = createConfigRest.reduce((previousConfig, createConfigCurrent) => createConfigCurrent(previousConfig), createConfigFirst());\n configUtils = createConfigUtils(config);\n cacheGet = configUtils.cache.get;\n cacheSet = configUtils.cache.set;\n functionToCall = tailwindMerge;\n return tailwindMerge(classList);\n };\n const tailwindMerge = classList => {\n const cachedResult = cacheGet(classList);\n if (cachedResult) {\n return cachedResult;\n }\n const result = mergeClassList(classList, configUtils);\n cacheSet(classList, result);\n return result;\n };\n functionToCall = initTailwindMerge;\n return (...args) => functionToCall(twJoin(...args));\n};\nconst fallbackThemeArr = [];\nconst fromTheme = key => {\n const themeGetter = theme => theme[key] || fallbackThemeArr;\n themeGetter.isThemeGetter = true;\n return themeGetter;\n};\nconst arbitraryValueRegex = /^\\[(?:(\\w[\\w-]*):)?(.+)\\]$/i;\nconst arbitraryVariableRegex = /^\\((?:(\\w[\\w-]*):)?(.+)\\)$/i;\nconst fractionRegex = /^\\d+(?:\\.\\d+)?\\/\\d+(?:\\.\\d+)?$/;\nconst tshirtUnitRegex = /^(\\d+(\\.\\d+)?)?(xs|sm|md|lg|xl)$/;\nconst lengthUnitRegex = /\\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\\b(calc|min|max|clamp)\\(.+\\)|^0$/;\nconst colorFunctionRegex = /^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\\(.+\\)$/;\n// Shadow always begins with x and y offset separated by underscore optionally prepended by inset\nconst shadowRegex = /^(inset_)?-?((\\d+)?\\.?(\\d+)[a-z]+|0)_-?((\\d+)?\\.?(\\d+)[a-z]+|0)/;\nconst imageRegex = /^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\\(.+\\)$/;\nconst isFraction = value => fractionRegex.test(value);\nconst isNumber = value => !!value && !Number.isNaN(Number(value));\nconst isInteger = value => !!value && Number.isInteger(Number(value));\nconst isPercent = value => value.endsWith('%') && isNumber(value.slice(0, -1));\nconst isTshirtSize = value => tshirtUnitRegex.test(value);\nconst isAny = () => true;\nconst isLengthOnly = value =>\n// `colorFunctionRegex` check is necessary because color functions can have percentages in them which which would be incorrectly classified as lengths.\n// For example, `hsl(0 0% 0%)` would be classified as a length without this check.\n// I could also use lookbehind assertion in `lengthUnitRegex` but that isn't supported widely enough.\nlengthUnitRegex.test(value) && !colorFunctionRegex.test(value);\nconst isNever = () => false;\nconst isShadow = value => shadowRegex.test(value);\nconst isImage = value => imageRegex.test(value);\nconst isAnyNonArbitrary = value => !isArbitraryValue(value) && !isArbitraryVariable(value);\nconst isNamedContainerQuery = value => value.startsWith('@container') && (value[10] === '/' && value[11] !== undefined || value[11] === 's' && value[16] !== undefined && value.startsWith('-size/', 10) || value[11] === 'n' && value[18] !== undefined && value.startsWith('-normal/', 10));\nconst isArbitrarySize = value => getIsArbitraryValue(value, isLabelSize, isNever);\nconst isArbitraryValue = value => arbitraryValueRegex.test(value);\nconst isArbitraryLength = value => getIsArbitraryValue(value, isLabelLength, isLengthOnly);\nconst isArbitraryNumber = value => getIsArbitraryValue(value, isLabelNumber, isNumber);\nconst isArbitraryWeight = value => getIsArbitraryValue(value, isLabelWeight, isAny);\nconst isArbitraryFamilyName = value => getIsArbitraryValue(value, isLabelFamilyName, isNever);\nconst isArbitraryPosition = value => getIsArbitraryValue(value, isLabelPosition, isNever);\nconst isArbitraryImage = value => getIsArbitraryValue(value, isLabelImage, isImage);\nconst isArbitraryShadow = value => getIsArbitraryValue(value, isLabelShadow, isShadow);\nconst isArbitraryVariable = value => arbitraryVariableRegex.test(value);\nconst isArbitraryVariableLength = value => getIsArbitraryVariable(value, isLabelLength);\nconst isArbitraryVariableFamilyName = value => getIsArbitraryVariable(value, isLabelFamilyName);\nconst isArbitraryVariablePosition = value => getIsArbitraryVariable(value, isLabelPosition);\nconst isArbitraryVariableSize = value => getIsArbitraryVariable(value, isLabelSize);\nconst isArbitraryVariableImage = value => getIsArbitraryVariable(value, isLabelImage);\nconst isArbitraryVariableShadow = value => getIsArbitraryVariable(value, isLabelShadow, true);\nconst isArbitraryVariableWeight = value => getIsArbitraryVariable(value, isLabelWeight, true);\n// Helpers\nconst getIsArbitraryValue = (value, testLabel, testValue) => {\n const result = arbitraryValueRegex.exec(value);\n if (result) {\n if (result[1]) {\n return testLabel(result[1]);\n }\n return testValue(result[2]);\n }\n return false;\n};\nconst getIsArbitraryVariable = (value, testLabel, shouldMatchNoLabel = false) => {\n const result = arbitraryVariableRegex.exec(value);\n if (result) {\n if (result[1]) {\n return testLabel(result[1]);\n }\n return shouldMatchNoLabel;\n }\n return false;\n};\n// Labels\nconst isLabelPosition = label => label === 'position' || label === 'percentage';\nconst isLabelImage = label => label === 'image' || label === 'url';\nconst isLabelSize = label => label === 'length' || label === 'size' || label === 'bg-size';\nconst isLabelLength = label => label === 'length';\nconst isLabelNumber = label => label === 'number';\nconst isLabelFamilyName = label => label === 'family-name';\nconst isLabelWeight = label => label === 'number' || label === 'weight';\nconst isLabelShadow = label => label === 'shadow';\nconst validators = /*#__PURE__*/Object.defineProperty({\n __proto__: null,\n isAny,\n isAnyNonArbitrary,\n isArbitraryFamilyName,\n isArbitraryImage,\n isArbitraryLength,\n isArbitraryNumber,\n isArbitraryPosition,\n isArbitraryShadow,\n isArbitrarySize,\n isArbitraryValue,\n isArbitraryVariable,\n isArbitraryVariableFamilyName,\n isArbitraryVariableImage,\n isArbitraryVariableLength,\n isArbitraryVariablePosition,\n isArbitraryVariableShadow,\n isArbitraryVariableSize,\n isArbitraryVariableWeight,\n isArbitraryWeight,\n isFraction,\n isInteger,\n isNamedContainerQuery,\n isNumber,\n isPercent,\n isTshirtSize\n}, Symbol.toStringTag, {\n value: 'Module'\n});\nconst getDefaultConfig = () => {\n /**\n * Theme getters for theme variable namespaces\n * @see https://tailwindcss.com/docs/theme#theme-variable-namespaces\n */\n /***/\n const themeColor = fromTheme('color');\n const themeFont = fromTheme('font');\n const themeText = fromTheme('text');\n const themeFontWeight = fromTheme('font-weight');\n const themeTracking = fromTheme('tracking');\n const themeLeading = fromTheme('leading');\n const themeBreakpoint = fromTheme('breakpoint');\n const themeContainer = fromTheme('container');\n const themeSpacing = fromTheme('spacing');\n const themeRadius = fromTheme('radius');\n const themeShadow = fromTheme('shadow');\n const themeInsetShadow = fromTheme('inset-shadow');\n const themeTextShadow = fromTheme('text-shadow');\n const themeDropShadow = fromTheme('drop-shadow');\n const themeBlur = fromTheme('blur');\n const themePerspective = fromTheme('perspective');\n const themeAspect = fromTheme('aspect');\n const themeEase = fromTheme('ease');\n const themeAnimate = fromTheme('animate');\n /**\n * Helpers to avoid repeating the same scales\n *\n * We use functions that create a new array every time they're called instead of static arrays.\n * This ensures that users who modify any scale by mutating the array (e.g. with `array.push(element)`) don't accidentally mutate arrays in other parts of the config.\n */\n /***/\n const scaleBreak = () => ['auto', 'avoid', 'all', 'avoid-page', 'page', 'left', 'right', 'column'];\n const scalePosition = () => ['center', 'top', 'bottom', 'left', 'right', 'top-left',\n // Deprecated since Tailwind CSS v4.1.0, see https://github.com/tailwindlabs/tailwindcss/pull/17378\n 'left-top', 'top-right',\n // Deprecated since Tailwind CSS v4.1.0, see https://github.com/tailwindlabs/tailwindcss/pull/17378\n 'right-top', 'bottom-right',\n // Deprecated since Tailwind CSS v4.1.0, see https://github.com/tailwindlabs/tailwindcss/pull/17378\n 'right-bottom', 'bottom-left',\n // Deprecated since Tailwind CSS v4.1.0, see https://github.com/tailwindlabs/tailwindcss/pull/17378\n 'left-bottom'];\n const scalePositionWithArbitrary = () => [...scalePosition(), isArbitraryVariable, isArbitraryValue];\n const scaleOverflow = () => ['auto', 'hidden', 'clip', 'visible', 'scroll'];\n const scaleOverscroll = () => ['auto', 'contain', 'none'];\n const scaleUnambiguousSpacing = () => [isArbitraryVariable, isArbitraryValue, themeSpacing];\n const scaleInset = () => [isFraction, 'full', 'auto', ...scaleUnambiguousSpacing()];\n const scaleGridTemplateColsRows = () => [isInteger, 'none', 'subgrid', isArbitraryVariable, isArbitraryValue];\n const scaleGridColRowStartAndEnd = () => ['auto', {\n span: ['full', isInteger, isArbitraryVariable, isArbitraryValue]\n }, isInteger, isArbitraryVariable, isArbitraryValue];\n const scaleGridColRowStartOrEnd = () => [isInteger, 'auto', isArbitraryVariable, isArbitraryValue];\n const scaleGridAutoColsRows = () => ['auto', 'min', 'max', 'fr', isArbitraryVariable, isArbitraryValue];\n const scaleAlignPrimaryAxis = () => ['start', 'end', 'center', 'between', 'around', 'evenly', 'stretch', 'baseline', 'center-safe', 'end-safe'];\n const scaleAlignSecondaryAxis = () => ['start', 'end', 'center', 'stretch', 'center-safe', 'end-safe'];\n const scaleMargin = () => ['auto', ...scaleUnambiguousSpacing()];\n const scaleSizing = () => [isFraction, 'auto', 'full', 'dvw', 'dvh', 'lvw', 'lvh', 'svw', 'svh', 'min', 'max', 'fit', ...scaleUnambiguousSpacing()];\n const scaleSizingInline = () => [isFraction, 'screen', 'full', 'dvw', 'lvw', 'svw', 'min', 'max', 'fit', ...scaleUnambiguousSpacing()];\n const scaleSizingBlock = () => [isFraction, 'screen', 'full', 'lh', 'dvh', 'lvh', 'svh', 'min', 'max', 'fit', ...scaleUnambiguousSpacing()];\n const scaleColor = () => [themeColor, isArbitraryVariable, isArbitraryValue];\n const scaleBgPosition = () => [...scalePosition(), isArbitraryVariablePosition, isArbitraryPosition, {\n position: [isArbitraryVariable, isArbitraryValue]\n }];\n const scaleBgRepeat = () => ['no-repeat', {\n repeat: ['', 'x', 'y', 'space', 'round']\n }];\n const scaleBgSize = () => ['auto', 'cover', 'contain', isArbitraryVariableSize, isArbitrarySize, {\n size: [isArbitraryVariable, isArbitraryValue]\n }];\n const scaleGradientStopPosition = () => [isPercent, isArbitraryVariableLength, isArbitraryLength];\n const scaleRadius = () => [\n // Deprecated since Tailwind CSS v4.0.0\n '', 'none', 'full', themeRadius, isArbitraryVariable, isArbitraryValue];\n const scaleBorderWidth = () => ['', isNumber, isArbitraryVariableLength, isArbitraryLength];\n const scaleLineStyle = () => ['solid', 'dashed', 'dotted', 'double'];\n const scaleBlendMode = () => ['normal', 'multiply', 'screen', 'overlay', 'darken', 'lighten', 'color-dodge', 'color-burn', 'hard-light', 'soft-light', 'difference', 'exclusion', 'hue', 'saturation', 'color', 'luminosity'];\n const scaleMaskImagePosition = () => [isNumber, isPercent, isArbitraryVariablePosition, isArbitraryPosition];\n const scaleBlur = () => [\n // Deprecated since Tailwind CSS v4.0.0\n '', 'none', themeBlur, isArbitraryVariable, isArbitraryValue];\n const scaleRotate = () => ['none', isNumber, isArbitraryVariable, isArbitraryValue];\n const scaleScale = () => ['none', isNumber, isArbitraryVariable, isArbitraryValue];\n const scaleSkew = () => [isNumber, isArbitraryVariable, isArbitraryValue];\n const scaleTranslate = () => [isFraction, 'full', ...scaleUnambiguousSpacing()];\n return {\n cacheSize: 500,\n theme: {\n animate: ['spin', 'ping', 'pulse', 'bounce'],\n aspect: ['video'],\n blur: [isTshirtSize],\n breakpoint: [isTshirtSize],\n color: [isAny],\n container: [isTshirtSize],\n 'drop-shadow': [isTshirtSize],\n ease: ['in', 'out', 'in-out'],\n font: [isAnyNonArbitrary],\n 'font-weight': ['thin', 'extralight', 'light', 'normal', 'medium', 'semibold', 'bold', 'extrabold', 'black'],\n 'inset-shadow': [isTshirtSize],\n leading: ['none', 'tight', 'snug', 'normal', 'relaxed', 'loose'],\n perspective: ['dramatic', 'near', 'normal', 'midrange', 'distant', 'none'],\n radius: [isTshirtSize],\n shadow: [isTshirtSize],\n spacing: ['px', isNumber],\n text: [isTshirtSize],\n 'text-shadow': [isTshirtSize],\n tracking: ['tighter', 'tight', 'normal', 'wide', 'wider', 'widest']\n },\n classGroups: {\n // --------------\n // --- Layout ---\n // --------------\n /**\n * Aspect Ratio\n * @see https://tailwindcss.com/docs/aspect-ratio\n */\n aspect: [{\n aspect: ['auto', 'square', isFraction, isArbitraryValue, isArbitraryVariable, themeAspect]\n }],\n /**\n * Container\n * @see https://tailwindcss.com/docs/container\n * @deprecated since Tailwind CSS v4.0.0\n */\n container: ['container'],\n /**\n * Container Type\n * @see https://tailwindcss.com/docs/responsive-design#container-queries\n */\n 'container-type': [{\n '@container': ['', 'normal', 'size', isArbitraryVariable, isArbitraryValue]\n }],\n /**\n * Container Name\n * @see https://tailwindcss.com/docs/responsive-design#named-containers\n */\n 'container-named': [isNamedContainerQuery],\n /**\n * Columns\n * @see https://tailwindcss.com/docs/columns\n */\n columns: [{\n columns: [isNumber, isArbitraryValue, isArbitraryVariable, themeContainer]\n }],\n /**\n * Break After\n * @see https://tailwindcss.com/docs/break-after\n */\n 'break-after': [{\n 'break-after': scaleBreak()\n }],\n /**\n * Break Before\n * @see https://tailwindcss.com/docs/break-before\n */\n 'break-before': [{\n 'break-before': scaleBreak()\n }],\n /**\n * Break Inside\n * @see https://tailwindcss.com/docs/break-inside\n */\n 'break-inside': [{\n 'break-inside': ['auto', 'avoid', 'avoid-page', 'avoid-column']\n }],\n /**\n * Box Decoration Break\n * @see https://tailwindcss.com/docs/box-decoration-break\n */\n 'box-decoration': [{\n 'box-decoration': ['slice', 'clone']\n }],\n /**\n * Box Sizing\n * @see https://tailwindcss.com/docs/box-sizing\n */\n box: [{\n box: ['border', 'content']\n }],\n /**\n * Display\n * @see https://tailwindcss.com/docs/display\n */\n display: ['block', 'inline-block', 'inline', 'flex', 'inline-flex', 'table', 'inline-table', 'table-caption', 'table-cell', 'table-column', 'table-column-group', 'table-footer-group', 'table-header-group', 'table-row-group', 'table-row', 'flow-root', 'grid', 'inline-grid', 'contents', 'list-item', 'hidden'],\n /**\n * Screen Reader Only\n * @see https://tailwindcss.com/docs/display#screen-reader-only\n */\n sr: ['sr-only', 'not-sr-only'],\n /**\n * Floats\n * @see https://tailwindcss.com/docs/float\n */\n float: [{\n float: ['right', 'left', 'none', 'start', 'end']\n }],\n /**\n * Clear\n * @see https://tailwindcss.com/docs/clear\n */\n clear: [{\n clear: ['left', 'right', 'both', 'none', 'start', 'end']\n }],\n /**\n * Isolation\n * @see https://tailwindcss.com/docs/isolation\n */\n isolation: ['isolate', 'isolation-auto'],\n /**\n * Object Fit\n * @see https://tailwindcss.com/docs/object-fit\n */\n 'object-fit': [{\n object: ['contain', 'cover', 'fill', 'none', 'scale-down']\n }],\n /**\n * Object Position\n * @see https://tailwindcss.com/docs/object-position\n */\n 'object-position': [{\n object: scalePositionWithArbitrary()\n }],\n /**\n * Overflow\n * @see https://tailwindcss.com/docs/overflow\n */\n overflow: [{\n overflow: scaleOverflow()\n }],\n /**\n * Overflow X\n * @see https://tailwindcss.com/docs/overflow\n */\n 'overflow-x': [{\n 'overflow-x': scaleOverflow()\n }],\n /**\n * Overflow Y\n * @see https://tailwindcss.com/docs/overflow\n */\n 'overflow-y': [{\n 'overflow-y': scaleOverflow()\n }],\n /**\n * Overscroll Behavior\n * @see https://tailwindcss.com/docs/overscroll-behavior\n */\n overscroll: [{\n overscroll: scaleOverscroll()\n }],\n /**\n * Overscroll Behavior X\n * @see https://tailwindcss.com/docs/overscroll-behavior\n */\n 'overscroll-x': [{\n 'overscroll-x': scaleOverscroll()\n }],\n /**\n * Overscroll Behavior Y\n * @see https://tailwindcss.com/docs/overscroll-behavior\n */\n 'overscroll-y': [{\n 'overscroll-y': scaleOverscroll()\n }],\n /**\n * Position\n * @see https://tailwindcss.com/docs/position\n */\n position: ['static', 'fixed', 'absolute', 'relative', 'sticky'],\n /**\n * Inset\n * @see https://tailwindcss.com/docs/top-right-bottom-left\n */\n inset: [{\n inset: scaleInset()\n }],\n /**\n * Inset Inline\n * @see https://tailwindcss.com/docs/top-right-bottom-left\n */\n 'inset-x': [{\n 'inset-x': scaleInset()\n }],\n /**\n * Inset Block\n * @see https://tailwindcss.com/docs/top-right-bottom-left\n */\n 'inset-y': [{\n 'inset-y': scaleInset()\n }],\n /**\n * Inset Inline Start\n * @see https://tailwindcss.com/docs/top-right-bottom-left\n * @todo class group will be renamed to `inset-s` in next major release\n */\n start: [{\n 'inset-s': scaleInset(),\n /**\n * @deprecated since Tailwind CSS v4.2.0 in favor of `inset-s-*` utilities.\n * @see https://github.com/tailwindlabs/tailwindcss/pull/19613\n */\n start: scaleInset()\n }],\n /**\n * Inset Inline End\n * @see https://tailwindcss.com/docs/top-right-bottom-left\n * @todo class group will be renamed to `inset-e` in next major release\n */\n end: [{\n 'inset-e': scaleInset(),\n /**\n * @deprecated since Tailwind CSS v4.2.0 in favor of `inset-e-*` utilities.\n * @see https://github.com/tailwindlabs/tailwindcss/pull/19613\n */\n end: scaleInset()\n }],\n /**\n * Inset Block Start\n * @see https://tailwindcss.com/docs/top-right-bottom-left\n */\n 'inset-bs': [{\n 'inset-bs': scaleInset()\n }],\n /**\n * Inset Block End\n * @see https://tailwindcss.com/docs/top-right-bottom-left\n */\n 'inset-be': [{\n 'inset-be': scaleInset()\n }],\n /**\n * Top\n * @see https://tailwindcss.com/docs/top-right-bottom-left\n */\n top: [{\n top: scaleInset()\n }],\n /**\n * Right\n * @see https://tailwindcss.com/docs/top-right-bottom-left\n */\n right: [{\n right: scaleInset()\n }],\n /**\n * Bottom\n * @see https://tailwindcss.com/docs/top-right-bottom-left\n */\n bottom: [{\n bottom: scaleInset()\n }],\n /**\n * Left\n * @see https://tailwindcss.com/docs/top-right-bottom-left\n */\n left: [{\n left: scaleInset()\n }],\n /**\n * Visibility\n * @see https://tailwindcss.com/docs/visibility\n */\n visibility: ['visible', 'invisible', 'collapse'],\n /**\n * Z-Index\n * @see https://tailwindcss.com/docs/z-index\n */\n z: [{\n z: [isInteger, 'auto', isArbitraryVariable, isArbitraryValue]\n }],\n // ------------------------\n // --- Flexbox and Grid ---\n // ------------------------\n /**\n * Flex Basis\n * @see https://tailwindcss.com/docs/flex-basis\n */\n basis: [{\n basis: [isFraction, 'full', 'auto', themeContainer, ...scaleUnambiguousSpacing()]\n }],\n /**\n * Flex Direction\n * @see https://tailwindcss.com/docs/flex-direction\n */\n 'flex-direction': [{\n flex: ['row', 'row-reverse', 'col', 'col-reverse']\n }],\n /**\n * Flex Wrap\n * @see https://tailwindcss.com/docs/flex-wrap\n */\n 'flex-wrap': [{\n flex: ['nowrap', 'wrap', 'wrap-reverse']\n }],\n /**\n * Flex\n * @see https://tailwindcss.com/docs/flex\n */\n flex: [{\n flex: [isNumber, isFraction, 'auto', 'initial', 'none', isArbitraryValue]\n }],\n /**\n * Flex Grow\n * @see https://tailwindcss.com/docs/flex-grow\n */\n grow: [{\n grow: ['', isNumber, isArbitraryVariable, isArbitraryValue]\n }],\n /**\n * Flex Shrink\n * @see https://tailwindcss.com/docs/flex-shrink\n */\n shrink: [{\n shrink: ['', isNumber, isArbitraryVariable, isArbitraryValue]\n }],\n /**\n * Order\n * @see https://tailwindcss.com/docs/order\n */\n order: [{\n order: [isInteger, 'first', 'last', 'none', isArbitraryVariable, isArbitraryValue]\n }],\n /**\n * Grid Template Columns\n * @see https://tailwindcss.com/docs/grid-template-columns\n */\n 'grid-cols': [{\n 'grid-cols': scaleGridTemplateColsRows()\n }],\n /**\n * Grid Column Start / End\n * @see https://tailwindcss.com/docs/grid-column\n */\n 'col-start-end': [{\n col: scaleGridColRowStartAndEnd()\n }],\n /**\n * Grid Column Start\n * @see https://tailwindcss.com/docs/grid-column\n */\n 'col-start': [{\n 'col-start': scaleGridColRowStartOrEnd()\n }],\n /**\n * Grid Column End\n * @see https://tailwindcss.com/docs/grid-column\n */\n 'col-end': [{\n 'col-end': scaleGridColRowStartOrEnd()\n }],\n /**\n * Grid Template Rows\n * @see https://tailwindcss.com/docs/grid-template-rows\n */\n 'grid-rows': [{\n 'grid-rows': scaleGridTemplateColsRows()\n }],\n /**\n * Grid Row Start / End\n * @see https://tailwindcss.com/docs/grid-row\n */\n 'row-start-end': [{\n row: scaleGridColRowStartAndEnd()\n }],\n /**\n * Grid Row Start\n * @see https://tailwindcss.com/docs/grid-row\n */\n 'row-start': [{\n 'row-start': scaleGridColRowStartOrEnd()\n }],\n /**\n * Grid Row End\n * @see https://tailwindcss.com/docs/grid-row\n */\n 'row-end': [{\n 'row-end': scaleGridColRowStartOrEnd()\n }],\n /**\n * Grid Auto Flow\n * @see https://tailwindcss.com/docs/grid-auto-flow\n */\n 'grid-flow': [{\n 'grid-flow': ['row', 'col', 'dense', 'row-dense', 'col-dense']\n }],\n /**\n * Grid Auto Columns\n * @see https://tailwindcss.com/docs/grid-auto-columns\n */\n 'auto-cols': [{\n 'auto-cols': scaleGridAutoColsRows()\n }],\n /**\n * Grid Auto Rows\n * @see https://tailwindcss.com/docs/grid-auto-rows\n */\n 'auto-rows': [{\n 'auto-rows': scaleGridAutoColsRows()\n }],\n /**\n * Gap\n * @see https://tailwindcss.com/docs/gap\n */\n gap: [{\n gap: scaleUnambiguousSpacing()\n }],\n /**\n * Gap X\n * @see https://tailwindcss.com/docs/gap\n */\n 'gap-x': [{\n 'gap-x': scaleUnambiguousSpacing()\n }],\n /**\n * Gap Y\n * @see https://tailwindcss.com/docs/gap\n */\n 'gap-y': [{\n 'gap-y': scaleUnambiguousSpacing()\n }],\n /**\n * Justify Content\n * @see https://tailwindcss.com/docs/justify-content\n */\n 'justify-content': [{\n justify: [...scaleAlignPrimaryAxis(), 'normal']\n }],\n /**\n * Justify Items\n * @see https://tailwindcss.com/docs/justify-items\n */\n 'justify-items': [{\n 'justify-items': [...scaleAlignSecondaryAxis(), 'normal']\n }],\n /**\n * Justify Self\n * @see https://tailwindcss.com/docs/justify-self\n */\n 'justify-self': [{\n 'justify-self': ['auto', ...scaleAlignSecondaryAxis()]\n }],\n /**\n * Align Content\n * @see https://tailwindcss.com/docs/align-content\n */\n 'align-content': [{\n content: ['normal', ...scaleAlignPrimaryAxis()]\n }],\n /**\n * Align Items\n * @see https://tailwindcss.com/docs/align-items\n */\n 'align-items': [{\n items: [...scaleAlignSecondaryAxis(), {\n baseline: ['', 'last']\n }]\n }],\n /**\n * Align Self\n * @see https://tailwindcss.com/docs/align-self\n */\n 'align-self': [{\n self: ['auto', ...scaleAlignSecondaryAxis(), {\n baseline: ['', 'last']\n }]\n }],\n /**\n * Place Content\n * @see https://tailwindcss.com/docs/place-content\n */\n 'place-content': [{\n 'place-content': scaleAlignPrimaryAxis()\n }],\n /**\n * Place Items\n * @see https://tailwindcss.com/docs/place-items\n */\n 'place-items': [{\n 'place-items': [...scaleAlignSecondaryAxis(), 'baseline']\n }],\n /**\n * Place Self\n * @see https://tailwindcss.com/docs/place-self\n */\n 'place-self': [{\n 'place-self': ['auto', ...scaleAlignSecondaryAxis()]\n }],\n // Spacing\n /**\n * Padding\n * @see https://tailwindcss.com/docs/padding\n */\n p: [{\n p: scaleUnambiguousSpacing()\n }],\n /**\n * Padding Inline\n * @see https://tailwindcss.com/docs/padding\n */\n px: [{\n px: scaleUnambiguousSpacing()\n }],\n /**\n * Padding Block\n * @see https://tailwindcss.com/docs/padding\n */\n py: [{\n py: scaleUnambiguousSpacing()\n }],\n /**\n * Padding Inline Start\n * @see https://tailwindcss.com/docs/padding\n */\n ps: [{\n ps: scaleUnambiguousSpacing()\n }],\n /**\n * Padding Inline End\n * @see https://tailwindcss.com/docs/padding\n */\n pe: [{\n pe: scaleUnambiguousSpacing()\n }],\n /**\n * Padding Block Start\n * @see https://tailwindcss.com/docs/padding\n */\n pbs: [{\n pbs: scaleUnambiguousSpacing()\n }],\n /**\n * Padding Block End\n * @see https://tailwindcss.com/docs/padding\n */\n pbe: [{\n pbe: scaleUnambiguousSpacing()\n }],\n /**\n * Padding Top\n * @see https://tailwindcss.com/docs/padding\n */\n pt: [{\n pt: scaleUnambiguousSpacing()\n }],\n /**\n * Padding Right\n * @see https://tailwindcss.com/docs/padding\n */\n pr: [{\n pr: scaleUnambiguousSpacing()\n }],\n /**\n * Padding Bottom\n * @see https://tailwindcss.com/docs/padding\n */\n pb: [{\n pb: scaleUnambiguousSpacing()\n }],\n /**\n * Padding Left\n * @see https://tailwindcss.com/docs/padding\n */\n pl: [{\n pl: scaleUnambiguousSpacing()\n }],\n /**\n * Margin\n * @see https://tailwindcss.com/docs/margin\n */\n m: [{\n m: scaleMargin()\n }],\n /**\n * Margin Inline\n * @see https://tailwindcss.com/docs/margin\n */\n mx: [{\n mx: scaleMargin()\n }],\n /**\n * Margin Block\n * @see https://tailwindcss.com/docs/margin\n */\n my: [{\n my: scaleMargin()\n }],\n /**\n * Margin Inline Start\n * @see https://tailwindcss.com/docs/margin\n */\n ms: [{\n ms: scaleMargin()\n }],\n /**\n * Margin Inline End\n * @see https://tailwindcss.com/docs/margin\n */\n me: [{\n me: scaleMargin()\n }],\n /**\n * Margin Block Start\n * @see https://tailwindcss.com/docs/margin\n */\n mbs: [{\n mbs: scaleMargin()\n }],\n /**\n * Margin Block End\n * @see https://tailwindcss.com/docs/margin\n */\n mbe: [{\n mbe: scaleMargin()\n }],\n /**\n * Margin Top\n * @see https://tailwindcss.com/docs/margin\n */\n mt: [{\n mt: scaleMargin()\n }],\n /**\n * Margin Right\n * @see https://tailwindcss.com/docs/margin\n */\n mr: [{\n mr: scaleMargin()\n }],\n /**\n * Margin Bottom\n * @see https://tailwindcss.com/docs/margin\n */\n mb: [{\n mb: scaleMargin()\n }],\n /**\n * Margin Left\n * @see https://tailwindcss.com/docs/margin\n */\n ml: [{\n ml: scaleMargin()\n }],\n /**\n * Space Between X\n * @see https://tailwindcss.com/docs/margin#adding-space-between-children\n */\n 'space-x': [{\n 'space-x': scaleUnambiguousSpacing()\n }],\n /**\n * Space Between X Reverse\n * @see https://tailwindcss.com/docs/margin#adding-space-between-children\n */\n 'space-x-reverse': ['space-x-reverse'],\n /**\n * Space Between Y\n * @see https://tailwindcss.com/docs/margin#adding-space-between-children\n */\n 'space-y': [{\n 'space-y': scaleUnambiguousSpacing()\n }],\n /**\n * Space Between Y Reverse\n * @see https://tailwindcss.com/docs/margin#adding-space-between-children\n */\n 'space-y-reverse': ['space-y-reverse'],\n // --------------\n // --- Sizing ---\n // --------------\n /**\n * Size\n * @see https://tailwindcss.com/docs/width#setting-both-width-and-height\n */\n size: [{\n size: scaleSizing()\n }],\n /**\n * Inline Size\n * @see https://tailwindcss.com/docs/width\n */\n 'inline-size': [{\n inline: ['auto', ...scaleSizingInline()]\n }],\n /**\n * Min-Inline Size\n * @see https://tailwindcss.com/docs/min-width\n */\n 'min-inline-size': [{\n 'min-inline': ['auto', ...scaleSizingInline()]\n }],\n /**\n * Max-Inline Size\n * @see https://tailwindcss.com/docs/max-width\n */\n 'max-inline-size': [{\n 'max-inline': ['none', ...scaleSizingInline()]\n }],\n /**\n * Block Size\n * @see https://tailwindcss.com/docs/height\n */\n 'block-size': [{\n block: ['auto', ...scaleSizingBlock()]\n }],\n /**\n * Min-Block Size\n * @see https://tailwindcss.com/docs/min-height\n */\n 'min-block-size': [{\n 'min-block': ['auto', ...scaleSizingBlock()]\n }],\n /**\n * Max-Block Size\n * @see https://tailwindcss.com/docs/max-height\n */\n 'max-block-size': [{\n 'max-block': ['none', ...scaleSizingBlock()]\n }],\n /**\n * Width\n * @see https://tailwindcss.com/docs/width\n */\n w: [{\n w: [themeContainer, 'screen', ...scaleSizing()]\n }],\n /**\n * Min-Width\n * @see https://tailwindcss.com/docs/min-width\n */\n 'min-w': [{\n 'min-w': [themeContainer, 'screen', /** Deprecated. @see https://github.com/tailwindlabs/tailwindcss.com/issues/2027#issuecomment-2620152757 */\n 'none', ...scaleSizing()]\n }],\n /**\n * Max-Width\n * @see https://tailwindcss.com/docs/max-width\n */\n 'max-w': [{\n 'max-w': [themeContainer, 'screen', 'none', /** Deprecated since Tailwind CSS v4.0.0. @see https://github.com/tailwindlabs/tailwindcss.com/issues/2027#issuecomment-2620152757 */\n 'prose', /** Deprecated since Tailwind CSS v4.0.0. @see https://github.com/tailwindlabs/tailwindcss.com/issues/2027#issuecomment-2620152757 */\n {\n screen: [themeBreakpoint]\n }, ...scaleSizing()]\n }],\n /**\n * Height\n * @see https://tailwindcss.com/docs/height\n */\n h: [{\n h: ['screen', 'lh', ...scaleSizing()]\n }],\n /**\n * Min-Height\n * @see https://tailwindcss.com/docs/min-height\n */\n 'min-h': [{\n 'min-h': ['screen', 'lh', 'none', ...scaleSizing()]\n }],\n /**\n * Max-Height\n * @see https://tailwindcss.com/docs/max-height\n */\n 'max-h': [{\n 'max-h': ['screen', 'lh', ...scaleSizing()]\n }],\n // ------------------\n // --- Typography ---\n // ------------------\n /**\n * Font Size\n * @see https://tailwindcss.com/docs/font-size\n */\n 'font-size': [{\n text: ['base', themeText, isArbitraryVariableLength, isArbitraryLength]\n }],\n /**\n * Font Smoothing\n * @see https://tailwindcss.com/docs/font-smoothing\n */\n 'font-smoothing': ['antialiased', 'subpixel-antialiased'],\n /**\n * Font Style\n * @see https://tailwindcss.com/docs/font-style\n */\n 'font-style': ['italic', 'not-italic'],\n /**\n * Font Weight\n * @see https://tailwindcss.com/docs/font-weight\n */\n 'font-weight': [{\n font: [themeFontWeight, isArbitraryVariableWeight, isArbitraryWeight]\n }],\n /**\n * Font Stretch\n * @see https://tailwindcss.com/docs/font-stretch\n */\n 'font-stretch': [{\n 'font-stretch': ['ultra-condensed', 'extra-condensed', 'condensed', 'semi-condensed', 'normal', 'semi-expanded', 'expanded', 'extra-expanded', 'ultra-expanded', isPercent, isArbitraryValue]\n }],\n /**\n * Font Family\n * @see https://tailwindcss.com/docs/font-family\n */\n 'font-family': [{\n font: [isArbitraryVariableFamilyName, isArbitraryFamilyName, themeFont]\n }],\n /**\n * Font Feature Settings\n * @see https://tailwindcss.com/docs/font-feature-settings\n */\n 'font-features': [{\n 'font-features': [isArbitraryValue]\n }],\n /**\n * Font Variant Numeric\n * @see https://tailwindcss.com/docs/font-variant-numeric\n */\n 'fvn-normal': ['normal-nums'],\n /**\n * Font Variant Numeric\n * @see https://tailwindcss.com/docs/font-variant-numeric\n */\n 'fvn-ordinal': ['ordinal'],\n /**\n * Font Variant Numeric\n * @see https://tailwindcss.com/docs/font-variant-numeric\n */\n 'fvn-slashed-zero': ['slashed-zero'],\n /**\n * Font Variant Numeric\n * @see https://tailwindcss.com/docs/font-variant-numeric\n */\n 'fvn-figure': ['lining-nums', 'oldstyle-nums'],\n /**\n * Font Variant Numeric\n * @see https://tailwindcss.com/docs/font-variant-numeric\n */\n 'fvn-spacing': ['proportional-nums', 'tabular-nums'],\n /**\n * Font Variant Numeric\n * @see https://tailwindcss.com/docs/font-variant-numeric\n */\n 'fvn-fraction': ['diagonal-fractions', 'stacked-fractions'],\n /**\n * Letter Spacing\n * @see https://tailwindcss.com/docs/letter-spacing\n */\n tracking: [{\n tracking: [themeTracking, isArbitraryVariable, isArbitraryValue]\n }],\n /**\n * Line Clamp\n * @see https://tailwindcss.com/docs/line-clamp\n */\n 'line-clamp': [{\n 'line-clamp': [isNumber, 'none', isArbitraryVariable, isArbitraryNumber]\n }],\n /**\n * Line Height\n * @see https://tailwindcss.com/docs/line-height\n */\n leading: [{\n leading: [/** Deprecated since Tailwind CSS v4.0.0. @see https://github.com/tailwindlabs/tailwindcss.com/issues/2027#issuecomment-2620152757 */\n themeLeading, ...scaleUnambiguousSpacing()]\n }],\n /**\n * List Style Image\n * @see https://tailwindcss.com/docs/list-style-image\n */\n 'list-image': [{\n 'list-image': ['none', isArbitraryVariable, isArbitraryValue]\n }],\n /**\n * List Style Position\n * @see https://tailwindcss.com/docs/list-style-position\n */\n 'list-style-position': [{\n list: ['inside', 'outside']\n }],\n /**\n * List Style Type\n * @see https://tailwindcss.com/docs/list-style-type\n */\n 'list-style-type': [{\n list: ['disc', 'decimal', 'none', isArbitraryVariable, isArbitraryValue]\n }],\n /**\n * Text Alignment\n * @see https://tailwindcss.com/docs/text-align\n */\n 'text-alignment': [{\n text: ['left', 'center', 'right', 'justify', 'start', 'end']\n }],\n /**\n * Placeholder Color\n * @deprecated since Tailwind CSS v3.0.0\n * @see https://v3.tailwindcss.com/docs/placeholder-color\n */\n 'placeholder-color': [{\n placeholder: scaleColor()\n }],\n /**\n * Text Color\n * @see https://tailwindcss.com/docs/text-color\n */\n 'text-color': [{\n text: scaleColor()\n }],\n /**\n * Text Decoration\n * @see https://tailwindcss.com/docs/text-decoration\n */\n 'text-decoration': ['underline', 'overline', 'line-through', 'no-underline'],\n /**\n * Text Decoration Style\n * @see https://tailwindcss.com/docs/text-decoration-style\n */\n 'text-decoration-style': [{\n decoration: [...scaleLineStyle(), 'wavy']\n }],\n /**\n * Text Decoration Thickness\n * @see https://tailwindcss.com/docs/text-decoration-thickness\n */\n 'text-decoration-thickness': [{\n decoration: [isNumber, 'from-font', 'auto', isArbitraryVariable, isArbitraryLength]\n }],\n /**\n * Text Decoration Color\n * @see https://tailwindcss.com/docs/text-decoration-color\n */\n 'text-decoration-color': [{\n decoration: scaleColor()\n }],\n /**\n * Text Underline Offset\n * @see https://tailwindcss.com/docs/text-underline-offset\n */\n 'underline-offset': [{\n 'underline-offset': [isNumber, 'auto', isArbitraryVariable, isArbitraryValue]\n }],\n /**\n * Text Transform\n * @see https://tailwindcss.com/docs/text-transform\n */\n 'text-transform': ['uppercase', 'lowercase', 'capitalize', 'normal-case'],\n /**\n * Text Overflow\n * @see https://tailwindcss.com/docs/text-overflow\n */\n 'text-overflow': ['truncate', 'text-ellipsis', 'text-clip'],\n /**\n * Text Wrap\n * @see https://tailwindcss.com/docs/text-wrap\n */\n 'text-wrap': [{\n text: ['wrap', 'nowrap', 'balance', 'pretty']\n }],\n /**\n * Text Indent\n * @see https://tailwindcss.com/docs/text-indent\n */\n indent: [{\n indent: scaleUnambiguousSpacing()\n }],\n /**\n * Tab Size\n * @see https://tailwindcss.com/docs/tab-size\n */\n 'tab-size': [{\n tab: [isInteger, isArbitraryVariable, isArbitraryValue]\n }],\n /**\n * Vertical Alignment\n * @see https://tailwindcss.com/docs/vertical-align\n */\n 'vertical-align': [{\n align: ['baseline', 'top', 'middle', 'bottom', 'text-top', 'text-bottom', 'sub', 'super', isArbitraryVariable, isArbitraryValue]\n }],\n /**\n * Whitespace\n * @see https://tailwindcss.com/docs/whitespace\n */\n whitespace: [{\n whitespace: ['normal', 'nowrap', 'pre', 'pre-line', 'pre-wrap', 'break-spaces']\n }],\n /**\n * Word Break\n * @see https://tailwindcss.com/docs/word-break\n */\n break: [{\n break: ['normal', 'words', 'all', 'keep']\n }],\n /**\n * Overflow Wrap\n * @see https://tailwindcss.com/docs/overflow-wrap\n */\n wrap: [{\n wrap: ['break-word', 'anywhere', 'normal']\n }],\n /**\n * Hyphens\n * @see https://tailwindcss.com/docs/hyphens\n */\n hyphens: [{\n hyphens: ['none', 'manual', 'auto']\n }],\n /**\n * Content\n * @see https://tailwindcss.com/docs/content\n */\n content: [{\n content: ['none', isArbitraryVariable, isArbitraryValue]\n }],\n // -------------------\n // --- Backgrounds ---\n // -------------------\n /**\n * Background Attachment\n * @see https://tailwindcss.com/docs/background-attachment\n */\n 'bg-attachment': [{\n bg: ['fixed', 'local', 'scroll']\n }],\n /**\n * Background Clip\n * @see https://tailwindcss.com/docs/background-clip\n */\n 'bg-clip': [{\n 'bg-clip': ['border', 'padding', 'content', 'text']\n }],\n /**\n * Background Origin\n * @see https://tailwindcss.com/docs/background-origin\n */\n 'bg-origin': [{\n 'bg-origin': ['border', 'padding', 'content']\n }],\n /**\n * Background Position\n * @see https://tailwindcss.com/docs/background-position\n */\n 'bg-position': [{\n bg: scaleBgPosition()\n }],\n /**\n * Background Repeat\n * @see https://tailwindcss.com/docs/background-repeat\n */\n 'bg-repeat': [{\n bg: scaleBgRepeat()\n }],\n /**\n * Background Size\n * @see https://tailwindcss.com/docs/background-size\n */\n 'bg-size': [{\n bg: scaleBgSize()\n }],\n /**\n * Background Image\n * @see https://tailwindcss.com/docs/background-image\n */\n 'bg-image': [{\n bg: ['none', {\n linear: [{\n to: ['t', 'tr', 'r', 'br', 'b', 'bl', 'l', 'tl']\n }, isInteger, isArbitraryVariable, isArbitraryValue],\n radial: ['', isArbitraryVariable, isArbitraryValue],\n conic: [isInteger, isArbitraryVariable, isArbitraryValue]\n }, isArbitraryVariableImage, isArbitraryImage]\n }],\n /**\n * Background Color\n * @see https://tailwindcss.com/docs/background-color\n */\n 'bg-color': [{\n bg: scaleColor()\n }],\n /**\n * Gradient Color Stops From Position\n * @see https://tailwindcss.com/docs/gradient-color-stops\n */\n 'gradient-from-pos': [{\n from: scaleGradientStopPosition()\n }],\n /**\n * Gradient Color Stops Via Position\n * @see https://tailwindcss.com/docs/gradient-color-stops\n */\n 'gradient-via-pos': [{\n via: scaleGradientStopPosition()\n }],\n /**\n * Gradient Color Stops To Position\n * @see https://tailwindcss.com/docs/gradient-color-stops\n */\n 'gradient-to-pos': [{\n to: scaleGradientStopPosition()\n }],\n /**\n * Gradient Color Stops From\n * @see https://tailwindcss.com/docs/gradient-color-stops\n */\n 'gradient-from': [{\n from: scaleColor()\n }],\n /**\n * Gradient Color Stops Via\n * @see https://tailwindcss.com/docs/gradient-color-stops\n */\n 'gradient-via': [{\n via: scaleColor()\n }],\n /**\n * Gradient Color Stops To\n * @see https://tailwindcss.com/docs/gradient-color-stops\n */\n 'gradient-to': [{\n to: scaleColor()\n }],\n // ---------------\n // --- Borders ---\n // ---------------\n /**\n * Border Radius\n * @see https://tailwindcss.com/docs/border-radius\n */\n rounded: [{\n rounded: scaleRadius()\n }],\n /**\n * Border Radius Start\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-s': [{\n 'rounded-s': scaleRadius()\n }],\n /**\n * Border Radius End\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-e': [{\n 'rounded-e': scaleRadius()\n }],\n /**\n * Border Radius Top\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-t': [{\n 'rounded-t': scaleRadius()\n }],\n /**\n * Border Radius Right\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-r': [{\n 'rounded-r': scaleRadius()\n }],\n /**\n * Border Radius Bottom\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-b': [{\n 'rounded-b': scaleRadius()\n }],\n /**\n * Border Radius Left\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-l': [{\n 'rounded-l': scaleRadius()\n }],\n /**\n * Border Radius Start Start\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-ss': [{\n 'rounded-ss': scaleRadius()\n }],\n /**\n * Border Radius Start End\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-se': [{\n 'rounded-se': scaleRadius()\n }],\n /**\n * Border Radius End End\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-ee': [{\n 'rounded-ee': scaleRadius()\n }],\n /**\n * Border Radius End Start\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-es': [{\n 'rounded-es': scaleRadius()\n }],\n /**\n * Border Radius Top Left\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-tl': [{\n 'rounded-tl': scaleRadius()\n }],\n /**\n * Border Radius Top Right\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-tr': [{\n 'rounded-tr': scaleRadius()\n }],\n /**\n * Border Radius Bottom Right\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-br': [{\n 'rounded-br': scaleRadius()\n }],\n /**\n * Border Radius Bottom Left\n * @see https://tailwindcss.com/docs/border-radius\n */\n 'rounded-bl': [{\n 'rounded-bl': scaleRadius()\n }],\n /**\n * Border Width\n * @see https://tailwindcss.com/docs/border-width\n */\n 'border-w': [{\n border: scaleBorderWidth()\n }],\n /**\n * Border Width Inline\n * @see https://tailwindcss.com/docs/border-width\n */\n 'border-w-x': [{\n 'border-x': scaleBorderWidth()\n }],\n /**\n * Border Width Block\n * @see https://tailwindcss.com/docs/border-width\n */\n 'border-w-y': [{\n 'border-y': scaleBorderWidth()\n }],\n /**\n * Border Width Inline Start\n * @see https://tailwindcss.com/docs/border-width\n */\n 'border-w-s': [{\n 'border-s': scaleBorderWidth()\n }],\n /**\n * Border Width Inline End\n * @see https://tailwindcss.com/docs/border-width\n */\n 'border-w-e': [{\n 'border-e': scaleBorderWidth()\n }],\n /**\n * Border Width Block Start\n * @see https://tailwindcss.com/docs/border-width\n */\n 'border-w-bs': [{\n 'border-bs': scaleBorderWidth()\n }],\n /**\n * Border Width Block End\n * @see https://tailwindcss.com/docs/border-width\n */\n 'border-w-be': [{\n 'border-be': scaleBorderWidth()\n }],\n /**\n * Border Width Top\n * @see https://tailwindcss.com/docs/border-width\n */\n 'border-w-t': [{\n 'border-t': scaleBorderWidth()\n }],\n /**\n * Border Width Right\n * @see https://tailwindcss.com/docs/border-width\n */\n 'border-w-r': [{\n 'border-r': scaleBorderWidth()\n }],\n /**\n * Border Width Bottom\n * @see https://tailwindcss.com/docs/border-width\n */\n 'border-w-b': [{\n 'border-b': scaleBorderWidth()\n }],\n /**\n * Border Width Left\n * @see https://tailwindcss.com/docs/border-width\n */\n 'border-w-l': [{\n 'border-l': scaleBorderWidth()\n }],\n /**\n * Divide Width X\n * @see https://tailwindcss.com/docs/border-width#between-children\n */\n 'divide-x': [{\n 'divide-x': scaleBorderWidth()\n }],\n /**\n * Divide Width X Reverse\n * @see https://tailwindcss.com/docs/border-width#between-children\n */\n 'divide-x-reverse': ['divide-x-reverse'],\n /**\n * Divide Width Y\n * @see https://tailwindcss.com/docs/border-width#between-children\n */\n 'divide-y': [{\n 'divide-y': scaleBorderWidth()\n }],\n /**\n * Divide Width Y Reverse\n * @see https://tailwindcss.com/docs/border-width#between-children\n */\n 'divide-y-reverse': ['divide-y-reverse'],\n /**\n * Border Style\n * @see https://tailwindcss.com/docs/border-style\n */\n 'border-style': [{\n border: [...scaleLineStyle(), 'hidden', 'none']\n }],\n /**\n * Divide Style\n * @see https://tailwindcss.com/docs/border-style#setting-the-divider-style\n */\n 'divide-style': [{\n divide: [...scaleLineStyle(), 'hidden', 'none']\n }],\n /**\n * Border Color\n * @see https://tailwindcss.com/docs/border-color\n */\n 'border-color': [{\n border: scaleColor()\n }],\n /**\n * Border Color Inline\n * @see https://tailwindcss.com/docs/border-color\n */\n 'border-color-x': [{\n 'border-x': scaleColor()\n }],\n /**\n * Border Color Block\n * @see https://tailwindcss.com/docs/border-color\n */\n 'border-color-y': [{\n 'border-y': scaleColor()\n }],\n /**\n * Border Color Inline Start\n * @see https://tailwindcss.com/docs/border-color\n */\n 'border-color-s': [{\n 'border-s': scaleColor()\n }],\n /**\n * Border Color Inline End\n * @see https://tailwindcss.com/docs/border-color\n */\n 'border-color-e': [{\n 'border-e': scaleColor()\n }],\n /**\n * Border Color Block Start\n * @see https://tailwindcss.com/docs/border-color\n */\n 'border-color-bs': [{\n 'border-bs': scaleColor()\n }],\n /**\n * Border Color Block End\n * @see https://tailwindcss.com/docs/border-color\n */\n 'border-color-be': [{\n 'border-be': scaleColor()\n }],\n /**\n * Border Color Top\n * @see https://tailwindcss.com/docs/border-color\n */\n 'border-color-t': [{\n 'border-t': scaleColor()\n }],\n /**\n * Border Color Right\n * @see https://tailwindcss.com/docs/border-color\n */\n 'border-color-r': [{\n 'border-r': scaleColor()\n }],\n /**\n * Border Color Bottom\n * @see https://tailwindcss.com/docs/border-color\n */\n 'border-color-b': [{\n 'border-b': scaleColor()\n }],\n /**\n * Border Color Left\n * @see https://tailwindcss.com/docs/border-color\n */\n 'border-color-l': [{\n 'border-l': scaleColor()\n }],\n /**\n * Divide Color\n * @see https://tailwindcss.com/docs/divide-color\n */\n 'divide-color': [{\n divide: scaleColor()\n }],\n /**\n * Outline Style\n * @see https://tailwindcss.com/docs/outline-style\n */\n 'outline-style': [{\n outline: [...scaleLineStyle(), 'none', 'hidden']\n }],\n /**\n * Outline Offset\n * @see https://tailwindcss.com/docs/outline-offset\n */\n 'outline-offset': [{\n 'outline-offset': [isNumber, isArbitraryVariable, isArbitraryValue]\n }],\n /**\n * Outline Width\n * @see https://tailwindcss.com/docs/outline-width\n */\n 'outline-w': [{\n outline: ['', isNumber, isArbitraryVariableLength, isArbitraryLength]\n }],\n /**\n * Outline Color\n * @see https://tailwindcss.com/docs/outline-color\n */\n 'outline-color': [{\n outline: scaleColor()\n }],\n // ---------------\n // --- Effects ---\n // ---------------\n /**\n * Box Shadow\n * @see https://tailwindcss.com/docs/box-shadow\n */\n shadow: [{\n shadow: [\n // Deprecated since Tailwind CSS v4.0.0\n '', 'none', themeShadow, isArbitraryVariableShadow, isArbitraryShadow]\n }],\n /**\n * Box Shadow Color\n * @see https://tailwindcss.com/docs/box-shadow#setting-the-shadow-color\n */\n 'shadow-color': [{\n shadow: scaleColor()\n }],\n /**\n * Inset Box Shadow\n * @see https://tailwindcss.com/docs/box-shadow#adding-an-inset-shadow\n */\n 'inset-shadow': [{\n 'inset-shadow': ['none', themeInsetShadow, isArbitraryVariableShadow, isArbitraryShadow]\n }],\n /**\n * Inset Box Shadow Color\n * @see https://tailwindcss.com/docs/box-shadow#setting-the-inset-shadow-color\n */\n 'inset-shadow-color': [{\n 'inset-shadow': scaleColor()\n }],\n /**\n * Ring Width\n * @see https://tailwindcss.com/docs/box-shadow#adding-a-ring\n */\n 'ring-w': [{\n ring: scaleBorderWidth()\n }],\n /**\n * Ring Width Inset\n * @see https://v3.tailwindcss.com/docs/ring-width#inset-rings\n * @deprecated since Tailwind CSS v4.0.0\n * @see https://github.com/tailwindlabs/tailwindcss/blob/v4.0.0/packages/tailwindcss/src/utilities.ts#L4158\n */\n 'ring-w-inset': ['ring-inset'],\n /**\n * Ring Color\n * @see https://tailwindcss.com/docs/box-shadow#setting-the-ring-color\n */\n 'ring-color': [{\n ring: scaleColor()\n }],\n /**\n * Ring Offset Width\n * @see https://v3.tailwindcss.com/docs/ring-offset-width\n * @deprecated since Tailwind CSS v4.0.0\n * @see https://github.com/tailwindlabs/tailwindcss/blob/v4.0.0/packages/tailwindcss/src/utilities.ts#L4158\n */\n 'ring-offset-w': [{\n 'ring-offset': [isNumber, isArbitraryLength]\n }],\n /**\n * Ring Offset Color\n * @see https://v3.tailwindcss.com/docs/ring-offset-color\n * @deprecated since Tailwind CSS v4.0.0\n * @see https://github.com/tailwindlabs/tailwindcss/blob/v4.0.0/packages/tailwindcss/src/utilities.ts#L4158\n */\n 'ring-offset-color': [{\n 'ring-offset': scaleColor()\n }],\n /**\n * Inset Ring Width\n * @see https://tailwindcss.com/docs/box-shadow#adding-an-inset-ring\n */\n 'inset-ring-w': [{\n 'inset-ring': scaleBorderWidth()\n }],\n /**\n * Inset Ring Color\n * @see https://tailwindcss.com/docs/box-shadow#setting-the-inset-ring-color\n */\n 'inset-ring-color': [{\n 'inset-ring': scaleColor()\n }],\n /**\n * Text Shadow\n * @see https://tailwindcss.com/docs/text-shadow\n */\n 'text-shadow': [{\n 'text-shadow': ['none', themeTextShadow, isArbitraryVariableShadow, isArbitraryShadow]\n }],\n /**\n * Text Shadow Color\n * @see https://tailwindcss.com/docs/text-shadow#setting-the-shadow-color\n */\n 'text-shadow-color': [{\n 'text-shadow': scaleColor()\n }],\n /**\n * Opacity\n * @see https://tailwindcss.com/docs/opacity\n */\n opacity: [{\n opacity: [isNumber, isArbitraryVariable, isArbitraryValue]\n }],\n /**\n * Mix Blend Mode\n * @see https://tailwindcss.com/docs/mix-blend-mode\n */\n 'mix-blend': [{\n 'mix-blend': [...scaleBlendMode(), 'plus-darker', 'plus-lighter']\n }],\n /**\n * Background Blend Mode\n * @see https://tailwindcss.com/docs/background-blend-mode\n */\n 'bg-blend': [{\n 'bg-blend': scaleBlendMode()\n }],\n /**\n * Mask Clip\n * @see https://tailwindcss.com/docs/mask-clip\n */\n 'mask-clip': [{\n 'mask-clip': ['border', 'padding', 'content', 'fill', 'stroke', 'view']\n }, 'mask-no-clip'],\n /**\n * Mask Composite\n * @see https://tailwindcss.com/docs/mask-composite\n */\n 'mask-composite': [{\n mask: ['add', 'subtract', 'intersect', 'exclude']\n }],\n /**\n * Mask Image\n * @see https://tailwindcss.com/docs/mask-image\n */\n 'mask-image-linear-pos': [{\n 'mask-linear': [isNumber]\n }],\n 'mask-image-linear-from-pos': [{\n 'mask-linear-from': scaleMaskImagePosition()\n }],\n 'mask-image-linear-to-pos': [{\n 'mask-linear-to': scaleMaskImagePosition()\n }],\n 'mask-image-linear-from-color': [{\n 'mask-linear-from': scaleColor()\n }],\n 'mask-image-linear-to-color': [{\n 'mask-linear-to': scaleColor()\n }],\n 'mask-image-t-from-pos': [{\n 'mask-t-from': scaleMaskImagePosition()\n }],\n 'mask-image-t-to-pos': [{\n 'mask-t-to': scaleMaskImagePosition()\n }],\n 'mask-image-t-from-color': [{\n 'mask-t-from': scaleColor()\n }],\n 'mask-image-t-to-color': [{\n 'mask-t-to': scaleColor()\n }],\n 'mask-image-r-from-pos': [{\n 'mask-r-from': scaleMaskImagePosition()\n }],\n 'mask-image-r-to-pos': [{\n 'mask-r-to': scaleMaskImagePosition()\n }],\n 'mask-image-r-from-color': [{\n 'mask-r-from': scaleColor()\n }],\n 'mask-image-r-to-color': [{\n 'mask-r-to': scaleColor()\n }],\n 'mask-image-b-from-pos': [{\n 'mask-b-from': scaleMaskImagePosition()\n }],\n 'mask-image-b-to-pos': [{\n 'mask-b-to': scaleMaskImagePosition()\n }],\n 'mask-image-b-from-color': [{\n 'mask-b-from': scaleColor()\n }],\n 'mask-image-b-to-color': [{\n 'mask-b-to': scaleColor()\n }],\n 'mask-image-l-from-pos': [{\n 'mask-l-from': scaleMaskImagePosition()\n }],\n 'mask-image-l-to-pos': [{\n 'mask-l-to': scaleMaskImagePosition()\n }],\n 'mask-image-l-from-color': [{\n 'mask-l-from': scaleColor()\n }],\n 'mask-image-l-to-color': [{\n 'mask-l-to': scaleColor()\n }],\n 'mask-image-x-from-pos': [{\n 'mask-x-from': scaleMaskImagePosition()\n }],\n 'mask-image-x-to-pos': [{\n 'mask-x-to': scaleMaskImagePosition()\n }],\n 'mask-image-x-from-color': [{\n 'mask-x-from': scaleColor()\n }],\n 'mask-image-x-to-color': [{\n 'mask-x-to': scaleColor()\n }],\n 'mask-image-y-from-pos': [{\n 'mask-y-from': scaleMaskImagePosition()\n }],\n 'mask-image-y-to-pos': [{\n 'mask-y-to': scaleMaskImagePosition()\n }],\n 'mask-image-y-from-color': [{\n 'mask-y-from': scaleColor()\n }],\n 'mask-image-y-to-color': [{\n 'mask-y-to': scaleColor()\n }],\n 'mask-image-radial': [{\n 'mask-radial': [isArbitraryVariable, isArbitraryValue]\n }],\n 'mask-image-radial-from-pos': [{\n 'mask-radial-from': scaleMaskImagePosition()\n }],\n 'mask-image-radial-to-pos': [{\n 'mask-radial-to': scaleMaskImagePosition()\n }],\n 'mask-image-radial-from-color': [{\n 'mask-radial-from': scaleColor()\n }],\n 'mask-image-radial-to-color': [{\n 'mask-radial-to': scaleColor()\n }],\n 'mask-image-radial-shape': [{\n 'mask-radial': ['circle', 'ellipse']\n }],\n 'mask-image-radial-size': [{\n 'mask-radial': [{\n closest: ['side', 'corner'],\n farthest: ['side', 'corner']\n }]\n }],\n 'mask-image-radial-pos': [{\n 'mask-radial-at': scalePosition()\n }],\n 'mask-image-conic-pos': [{\n 'mask-conic': [isNumber]\n }],\n 'mask-image-conic-from-pos': [{\n 'mask-conic-from': scaleMaskImagePosition()\n }],\n 'mask-image-conic-to-pos': [{\n 'mask-conic-to': scaleMaskImagePosition()\n }],\n 'mask-image-conic-from-color': [{\n 'mask-conic-from': scaleColor()\n }],\n 'mask-image-conic-to-color': [{\n 'mask-conic-to': scaleColor()\n }],\n /**\n * Mask Mode\n * @see https://tailwindcss.com/docs/mask-mode\n */\n 'mask-mode': [{\n mask: ['alpha', 'luminance', 'match']\n }],\n /**\n * Mask Origin\n * @see https://tailwindcss.com/docs/mask-origin\n */\n 'mask-origin': [{\n 'mask-origin': ['border', 'padding', 'content', 'fill', 'stroke', 'view']\n }],\n /**\n * Mask Position\n * @see https://tailwindcss.com/docs/mask-position\n */\n 'mask-position': [{\n mask: scaleBgPosition()\n }],\n /**\n * Mask Repeat\n * @see https://tailwindcss.com/docs/mask-repeat\n */\n 'mask-repeat': [{\n mask: scaleBgRepeat()\n }],\n /**\n * Mask Size\n * @see https://tailwindcss.com/docs/mask-size\n */\n 'mask-size': [{\n mask: scaleBgSize()\n }],\n /**\n * Mask Type\n * @see https://tailwindcss.com/docs/mask-type\n */\n 'mask-type': [{\n 'mask-type': ['alpha', 'luminance']\n }],\n /**\n * Mask Image\n * @see https://tailwindcss.com/docs/mask-image\n */\n 'mask-image': [{\n mask: ['none', isArbitraryVariable, isArbitraryValue]\n }],\n // ---------------\n // --- Filters ---\n // ---------------\n /**\n * Filter\n * @see https://tailwindcss.com/docs/filter\n */\n filter: [{\n filter: [\n // Deprecated since Tailwind CSS v3.0.0\n '', 'none', isArbitraryVariable, isArbitraryValue]\n }],\n /**\n * Blur\n * @see https://tailwindcss.com/docs/blur\n */\n blur: [{\n blur: scaleBlur()\n }],\n /**\n * Brightness\n * @see https://tailwindcss.com/docs/brightness\n */\n brightness: [{\n brightness: [isNumber, isArbitraryVariable, isArbitraryValue]\n }],\n /**\n * Contrast\n * @see https://tailwindcss.com/docs/contrast\n */\n contrast: [{\n contrast: [isNumber, isArbitraryVariable, isArbitraryValue]\n }],\n /**\n * Drop Shadow\n * @see https://tailwindcss.com/docs/drop-shadow\n */\n 'drop-shadow': [{\n 'drop-shadow': [\n // Deprecated since Tailwind CSS v4.0.0\n '', 'none', themeDropShadow, isArbitraryVariableShadow, isArbitraryShadow]\n }],\n /**\n * Drop Shadow Color\n * @see https://tailwindcss.com/docs/filter-drop-shadow#setting-the-shadow-color\n */\n 'drop-shadow-color': [{\n 'drop-shadow': scaleColor()\n }],\n /**\n * Grayscale\n * @see https://tailwindcss.com/docs/grayscale\n */\n grayscale: [{\n grayscale: ['', isNumber, isArbitraryVariable, isArbitraryValue]\n }],\n /**\n * Hue Rotate\n * @see https://tailwindcss.com/docs/hue-rotate\n */\n 'hue-rotate': [{\n 'hue-rotate': [isNumber, isArbitraryVariable, isArbitraryValue]\n }],\n /**\n * Invert\n * @see https://tailwindcss.com/docs/invert\n */\n invert: [{\n invert: ['', isNumber, isArbitraryVariable, isArbitraryValue]\n }],\n /**\n * Saturate\n * @see https://tailwindcss.com/docs/saturate\n */\n saturate: [{\n saturate: [isNumber, isArbitraryVariable, isArbitraryValue]\n }],\n /**\n * Sepia\n * @see https://tailwindcss.com/docs/sepia\n */\n sepia: [{\n sepia: ['', isNumber, isArbitraryVariable, isArbitraryValue]\n }],\n /**\n * Backdrop Filter\n * @see https://tailwindcss.com/docs/backdrop-filter\n */\n 'backdrop-filter': [{\n 'backdrop-filter': [\n // Deprecated since Tailwind CSS v3.0.0\n '', 'none', isArbitraryVariable, isArbitraryValue]\n }],\n /**\n * Backdrop Blur\n * @see https://tailwindcss.com/docs/backdrop-blur\n */\n 'backdrop-blur': [{\n 'backdrop-blur': scaleBlur()\n }],\n /**\n * Backdrop Brightness\n * @see https://tailwindcss.com/docs/backdrop-brightness\n */\n 'backdrop-brightness': [{\n 'backdrop-brightness': [isNumber, isArbitraryVariable, isArbitraryValue]\n }],\n /**\n * Backdrop Contrast\n * @see https://tailwindcss.com/docs/backdrop-contrast\n */\n 'backdrop-contrast': [{\n 'backdrop-contrast': [isNumber, isArbitraryVariable, isArbitraryValue]\n }],\n /**\n * Backdrop Grayscale\n * @see https://tailwindcss.com/docs/backdrop-grayscale\n */\n 'backdrop-grayscale': [{\n 'backdrop-grayscale': ['', isNumber, isArbitraryVariable, isArbitraryValue]\n }],\n /**\n * Backdrop Hue Rotate\n * @see https://tailwindcss.com/docs/backdrop-hue-rotate\n */\n 'backdrop-hue-rotate': [{\n 'backdrop-hue-rotate': [isNumber, isArbitraryVariable, isArbitraryValue]\n }],\n /**\n * Backdrop Invert\n * @see https://tailwindcss.com/docs/backdrop-invert\n */\n 'backdrop-invert': [{\n 'backdrop-invert': ['', isNumber, isArbitraryVariable, isArbitraryValue]\n }],\n /**\n * Backdrop Opacity\n * @see https://tailwindcss.com/docs/backdrop-opacity\n */\n 'backdrop-opacity': [{\n 'backdrop-opacity': [isNumber, isArbitraryVariable, isArbitraryValue]\n }],\n /**\n * Backdrop Saturate\n * @see https://tailwindcss.com/docs/backdrop-saturate\n */\n 'backdrop-saturate': [{\n 'backdrop-saturate': [isNumber, isArbitraryVariable, isArbitraryValue]\n }],\n /**\n * Backdrop Sepia\n * @see https://tailwindcss.com/docs/backdrop-sepia\n */\n 'backdrop-sepia': [{\n 'backdrop-sepia': ['', isNumber, isArbitraryVariable, isArbitraryValue]\n }],\n // --------------\n // --- Tables ---\n // --------------\n /**\n * Border Collapse\n * @see https://tailwindcss.com/docs/border-collapse\n */\n 'border-collapse': [{\n border: ['collapse', 'separate']\n }],\n /**\n * Border Spacing\n * @see https://tailwindcss.com/docs/border-spacing\n */\n 'border-spacing': [{\n 'border-spacing': scaleUnambiguousSpacing()\n }],\n /**\n * Border Spacing X\n * @see https://tailwindcss.com/docs/border-spacing\n */\n 'border-spacing-x': [{\n 'border-spacing-x': scaleUnambiguousSpacing()\n }],\n /**\n * Border Spacing Y\n * @see https://tailwindcss.com/docs/border-spacing\n */\n 'border-spacing-y': [{\n 'border-spacing-y': scaleUnambiguousSpacing()\n }],\n /**\n * Table Layout\n * @see https://tailwindcss.com/docs/table-layout\n */\n 'table-layout': [{\n table: ['auto', 'fixed']\n }],\n /**\n * Caption Side\n * @see https://tailwindcss.com/docs/caption-side\n */\n caption: [{\n caption: ['top', 'bottom']\n }],\n // ---------------------------------\n // --- Transitions and Animation ---\n // ---------------------------------\n /**\n * Transition Property\n * @see https://tailwindcss.com/docs/transition-property\n */\n transition: [{\n transition: ['', 'all', 'colors', 'opacity', 'shadow', 'transform', 'none', isArbitraryVariable, isArbitraryValue]\n }],\n /**\n * Transition Behavior\n * @see https://tailwindcss.com/docs/transition-behavior\n */\n 'transition-behavior': [{\n transition: ['normal', 'discrete']\n }],\n /**\n * Transition Duration\n * @see https://tailwindcss.com/docs/transition-duration\n */\n duration: [{\n duration: [isNumber, 'initial', isArbitraryVariable, isArbitraryValue]\n }],\n /**\n * Transition Timing Function\n * @see https://tailwindcss.com/docs/transition-timing-function\n */\n ease: [{\n ease: ['linear', 'initial', themeEase, isArbitraryVariable, isArbitraryValue]\n }],\n /**\n * Transition Delay\n * @see https://tailwindcss.com/docs/transition-delay\n */\n delay: [{\n delay: [isNumber, isArbitraryVariable, isArbitraryValue]\n }],\n /**\n * Animation\n * @see https://tailwindcss.com/docs/animation\n */\n animate: [{\n animate: ['none', themeAnimate, isArbitraryVariable, isArbitraryValue]\n }],\n // ------------------\n // --- Transforms ---\n // ------------------\n /**\n * Backface Visibility\n * @see https://tailwindcss.com/docs/backface-visibility\n */\n backface: [{\n backface: ['hidden', 'visible']\n }],\n /**\n * Perspective\n * @see https://tailwindcss.com/docs/perspective\n */\n perspective: [{\n perspective: [themePerspective, isArbitraryVariable, isArbitraryValue]\n }],\n /**\n * Perspective Origin\n * @see https://tailwindcss.com/docs/perspective-origin\n */\n 'perspective-origin': [{\n 'perspective-origin': scalePositionWithArbitrary()\n }],\n /**\n * Rotate\n * @see https://tailwindcss.com/docs/rotate\n */\n rotate: [{\n rotate: scaleRotate()\n }],\n /**\n * Rotate X\n * @see https://tailwindcss.com/docs/rotate\n */\n 'rotate-x': [{\n 'rotate-x': scaleRotate()\n }],\n /**\n * Rotate Y\n * @see https://tailwindcss.com/docs/rotate\n */\n 'rotate-y': [{\n 'rotate-y': scaleRotate()\n }],\n /**\n * Rotate Z\n * @see https://tailwindcss.com/docs/rotate\n */\n 'rotate-z': [{\n 'rotate-z': scaleRotate()\n }],\n /**\n * Scale\n * @see https://tailwindcss.com/docs/scale\n */\n scale: [{\n scale: scaleScale()\n }],\n /**\n * Scale X\n * @see https://tailwindcss.com/docs/scale\n */\n 'scale-x': [{\n 'scale-x': scaleScale()\n }],\n /**\n * Scale Y\n * @see https://tailwindcss.com/docs/scale\n */\n 'scale-y': [{\n 'scale-y': scaleScale()\n }],\n /**\n * Scale Z\n * @see https://tailwindcss.com/docs/scale\n */\n 'scale-z': [{\n 'scale-z': scaleScale()\n }],\n /**\n * Scale 3D\n * @see https://tailwindcss.com/docs/scale\n */\n 'scale-3d': ['scale-3d'],\n /**\n * Skew\n * @see https://tailwindcss.com/docs/skew\n */\n skew: [{\n skew: scaleSkew()\n }],\n /**\n * Skew X\n * @see https://tailwindcss.com/docs/skew\n */\n 'skew-x': [{\n 'skew-x': scaleSkew()\n }],\n /**\n * Skew Y\n * @see https://tailwindcss.com/docs/skew\n */\n 'skew-y': [{\n 'skew-y': scaleSkew()\n }],\n /**\n * Transform\n * @see https://tailwindcss.com/docs/transform\n */\n transform: [{\n transform: [isArbitraryVariable, isArbitraryValue, '', 'none', 'gpu', 'cpu']\n }],\n /**\n * Transform Origin\n * @see https://tailwindcss.com/docs/transform-origin\n */\n 'transform-origin': [{\n origin: scalePositionWithArbitrary()\n }],\n /**\n * Transform Style\n * @see https://tailwindcss.com/docs/transform-style\n */\n 'transform-style': [{\n transform: ['3d', 'flat']\n }],\n /**\n * Translate\n * @see https://tailwindcss.com/docs/translate\n */\n translate: [{\n translate: scaleTranslate()\n }],\n /**\n * Translate X\n * @see https://tailwindcss.com/docs/translate\n */\n 'translate-x': [{\n 'translate-x': scaleTranslate()\n }],\n /**\n * Translate Y\n * @see https://tailwindcss.com/docs/translate\n */\n 'translate-y': [{\n 'translate-y': scaleTranslate()\n }],\n /**\n * Translate Z\n * @see https://tailwindcss.com/docs/translate\n */\n 'translate-z': [{\n 'translate-z': scaleTranslate()\n }],\n /**\n * Translate None\n * @see https://tailwindcss.com/docs/translate\n */\n 'translate-none': ['translate-none'],\n /**\n * Zoom\n * @see https://tailwindcss.com/docs/zoom\n */\n zoom: [{\n zoom: [isInteger, isArbitraryVariable, isArbitraryValue]\n }],\n // ---------------------\n // --- Interactivity ---\n // ---------------------\n /**\n * Accent Color\n * @see https://tailwindcss.com/docs/accent-color\n */\n accent: [{\n accent: scaleColor()\n }],\n /**\n * Appearance\n * @see https://tailwindcss.com/docs/appearance\n */\n appearance: [{\n appearance: ['none', 'auto']\n }],\n /**\n * Caret Color\n * @see https://tailwindcss.com/docs/just-in-time-mode#caret-color-utilities\n */\n 'caret-color': [{\n caret: scaleColor()\n }],\n /**\n * Color Scheme\n * @see https://tailwindcss.com/docs/color-scheme\n */\n 'color-scheme': [{\n scheme: ['normal', 'dark', 'light', 'light-dark', 'only-dark', 'only-light']\n }],\n /**\n * Cursor\n * @see https://tailwindcss.com/docs/cursor\n */\n cursor: [{\n cursor: ['auto', 'default', 'pointer', 'wait', 'text', 'move', 'help', 'not-allowed', 'none', 'context-menu', 'progress', 'cell', 'crosshair', 'vertical-text', 'alias', 'copy', 'no-drop', 'grab', 'grabbing', 'all-scroll', 'col-resize', 'row-resize', 'n-resize', 'e-resize', 's-resize', 'w-resize', 'ne-resize', 'nw-resize', 'se-resize', 'sw-resize', 'ew-resize', 'ns-resize', 'nesw-resize', 'nwse-resize', 'zoom-in', 'zoom-out', isArbitraryVariable, isArbitraryValue]\n }],\n /**\n * Field Sizing\n * @see https://tailwindcss.com/docs/field-sizing\n */\n 'field-sizing': [{\n 'field-sizing': ['fixed', 'content']\n }],\n /**\n * Pointer Events\n * @see https://tailwindcss.com/docs/pointer-events\n */\n 'pointer-events': [{\n 'pointer-events': ['auto', 'none']\n }],\n /**\n * Resize\n * @see https://tailwindcss.com/docs/resize\n */\n resize: [{\n resize: ['none', '', 'y', 'x']\n }],\n /**\n * Scroll Behavior\n * @see https://tailwindcss.com/docs/scroll-behavior\n */\n 'scroll-behavior': [{\n scroll: ['auto', 'smooth']\n }],\n /**\n * Scrollbar Thumb Color\n * @see https://tailwindcss.com/docs/scrollbar-color\n */\n 'scrollbar-thumb-color': [{\n 'scrollbar-thumb': scaleColor()\n }],\n /**\n * Scrollbar Track Color\n * @see https://tailwindcss.com/docs/scrollbar-color\n */\n 'scrollbar-track-color': [{\n 'scrollbar-track': scaleColor()\n }],\n /**\n * Scrollbar Gutter\n * @see https://tailwindcss.com/docs/scrollbar-gutter\n */\n 'scrollbar-gutter': [{\n 'scrollbar-gutter': ['auto', 'stable', 'both']\n }],\n /**\n * Scrollbar Width\n * @see https://tailwindcss.com/docs/scrollbar-width\n */\n 'scrollbar-w': [{\n scrollbar: ['auto', 'thin', 'none']\n }],\n /**\n * Scroll Margin\n * @see https://tailwindcss.com/docs/scroll-margin\n */\n 'scroll-m': [{\n 'scroll-m': scaleUnambiguousSpacing()\n }],\n /**\n * Scroll Margin Inline\n * @see https://tailwindcss.com/docs/scroll-margin\n */\n 'scroll-mx': [{\n 'scroll-mx': scaleUnambiguousSpacing()\n }],\n /**\n * Scroll Margin Block\n * @see https://tailwindcss.com/docs/scroll-margin\n */\n 'scroll-my': [{\n 'scroll-my': scaleUnambiguousSpacing()\n }],\n /**\n * Scroll Margin Inline Start\n * @see https://tailwindcss.com/docs/scroll-margin\n */\n 'scroll-ms': [{\n 'scroll-ms': scaleUnambiguousSpacing()\n }],\n /**\n * Scroll Margin Inline End\n * @see https://tailwindcss.com/docs/scroll-margin\n */\n 'scroll-me': [{\n 'scroll-me': scaleUnambiguousSpacing()\n }],\n /**\n * Scroll Margin Block Start\n * @see https://tailwindcss.com/docs/scroll-margin\n */\n 'scroll-mbs': [{\n 'scroll-mbs': scaleUnambiguousSpacing()\n }],\n /**\n * Scroll Margin Block End\n * @see https://tailwindcss.com/docs/scroll-margin\n */\n 'scroll-mbe': [{\n 'scroll-mbe': scaleUnambiguousSpacing()\n }],\n /**\n * Scroll Margin Top\n * @see https://tailwindcss.com/docs/scroll-margin\n */\n 'scroll-mt': [{\n 'scroll-mt': scaleUnambiguousSpacing()\n }],\n /**\n * Scroll Margin Right\n * @see https://tailwindcss.com/docs/scroll-margin\n */\n 'scroll-mr': [{\n 'scroll-mr': scaleUnambiguousSpacing()\n }],\n /**\n * Scroll Margin Bottom\n * @see https://tailwindcss.com/docs/scroll-margin\n */\n 'scroll-mb': [{\n 'scroll-mb': scaleUnambiguousSpacing()\n }],\n /**\n * Scroll Margin Left\n * @see https://tailwindcss.com/docs/scroll-margin\n */\n 'scroll-ml': [{\n 'scroll-ml': scaleUnambiguousSpacing()\n }],\n /**\n * Scroll Padding\n * @see https://tailwindcss.com/docs/scroll-padding\n */\n 'scroll-p': [{\n 'scroll-p': scaleUnambiguousSpacing()\n }],\n /**\n * Scroll Padding Inline\n * @see https://tailwindcss.com/docs/scroll-padding\n */\n 'scroll-px': [{\n 'scroll-px': scaleUnambiguousSpacing()\n }],\n /**\n * Scroll Padding Block\n * @see https://tailwindcss.com/docs/scroll-padding\n */\n 'scroll-py': [{\n 'scroll-py': scaleUnambiguousSpacing()\n }],\n /**\n * Scroll Padding Inline Start\n * @see https://tailwindcss.com/docs/scroll-padding\n */\n 'scroll-ps': [{\n 'scroll-ps': scaleUnambiguousSpacing()\n }],\n /**\n * Scroll Padding Inline End\n * @see https://tailwindcss.com/docs/scroll-padding\n */\n 'scroll-pe': [{\n 'scroll-pe': scaleUnambiguousSpacing()\n }],\n /**\n * Scroll Padding Block Start\n * @see https://tailwindcss.com/docs/scroll-padding\n */\n 'scroll-pbs': [{\n 'scroll-pbs': scaleUnambiguousSpacing()\n }],\n /**\n * Scroll Padding Block End\n * @see https://tailwindcss.com/docs/scroll-padding\n */\n 'scroll-pbe': [{\n 'scroll-pbe': scaleUnambiguousSpacing()\n }],\n /**\n * Scroll Padding Top\n * @see https://tailwindcss.com/docs/scroll-padding\n */\n 'scroll-pt': [{\n 'scroll-pt': scaleUnambiguousSpacing()\n }],\n /**\n * Scroll Padding Right\n * @see https://tailwindcss.com/docs/scroll-padding\n */\n 'scroll-pr': [{\n 'scroll-pr': scaleUnambiguousSpacing()\n }],\n /**\n * Scroll Padding Bottom\n * @see https://tailwindcss.com/docs/scroll-padding\n */\n 'scroll-pb': [{\n 'scroll-pb': scaleUnambiguousSpacing()\n }],\n /**\n * Scroll Padding Left\n * @see https://tailwindcss.com/docs/scroll-padding\n */\n 'scroll-pl': [{\n 'scroll-pl': scaleUnambiguousSpacing()\n }],\n /**\n * Scroll Snap Align\n * @see https://tailwindcss.com/docs/scroll-snap-align\n */\n 'snap-align': [{\n snap: ['start', 'end', 'center', 'align-none']\n }],\n /**\n * Scroll Snap Stop\n * @see https://tailwindcss.com/docs/scroll-snap-stop\n */\n 'snap-stop': [{\n snap: ['normal', 'always']\n }],\n /**\n * Scroll Snap Type\n * @see https://tailwindcss.com/docs/scroll-snap-type\n */\n 'snap-type': [{\n snap: ['none', 'x', 'y', 'both']\n }],\n /**\n * Scroll Snap Type Strictness\n * @see https://tailwindcss.com/docs/scroll-snap-type\n */\n 'snap-strictness': [{\n snap: ['mandatory', 'proximity']\n }],\n /**\n * Touch Action\n * @see https://tailwindcss.com/docs/touch-action\n */\n touch: [{\n touch: ['auto', 'none', 'manipulation']\n }],\n /**\n * Touch Action X\n * @see https://tailwindcss.com/docs/touch-action\n */\n 'touch-x': [{\n 'touch-pan': ['x', 'left', 'right']\n }],\n /**\n * Touch Action Y\n * @see https://tailwindcss.com/docs/touch-action\n */\n 'touch-y': [{\n 'touch-pan': ['y', 'up', 'down']\n }],\n /**\n * Touch Action Pinch Zoom\n * @see https://tailwindcss.com/docs/touch-action\n */\n 'touch-pz': ['touch-pinch-zoom'],\n /**\n * User Select\n * @see https://tailwindcss.com/docs/user-select\n */\n select: [{\n select: ['none', 'text', 'all', 'auto']\n }],\n /**\n * Will Change\n * @see https://tailwindcss.com/docs/will-change\n */\n 'will-change': [{\n 'will-change': ['auto', 'scroll', 'contents', 'transform', isArbitraryVariable, isArbitraryValue]\n }],\n // -----------\n // --- SVG ---\n // -----------\n /**\n * Fill\n * @see https://tailwindcss.com/docs/fill\n */\n fill: [{\n fill: ['none', ...scaleColor()]\n }],\n /**\n * Stroke Width\n * @see https://tailwindcss.com/docs/stroke-width\n */\n 'stroke-w': [{\n stroke: [isNumber, isArbitraryVariableLength, isArbitraryLength, isArbitraryNumber]\n }],\n /**\n * Stroke\n * @see https://tailwindcss.com/docs/stroke\n */\n stroke: [{\n stroke: ['none', ...scaleColor()]\n }],\n // ---------------------\n // --- Accessibility ---\n // ---------------------\n /**\n * Forced Color Adjust\n * @see https://tailwindcss.com/docs/forced-color-adjust\n */\n 'forced-color-adjust': [{\n 'forced-color-adjust': ['auto', 'none']\n }]\n },\n conflictingClassGroups: {\n 'container-named': ['container-type'],\n overflow: ['overflow-x', 'overflow-y'],\n overscroll: ['overscroll-x', 'overscroll-y'],\n inset: ['inset-x', 'inset-y', 'inset-bs', 'inset-be', 'start', 'end', 'top', 'right', 'bottom', 'left'],\n 'inset-x': ['right', 'left'],\n 'inset-y': ['top', 'bottom'],\n flex: ['basis', 'grow', 'shrink'],\n gap: ['gap-x', 'gap-y'],\n p: ['px', 'py', 'ps', 'pe', 'pbs', 'pbe', 'pt', 'pr', 'pb', 'pl'],\n px: ['pr', 'pl'],\n py: ['pt', 'pb'],\n m: ['mx', 'my', 'ms', 'me', 'mbs', 'mbe', 'mt', 'mr', 'mb', 'ml'],\n mx: ['mr', 'ml'],\n my: ['mt', 'mb'],\n size: ['w', 'h'],\n 'font-size': ['leading'],\n 'fvn-normal': ['fvn-ordinal', 'fvn-slashed-zero', 'fvn-figure', 'fvn-spacing', 'fvn-fraction'],\n 'fvn-ordinal': ['fvn-normal'],\n 'fvn-slashed-zero': ['fvn-normal'],\n 'fvn-figure': ['fvn-normal'],\n 'fvn-spacing': ['fvn-normal'],\n 'fvn-fraction': ['fvn-normal'],\n 'line-clamp': ['display', 'overflow'],\n rounded: ['rounded-s', 'rounded-e', 'rounded-t', 'rounded-r', 'rounded-b', 'rounded-l', 'rounded-ss', 'rounded-se', 'rounded-ee', 'rounded-es', 'rounded-tl', 'rounded-tr', 'rounded-br', 'rounded-bl'],\n 'rounded-s': ['rounded-ss', 'rounded-es'],\n 'rounded-e': ['rounded-se', 'rounded-ee'],\n 'rounded-t': ['rounded-tl', 'rounded-tr'],\n 'rounded-r': ['rounded-tr', 'rounded-br'],\n 'rounded-b': ['rounded-br', 'rounded-bl'],\n 'rounded-l': ['rounded-tl', 'rounded-bl'],\n 'border-spacing': ['border-spacing-x', 'border-spacing-y'],\n 'border-w': ['border-w-x', 'border-w-y', 'border-w-s', 'border-w-e', 'border-w-bs', 'border-w-be', 'border-w-t', 'border-w-r', 'border-w-b', 'border-w-l'],\n 'border-w-x': ['border-w-r', 'border-w-l'],\n 'border-w-y': ['border-w-t', 'border-w-b'],\n 'border-color': ['border-color-x', 'border-color-y', 'border-color-s', 'border-color-e', 'border-color-bs', 'border-color-be', 'border-color-t', 'border-color-r', 'border-color-b', 'border-color-l'],\n 'border-color-x': ['border-color-r', 'border-color-l'],\n 'border-color-y': ['border-color-t', 'border-color-b'],\n translate: ['translate-x', 'translate-y', 'translate-none'],\n 'translate-none': ['translate', 'translate-x', 'translate-y', 'translate-z'],\n 'scroll-m': ['scroll-mx', 'scroll-my', 'scroll-ms', 'scroll-me', 'scroll-mbs', 'scroll-mbe', 'scroll-mt', 'scroll-mr', 'scroll-mb', 'scroll-ml'],\n 'scroll-mx': ['scroll-mr', 'scroll-ml'],\n 'scroll-my': ['scroll-mt', 'scroll-mb'],\n 'scroll-p': ['scroll-px', 'scroll-py', 'scroll-ps', 'scroll-pe', 'scroll-pbs', 'scroll-pbe', 'scroll-pt', 'scroll-pr', 'scroll-pb', 'scroll-pl'],\n 'scroll-px': ['scroll-pr', 'scroll-pl'],\n 'scroll-py': ['scroll-pt', 'scroll-pb'],\n touch: ['touch-x', 'touch-y', 'touch-pz'],\n 'touch-x': ['touch'],\n 'touch-y': ['touch'],\n 'touch-pz': ['touch']\n },\n conflictingClassGroupModifiers: {\n 'font-size': ['leading']\n },\n postfixLookupClassGroups: ['container-type'],\n orderSensitiveModifiers: ['*', '**', 'after', 'backdrop', 'before', 'details-content', 'file', 'first-letter', 'first-line', 'marker', 'placeholder', 'selection']\n };\n};\n\n/**\n * @param baseConfig Config where other config will be merged into. This object will be mutated.\n * @param configExtension Partial config to merge into the `baseConfig`.\n */\nconst mergeConfigs = (baseConfig, {\n cacheSize,\n prefix,\n experimentalParseClassName,\n extend = {},\n override = {}\n}) => {\n overrideProperty(baseConfig, 'cacheSize', cacheSize);\n overrideProperty(baseConfig, 'prefix', prefix);\n overrideProperty(baseConfig, 'experimentalParseClassName', experimentalParseClassName);\n overrideConfigProperties(baseConfig.theme, override.theme);\n overrideConfigProperties(baseConfig.classGroups, override.classGroups);\n overrideConfigProperties(baseConfig.conflictingClassGroups, override.conflictingClassGroups);\n overrideConfigProperties(baseConfig.conflictingClassGroupModifiers, override.conflictingClassGroupModifiers);\n overrideProperty(baseConfig, 'postfixLookupClassGroups', override.postfixLookupClassGroups);\n overrideProperty(baseConfig, 'orderSensitiveModifiers', override.orderSensitiveModifiers);\n mergeConfigProperties(baseConfig.theme, extend.theme);\n mergeConfigProperties(baseConfig.classGroups, extend.classGroups);\n mergeConfigProperties(baseConfig.conflictingClassGroups, extend.conflictingClassGroups);\n mergeConfigProperties(baseConfig.conflictingClassGroupModifiers, extend.conflictingClassGroupModifiers);\n mergeArrayProperties(baseConfig, extend, 'postfixLookupClassGroups');\n mergeArrayProperties(baseConfig, extend, 'orderSensitiveModifiers');\n return baseConfig;\n};\nconst overrideProperty = (baseObject, overrideKey, overrideValue) => {\n if (overrideValue !== undefined) {\n baseObject[overrideKey] = overrideValue;\n }\n};\nconst overrideConfigProperties = (baseObject, overrideObject) => {\n if (overrideObject) {\n for (const key in overrideObject) {\n overrideProperty(baseObject, key, overrideObject[key]);\n }\n }\n};\nconst mergeConfigProperties = (baseObject, mergeObject) => {\n if (mergeObject) {\n for (const key in mergeObject) {\n mergeArrayProperties(baseObject, mergeObject, key);\n }\n }\n};\nconst mergeArrayProperties = (baseObject, mergeObject, key) => {\n const mergeValue = mergeObject[key];\n if (mergeValue !== undefined) {\n baseObject[key] = baseObject[key] ? baseObject[key].concat(mergeValue) : mergeValue;\n }\n};\nconst extendTailwindMerge = (configExtension, ...createConfig) => typeof configExtension === 'function' ? createTailwindMerge(getDefaultConfig, configExtension, ...createConfig) : createTailwindMerge(() => mergeConfigs(getDefaultConfig(), configExtension), ...createConfig);\nconst twMerge = /*#__PURE__*/createTailwindMerge(getDefaultConfig);\nexport { createTailwindMerge, extendTailwindMerge, fromTheme, getDefaultConfig, mergeConfigs, twJoin, twMerge, validators };\n//# sourceMappingURL=bundle-mjs.mjs.map\n","import { twMerge } from \"tailwind-merge\";\r\n\r\n/** Une clases condicionales y resuelve conflictos de Tailwind (gana la última). */\r\nexport function cn(...clases: Array<string | false | null | undefined>): string {\r\n return twMerge(clases.filter(Boolean).join(\" \"));\r\n}\r\n","/** Props de `MensajeError`. */\r\ninterface MensajeErrorProps {\r\n titulo?: string;\r\n mensaje?: string;\r\n}\r\n\r\n/** Bloque de error consistente para páginas y paneles. */\r\nexport function MensajeError({ titulo, mensaje }: MensajeErrorProps) {\r\n return (\r\n <div className=\"mx-auto max-w-md rounded-xl border border-red-900/60 bg-red-950/40 p-5 text-center\">\r\n <p className=\"text-sm font-semibold text-red-300\">\r\n {titulo ?? \"Ocurrió un problema\"}\r\n </p>\r\n <p className=\"mt-1 text-xs text-red-200/80\">\r\n {mensaje ?? \"Hubo un error inesperado en la carga del visor. Intente nuevamente más tarde o contacte con el administrador.\"}\r\n </p>\r\n </div>\r\n );\r\n}\r\n","import { createContext, useContext } from \"react\";\r\nimport type { RecursoAsync } from \"@/shared/hooks/useRecursoAsync\";\r\nimport type { ConfiguracionAplicacion } from \"../types\";\r\n\r\n/** Estado de la configuración compartida en el árbol de la app. */\r\nexport const ContextoConfiguracion =\r\n createContext<RecursoAsync<ConfiguracionAplicacion> | null>(null);\r\n\r\n/** Accede a la configuración cargada; debe usarse dentro de <ProveedorConfiguracion>. */\r\nexport function useConfiguracionAplicacion(): RecursoAsync<ConfiguracionAplicacion> {\r\n const contexto = useContext(ContextoConfiguracion);\r\n // Sin proveedor no hay configuración: error explícito.\r\n if (!contexto) {\r\n throw new Error(\r\n \"useConfiguracionAplicacion debe usarse dentro de <ProveedorConfiguracion>.\",\r\n );\r\n }\r\n return contexto;\r\n}\r\n","import type { ProveedorTokenAcceso } from \"./configuracion-aplicacion\";\n\n/** Por qué no se pudo obtener o usar el token de acceso. */\nexport type MotivoErrorToken =\n | \"sin-configurar\"\n | \"controlador\"\n | \"vacio\"\n | \"rechazado\";\n\n/** Error de token: el visor no carga sin un JWT válido (no hay respaldo). */\nexport class ErrorToken extends Error {\n readonly motivo: MotivoErrorToken;\n\n constructor(motivo: MotivoErrorToken, mensaje: string, opciones?: ErrorOptions) {\n super(mensaje, opciones);\n this.name = \"ErrorToken\";\n this.motivo = motivo;\n }\n}\n\n/** De dónde sale el token: la URL del controlador del anfitrión o una función propia. */\nexport interface OrigenToken {\n /** Controlador que emite el JWT: recibe `POST { clientId }` y responde `{ token }`. */\n urlToken?: string;\n /** Alternativa a `urlToken` para controlar la llamada (headers, cookies, etc.). */\n getAccessToken?: ProveedorTokenAcceso;\n}\n\n/** Cuánto se espera como máximo al controlador de tokens. */\nconst TIEMPO_ESPERA_TOKEN_MS = 15_000;\n\n/** Lee el token de la respuesta: JSON `{ token }` (o `accessToken`/`access_token`) o texto plano. */\nfunction leerToken(cuerpo: string): string {\n const texto = cuerpo.trim();\n if (!texto.startsWith(\"{\")) return texto.replace(/^\"|\"$/g, \"\");\n\n const json = JSON.parse(texto) as Record<string, unknown>;\n const token = json.token ?? json.accessToken ?? json.access_token;\n return typeof token === \"string\" ? token.trim() : \"\";\n}\n\n/** Pide el JWT al controlador del anfitrión (`POST urlToken` con `{ clientId }`). */\nasync function pedirTokenAControlador(urlToken: string, clientId: string): Promise<string> {\n let respuesta: Response;\n try {\n respuesta = await fetch(urlToken, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ clientId }),\n signal: AbortSignal.timeout(TIEMPO_ESPERA_TOKEN_MS),\n });\n } catch (causa: unknown) {\n throw new ErrorToken(\n \"controlador\",\n `No se pudo contactar el controlador de tokens (${urlToken}).`,\n { cause: causa },\n );\n }\n if (!respuesta.ok) {\n throw new ErrorToken(\n \"controlador\",\n `El controlador de tokens respondió ${respuesta.status}.`,\n );\n }\n\n let token: string;\n try {\n token = leerToken(await respuesta.text());\n } catch (causa: unknown) {\n throw new ErrorToken(\n \"controlador\",\n \"El controlador de tokens devolvió una respuesta que no se pudo leer.\",\n { cause: causa },\n );\n }\n return token;\n}\n\n/**\n * Arma el proveedor de tokens del visor. Sin `urlToken` ni `getAccessToken`\n * el proveedor falla siempre: el mapa no carga sin token.\n */\nexport function crearProveedorToken({ urlToken, getAccessToken }: OrigenToken): ProveedorTokenAcceso {\n return async (clientId) => {\n let token: string;\n if (getAccessToken) {\n try {\n token = await getAccessToken(clientId);\n } catch (causa: unknown) {\n if (causa instanceof ErrorToken) throw causa;\n throw new ErrorToken(\n \"controlador\",\n \"La función getAccessToken falló al obtener el token.\",\n { cause: causa },\n );\n }\n } else if (urlToken?.trim()) {\n token = await pedirTokenAControlador(urlToken.trim(), clientId);\n } else {\n throw new ErrorToken(\n \"sin-configurar\",\n \"Falta configurar el token: indica urlToken o getAccessToken.\",\n );\n }\n\n if (typeof token !== \"string\" || !token.trim()) {\n throw new ErrorToken(\"vacio\", \"El controlador de tokens devolvió un token vacío.\");\n }\n return token.trim();\n };\n}\n","import type { MapViewOrSceneView } from \"@arcgis/core/views/MapViewOrSceneView\";\r\nimport type { HerramientaMapa } from \"./herramienta.types\";\r\n\r\n/** Vista de ArcGIS sobre la que opera el visor: 2D (`MapView`) o 3D (`SceneView`). */\r\nexport type VistaMapa = MapViewOrSceneView;\r\n\r\n/**\r\n * Nombres reservados que el backend usa para distinguir el modo de\r\n * presentación del mapa dentro de `mapas[]`.\r\n */\r\nexport const MODO_MAPA = {\r\n pantallaCompleta: \"FULLSCREEN\",\r\n integrado: \"EMBEDDED\",\r\n} as const;\r\n\r\n/** Modo de presentación del mapa (`\"FULLSCREEN\"` o `\"EMBEDDED\"`). */\r\nexport type ModoMapa = (typeof MODO_MAPA)[keyof typeof MODO_MAPA];\r\n\r\n/** Configuración visual inicial de un mapa. */\r\nexport interface ConfiguracionVisualMapa {\r\n zoom: number;\r\n width: string;\r\n /** [longitud, latitud] */\r\n center: [number, number];\r\n height: string;\r\n /** Código dentro de `galeriaMapas`. */\r\n basemap: string;\r\n}\r\n\r\n/** Una instancia de mapa publicada por el backend. */\r\nexport interface DefinicionMapa {\r\n nombre: string;\r\n descripcion: string;\r\n configuracion: ConfiguracionVisualMapa;\r\n herramientas: HerramientaMapa[];\r\n}\r\n\r\n/** Localiza la definición de un mapa por su nombre de modo. */\r\nexport function buscarDefinicionPorModo(\r\n mapas: readonly DefinicionMapa[],\r\n modo: ModoMapa,\r\n): DefinicionMapa | undefined {\r\n return (\r\n mapas.find((mapa) => mapa.nombre === modo) ??\r\n (mapas.length > 0 ? mapas[0] : undefined)\r\n );\r\n}\r\n","/** Plataformas GIS que el backend puede publicar. */\r\nexport type PlataformaGis = \"ARCGIS\" | \"GEOSERVER\";\r\n\r\n/**\r\n * Tipos de servicio soportados por el contrato.\r\n * El registro de capas es exhaustivo sobre esta unión.\r\n */\r\nexport type TipoServicioGis =\r\n | \"ARCGIS_MAP\"\r\n | \"ARCGIS_FEATURE\"\r\n | \"ARCGIS_TILE\"\r\n | \"OGC_WMS\"\r\n | \"OGC_WMTS\"\r\n | \"OGC_WFS\"\r\n | \"OGC_API_FEATURES\";\r\n\r\n/** Mecanismo de autenticación con el que se consume un servicio. */\r\nexport type TipoAutenticacionGis = \"TOKEN\" | \"BASIC\" | \"NINGUNA\";\r\n\r\n/** Nivel de acceso concedido sobre un servicio. */\r\nexport type NivelAccesoGis = \"LECTURA\" | \"ESCRITURA\";\r\n\r\n/** Subcapa declarada en el contrato o descubierta desde el proveedor GIS. */\r\nexport interface CapaServicio {\r\n titulo: string;\r\n visible: boolean;\r\n /** Opacidad propia; si no viene, hereda la del servicio. */\r\n opacidad?: number;\r\n /** Escala más alejada y más cercana permitidas; `0` significa sin límite. */\r\n minScale?: number;\r\n maxScale?: number;\r\n /** Entero no negativo (ArcGIS) o texto (OGC); siempre `string` en el front. */\r\n identificador: string;\r\n}\r\n\r\n/** Configuración de las capas declaradas por un servicio GIS. */\r\nexport interface ConfiguracionCapas {\r\n /** Opcional: servicios sin subcapas solo se controlan a nivel de servicio. */\r\n capas?: CapaServicio[];\r\n [clave: string]: unknown;\r\n}\r\n\r\n/** Un servicio GIS publicado por el backend para la aplicación. */\r\nexport interface ServicioGis {\r\n nombre: string;\r\n descripcion: string;\r\n plataformaGis: PlataformaGis;\r\n tipoServicio: TipoServicioGis;\r\n tipoAutenticacion: TipoAutenticacionGis;\r\n nivelAcceso: NivelAccesoGis;\r\n /**\r\n * URL directa del proveedor o, cuando la autenticación la maneja el\r\n * backend (p. ej. WMS Basic), la URL de proxy lista para consumir.\r\n */\r\n url: string;\r\n configuracionServicio: Record<string, unknown>;\r\n configuracionCapas: ConfiguracionCapas;\r\n orden: number;\r\n visible: boolean;\r\n opacidad: number;\r\n metadatos: Record<string, unknown>;\r\n /** Credencial temporal ArcGIS o del proxy GeoServer. */\r\n token?: string;\r\n /** Vigencia del token en epoch milisegundos. */\r\n expires?: number;\r\n ssl?: boolean;\r\n}\r\n\r\n/** Grupo ordenado de servicios GIS publicado por el backend. */\r\nexport interface GrupoServicios {\r\n nombre: string;\r\n descripcion: string;\r\n orden: number;\r\n servicios: ServicioGis[];\r\n}\r\n\r\n/** Aplana los grupos respetando el orden declarado por el backend. */\r\nexport function aplanarServicios(grupos: readonly GrupoServicios[]): ServicioGis[] {\r\n return [...grupos]\r\n .sort((a, b) => a.orden - b.orden)\r\n .flatMap((grupo) => [...grupo.servicios].sort((a, b) => a.orden - b.orden));\r\n}\r\n","/** Descarga un texto (p. ej. GeoJSON) como archivo vía un enlace temporal a un `Blob`. */\r\n\r\n/** Caracteres no permitidos en un nombre de archivo según el sistema. */\r\nconst CARACTERES_PELIGROSOS = /[\\p{Cc}<>:\"/\\\\|?*]+/gu;\r\n\r\n/** Quita rutas y caracteres inválidos; nunca devuelve un nombre vacío. */\r\nfunction nombreSeguro(nombreArchivo: string): string {\r\n const sinRuta = nombreArchivo.replace(/^.*[\\\\/]/, \"\");\r\n const saneado = sinRuta.replace(CARACTERES_PELIGROSOS, \"_\");\r\n const sinPuntosRaros = saneado.replace(/^\\.+/, \"\");\r\n return sinPuntosRaros.trim() || \"descarga.txt\";\r\n}\r\n\r\nexport function descargarArchivo(\r\n nombreArchivo: string,\r\n contenido: string,\r\n tipoMime: string,\r\n): void {\r\n const url = URL.createObjectURL(new Blob([contenido], { type: tipoMime }));\r\n const enlace = document.createElement(\"a\");\r\n enlace.href = url;\r\n enlace.download = nombreSeguro(nombreArchivo);\r\n enlace.click();\r\n // El revoke se difiere al siguiente turno: revocar en este mismo tick puede\r\n // cancelar la descarga en algunos navegadores (Firefox).\r\n setTimeout(() => URL.revokeObjectURL(url), 0);\r\n}\r\n","/** Formatea una duración en ms como `m:ss min` (p. ej. 90000 → \"1:30 min\"). */\r\nexport function formatearDuracion(milisegundos: number): string {\r\n const totalSegundos = Math.round(milisegundos / 1000);\r\n const minutos = Math.floor(totalSegundos / 60);\r\n const segundos = String(totalSegundos % 60).padStart(2, \"0\");\r\n return `${minutos}:${segundos} min`;\r\n}\r\n","import type { ReactNode } from \"react\";\nimport { createContext, useContext } from \"react\";\n\n/**\n * Aviso mostrado al usuario: informativo (un solo botón) o, con `alConfirmar`,\n * de confirmación (dos botones, \"No\"/\"Sí\").\n */\nexport interface Alerta {\n /** Identificador interno para quitarla de la cola. */\n id: string;\n /** Título breve de la cabecera. */\n titulo: string;\n /** Cuerpo del aviso; acepta ReactNode para resaltar parte del texto. */\n mensaje: ReactNode;\n /** Texto del botón principal. Por defecto \"Entendido\", o \"Sí\" en modo confirmación. */\n textoBoton?: string;\n /** Solo en modo confirmación: texto del botón secundario. Por defecto \"No\". */\n textoCancelar?: string;\n /** Con manejador, el aviso pasa a modo confirmación. Se llama al elegir el botón principal. */\n alConfirmar?: () => void;\n /** Solo en confirmación: se llama al declinar, antes de quitar el aviso. */\n alCancelar?: () => void;\n}\n\n/** API para mostrar y cerrar avisos desde cualquier parte del árbol. */\nexport interface ContextoAlertasValor {\n /** Encola un aviso; ignora los repetidos (mismo `titulo` ya en cola). */\n mostrar: (alerta: Omit<Alerta, \"id\">) => void;\n /** Quita de la cola el aviso con ese `id`. */\n cerrar: (id: string) => void;\n}\n\n/** Estado de los avisos compartido en el árbol de la app. */\nexport const ContextoAlertas = createContext<ContextoAlertasValor | null>(null);\n\n/** Accede a la API de avisos; debe usarse dentro de <ProveedorAlertas>. */\nexport function useAlerta(): ContextoAlertasValor {\n const contexto = useContext(ContextoAlertas);\n // Sin proveedor no hay dónde mostrar el aviso: error explícito.\n if (!contexto) {\n throw new Error(\"useAlerta debe usarse dentro de <ProveedorAlertas>.\");\n }\n return contexto;\n}\n","import * as reactiveUtils from \"@arcgis/core/core/reactiveUtils\";\r\nimport { useEffect, useState } from \"react\";\r\nimport type { VistaMapa } from \"../types\";\r\n\r\n/** Coordenadas geográficas (longitud/latitud). */\r\nexport interface CoordenadasPuntero {\r\n longitud: number;\r\n latitud: number;\r\n}\r\n\r\n/**\r\n * Coordenadas geográficas bajo el puntero (conserva la última al salir del mapa).\r\n * Se calcula una vez por `requestAnimationFrame` y solo si cambió.\r\n */\r\nexport function useCoordenadasPuntero(\r\n vista: VistaMapa | null,\r\n): CoordenadasPuntero | null {\r\n const [coordenadas, setCoordenadas] = useState<CoordenadasPuntero | null>(null);\r\n\r\n useEffect(() => {\r\n if (!vista) return;\r\n\r\n // Última posición de pantalla conocida del puntero.\r\n let puntoPantalla: { x: number; y: number } | null = null;\r\n let ultimaLectura: CoordenadasPuntero | null = null;\r\n let cuadroPendiente: number | null = null;\r\n\r\n // Convierte esa posición a coordenadas del mapa.\r\n const actualizar = () => {\r\n cuadroPendiente = null;\r\n if (!puntoPantalla) return;\r\n const { longitude, latitude } = vista.toMap(puntoPantalla) ?? {};\r\n if (typeof longitude !== \"number\" || typeof latitude !== \"number\") return;\r\n if (\r\n ultimaLectura &&\r\n ultimaLectura.longitud === longitude &&\r\n ultimaLectura.latitud === latitude\r\n ) {\r\n return;\r\n }\r\n ultimaLectura = { longitud: longitude, latitud: latitude };\r\n setCoordenadas(ultimaLectura);\r\n };\r\n\r\n const solicitarActualizacion = () => {\r\n cuadroPendiente ??= requestAnimationFrame(actualizar);\r\n };\r\n\r\n // Recalcula al mover el puntero y al cambiar la extensión de la vista.\r\n const manejadorPuntero = vista.on(\"pointer-move\", (evento) => {\r\n puntoPantalla = { x: evento.x, y: evento.y };\r\n solicitarActualizacion();\r\n });\r\n const manejadorExtent = reactiveUtils.watch(() => vista.extent, solicitarActualizacion);\r\n\r\n // Limpieza: cancela el cuadro pendiente, quita los listeners y resetea la lectura.\r\n return () => {\r\n if (cuadroPendiente !== null) cancelAnimationFrame(cuadroPendiente);\r\n manejadorPuntero.remove();\r\n manejadorExtent.remove();\r\n setCoordenadas(null);\r\n };\r\n }, [vista]);\r\n\r\n return coordenadas;\r\n}\r\n","import Graphic from \"@arcgis/core/Graphic\";\r\nimport type Point from \"@arcgis/core/geometry/Point\";\r\nimport SimpleMarkerSymbol from \"@arcgis/core/symbols/SimpleMarkerSymbol\";\r\nimport { useCallback, useEffect, useRef } from \"react\";\r\nimport type { VistaMapa } from \"../types\";\r\n\r\n/** Símbolo del punto de referencia, compartido con `useCoordenadasSeleccion`. */\r\nexport const SIMBOLO_MARCADOR_PUNTO = new SimpleMarkerSymbol({\r\n color: [56, 189, 248],\r\n size: 10,\r\n outline: { color: [255, 255, 255], width: 1.5 },\r\n});\r\n\r\n/** Valor devuelto por `useMarcadorPunto`. */\r\ninterface MarcadorPunto {\r\n /** Coloca (o mueve, si ya existe) el punto de referencia en `vista.graphics`. */\r\n marcar: (punto: Point) => void;\r\n /** Quita el punto de referencia de la vista. */\r\n quitar: () => void;\r\n}\r\n\r\n/** Marca un único punto en la vista (lo añade una vez y luego lo mueve); se quita al desmontar. */\r\nexport function useMarcadorPunto(vista: VistaMapa): MarcadorPunto {\r\n const graficoRef = useRef<Graphic | null>(null);\r\n\r\n useEffect(\r\n () => () => {\r\n if (graficoRef.current) vista.graphics.remove(graficoRef.current);\r\n graficoRef.current = null;\r\n },\r\n [vista],\r\n );\r\n\r\n const marcar = useCallback(\r\n (punto: Point) => {\r\n if (!graficoRef.current) {\r\n graficoRef.current = new Graphic({ symbol: SIMBOLO_MARCADOR_PUNTO });\r\n vista.graphics.add(graficoRef.current);\r\n }\r\n graficoRef.current.geometry = punto;\r\n },\r\n [vista],\r\n );\r\n\r\n const quitar = useCallback(() => {\r\n if (graficoRef.current) vista.graphics.remove(graficoRef.current);\r\n graficoRef.current = null;\r\n }, [vista]);\r\n\r\n return { marcar, quitar };\r\n}\r\n","import Graphic from \"@arcgis/core/Graphic\";\r\nimport { useEffect, useState } from \"react\";\r\nimport { SIMBOLO_MARCADOR_PUNTO } from \"./useMarcadorPunto\";\r\nimport type { VistaMapa } from \"../types\";\r\nimport type { CoordenadasPuntero } from \"./useCoordenadasPuntero\";\r\n\r\n/** Coordenadas WGS84 del último clic mientras `activa`, con un punto de referencia. */\r\nexport function useCoordenadasSeleccion(\r\n vista: VistaMapa | null,\r\n activa: boolean,\r\n): CoordenadasPuntero | null {\r\n const [coordenadas, setCoordenadas] = useState<CoordenadasPuntero | null>(null);\r\n\r\n useEffect(() => {\r\n if (!vista || !activa) return;\r\n\r\n // Punto de referencia visible en la vista.\r\n const referencia = new Graphic({ symbol: SIMBOLO_MARCADOR_PUNTO });\r\n vista.graphics.add(referencia);\r\n\r\n // Cada clic mueve el punto y actualiza la lectura.\r\n const manejador = vista.on(\"click\", (evento) => {\r\n evento.stopPropagation();\r\n const punto = evento.mapPoint;\r\n if (\r\n !punto ||\r\n typeof punto.longitude !== \"number\" ||\r\n typeof punto.latitude !== \"number\"\r\n ) {\r\n return;\r\n }\r\n referencia.geometry = punto;\r\n setCoordenadas({ longitud: punto.longitude, latitud: punto.latitude });\r\n });\r\n\r\n // Limpieza: quita el listener, el punto y la lectura.\r\n return () => {\r\n manejador.remove();\r\n vista.graphics.remove(referencia);\r\n setCoordenadas(null);\r\n };\r\n }, [vista, activa]);\r\n\r\n return coordenadas;\r\n}\r\n","import { useCallback, useRef, type PointerEvent } from \"react\";\r\n\r\n/** Superficies ancladas: se apilan bajo `z-40` sin tapar las modales (\"capas\" no entra). */\r\nconst SUPERFICIES_ANCLADAS: ReadonlySet<string> = new Set([\"metadata\", \"basemap\"]);\r\n\r\n/**\r\n * Orden de apilamiento de las superficies por `z-index`, con contadores separados\r\n * para ancladas y flotantes. `raizRef` va en el contenedor.\r\n */\r\nexport function useElevarSuperficies<Elemento extends HTMLElement>() {\r\n const raizRef = useRef<Elemento | null>(null);\r\n const zIndexAncladoRef = useRef(20);\r\n const zIndexModalRef = useRef(40);\r\n\r\n const elevarModal = useCallback((evento: PointerEvent<HTMLElement>) => {\r\n const superficie = (evento.target as HTMLElement).closest<HTMLElement>(\r\n \"[data-superficie-modal]\",\r\n );\r\n if (!superficie) return;\r\n /* istanbul ignore next -- el valor por defecto es solo para el tipado */\r\n const clave = superficie.dataset.superficieModal ?? \"\";\r\n if (SUPERFICIES_ANCLADAS.has(clave)) {\r\n zIndexAncladoRef.current = Math.min(39, zIndexAncladoRef.current + 1);\r\n superficie.style.zIndex = String(zIndexAncladoRef.current);\r\n } else {\r\n superficie.style.zIndex = String(++zIndexModalRef.current);\r\n }\r\n }, []);\r\n\r\n const elevarSuperficie = useCallback((clave: string) => {\r\n const superficie = raizRef.current?.querySelector<HTMLElement>(\r\n `[data-superficie-modal=\"${clave}\"]`,\r\n );\r\n /* istanbul ignore next -- el efecto que la llama solo corre tras montar la superficie */\r\n if (!superficie) return;\r\n superficie.style.zIndex = String(++zIndexModalRef.current);\r\n }, []);\r\n\r\n return { raizRef, elevarModal, elevarSuperficie };\r\n}","import { useCallback, useState } from \"react\";\r\nimport type { GestorCapasMapa } from \"../services/layers/gestor-capas\";\r\nimport type { EstadosCapas, ServicioGis } from \"../types\";\r\n\r\n/** Deriva el estado inicial de visibilidad/opacidad desde el contrato. */\r\nfunction estadosIniciales(servicios: readonly ServicioGis[]): EstadosCapas {\r\n const serviciosVisibles: Record<string, boolean> = {};\r\n const opacidades: Record<string, number> = {};\r\n const capas: Record<string, Record<string, boolean>> = {};\r\n const opacidadesCapas: Record<string, Record<string, number>> = {};\r\n\r\n for (const servicio of servicios) {\r\n const subcapas = servicio.configuracionCapas.capas ?? [];\r\n serviciosVisibles[servicio.nombre] = subcapas.length > 0;\r\n opacidades[servicio.nombre] = servicio.opacidad;\r\n // Todas las capas arrancan desactivadas: el usuario las enciende desde el panel.\r\n capas[servicio.nombre] = Object.fromEntries(\r\n subcapas.map((capa) => [capa.identificador, false]),\r\n );\r\n opacidadesCapas[servicio.nombre] = Object.fromEntries(\r\n subcapas.map((capa) => [capa.identificador, capa.opacidad ?? servicio.opacidad]),\r\n );\r\n }\r\n\r\n return { servicios: serviciosVisibles, opacidades, capas, opacidadesCapas };\r\n}\r\n\r\n/** Valor devuelto por `useEstadosCapas`. */\r\ninterface ControlEstadosCapas {\r\n estados: EstadosCapas;\r\n onCambioServicio: (nombre: string, visible: boolean) => void;\r\n onCambioOpacidad: (nombre: string, opacidad: number) => void;\r\n onCambioOpacidadCapa: (\r\n nombre: string,\r\n identificador: string,\r\n opacidad: number,\r\n ) => void;\r\n onCambioCapa: (nombre: string, identificador: string, visible: boolean) => void;\r\n}\r\n\r\n/**\r\n * Estado del panel de capas sincronizado con el gestor imperativo de ArcGIS:\r\n * cada cambio actualiza React y aplica la operación sobre `gestorRef.current`.\r\n */\r\nexport function useEstadosCapas(\r\n servicios: readonly ServicioGis[],\r\n gestorRef: React.RefObject<GestorCapasMapa | null>,\r\n): ControlEstadosCapas {\r\n const [estados, setEstados] = useState<EstadosCapas>(() =>\r\n estadosIniciales(servicios),\r\n );\r\n\r\n // Alterna la visibilidad de un servicio completo.\r\n const onCambioServicio = useCallback(\r\n (nombre: string, visible: boolean) => {\r\n setEstados((previo) => ({\r\n ...previo,\r\n servicios: { ...previo.servicios, [nombre]: visible },\r\n }));\r\n gestorRef.current?.cambiaVisibilidadDelServicio(nombre, visible);\r\n },\r\n [gestorRef],\r\n );\r\n\r\n // Ajusta la opacidad de un servicio.\r\n const onCambioOpacidad = useCallback(\r\n (nombre: string, opacidad: number) => {\r\n setEstados((previo) => ({\r\n ...previo,\r\n opacidades: { ...previo.opacidades, [nombre]: opacidad },\r\n }));\r\n gestorRef.current?.cambiarOpacidadServicio(nombre, opacidad);\r\n },\r\n [gestorRef],\r\n );\r\n\r\n // Ajusta la opacidad de una subcapa.\r\n const onCambioOpacidadCapa = useCallback(\r\n (nombre: string, identificador: string, opacidad: number) => {\r\n setEstados((previo) => ({\r\n ...previo,\r\n opacidadesCapas: {\r\n ...previo.opacidadesCapas,\r\n [nombre]: {\r\n ...previo.opacidadesCapas?.[nombre],\r\n [identificador]: opacidad,\r\n },\r\n },\r\n }));\r\n gestorRef.current?.cambiarOpacidadCapa(nombre, identificador, opacidad);\r\n },\r\n [gestorRef],\r\n );\r\n\r\n // Alterna la visibilidad de una subcapa concreta.\r\n const onCambioCapa = useCallback(\r\n (nombre: string, identificador: string, visible: boolean) => {\r\n setEstados((previo) => ({\r\n ...previo,\r\n capas: {\r\n ...previo.capas,\r\n [nombre]: { ...previo.capas[nombre], [identificador]: visible },\r\n },\r\n }));\r\n gestorRef.current?.cambiarVisibilidadCapa(nombre, identificador, visible);\r\n },\r\n [gestorRef],\r\n );\r\n\r\n return {\r\n estados,\r\n onCambioServicio,\r\n onCambioOpacidad,\r\n onCambioOpacidadCapa,\r\n onCambioCapa,\r\n };\r\n}\r\n","import FeatureLayer from \"@arcgis/core/layers/FeatureLayer\";\r\nimport MapImageLayer from \"@arcgis/core/layers/MapImageLayer\";\r\nimport TileLayer from \"@arcgis/core/layers/TileLayer\";\r\nimport type Layer from \"@arcgis/core/layers/Layer\";\r\nimport type { CapaServicio, ServicioGis } from \"@/features/maps/types\";\r\nimport type { CapasServicioConstruidas } from \"./types\";\r\n\r\n/** Valida y convierte el identificador común al id numérico de ArcGIS. */\r\nfunction idNumerico(capa: CapaServicio): number {\r\n const id = Number(capa.identificador);\r\n if (!Number.isInteger(id) || id < 0) {\r\n throw new Error(\r\n `La capa \"${capa.titulo}\" requiere un identificador numérico de ArcGIS.`,\r\n );\r\n }\r\n return id;\r\n}\r\n\r\n/** URL de una FeatureLayer concreta: `<url del servicio>/<id numérico>`. */\r\nfunction urlCapaFeature(servicio: ServicioGis, capa: CapaServicio): string {\r\n return `${servicio.url.replace(/\\/$/, \"\")}/${idNumerico(capa)}`;\r\n}\r\n\r\n/** ARCGIS_MAP: un único MapImageLayer con subcapas opcionales. */\r\nexport function crearMapaImagen(servicio: ServicioGis): CapasServicioConstruidas {\r\n const capa = new MapImageLayer({\r\n url: servicio.url,\r\n title: servicio.nombre,\r\n visible: servicio.visible,\r\n opacity: servicio.opacidad,\r\n ...(servicio.configuracionCapas.capas?.length\r\n ? {\r\n sublayers: servicio.configuracionCapas.capas.map((item) => ({\r\n id: idNumerico(item),\r\n title: item.titulo,\r\n visible: item.visible,\r\n opacity: item.opacidad ?? servicio.opacidad,\r\n minScale: item.minScale,\r\n maxScale: item.maxScale,\r\n })),\r\n }\r\n : {}),\r\n });\r\n\r\n return {\r\n capasRaiz: [capa],\r\n subcapas: {\r\n establecerVisible(identificador, visible) {\r\n const subcapa = capa.findSublayerById(Number(identificador));\r\n if (subcapa) subcapa.visible = visible;\r\n },\r\n establecerOpacidad(identificador, opacidad) {\r\n const subcapa = capa.findSublayerById(Number(identificador));\r\n if (subcapa) subcapa.opacity = opacidad;\r\n },\r\n },\r\n };\r\n}\r\n\r\n/** ARCGIS_FEATURE: una FeatureLayer por cada capa configurada. */\r\nexport function crearFeatures(servicio: ServicioGis): CapasServicioConstruidas {\r\n const individuales = new Map<string, Layer>();\r\n\r\n for (const item of servicio.configuracionCapas.capas ?? []) {\r\n individuales.set(\r\n item.identificador,\r\n new FeatureLayer({\r\n url: urlCapaFeature(servicio, item),\r\n title: item.titulo,\r\n opacity: item.opacidad ?? servicio.opacidad,\r\n minScale: item.minScale,\r\n maxScale: item.maxScale,\r\n }),\r\n );\r\n }\r\n\r\n return { capasRaiz: [...individuales.values()], individuales };\r\n}\r\n\r\n/** ARCGIS_TILE: exactamente una capa cacheada por servicio. */\r\nexport function crearTileCachedo(servicio: ServicioGis): CapasServicioConstruidas {\r\n const capas = servicio.configuracionCapas.capas ?? [];\r\n const [primera] = capas;\r\n if (!primera || capas.length !== 1) {\r\n throw new Error(\r\n `El servicio cacheado \"${servicio.nombre}\" debe declarar exactamente una capa.`,\r\n );\r\n }\r\n\r\n const capa: Layer = new TileLayer({\r\n url: servicio.url,\r\n title: primera.titulo,\r\n opacity: primera.opacidad ?? servicio.opacidad,\r\n minScale: primera.minScale,\r\n maxScale: primera.maxScale,\r\n });\r\n\r\n return {\r\n capasRaiz: [capa],\r\n individuales: new Map([[primera.identificador, capa]]),\r\n };\r\n}\r\n","import type { CampoConsulta, FiltroConsulta } from \"@/features/maps/types\";\r\n\r\n/**\r\n * Filtros comunes a la consulta ArcGIS REST y WFS. Los topes de la consulta\r\n * (`ParametrosConsulta`) vienen de BD vía `obtenerParametrosConsulta`.\r\n */\r\n\r\n/** Escapa comillas simples en un valor de texto, para que la expresión quede bien formada. */\r\nfunction escaparTexto(valor: string): string {\r\n return valor.replace(/'/g, \"''\");\r\n}\r\n\r\n/** Traduce el filtro al lenguaje del backend; solo cambia el operador `LIKE`. */\r\nexport function armarFiltro(\r\n filtro: FiltroConsulta,\r\n campos: readonly CampoConsulta[],\r\n /** Expresión para el operador `LIKE`. */\r\n like: (campo: string, valor: string) => string,\r\n): string {\r\n if (filtro.operador === \"LIKE\") {\r\n return like(filtro.campo, escaparTexto(filtro.valor));\r\n }\r\n\r\n // Solo los campos numéricos (con valor numérico) van sin comillas; el resto, como texto.\r\n const campo = campos.find((item) => item.nombre === filtro.campo);\r\n const esNumero = campo?.tipo === \"numero\" && Number.isFinite(Number(filtro.valor));\r\n const valor = esNumero ? filtro.valor : `'${escaparTexto(filtro.valor)}'`;\r\n return `${filtro.campo} ${filtro.operador} ${valor}`;\r\n}\r\n","import type SpatialReference from \"@arcgis/core/geometry/SpatialReference\";\r\nimport type FeatureLayer from \"@arcgis/core/layers/FeatureLayer\";\r\nimport type { FieldType } from \"@arcgis/core/layers/support/types\";\r\nimport esriRequest from \"@arcgis/core/request\";\r\nimport { executeForExtent, executeQueryJSON } from \"@arcgis/core/rest/query\";\r\nimport type {\r\n CampoConsulta,\r\n FiltroConsulta,\r\n ParametrosConsulta,\r\n ResultadoConsultaCapa,\r\n TipoCampoConsulta,\r\n ValoresDistintosCampo,\r\n} from \"@/features/maps/types\";\r\nimport { armarFiltro } from \"./consulta.constantes\";\r\n\r\n/** Tipos de campo de la JS API que no son datos consultables por el usuario. */\r\nconst TIPOS_EXCLUIDOS: ReadonlySet<FieldType> = new Set([\r\n \"oid\",\r\n \"geometry\",\r\n \"global-id\",\r\n]);\r\n\r\n/** Campo crudo de la respuesta REST `?f=json` de un MapServer/sublayer. */\r\ninterface CampoRest {\r\n name: string;\r\n alias?: string;\r\n type: string;\r\n}\r\n\r\n/** Tipos REST (`esriFieldType*`) que no son datos consultables por el usuario. */\r\nconst TIPOS_REST_EXCLUIDOS: ReadonlySet<string> = new Set([\r\n \"esriFieldTypeOID\",\r\n \"esriFieldTypeGeometry\",\r\n \"esriFieldTypeGlobalID\",\r\n]);\r\n\r\n/** Mapea el tipo de campo de la JS API al tipo general de `CampoConsulta`. */\r\nfunction tipoDesdeJsApi(tipo: FieldType): TipoCampoConsulta {\r\n switch (tipo) {\r\n case \"string\":\r\n case \"guid\":\r\n case \"xml\":\r\n return \"texto\";\r\n case \"small-integer\":\r\n case \"integer\":\r\n case \"single\":\r\n case \"double\":\r\n case \"long\":\r\n case \"big-integer\":\r\n return \"numero\";\r\n case \"date\":\r\n case \"date-only\":\r\n case \"time-only\":\r\n case \"timestamp-offset\":\r\n return \"fecha\";\r\n default:\r\n return \"otro\";\r\n }\r\n}\r\n\r\n/** Mapea el tipo de campo REST (`esriFieldType*`) al tipo general de `CampoConsulta`. */\r\nfunction tipoDesdeRest(tipo: string): TipoCampoConsulta {\r\n switch (tipo) {\r\n case \"esriFieldTypeString\":\r\n case \"esriFieldTypeGUID\":\r\n case \"esriFieldTypeXML\":\r\n return \"texto\";\r\n case \"esriFieldTypeSmallInteger\":\r\n case \"esriFieldTypeInteger\":\r\n case \"esriFieldTypeSingle\":\r\n case \"esriFieldTypeDouble\":\r\n case \"esriFieldTypeBigInteger\":\r\n return \"numero\";\r\n case \"esriFieldTypeDate\":\r\n return \"fecha\";\r\n default:\r\n return \"otro\";\r\n }\r\n}\r\n\r\n/**\r\n * Traduce el filtro a un `where` de ArcGIS REST: `LIKE` usa `UPPER(...) LIKE UPPER(...)`\r\n * y los demás comillan el valor si el campo no es numérico.\r\n */\r\nexport function armarWhereArcgis(\r\n filtro: FiltroConsulta,\r\n campos: readonly CampoConsulta[],\r\n): string {\r\n return armarFiltro(\r\n filtro,\r\n campos,\r\n (campo, valor) => `UPPER(${campo}) LIKE UPPER('%${valor}%')`,\r\n );\r\n}\r\n\r\n/** Campos consultables de una `FeatureLayer` individual (`ARCGIS_FEATURE`). */\r\nexport async function camposArcgisFeature(\r\n capa: FeatureLayer,\r\n): Promise<CampoConsulta[]> {\r\n await capa.load();\r\n return capa.fields\r\n .filter((campo) => !TIPOS_EXCLUIDOS.has(campo.type))\r\n .map((campo) => ({\r\n nombre: campo.name,\r\n alias: campo.alias || campo.name,\r\n tipo: tipoDesdeJsApi(campo.type),\r\n }));\r\n}\r\n\r\n/** Campos consultables de una subcapa de `MapImageLayer`, vía su metadata REST. */\r\nexport async function camposArcgisRest(\r\n url: string,\r\n token?: string,\r\n): Promise<CampoConsulta[]> {\r\n const { data } = await esriRequest(url, {\r\n query: { f: \"json\", ...(token ? { token } : {}) },\r\n });\r\n const campos = (data as { fields?: CampoRest[] }).fields ?? [];\r\n return campos\r\n .filter((campo) => !TIPOS_REST_EXCLUIDOS.has(campo.type))\r\n .map((campo) => ({\r\n nombre: campo.name,\r\n alias: campo.alias || campo.name,\r\n tipo: tipoDesdeRest(campo.type),\r\n }));\r\n}\r\n\r\n/** Valores distintos de un campo (combo buscable de \"Valores\"), acotados a `topeValoresConsulta`. */\r\nexport async function valoresDistintosArcgis(\r\n url: string,\r\n campo: string,\r\n parametros: ParametrosConsulta,\r\n token?: string,\r\n): Promise<ValoresDistintosCampo> {\r\n const { topeValoresConsulta } = parametros;\r\n const conjunto = await executeQueryJSON(\r\n url,\r\n {\r\n where: \"1=1\",\r\n outFields: [campo],\r\n returnGeometry: false,\r\n returnDistinctValues: true,\r\n orderByFields: [campo],\r\n num: topeValoresConsulta,\r\n },\r\n token ? { query: { token } } : undefined,\r\n );\r\n\r\n const valores = conjunto.features\r\n .map((feature) => feature.attributes?.[campo])\r\n .filter((valor): valor is string | number => valor !== null && valor !== undefined)\r\n .map((valor) => String(valor));\r\n\r\n // Truncado si se llegó al tope que nosotros pedimos (`num`) -pudo haber más\r\n // sin pedirlos- o si el servidor señala que además él mismo cortó por su\r\n // propio límite de transferencia.\r\n return {\r\n valores,\r\n truncado: valores.length >= topeValoresConsulta || conjunto.exceededTransferLimit === true,\r\n };\r\n}\r\n\r\n/** Resultado crudo de una consulta ArcGIS; `total` son las entidades devueltas. */\r\nexport type ResultadoConsultaArcgis = Omit<\r\n ResultadoConsultaCapa,\r\n \"campos\" | \"filasDevueltas\"\r\n> & { total: number };\r\n\r\n/** Ejecuta la consulta por atributos y resuelve, en paralelo, su extensión real. */\r\nexport async function ejecutarConsultaArcgis(\r\n url: string,\r\n where: string,\r\n parametros: ParametrosConsulta,\r\n outSpatialReference?: SpatialReference,\r\n token?: string,\r\n): Promise<ResultadoConsultaArcgis> {\r\n const { topeFilasConsulta } = parametros;\r\n const requestOptions = token ? { query: { token } } : undefined;\r\n\r\n const [conjunto, { extent }] = await Promise.all([\r\n executeQueryJSON(\r\n url,\r\n {\r\n where,\r\n outFields: [\"*\"],\r\n returnGeometry: true,\r\n outSpatialReference,\r\n num: topeFilasConsulta,\r\n },\r\n requestOptions,\r\n ),\r\n executeForExtent(url, { where, outSpatialReference }, requestOptions),\r\n ]);\r\n\r\n // Truncado si se llegó al tope pedido o si el servidor avisa su propio límite.\r\n return {\r\n graficos: conjunto.features,\r\n extent,\r\n total: conjunto.features.length,\r\n incompleto:\r\n conjunto.features.length >= topeFilasConsulta || conjunto.exceededTransferLimit === true,\r\n };\r\n}\r\n","/** Utilidades de GeoServer/WFS compartidas por la descarga y la consulta de capas. */\n\n/** Versión de WFS con la que se habla siempre con GeoServer. */\nconst VERSION_WFS = \"2.0.0\";\n\n/** Endpoint WFS de un servicio: `.../wms` pasa a `.../ows` (despachador genérico); lo demás no se toca. */\nexport function endpointWfsDe(urlServicio: string): string {\n const base = urlServicio.split(\"?\")[0].replace(/\\/+$/, \"\");\n return /\\/wms$/i.test(base) ? base.replace(/\\/wms$/i, \"/ows\") : base;\n}\n\n/** Parámetros comunes de una petición WFS (versión, protocolo y token) más su `complemento`. */\nexport function parametrosWfs(\n complemento: Record<string, unknown>,\n token?: string,\n): Record<string, unknown> {\n return {\n service: \"WFS\",\n version: VERSION_WFS,\n ...complemento,\n ...(token ? { token } : {}),\n };\n}\n","/** Elementos descendientes por nombre local, tolere o no el parser el namespace. */\r\nexport function descendientes(\r\n contexto: Document | Element,\r\n etiqueta: string,\r\n): Element[] {\r\n const conNs = contexto.getElementsByTagNameNS(\"*\", etiqueta);\r\n /* istanbul ignore next -- el entorno de pruebas no resuelve NS; el navegador sí */\r\n const encontrados = conNs.length ? conNs : contexto.getElementsByTagName(etiqueta);\r\n return Array.from(encontrados);\r\n}\r\n\r\n/** Nombre local sin el prefijo de workspace (`movi:torre` → `torre`). */\r\nexport function sinPrefijo(valor: string): string {\r\n /* istanbul ignore next -- `split(\":\").pop()` siempre devuelve una cadena */\r\n return valor.split(\":\").pop() ?? valor;\r\n}\r\n","import Extent from \"@arcgis/core/geometry/Extent\";\r\nimport type { MultipointProperties } from \"@arcgis/core/geometry/Multipoint\";\r\nimport type { PointProperties } from \"@arcgis/core/geometry/Point\";\r\nimport type { PolygonProperties } from \"@arcgis/core/geometry/Polygon\";\r\nimport type { PolylineProperties } from \"@arcgis/core/geometry/Polyline\";\r\nimport Graphic from \"@arcgis/core/Graphic\";\r\nimport esriRequest from \"@arcgis/core/request\";\r\nimport type {\r\n CampoConsulta,\r\n FiltroConsulta,\r\n ParametrosConsulta,\r\n ResultadoConsultaCapa,\r\n ServicioGis,\r\n TipoCampoConsulta,\r\n ValoresDistintosCampo,\r\n} from \"@/features/maps/types\";\r\nimport { armarFiltro } from \"./consulta.constantes\";\r\nimport { endpointWfsDe, parametrosWfs } from \"./geoserver\";\r\nimport { descendientes, sinPrefijo } from \"./xml-utils\";\r\n\r\n/** Unión de geometrías GeoJSON que este módulo sabe convertir a `Graphic`. */\r\ntype GeometriaGraphic =\r\n | (PointProperties & { type: \"point\" })\r\n | (MultipointProperties & { type: \"multipoint\" })\r\n | (PolylineProperties & { type: \"polyline\" })\r\n | (PolygonProperties & { type: \"polygon\" });\r\n\r\n/** WFS/GeoJSON siempre se pide en WGS84: `View.goTo`/render reproyectan sobre la marcha. */\r\nconst WKID_SALIDA_WFS = 4326;\r\n\r\n/** Elemento `<xsd:element name=\"...\" type=\"...\">` de un `DescribeFeatureType`. */\r\ninterface ElementoXsd {\r\n nombre: string;\r\n tipo: string;\r\n}\r\n\r\n/** Tipos XSD que representan geometría (GML), no un dato consultable por el usuario. */\r\nfunction esTipoGeometria(tipoSinPrefijo: string): boolean {\r\n return (\r\n tipoSinPrefijo.endsWith(\"PropertyType\") ||\r\n [\"PointType\", \"LineStringType\", \"PolygonType\", \"GeometryType\"].includes(\r\n tipoSinPrefijo,\r\n )\r\n );\r\n}\r\n\r\n/** Mapea el tipo XSD (`xsd:*`) al tipo general de `CampoConsulta`. */\r\nfunction tipoDesdeXsd(tipoSinPrefijo: string): TipoCampoConsulta {\r\n switch (tipoSinPrefijo) {\r\n case \"string\":\r\n case \"anyURI\":\r\n return \"texto\";\r\n case \"int\":\r\n case \"integer\":\r\n case \"short\":\r\n case \"long\":\r\n case \"decimal\":\r\n case \"double\":\r\n case \"float\":\r\n case \"positiveInteger\":\r\n case \"nonNegativeInteger\":\r\n return \"numero\";\r\n case \"date\":\r\n case \"dateTime\":\r\n case \"time\":\r\n return \"fecha\";\r\n default:\r\n return \"otro\";\r\n }\r\n}\r\n\r\n/**\r\n * Traduce el filtro a `CQL_FILTER`: `LIKE` usa `ILIKE` (sin distinguir mayúsculas);\r\n * los demás comillan el valor si el campo no es numérico.\r\n */\r\nexport function armarCqlGeoserver(\r\n filtro: FiltroConsulta,\r\n campos: readonly CampoConsulta[],\r\n): string {\r\n return armarFiltro(\r\n filtro,\r\n campos,\r\n (campo, valor) => `${campo} ILIKE '%${valor}%'`,\r\n );\r\n}\r\n\r\n/** Campos consultables de una capa WFS vía `DescribeFeatureType` (GeoServer WFS 2.0). */\r\nexport async function describeFeatureTypeWfs(\r\n servicio: ServicioGis,\r\n identificador: string,\r\n): Promise<CampoConsulta[]> {\r\n const { data } = await esriRequest(endpointWfsDe(servicio.url), {\r\n responseType: \"text\",\r\n query: parametrosWfs(\r\n { request: \"DescribeFeatureType\", typeNames: identificador },\r\n servicio.token,\r\n ),\r\n });\r\n const doc = new DOMParser().parseFromString(String(data), \"text/xml\");\r\n\r\n const elementos: ElementoXsd[] = descendientes(doc, \"element\")\r\n .map((el) => ({\r\n nombre: el.getAttribute(\"name\") ?? \"\",\r\n tipo: el.getAttribute(\"type\") ?? \"\",\r\n }))\r\n .filter((el) => el.nombre !== \"\" && el.tipo !== \"\");\r\n\r\n return elementos\r\n .filter((el) => !esTipoGeometria(sinPrefijo(el.tipo)))\r\n .map((el) => ({\r\n nombre: el.nombre,\r\n alias: el.nombre,\r\n tipo: tipoDesdeXsd(sinPrefijo(el.tipo)),\r\n }));\r\n}\r\n\r\n/** Colección GeoJSON que devuelve GeoServer para `GetFeature`. */\r\ninterface ColeccionGeoJsonWfs {\r\n type: \"FeatureCollection\";\r\n features: readonly {\r\n type: \"Feature\";\r\n geometry?: { type: string; coordinates: unknown } | null;\r\n properties?: Record<string, unknown>;\r\n }[];\r\n numberMatched?: number;\r\n totalFeatures?: number;\r\n}\r\n\r\n/**\r\n * Valores distintos de un campo vía `GetFeature` sin geometría, deduplicados en\r\n * cliente (WFS no tiene `DISTINCT`); pueden quedar incompletos si se trunca.\r\n * Se piden `topeCrudoValoresWfs` entidades y se muestran hasta `topeValoresConsulta`.\r\n */\r\nexport async function valoresDistintosWfs(\r\n servicio: ServicioGis,\r\n identificador: string,\r\n campo: string,\r\n parametros: ParametrosConsulta,\r\n): Promise<ValoresDistintosCampo> {\r\n const { topeCrudoValoresWfs, topeValoresConsulta } = parametros;\r\n const { data } = await esriRequest(endpointWfsDe(servicio.url), {\r\n responseType: \"json\",\r\n query: parametrosWfs(\r\n {\r\n request: \"GetFeature\",\r\n typeNames: identificador,\r\n outputFormat: \"application/json\",\r\n propertyName: campo,\r\n count: topeCrudoValoresWfs,\r\n },\r\n servicio.token,\r\n ),\r\n });\r\n const geojson = data as ColeccionGeoJsonWfs;\r\n const crudos = geojson.features\r\n .map((feature) => feature.properties?.[campo])\r\n .filter((valor): valor is string | number => valor !== null && valor !== undefined);\r\n\r\n const distintos = [...new Set(crudos.map((valor) => String(valor)))].sort();\r\n const truncadoPorTopeCrudo = geojson.features.length >= topeCrudoValoresWfs;\r\n const valores = distintos.slice(0, topeValoresConsulta);\r\n\r\n return {\r\n valores,\r\n truncado: truncadoPorTopeCrudo || distintos.length > topeValoresConsulta,\r\n };\r\n}\r\n\r\n/** Recorre recursivamente un array de coordenadas GeoJSON (a cualquier nivel de anidado). */\r\nfunction recorrerCoordenadas(valor: unknown, visitar: (x: number, y: number) => void): void {\r\n if (!Array.isArray(valor)) return;\r\n if (typeof valor[0] === \"number\" && typeof valor[1] === \"number\") {\r\n visitar(valor[0], valor[1]);\r\n return;\r\n }\r\n for (const item of valor) recorrerCoordenadas(item, visitar);\r\n}\r\n\r\n/** Convierte una geometría GeoJSON a su equivalente autocasteable por `Graphic`. */\r\nfunction geometriaDesdeGeoJson(\r\n geometria: { type: string; coordinates: unknown },\r\n wkid: number,\r\n): GeometriaGraphic | null {\r\n const spatialReference = { wkid };\r\n switch (geometria.type) {\r\n case \"Point\": {\r\n const [x, y] = geometria.coordinates as [number, number];\r\n return { type: \"point\", x, y, spatialReference };\r\n }\r\n case \"MultiPoint\":\r\n return {\r\n type: \"multipoint\",\r\n points: geometria.coordinates as [number, number][],\r\n spatialReference,\r\n };\r\n case \"LineString\":\r\n return {\r\n type: \"polyline\",\r\n paths: [geometria.coordinates as [number, number][]],\r\n spatialReference,\r\n };\r\n case \"MultiLineString\":\r\n return {\r\n type: \"polyline\",\r\n paths: geometria.coordinates as [number, number][][],\r\n spatialReference,\r\n };\r\n case \"Polygon\":\r\n return {\r\n type: \"polygon\",\r\n rings: geometria.coordinates as [number, number][][],\r\n spatialReference,\r\n };\r\n case \"MultiPolygon\":\r\n return {\r\n type: \"polygon\",\r\n rings: (geometria.coordinates as [number, number][][][]).flat(1),\r\n spatialReference,\r\n };\r\n default:\r\n return null;\r\n }\r\n}\r\n\r\n/** Convierte una `Feature` GeoJSON de GeoServer a un `Graphic` de ArcGIS. */\r\nfunction graficoDesdeGeoJson(\r\n feature: ColeccionGeoJsonWfs[\"features\"][number],\r\n wkid: number,\r\n): Graphic {\r\n const geometry = feature.geometry ? geometriaDesdeGeoJson(feature.geometry, wkid) : null;\r\n return new Graphic({\r\n ...(geometry ? { geometry } : {}),\r\n attributes: feature.properties ?? {},\r\n });\r\n}\r\n\r\n/** Extensión (en `wkid`) de todas las geometrías de una colección GeoJSON, calculada en cliente. */\r\nfunction extentDeFeaturesGeoJson(\r\n features: ColeccionGeoJsonWfs[\"features\"],\r\n wkid: number,\r\n): Extent | null {\r\n let xmin = Infinity;\r\n let ymin = Infinity;\r\n let xmax = -Infinity;\r\n let ymax = -Infinity;\r\n let alguno = false;\r\n\r\n for (const feature of features) {\r\n if (!feature.geometry) continue;\r\n recorrerCoordenadas(feature.geometry.coordinates, (x, y) => {\r\n alguno = true;\r\n if (x < xmin) xmin = x;\r\n if (x > xmax) xmax = x;\r\n if (y < ymin) ymin = y;\r\n if (y > ymax) ymax = y;\r\n });\r\n }\r\n\r\n return alguno ? new Extent({ xmin, ymin, xmax, ymax, spatialReference: { wkid } }) : null;\r\n}\r\n\r\n/** Resultado crudo de una consulta WFS; `total` son las entidades devueltas. */\r\nexport type ResultadoConsultaWfs = Omit<\r\n ResultadoConsultaCapa,\r\n \"campos\" | \"filasDevueltas\"\r\n> & { total: number };\r\n\r\n/** Consulta por atributos vía `GetFeature` con `CQL_FILTER`; la salida va en WGS84. */\r\nexport async function ejecutarConsultaWfs(\r\n servicio: ServicioGis,\r\n identificador: string,\r\n cqlFilter: string,\r\n parametros: ParametrosConsulta,\r\n): Promise<ResultadoConsultaWfs> {\r\n const { topeFilasConsulta } = parametros;\r\n const { data } = await esriRequest(endpointWfsDe(servicio.url), {\r\n responseType: \"json\",\r\n query: parametrosWfs(\r\n {\r\n request: \"GetFeature\",\r\n typeNames: identificador,\r\n outputFormat: \"application/json\",\r\n srsName: `EPSG:${WKID_SALIDA_WFS}`,\r\n CQL_FILTER: cqlFilter,\r\n count: topeFilasConsulta,\r\n },\r\n servicio.token,\r\n ),\r\n });\r\n const geojson = data as ColeccionGeoJsonWfs;\r\n const total = geojson.features.length;\r\n const declarado = geojson.numberMatched ?? geojson.totalFeatures;\r\n\r\n return {\r\n graficos: geojson.features.map((feature) => graficoDesdeGeoJson(feature, WKID_SALIDA_WFS)),\r\n extent: extentDeFeaturesGeoJson(geojson.features, WKID_SALIDA_WFS),\r\n total,\r\n incompleto: declarado !== undefined ? declarado > total : total >= topeFilasConsulta,\r\n };\r\n}\r\n","/** Recorta una URL a origin + pathname para loguearla sin credenciales; si no es URL, la deja igual. */\r\nexport function urlSinQuery(url: string): string {\r\n try {\r\n const { origin, pathname } = new URL(url);\r\n return `${origin}${pathname}`;\r\n } catch {\r\n return \"[URL no válida]\";\r\n }\r\n}\r\n","import type Extent from \"@arcgis/core/geometry/Extent\";\nimport esriRequest from \"@arcgis/core/request\";\nimport type { ParametrosDescarga, ServicioGis } from \"@/features/maps/types\";\nimport { webMercatorToGeographic } from \"@arcgis/core/geometry/support/webMercatorUtils\";\nimport { formatearDuracion } from \"@/shared/helpers/formato-duracion\";\nimport { endpointWfsDe, parametrosWfs } from \"./geoserver\";\nimport { urlSinQuery } from \"./url-sin-query\";\n\n// Los límites y tiempos de la descarga (`ParametrosDescarga`) vienen de BD vía\n// `obtenerParametrosDescarga`; aquí solo quedan detalles del protocolo.\n// ArcGIS REST recorta cada respuesta a su `maxRecordCount`: se pagina con `resultOffset`.\n// WFS no pagina (manda todo de una vez): se avisa con un conteo y se limita el tiempo.\n\n/** Vueltas extra del cinturón de seguridad, más allá del límite natural de iteraciones. */\nconst MARGEN_ITERACIONES_PAGINACION = 10;\n\n/** Colección GeoJSON mínima que produce este módulo. */\nexport interface ColeccionGeoJson {\n readonly type: \"FeatureCollection\";\n readonly features: readonly Record<string, unknown>[];\n readonly [clave: string]: unknown;\n}\n\n/** Resultado de descargar una capa: el GeoJSON y si se recortó por el límite. */\nexport interface ResultadoDescargaCapa {\n readonly geojson: ColeccionGeoJson;\n readonly incompleta: boolean;\n}\n\n/** El servicio no admite descargar sus datos (p. ej. WMS sin WFS habilitado). */\nexport class DescargaNoSoportadaError extends Error {}\n\n/** La descarga WFS superó `tiempoEsperaDescargaWfsMs` y se canceló. */\nexport class DescargaDemasiadoLentaError extends Error {\n /** Tope de espera que se superó (ms), para informarlo al usuario. */\n readonly tiempoMaximoMs: number;\n\n constructor(mensaje: string, tiempoMaximoMs: number) {\n super(mensaje);\n this.tiempoMaximoMs = tiempoMaximoMs;\n }\n}\n\n/** Falló la descarga WFS y el conteo supera el umbral: probablemente fue rechazada por pesada. */\nexport class DescargaMuyPesadaError extends Error {}\n\n/** El usuario no confirmó tras el aviso de descarga grande y se abortó la descarga WFS. */\nexport class DescargaCanceladaError extends Error {}\n\n/** Recorta a `limite` entidades y marca si sobraban. */\nfunction acotar(geojson: ColeccionGeoJson, limite: number): ResultadoDescargaCapa {\n const incompleta = geojson.features.length > limite;\n return {\n geojson: incompleta\n ? { ...geojson, features: geojson.features.slice(0, limite) }\n : geojson,\n incompleta,\n };\n}\n\n/** Envoltura del extent como envelope JSON para el parámetro `geometry` de ArcGIS REST. */\nfunction envelopeDe(extent: Extent): string {\n return JSON.stringify({\n xmin: extent.xmin,\n ymin: extent.ymin,\n xmax: extent.xmax,\n ymax: extent.ymax,\n spatialReference: { wkid: extent.spatialReference.wkid },\n });\n}\n\n/** Pide una sola página de entidades a `<urlBase>/query`, desde `offset`. */\nasync function pedirPagina(\n urlBase: string,\n extent: Extent,\n offset: number,\n tamano: number,\n timeoutMs: number,\n token?: string,\n): Promise<ColeccionGeoJson> {\n const { data } = await esriRequest(`${urlBase}/query`, {\n responseType: \"json\",\n timeout: timeoutMs,\n query: {\n f: \"geojson\",\n geometry: envelopeDe(extent),\n geometryType: \"esriGeometryEnvelope\",\n inSR: extent.spatialReference.wkid,\n spatialRel: \"esriSpatialRelIntersects\",\n outFields: \"*\",\n returnGeometry: true,\n resultRecordCount: tamano,\n resultOffset: offset,\n ...(token ? { token } : {}),\n },\n });\n return data as ColeccionGeoJson;\n}\n\n/** Resultado de una página, o `\"agotado\"` si el backoff no pudo obtenerla. */\ntype ResultadoPagina = { pagina: ColeccionGeoJson; tamanoUsado: number } | \"agotado\";\n\n/**\n * Pide una página con reintentos; si fallan, achica el tamaño a la mitad (piso\n * `tamanoPaginaMinimoDescarga`). En el piso devuelve `\"agotado\"` en vez de lanzar.\n */\nasync function pedirPaginaConBackoff(\n urlBase: string,\n extent: Extent,\n offset: number,\n tamanoInicial: number,\n parametros: ParametrosDescarga,\n token?: string,\n): Promise<ResultadoPagina> {\n const { reintentosPaginaDescarga, tamanoPaginaMinimoDescarga, timeoutPaginaDescargaMs } =\n parametros;\n let tamano = tamanoInicial;\n for (;;) {\n for (let intento = 0; intento <= reintentosPaginaDescarga; intento++) {\n try {\n const pagina = await pedirPagina(\n urlBase,\n extent,\n offset,\n tamano,\n timeoutPaginaDescargaMs,\n token,\n );\n return { pagina, tamanoUsado: tamano };\n } catch (error: unknown) {\n console.warn(\n `Página ArcGIS REST falló (offset=${offset}, tamaño=${tamano}, intento ${intento + 1}).`,\n error,\n );\n }\n }\n if (tamano <= tamanoPaginaMinimoDescarga) return \"agotado\";\n tamano = Math.max(tamanoPaginaMinimoDescarga, Math.floor(tamano / 2));\n }\n}\n\n/**\n * Descarga por `query` REST (ArcGIS) los elementos dentro de `extent` en GeoJSON\n * (WGS84). Sirve para `FeatureLayer` y subcapas de `MapImageLayer`. Pagina con\n * `resultOffset` avanzando según lo recibido, no lo pedido, para no dejar huecos.\n */\nexport async function descargarCapaArcgisRest(\n url: string,\n extent: Extent,\n parametros: ParametrosDescarga,\n token?: string,\n): Promise<ResultadoDescargaCapa> {\n const { limiteGeoJson, tamanoPaginaMinimoDescarga, tiempoMaximoDescargaMs } = parametros;\n const urlBase = url.replace(/\\/+$/, \"\");\n const features: Record<string, unknown>[] = [];\n let ultimaPagina: ColeccionGeoJson = { type: \"FeatureCollection\", features: [] };\n let offset = 0;\n let tamanoPagina = parametros.tamanoPaginaDescarga;\n // Cinturón de seguridad redundante, más allá del límite natural de iteraciones.\n const maxIteraciones =\n Math.ceil(limiteGeoJson / tamanoPaginaMinimoDescarga) + MARGEN_ITERACIONES_PAGINACION;\n // Corte antes del fin de los datos: se fuerza `incompleta` (acotar() no siempre lo ve).\n let seDetuvoAMitadDeCamino = false;\n const inicio = Date.now();\n\n for (let i = 0; i < maxIteraciones; i++) {\n if (features.length >= limiteGeoJson) {\n seDetuvoAMitadDeCamino = true;\n break;\n }\n // Tope de tiempo total: en el peor caso el backoff podría tardar horas.\n if (Date.now() - inicio >= tiempoMaximoDescargaMs) {\n seDetuvoAMitadDeCamino = true;\n break;\n }\n\n const resultado = await pedirPaginaConBackoff(\n urlBase,\n extent,\n offset,\n tamanoPagina,\n parametros,\n token,\n );\n if (resultado === \"agotado\") {\n seDetuvoAMitadDeCamino = true;\n break;\n }\n\n const { pagina, tamanoUsado } = resultado;\n tamanoPagina = tamanoUsado;\n ultimaPagina = pagina;\n\n // Una página corta no implica la última (el servidor recorta): solo una vacía es el fin.\n const nuevas = pagina.features ?? [];\n features.push(...nuevas);\n if (nuevas.length === 0) break;\n offset += nuevas.length;\n }\n\n const resultado = acotar({ ...ultimaPagina, features }, limiteGeoJson);\n return seDetuvoAMitadDeCamino ? { ...resultado, incompleta: true } : resultado;\n}\n\n/** Query `GetFeature` común a la descarga real y al conteo previo (`resultType=hits`). */\nfunction construirQueryWfs(\n identificador: string,\n wkid: number,\n geoExtent: Extent,\n token?: string,\n): Record<string, unknown> {\n return parametrosWfs(\n {\n request: \"GetFeature\",\n typeNames: identificador,\n outputFormat: \"application/json\",\n srsName: `EPSG:${wkid}`,\n bbox: `${geoExtent.xmin},${geoExtent.ymin},${geoExtent.xmax},${geoExtent.ymax},EPSG:${wkid}`,\n },\n token,\n );\n}\n\n/**\n * Extrae el conteo de un `resultType=hits` buscándolo como texto: GeoServer\n * puede responder en JSON o en XML aunque se pida JSON.\n */\nfunction extraerConteoWfs(texto: string): number | undefined {\n const coincidencia =\n /\"(?:numberMatched|totalFeatures)\"\\s*:\\s*(\\d+)/.exec(texto) ??\n /(?:numberMatched|totalFeatures)=\"(\\d+)\"/.exec(texto);\n return coincidencia ? Number(coincidencia[1]) : undefined;\n}\n\n/** Cuenta las entidades de la zona (WFS `resultType=hits`). Ante fallas resuelve `undefined`. */\nasync function contarEntidadesWfs(\n url: string,\n query: Record<string, unknown>,\n timeoutMs: number,\n): Promise<number | undefined> {\n try {\n // Como texto: `hits` suele venir en XML y pedirlo como JSON rompería el parseo.\n const { data } = await esriRequest(url, {\n responseType: \"text\",\n timeout: timeoutMs,\n query: { ...query, resultType: \"hits\" },\n });\n return extraerConteoWfs(String(data));\n } catch {\n return undefined;\n }\n}\n\n/**\n * Descarga por WFS `GetFeature` (GeoServer) los elementos dentro de `extent`.\n * En paralelo cuenta las entidades y, si superan `umbralAvisoDescargaWfs`,\n * pregunta vía `onDescargaGrande` si continuar. Errores:\n * - `DescargaCanceladaError`: el usuario no quiso continuar.\n * - `DescargaDemasiadoLentaError`: se superó `tiempoEsperaDescargaWfsMs`.\n * - `DescargaMuyPesadaError`: falló y el conteo supera el umbral.\n * - `DescargaNoSoportadaError`: cualquier otra falla (p. ej. WMS sin WFS).\n */\nexport async function descargarCapaWfs(\n servicio: ServicioGis,\n identificador: string,\n extent: Extent,\n parametros: ParametrosDescarga,\n /** Se llama si el conteo supera el umbral; resuelve si continuar (sin manejador, sí). */\n onDescargaGrande?: (cantidad: number) => Promise<boolean>,\n): Promise<ResultadoDescargaCapa> {\n const { umbralAvisoDescargaWfs, tiempoEsperaDescargaWfsMs } = parametros;\n const url = endpointWfsDe(servicio.url);\n\n // GeoServer no reconoce EPSG:102100; se mapea al wkid configurado en BD.\n const wkid = (extent.spatialReference.wkid === 102100 || !extent.spatialReference.wkid)\n ? parametros.wkid\n : extent.spatialReference.wkid;\n\n // Proyecta el extent de Web Mercator (metros) a EPSG:4326 (grados)\n const geoExtent = (\n extent.spatialReference?.isWebMercator\n ? webMercatorToGeographic(extent)\n : extent\n ) as Extent;\n\n const query = construirQueryWfs(identificador, wkid, geoExtent, servicio.token);\n\n const controlador = new AbortController();\n // Distingue la cancelación del usuario del abort por tiempo.\n let canceladaPorUsuario = false;\n\n // Se guarda la promesa para reusar el conteo en el catch.\n const promesaConteo = contarEntidadesWfs(url, query, parametros.tiempoEsperaConteoWfsMs);\n void promesaConteo.then(async (cantidad) => {\n if (cantidad === undefined || cantidad <= umbralAvisoDescargaWfs) return;\n const continuar = (await onDescargaGrande?.(cantidad)) ?? true;\n if (!continuar) {\n canceladaPorUsuario = true;\n controlador.abort();\n }\n });\n\n const temporizador = setTimeout(() => controlador.abort(), tiempoEsperaDescargaWfsMs);\n try {\n const { data } = await esriRequest(url, {\n responseType: \"json\",\n signal: controlador.signal,\n query,\n });\n const geojson = data as ColeccionGeoJson;\n if (geojson?.type !== \"FeatureCollection\" || !Array.isArray(geojson.features)) {\n throw new Error(\"Respuesta WFS sin FeatureCollection.\");\n }\n return acotar(geojson, parametros.limiteGeoJson);\n } catch (error: unknown) {\n if (canceladaPorUsuario) {\n throw new DescargaCanceladaError(\n `La descarga de \"${identificador}\" se canceló: el usuario no confirmó tras el aviso de descarga grande.`,\n );\n }\n if (controlador.signal.aborted) {\n throw new DescargaDemasiadoLentaError(\n `La descarga de \"${identificador}\" superó el tiempo máximo de espera ` +\n `(${formatearDuracion(tiempoEsperaDescargaWfsMs)}).`,\n tiempoEsperaDescargaWfsMs,\n );\n }\n console.warn(\n `WFS GetFeature falló en \"${servicio.nombre}\" (${urlSinQuery(url)}) para \"${identificador}\".`,\n error,\n );\n const cantidad = await promesaConteo;\n if (cantidad !== undefined && cantidad > umbralAvisoDescargaWfs) {\n throw new DescargaMuyPesadaError(\n `La descarga de \"${identificador}\" tiene ${cantidad} elementos y no se ` +\n \"pudo completar; probablemente el servidor la rechazó por pesada.\",\n { cause: error },\n );\n }\n throw new DescargaNoSoportadaError(\n `El servicio \"${servicio.nombre}\" no permite descargar la capa \"${identificador}\".`,\n { cause: error },\n );\n } finally {\n clearTimeout(temporizador);\n }\n}","import type FeatureLayer from \"@arcgis/core/layers/FeatureLayer\";\r\nimport esriRequest from \"@arcgis/core/request\";\r\nimport * as symbolUtils from \"@arcgis/core/symbols/support/symbolUtils\";\r\nimport type { SymbolUnion } from \"@arcgis/core/symbols/types\";\r\nimport type { ItemLeyenda, ServicioGis } from \"@/features/maps/types\";\r\nimport { urlSinQuery } from \"./url-sin-query\";\r\n\r\n/** Un elemento de leyenda tal como lo entrega el recurso REST `/legend`. */\r\ninterface ElementoLeyendaArcgis {\r\n label?: string;\r\n contentType: string;\r\n imageData: string;\r\n}\r\n\r\n/** Respuesta del recurso REST `/legend?f=json` de un servicio de mapas ArcGIS. */\r\nexport interface RespuestaLeyendaArcgis {\r\n layers: { layerId: number; legend: ElementoLeyendaArcgis[] }[];\r\n}\r\n\r\n/**\r\n * Leyenda de un MapServer/TileServer ArcGIS vía REST `/legend`, emparejada por\r\n * `layerId` y cacheada por URL. Sin `label`, usa `etiquetaCapa`.\r\n */\r\nexport async function obtenerLeyendaMapaImagen(\r\n urlServicio: string,\r\n layerId: number,\r\n etiquetaCapa: string,\r\n token: string | undefined,\r\n cache: Map<string, Promise<RespuestaLeyendaArcgis | null>>,\r\n): Promise<ItemLeyenda[]> {\r\n const base = urlServicio.replace(/\\/+$/, \"\");\r\n let peticion = cache.get(base);\r\n if (!peticion) {\r\n peticion = esriRequest(`${base}/legend`, {\r\n query: { f: \"json\", ...(token ? { token } : {}) },\r\n })\r\n .then(({ data }) => data as RespuestaLeyendaArcgis)\r\n .catch((error: unknown) => {\r\n console.warn(`No fue posible leer la leyenda de \"${urlSinQuery(base)}\".`, error);\r\n return null;\r\n });\r\n cache.set(base, peticion);\r\n }\r\n\r\n const respuesta = await peticion;\r\n const capa = respuesta?.layers.find((item) => item.layerId === layerId);\r\n return (capa?.legend ?? []).map((item) => ({\r\n tipo: \"imagen\" as const,\r\n etiqueta: item.label || etiquetaCapa,\r\n src: `data:${item.contentType};base64,${item.imageData}`,\r\n }));\r\n}\r\n\r\n/** Entrada {símbolo, etiqueta} homogénea, sin importar el tipo de renderer. */\r\ninterface EntradaSimbolo {\r\n etiqueta: string;\r\n symbol: SymbolUnion | null | undefined;\r\n}\r\n\r\n/** Entradas del renderer de una FeatureLayer ya cargada, según su tipo. */\r\nfunction entradasDelRenderer(capa: FeatureLayer): EntradaSimbolo[] {\r\n const renderer = capa.renderer;\r\n if (!renderer) return [];\r\n\r\n switch (renderer.type) {\r\n case \"simple\":\r\n return [\r\n { etiqueta: renderer.label || capa.title || \"\", symbol: renderer.symbol },\r\n ];\r\n\r\n case \"unique-value\": {\r\n const entradas = (renderer.uniqueValueInfos ?? []).map((info) => ({\r\n etiqueta: info.label || String(info.value),\r\n symbol: info.symbol,\r\n }));\r\n if (renderer.defaultSymbol) {\r\n entradas.push({\r\n etiqueta: renderer.defaultLabel || \"Otros\",\r\n symbol: renderer.defaultSymbol,\r\n });\r\n }\r\n return entradas;\r\n }\r\n\r\n case \"class-breaks\":\r\n return (renderer.classBreakInfos ?? []).map((info) => ({\r\n etiqueta: info.label || `${info.minValue} - ${info.maxValue}`,\r\n symbol: info.symbol,\r\n }));\r\n\r\n default:\r\n // Heatmap, dot-density, dictionary, pie-chart: sin equivalente simple hoy.\r\n return [];\r\n }\r\n}\r\n\r\n/** Leyenda de una `FeatureLayer` a partir de su `renderer`, sin llamada de red. */\r\nexport async function obtenerLeyendaFeature(capa: FeatureLayer): Promise<ItemLeyenda[]> {\r\n await capa.load();\r\n const entradas = entradasDelRenderer(capa);\r\n\r\n const items = await Promise.all(\r\n entradas.map(async (entrada): Promise<ItemLeyenda | null> => {\r\n if (!entrada.symbol) return null;\r\n const elemento = await symbolUtils.renderPreviewHTML(entrada.symbol, { size: 16 });\r\n if (!elemento) return null;\r\n return { tipo: \"simbolo\", etiqueta: entrada.etiqueta, elemento };\r\n }),\r\n );\r\n\r\n return items.filter((item): item is ItemLeyenda => item !== null);\r\n}\r\n\r\n/** Versión OGC asumida cuando el servicio no declara la suya. */\r\nconst VERSION_WMS_POR_DEFECTO = \"1.3.0\";\r\n\r\n/** Leyenda WMS vía `GetLegendGraphic`: la URL va directo al `<img>`; la etiqueta es el nombre. */\r\nexport function obtenerLeyendaWms(\r\n servicio: ServicioGis,\r\n identificador: string,\r\n etiquetaCapa: string,\r\n): ItemLeyenda[] {\r\n const version =\r\n typeof servicio.configuracionServicio.version === \"string\"\r\n ? servicio.configuracionServicio.version\r\n : VERSION_WMS_POR_DEFECTO;\r\n const base = servicio.url.split(\"?\")[0];\r\n const parametros = new URLSearchParams({\r\n SERVICE: \"WMS\",\r\n REQUEST: \"GetLegendGraphic\",\r\n VERSION: version,\r\n FORMAT: \"image/png\",\r\n // Sin esto GeoServer rellena el PNG con blanco opaco (se ve como un\r\n // recuadro blanco alrededor del símbolo); ArcGIS ya entrega el swatch\r\n // con fondo transparente.\r\n TRANSPARENT: \"true\",\r\n // Evita que GeoServer dibuje el título de la regla dentro del PNG (ya va como texto).\r\n LEGEND_OPTIONS: \"forceLabels:off\",\r\n LAYER: identificador,\r\n WIDTH: \"20\",\r\n HEIGHT: \"20\",\r\n });\r\n if (servicio.token) parametros.set(\"token\", servicio.token);\r\n\r\n return [\r\n { tipo: \"imagen\", etiqueta: etiquetaCapa, src: `${base}?${parametros.toString()}` },\r\n ];\r\n}\r\n","import Extent from \"@arcgis/core/geometry/Extent\";\r\nimport type SpatialReference from \"@arcgis/core/geometry/SpatialReference\";\r\nimport type FeatureLayer from \"@arcgis/core/layers/FeatureLayer\";\r\nimport MapImageLayer from \"@arcgis/core/layers/MapImageLayer\";\r\nimport type Sublayer from \"@arcgis/core/layers/support/Sublayer\";\r\nimport WMSLayer from \"@arcgis/core/layers/WMSLayer\";\r\nimport esriRequest from \"@arcgis/core/request\";\r\nimport { executeForExtent } from \"@arcgis/core/rest/query\";\r\nimport type {\r\n CampoConsulta,\r\n FiltroConsulta,\r\n ItemLeyenda,\r\n ParametrosConsulta,\r\n ParametrosDescarga,\r\n ResultadoConsultaCapa,\r\n ServicioGis,\r\n ValoresDistintosCampo,\r\n} from \"@/features/maps/types\";\r\nimport {\r\n armarWhereArcgis,\r\n camposArcgisFeature,\r\n camposArcgisRest,\r\n ejecutarConsultaArcgis,\r\n valoresDistintosArcgis,\r\n} from \"./consulta-arcgis\";\r\nimport {\r\n armarCqlGeoserver,\r\n describeFeatureTypeWfs,\r\n ejecutarConsultaWfs,\r\n valoresDistintosWfs,\r\n} from \"./consulta-wfs\";\r\nimport {\r\n DescargaNoSoportadaError,\r\n descargarCapaArcgisRest,\r\n descargarCapaWfs,\r\n type ResultadoDescargaCapa,\r\n} from \"./descarga-capa\";\r\nimport {\r\n obtenerLeyendaFeature,\r\n obtenerLeyendaMapaImagen,\r\n obtenerLeyendaWms,\r\n type RespuestaLeyendaArcgis,\r\n} from \"./leyenda\";\r\nimport type { CapasServicioConstruidas } from \"./types\";\r\nimport { urlSinQuery } from \"./url-sin-query\";\r\nimport { descendientes, sinPrefijo } from \"./xml-utils\";\r\n\r\n/**\r\n * Cómo hablarle a una subcapa, resuelto una sola vez para todas las operaciones:\r\n * - `featureLayer`: `FeatureLayer` propia (`ARCGIS_FEATURE`).\r\n * - `restArcgis`: hoja de un `MapImageLayer`, con su `url` REST.\r\n * - `wms`: capa de GeoServer, consultada por WFS.\r\n * - `sinMecanismo`: sin consulta por atributos (`ARCGIS_TILE`, sin url o sin capa).\r\n */\r\ntype MecanismoCapa =\r\n | { tipo: \"featureLayer\"; url: string; capa: FeatureLayer }\r\n | { tipo: \"restArcgis\"; url: string }\r\n | { tipo: \"wms\" }\r\n | { tipo: \"sinMecanismo\" };\r\n\r\n/**\r\n * `<Layer>` hoja del GetCapabilities que corresponde al identificador (por `<Name>`\r\n * o `<Title>`, sin distinguir mayúsculas ni workspace). Ignora capas de grupo.\r\n */\r\nfunction capaDeCapabilities(\r\n doc: Document,\r\n identificador: string,\r\n): Element | undefined {\r\n const objetivo = identificador.trim().toLowerCase();\r\n const texto = (elemento: Element, etiqueta: string): string | undefined =>\r\n descendientes(elemento, etiqueta)[0]?.textContent?.trim().toLowerCase();\r\n\r\n const hojas = descendientes(doc, \"Layer\").filter(\r\n (elemento) => descendientes(elemento, \"Layer\").length === 0,\r\n );\r\n return (\r\n hojas.find((elemento) => {\r\n const nombre = texto(elemento, \"Name\");\r\n return (\r\n nombre === objetivo ||\r\n (nombre !== undefined && sinPrefijo(nombre) === sinPrefijo(objetivo))\r\n );\r\n }) ?? hojas.find((elemento) => texto(elemento, \"Title\") === objetivo)\r\n );\r\n}\r\n\r\n/**\r\n * Bbox de una capa según el GetCapabilities WMS: prefiere Web Mercator; si no,\r\n * el geográfico en WGS 84. `null` si no hay una extensión válida.\r\n */\r\nfunction extentDeCapabilitiesWms(\r\n doc: Document,\r\n identificador: string,\r\n outSpatialReference?: SpatialReference,\r\n): Extent | null {\r\n const capa = capaDeCapabilities(doc, identificador);\r\n if (!capa) return null;\r\n\r\n const aExtent = (\r\n limites: { xmin: number; ymin: number; xmax: number; ymax: number },\r\n wkid: number,\r\n ): Extent | null =>\r\n Object.values(limites).every(Number.isFinite)\r\n ? new Extent({ ...limites, spatialReference: { wkid } })\r\n : null;\r\n\r\n // <BoundingBox CRS=\"EPSG:3857\"> ⇒ mismos ejes que la vista, sin reproyección.\r\n const wkidVista = outSpatialReference?.wkid;\r\n if (wkidVista === 3857 || wkidVista === 102100) {\r\n const caja = descendientes(capa, \"BoundingBox\").find((elemento) => {\r\n const crs = (\r\n elemento.getAttribute(\"CRS\") ??\r\n elemento.getAttribute(\"SRS\") ??\r\n \"\"\r\n ).toUpperCase();\r\n return [\"EPSG:3857\", \"EPSG:102100\", \"EPSG:900913\"].includes(crs);\r\n });\r\n if (caja) {\r\n const extent = aExtent(\r\n {\r\n xmin: Number(caja.getAttribute(\"minx\")),\r\n ymin: Number(caja.getAttribute(\"miny\")),\r\n xmax: Number(caja.getAttribute(\"maxx\")),\r\n ymax: Number(caja.getAttribute(\"maxy\")),\r\n },\r\n wkidVista,\r\n );\r\n if (extent) return extent;\r\n }\r\n }\r\n\r\n // WMS 1.3.0: <EX_GeographicBoundingBox> con límites en lon/lat (CRS:84).\r\n const geografico = descendientes(capa, \"EX_GeographicBoundingBox\")[0];\r\n if (geografico) {\r\n const numero = (etiqueta: string): number =>\r\n Number(descendientes(geografico, etiqueta)[0]?.textContent);\r\n const extent = aExtent(\r\n {\r\n xmin: numero(\"westBoundLongitude\"),\r\n xmax: numero(\"eastBoundLongitude\"),\r\n ymin: numero(\"southBoundLatitude\"),\r\n ymax: numero(\"northBoundLatitude\"),\r\n },\r\n 4326,\r\n );\r\n if (extent) return extent;\r\n }\r\n\r\n // WMS 1.1.1: <LatLonBoundingBox minx miny maxx maxy>.\r\n const latLon = descendientes(capa, \"LatLonBoundingBox\")[0];\r\n if (latLon) {\r\n return aExtent(\r\n {\r\n xmin: Number(latLon.getAttribute(\"minx\")),\r\n ymin: Number(latLon.getAttribute(\"miny\")),\r\n xmax: Number(latLon.getAttribute(\"maxx\")),\r\n ymax: Number(latLon.getAttribute(\"maxy\")),\r\n },\r\n 4326,\r\n );\r\n }\r\n return null;\r\n}\r\n\r\n/** Subcapa de un `MapImageLayer` por índice REST o por título. */\r\nfunction subcapaArcgis(\r\n raiz: MapImageLayer,\r\n identificador: string,\r\n): Sublayer | undefined {\r\n return raiz.allSublayers.find(\r\n (sub) => String(sub.id) === identificador || sub.title === identificador,\r\n );\r\n}\r\n\r\n/** Extensión real de las entidades de una `FeatureLayer`. `null` si no hay o falla. */\r\nasync function extentDeEntidades(\r\n capa: FeatureLayer,\r\n outSpatialReference?: SpatialReference,\r\n): Promise<Extent | null> {\r\n try {\r\n await capa.load();\r\n const { count, extent } = await capa.queryExtent(\r\n outSpatialReference ? { outSpatialReference } : undefined,\r\n );\r\n return count > 0 ? extent : null;\r\n } catch (error: unknown) {\r\n console.warn(\r\n `No fue posible consultar la extensión de \"${capa.title}\".`,\r\n error,\r\n );\r\n return null;\r\n }\r\n}\r\n\r\n/** Extensión real de las entidades de una capa REST ArcGIS. `null` si no hay o falla. */\r\nasync function extentDeEntidadesRest(\r\n url: string,\r\n outSpatialReference?: SpatialReference,\r\n): Promise<Extent | null> {\r\n try {\r\n const { count, extent } = await executeForExtent(url, {\r\n where: \"1=1\",\r\n outSpatialReference,\r\n });\r\n return count > 0 && extent && Number.isFinite(extent.xmin) ? extent : null;\r\n } catch (error: unknown) {\r\n console.warn(`No fue posible consultar la extensión de \"${urlSinQuery(url)}\".`, error);\r\n return null;\r\n }\r\n}\r\n\r\n/** URL REST de una subcapa de un servicio de mapa ArcGIS. `null` si no resuelve. */\r\nfunction resolverUrlRestDeSubcapa(\r\n raiz: MapImageLayer,\r\n urlServicio: string,\r\n identificador: string,\r\n): string | null {\r\n const sub = subcapaArcgis(raiz, identificador);\r\n return (\r\n sub?.url ??\r\n (/^\\d+$/.test(identificador)\r\n ? `${urlServicio.replace(/\\/+$/, \"\")}/${identificador}`\r\n : null)\r\n );\r\n}\r\n\r\n/**\r\n * Operaciones sobre una capa activa ya construida (extent, descarga, leyenda,\r\n * campos, valores y consulta). Separada de `GestorCapasMapa`, que maneja el ciclo\r\n * de vida de las capas; mantiene sus propias cachés de solo lectura.\r\n */\r\nexport class ConsultaCapaActiva {\r\n // GetCapabilities WMS ya parseado, por URL de servicio (para \"zoom a la capa\").\r\n private readonly capabilitiesWms = new Map<string, Document | null>();\r\n // Leyenda REST (`/legend?f=json`) de un MapServer/TileServer, por URL de servicio.\r\n private readonly legendCacheArcgis = new Map<string, Promise<RespuestaLeyendaArcgis | null>>();\r\n\r\n /**\r\n * Extensión para \"zoom a la capa\", según el servicio:\r\n * - FeatureServer: extensión real de las entidades.\r\n * - Servicio de mapa ArcGIS: extensión real de la subcapa por su URL REST.\r\n * - WMS: bbox de la capa en el GetCapabilities.\r\n * Si nada aplica, usa la extensión del servicio; `null` si no hay ninguna.\r\n */\r\n async extentDeCapa(\r\n servicio: ServicioGis,\r\n construidas: CapasServicioConstruidas,\r\n identificador: string,\r\n outSpatialReference?: SpatialReference,\r\n ): Promise<Extent | null> {\r\n const individual = construidas.individuales?.get(identificador) as\r\n | FeatureLayer\r\n | undefined;\r\n if (individual) {\r\n return (\r\n (await extentDeEntidades(individual, outSpatialReference)) ??\r\n individual.fullExtent ??\r\n null\r\n );\r\n }\r\n\r\n const raiz = construidas.capasRaiz[0];\r\n if (!raiz) return null;\r\n try {\r\n await raiz.load();\r\n } catch {\r\n return null;\r\n }\r\n\r\n if (raiz instanceof MapImageLayer) {\r\n const url = resolverUrlRestDeSubcapa(raiz, servicio.url, identificador);\r\n if (url) {\r\n const extent = await extentDeEntidadesRest(url, outSpatialReference);\r\n if (extent) return extent;\r\n }\r\n const sub = subcapaArcgis(raiz, identificador);\r\n if (sub?.fullExtent && Number.isFinite(sub.fullExtent.xmin)) {\r\n return sub.fullExtent;\r\n }\r\n }\r\n\r\n if (raiz instanceof WMSLayer) {\r\n const doc = await this.capabilitiesWmsDe(servicio.url, servicio.token);\r\n const desdeCaps =\r\n doc && extentDeCapabilitiesWms(doc, identificador, outSpatialReference);\r\n if (desdeCaps) return desdeCaps;\r\n\r\n const sub = raiz.findSublayerByName(identificador);\r\n if (sub?.fullExtent && Number.isFinite(sub.fullExtent.xmin)) {\r\n return sub.fullExtent;\r\n }\r\n }\r\n\r\n return raiz.fullExtent ?? null;\r\n }\r\n\r\n /**\r\n * Descarga en GeoJSON los elementos de una subcapa dentro de `extent`: por\r\n * `query` REST en ArcGIS o por WFS en GeoServer (puede lanzar\r\n * `DescargaNoSoportadaError`). `parametros` son los límites y tiempos de BD.\r\n */\r\n async descargarCapa(\r\n servicio: ServicioGis,\r\n construidas: CapasServicioConstruidas,\r\n identificador: string,\r\n extent: Extent,\r\n parametros: ParametrosDescarga,\r\n /** Solo WFS: pregunta si continuar cuando el conteo previo indica una zona densa. */\r\n onDescargaGrande?: (cantidad: number) => Promise<boolean>,\r\n ): Promise<ResultadoDescargaCapa> {\r\n const mecanismo = await this.mecanismoDe(servicio, construidas, identificador);\r\n\r\n if (mecanismo.tipo === \"featureLayer\" || mecanismo.tipo === \"restArcgis\") {\r\n return descargarCapaArcgisRest(mecanismo.url, extent, parametros, servicio.token);\r\n }\r\n\r\n if (mecanismo.tipo === \"wms\") {\r\n return descargarCapaWfs(servicio, identificador, extent, parametros, onDescargaGrande);\r\n }\r\n\r\n throw new DescargaNoSoportadaError(\r\n `El servicio \"${servicio.nombre}\" no permite descargar datos.`,\r\n );\r\n }\r\n\r\n /**\r\n * Leyenda de una capa activa (`/legend` REST, `renderer` o `GetLegendGraphic`).\r\n * `[]` si no hay mecanismo o falla. `etiquetaCapa` es el texto de respaldo.\r\n * Con `identificador` vacío arma la leyenda del servicio completo.\r\n */\r\n async leyendaDeCapa(\r\n servicio: ServicioGis,\r\n construidas: CapasServicioConstruidas,\r\n identificador: string,\r\n etiquetaCapa: string,\r\n ): Promise<ItemLeyenda[]> {\r\n try {\r\n switch (servicio.tipoServicio) {\r\n case \"ARCGIS_MAP\":\r\n case \"ARCGIS_TILE\": {\r\n const layerId = Number(identificador);\r\n if (!Number.isInteger(layerId)) return [];\r\n return await obtenerLeyendaMapaImagen(\r\n servicio.url,\r\n layerId,\r\n etiquetaCapa,\r\n servicio.token,\r\n this.legendCacheArcgis,\r\n );\r\n }\r\n case \"ARCGIS_FEATURE\": {\r\n const capa = construidas.individuales?.get(identificador) as\r\n | FeatureLayer\r\n | undefined;\r\n return capa ? await obtenerLeyendaFeature(capa) : [];\r\n }\r\n case \"OGC_WMS\": {\r\n if (identificador) return obtenerLeyendaWms(servicio, identificador, etiquetaCapa);\r\n\r\n const raiz = construidas.capasRaiz[0];\r\n if (!(raiz instanceof WMSLayer)) return [];\r\n await raiz.load();\r\n const hojas = raiz.allSublayers\r\n .filter((sub) => (sub.sublayers?.length ?? 0) === 0)\r\n .toArray();\r\n return hojas.flatMap((sub) =>\r\n obtenerLeyendaWms(servicio, sub.name, sub.title || etiquetaCapa),\r\n );\r\n }\r\n default:\r\n return [];\r\n }\r\n } catch (error: unknown) {\r\n console.warn(`No fue posible leer la leyenda de \"${identificador}\".`, error);\r\n return [];\r\n }\r\n }\r\n\r\n /**\r\n * Campos consultables de una capa activa (`fields`, metadata REST o\r\n * `DescribeFeatureType`). `[]` si no hay mecanismo o falla.\r\n */\r\n async camposDeCapa(\r\n servicio: ServicioGis,\r\n construidas: CapasServicioConstruidas,\r\n identificador: string,\r\n ): Promise<CampoConsulta[]> {\r\n try {\r\n const mecanismo = await this.mecanismoDe(servicio, construidas, identificador);\r\n\r\n if (mecanismo.tipo === \"featureLayer\") {\r\n return await camposArcgisFeature(mecanismo.capa);\r\n }\r\n if (mecanismo.tipo === \"restArcgis\") {\r\n return await camposArcgisRest(mecanismo.url, servicio.token);\r\n }\r\n if (mecanismo.tipo === \"wms\") {\r\n return await describeFeatureTypeWfs(servicio, identificador);\r\n }\r\n\r\n return [];\r\n } catch (error: unknown) {\r\n console.warn(`No fue posible leer los campos de \"${identificador}\".`, error);\r\n return [];\r\n }\r\n }\r\n\r\n /** Valores distintos de un campo de una capa activa, acotados a los topes de BD. */\r\n async valoresDistintosDeCampo(\r\n servicio: ServicioGis,\r\n construidas: CapasServicioConstruidas,\r\n identificador: string,\r\n campo: string,\r\n parametros: ParametrosConsulta,\r\n ): Promise<ValoresDistintosCampo> {\r\n const sinValores: ValoresDistintosCampo = { valores: [], truncado: false };\r\n\r\n try {\r\n const mecanismo = await this.mecanismoDe(servicio, construidas, identificador);\r\n\r\n if (mecanismo.tipo === \"featureLayer\" || mecanismo.tipo === \"restArcgis\") {\r\n return await valoresDistintosArcgis(mecanismo.url, campo, parametros, servicio.token);\r\n }\r\n if (mecanismo.tipo === \"wms\") {\r\n return await valoresDistintosWfs(servicio, identificador, campo, parametros);\r\n }\r\n\r\n return sinValores;\r\n } catch (error: unknown) {\r\n console.warn(`No fue posible leer los valores de \"${campo}\".`, error);\r\n return sinValores;\r\n }\r\n }\r\n\r\n /**\r\n * Ejecuta una consulta por atributos y devuelve entidades, extensión y si el\r\n * servidor recortó el resultado. El filtro va como `where` o `CQL_FILTER` (WFS).\r\n */\r\n async ejecutarConsulta(\r\n servicio: ServicioGis,\r\n construidas: CapasServicioConstruidas,\r\n identificador: string,\r\n filtro: FiltroConsulta,\r\n parametros: ParametrosConsulta,\r\n outSpatialReference?: SpatialReference,\r\n ): Promise<ResultadoConsultaCapa> {\r\n const campos = await this.camposDeCapa(servicio, construidas, identificador);\r\n const mecanismo = await this.mecanismoDe(servicio, construidas, identificador);\r\n\r\n /** Une los campos ya resueltos con el resultado crudo del mecanismo. */\r\n const conCampos = (\r\n resultado: Omit<ResultadoConsultaCapa, \"campos\" | \"filasDevueltas\"> & {\r\n total: number;\r\n },\r\n ) => ({\r\n campos,\r\n graficos: resultado.graficos,\r\n extent: resultado.extent,\r\n filasDevueltas: resultado.total,\r\n incompleto: resultado.incompleto,\r\n });\r\n\r\n const vacio: ResultadoConsultaCapa = {\r\n campos,\r\n graficos: [],\r\n extent: null,\r\n filasDevueltas: 0,\r\n incompleto: false,\r\n };\r\n\r\n if (mecanismo.tipo === \"featureLayer\" || mecanismo.tipo === \"restArcgis\") {\r\n return conCampos(\r\n await ejecutarConsultaArcgis(\r\n mecanismo.url,\r\n armarWhereArcgis(filtro, campos),\r\n parametros,\r\n outSpatialReference,\r\n servicio.token,\r\n ),\r\n );\r\n }\r\n\r\n if (mecanismo.tipo === \"wms\") {\r\n return conCampos(\r\n await ejecutarConsultaWfs(\r\n servicio,\r\n identificador,\r\n armarCqlGeoserver(filtro, campos),\r\n parametros,\r\n ),\r\n );\r\n }\r\n\r\n return vacio;\r\n }\r\n\r\n /** GetCapabilities WMS parseado y cacheado por URL (también los fallos). `null` si falla. */\r\n private async capabilitiesWmsDe(\r\n urlServicio: string,\r\n token?: string,\r\n ): Promise<Document | null> {\r\n const base = urlServicio.split(\"?\")[0];\r\n const cacheado = this.capabilitiesWms.get(base);\r\n if (cacheado !== undefined) return cacheado;\r\n\r\n let doc: Document | null = null;\r\n try {\r\n const { data } = await esriRequest(base, {\r\n responseType: \"text\",\r\n query: {\r\n service: \"WMS\",\r\n request: \"GetCapabilities\",\r\n version: \"1.3.0\",\r\n ...(token ? { token } : {}),\r\n },\r\n });\r\n doc = new DOMParser().parseFromString(String(data), \"text/xml\");\r\n } catch (error: unknown) {\r\n console.warn(\r\n `No fue posible leer el GetCapabilities WMS de \"${urlSinQuery(base)}\".`,\r\n error,\r\n );\r\n }\r\n this.capabilitiesWms.set(base, doc);\r\n return doc;\r\n }\r\n\r\n /** Resuelve cómo hablarle a una subcapa (ver `MecanismoCapa`). */\r\n private async mecanismoDe(\r\n servicio: ServicioGis,\r\n construidas: CapasServicioConstruidas,\r\n identificador: string,\r\n ): Promise<MecanismoCapa> {\r\n const individual = construidas.individuales?.get(identificador) as\r\n | FeatureLayer\r\n | undefined;\r\n if (individual?.url) {\r\n return { tipo: \"featureLayer\", url: individual.url, capa: individual };\r\n }\r\n\r\n const raiz = construidas.capasRaiz[0];\r\n if (!raiz) return { tipo: \"sinMecanismo\" };\r\n\r\n if (raiz instanceof MapImageLayer) {\r\n await raiz.load();\r\n const url = resolverUrlRestDeSubcapa(raiz, servicio.url, identificador);\r\n return url ? { tipo: \"restArcgis\", url } : { tipo: \"sinMecanismo\" };\r\n }\r\n\r\n if (raiz instanceof WMSLayer) return { tipo: \"wms\" };\r\n\r\n return { tipo: \"sinMecanismo\" };\r\n }\r\n\r\n /** Purga las cachés del servicio al cambiar la credencial. */\r\n invalidarCache(urlServicio: string): void {\r\n this.capabilitiesWms.delete(urlServicio.split(\"?\")[0]);\r\n this.legendCacheArcgis.delete(urlServicio.replace(/\\/+$/, \"\"));\r\n }\r\n\r\n /** Vacía ambas cachés (al retirar todas las capas administradas). */\r\n limpiarCache(): void {\r\n this.capabilitiesWms.clear();\r\n this.legendCacheArcgis.clear();\r\n }\r\n}\r\n","import identityManager from \"@arcgis/core/identity/IdentityManager\";\r\nimport type { ServicioGis } from \"@/features/maps/types\";\r\n\r\n/** Raíz que espera IdentityManager al registrar un token de servidor ArcGIS. */\r\nfunction obtenerUrlServidorToken(urlServicio: string): string {\r\n const rutaServicios = \"/rest/services\";\r\n const indice = urlServicio.toLowerCase().indexOf(rutaServicios);\r\n return indice === -1\r\n ? urlServicio\r\n : urlServicio.slice(0, indice + rutaServicios.length);\r\n}\r\n\r\n/** Registra el token ArcGIS del servicio antes de crear sus capas. */\r\nexport function registrarTokenArcgis(servicio: ServicioGis): void {\r\n if (servicio.plataformaGis !== \"ARCGIS\" || !servicio.token) return;\r\n\r\n identityManager.registerToken({\r\n server: obtenerUrlServidorToken(servicio.url),\r\n token: servicio.token,\r\n expires: servicio.expires,\r\n ssl: servicio.ssl,\r\n });\r\n}\r\n\r\n/** Indica si el token informado por el backend ya expiró (epoch ms). */\r\nexport function tokenVencido(servicio: ServicioGis): boolean {\r\n return typeof servicio.expires === \"number\" && Date.now() > servicio.expires;\r\n}\r\n","import WMSLayer from \"@arcgis/core/layers/WMSLayer\";\r\nimport type { ServicioGis } from \"@/features/maps/types\";\r\nimport type { WMSLayerFormatType } from \"@arcgis/core/layers/WMSLayer\";\r\nimport type { CapasServicioConstruidas } from \"./types\";\r\n\r\n/** Ajustes OGC del servicio ya validados. */\r\ninterface AjustesWms {\r\n version?: string;\r\n format?: WMSLayerFormatType;\r\n transparent?: boolean;\r\n}\r\n\r\n/** Formatos de imagen que admite `WMSLayer`. */\r\nconst FORMATOS_VALIDOS: readonly string[] = [\r\n \"image/jpeg\",\r\n \"image/bmp\",\r\n \"image/gif\",\r\n \"image/svg+xml\",\r\n \"image/png\",\r\n];\r\n\r\n/** Valida el formato informado por el backend contra los soportados. */\r\nfunction validarFormato(valor: unknown): WMSLayerFormatType | undefined {\r\n return typeof valor === \"string\" && FORMATOS_VALIDOS.includes(valor)\r\n ? (valor as WMSLayerFormatType)\r\n : undefined;\r\n}\r\n\r\n/** Lee con tipos seguros los ajustes OGC informados por el backend. */\r\nfunction leerAjustes(servicio: ServicioGis): AjustesWms {\r\n const configuracion = servicio.configuracionServicio;\r\n return {\r\n version:\r\n typeof configuracion.version === \"string\" ? configuracion.version : undefined,\r\n format: validarFormato(configuracion.format),\r\n transparent:\r\n typeof configuracion.transparent === \"boolean\"\r\n ? configuracion.transparent\r\n : undefined,\r\n };\r\n}\r\n\r\n/** OGC_WMS: un único WMSLayer por servicio; sus subcapas declaradas se controlan por nombre. */\r\nexport function crearWms(servicio: ServicioGis): CapasServicioConstruidas {\r\n const ajustes = leerAjustes(servicio);\r\n const declaradas = servicio.configuracionCapas.capas ?? [];\r\n\r\n const capa = new WMSLayer({\r\n url: servicio.url,\r\n title: servicio.nombre,\r\n visible: servicio.visible,\r\n opacity: servicio.opacidad,\r\n imageFormat: ajustes.format,\r\n imageTransparency: ajustes.transparent,\r\n version: ajustes.version,\r\n ...(servicio.token ? { customParameters: { token: servicio.token } } : {}),\r\n ...(declaradas.length > 0\r\n ? {\r\n sublayers: declaradas.map((item) => ({\r\n name: item.identificador,\r\n title: item.titulo,\r\n visible: item.visible,\r\n })),\r\n }\r\n : {}),\r\n });\r\n\r\n // URL usada para GetMap y GetFeatureInfo a través del proxy autenticado.\r\n capa.set(\"mapUrl\", servicio.url);\r\n capa.featureInfoUrl = servicio.url;\r\n // Habilita el GetFeatureInfo que consume el popup de la herramienta Identificar.\r\n capa.featureInfoFormat = \"text/html\";\r\n\r\n // Carga anticipada para detectar errores cuanto antes.\r\n void capa.load().catch((error: unknown) => {\r\n console.error(`No fue posible cargar el WMS \"${servicio.nombre}\".`, error);\r\n });\r\n\r\n // Sin subcapas declaradas la visibilidad se gobierna a nivel de servicio.\r\n if (declaradas.length === 0) {\r\n return { capasRaiz: [capa] };\r\n }\r\n\r\n return {\r\n capasRaiz: [capa],\r\n subcapas: {\r\n establecerVisible(identificador, visible) {\r\n const subcapa = capa.findSublayerByName(identificador);\r\n if (subcapa) subcapa.visible = visible;\r\n },\r\n establecerOpacidad(_identificador, opacidad) {\r\n capa.opacity = opacidad;\r\n },\r\n },\r\n };\r\n}\r\n","import type ArcGISMap from \"@arcgis/core/Map\";\r\nimport type Extent from \"@arcgis/core/geometry/Extent\";\r\nimport type SpatialReference from \"@arcgis/core/geometry/SpatialReference\";\r\nimport type Layer from \"@arcgis/core/layers/Layer\";\r\nimport MapImageLayer from \"@arcgis/core/layers/MapImageLayer\";\r\nimport WMSLayer from \"@arcgis/core/layers/WMSLayer\";\r\nimport type {\r\n CampoConsulta,\r\n CapaServicio,\r\n FiltroConsulta,\r\n ItemLeyenda,\r\n ParametrosConsulta,\r\n ParametrosDescarga,\r\n ResultadoConsultaCapa,\r\n ServicioGis,\r\n ValoresDistintosCampo,\r\n} from \"@/features/maps/types\";\r\nimport { crearFeatures, crearMapaImagen, crearTileCachedo } from \"./arcgis.factory\";\r\nimport { ConsultaCapaActiva } from \"./consulta-capa-activa\";\r\nimport { registrarTokenArcgis, tokenVencido } from \"./identity-manager\";\r\nimport type { CapasServicioConstruidas } from \"./types\";\r\nimport type { ResultadoDescargaCapa } from \"./descarga-capa\";\r\nimport { crearWms } from \"./wms.factory\";\r\n\r\n/** Servicio del contrato junto con las capas ArcGIS que produjo su fábrica. */\r\ninterface RegistroServicio {\r\n servicio: ServicioGis;\r\n construidas: CapasServicioConstruidas;\r\n}\r\n\r\n/** Fallo de carga asociado al servicio que lo produjo. */\r\nexport interface FalloServicio {\r\n servicio: ServicioGis;\r\n error: unknown;\r\n}\r\n\r\ntype ReportarFallos = (fallos: readonly FalloServicio[]) => void;\r\n\r\n/** Fuerza el chequeo exhaustivo del `switch` de tipos de servicio. */\r\nfunction tipoNoSoportado(tipo: never): never {\r\n throw new Error(`Tipo de servicio no soportado: ${String(tipo)}.`);\r\n}\r\n\r\n/** Selecciona la fábrica de capas según el tipo de servicio del contrato. */\r\nfunction construir(servicio: ServicioGis): CapasServicioConstruidas {\r\n switch (servicio.tipoServicio) {\r\n case \"ARCGIS_MAP\":\r\n return crearMapaImagen(servicio);\r\n case \"ARCGIS_FEATURE\":\r\n return crearFeatures(servicio);\r\n case \"ARCGIS_TILE\":\r\n return crearTileCachedo(servicio);\r\n case \"OGC_WMS\":\r\n return crearWms(servicio);\r\n case \"OGC_WMTS\":\r\n case \"OGC_WFS\":\r\n case \"OGC_API_FEATURES\":\r\n // Pendiente para una fase posterior del visor.\r\n throw new Error(\r\n `El tipo ${servicio.tipoServicio} se soportará en una fase posterior.`,\r\n );\r\n default:\r\n return tipoNoSoportado(servicio.tipoServicio);\r\n }\r\n}\r\n\r\n/** Administra las capas del mapa (visibilidad y opacidad) sin depender de React. */\r\nexport class GestorCapasMapa {\r\n private readonly mapa: ArcGISMap;\r\n private readonly reportarFallos?: ReportarFallos;\r\n // Servicios administrados y su estado de visibilidad/opacidad.\r\n private registros: RegistroServicio[] = [];\r\n private visibilidadServicios = new Map<string, boolean>();\r\n private opacidades = new Map<string, number>();\r\n private visibilidadCapas = new Map<string, Map<string, boolean>>();\r\n private opacidadesCapas = new Map<string, Map<string, number>>();\r\n // Todo lo que se puede pedir sobre una capa activa ya construida (extent,\r\n // descarga, leyenda, campos, valores, consulta): ver `ConsultaCapaActiva`.\r\n private readonly consultas = new ConsultaCapaActiva();\r\n\r\n constructor(mapa: ArcGISMap, reportarFallos?: ReportarFallos) {\r\n this.mapa = mapa;\r\n this.reportarFallos = reportarFallos;\r\n }\r\n\r\n /** Reemplaza todas las capas administradas según la lista de servicios. */\r\n establecer(servicios: readonly ServicioGis[]): void {\r\n this.limpiar();\r\n\r\n // Construye las capas de cada servicio y siembra su estado inicial.\r\n const todas: Layer[] = [];\r\n const fallos: FalloServicio[] = [];\r\n for (const servicio of servicios) {\r\n try {\r\n registrarTokenArcgis(servicio);\r\n if (tokenVencido(servicio)) {\r\n console.warn(\r\n `El token de \"${servicio.nombre}\" está vencido; se solicitará renovación vía validateToken.`,\r\n );\r\n }\r\n\r\n const construidas = construir(servicio);\r\n const capas = servicio.configuracionCapas.capas ?? [];\r\n\r\n this.registros.push({ servicio, construidas });\r\n this.visibilidadServicios.set(servicio.nombre, servicio.visible);\r\n this.opacidades.set(servicio.nombre, servicio.opacidad);\r\n this.sembrarEstadoCapas(servicio, capas);\r\n todas.push(...construidas.capasRaiz);\r\n } catch (error) {\r\n // Un servicio mal configurado (plataforma no soportada, etc.) no debe\r\n // tumbar la carga de los demás: se reporta y se sigue con el resto.\r\n fallos.push({ servicio, error });\r\n }\r\n }\r\n\r\n if (todas.length > 0) this.mapa.addMany(todas);\r\n this.registros.forEach((registro) => this.aplicarVisibilidad(registro));\r\n\r\n if (!this.reportarFallos) return;\r\n\r\n void Promise.all(\r\n this.registros.flatMap(({ servicio, construidas }) =>\r\n construidas.capasRaiz.map((capa) =>\r\n typeof capa.load === \"function\"\r\n ? capa.load().catch((error: unknown) => {\r\n fallos.push({ servicio, error });\r\n })\r\n : Promise.resolve(),\r\n ),\r\n ),\r\n ).then(() => {\r\n if (fallos.length > 0) this.reportarFallos?.(fallos);\r\n });\r\n }\r\n\r\n /** Muestra u oculta un servicio completo. */\r\n cambiaVisibilidadDelServicio(nombre: string, visible: boolean): void {\r\n this.visibilidadServicios.set(nombre, visible);\r\n this.aplicarVisibilidad(this.buscar(nombre));\r\n }\r\n\r\n /** Ajusta la opacidad de todas las capas raíz de un servicio. */\r\n cambiarOpacidadServicio(nombre: string, opacidad: number): void {\r\n this.opacidades.set(nombre, opacidad);\r\n const registro = this.buscar(nombre);\r\n registro.construidas.capasRaiz.forEach((capa) => {\r\n capa.opacity = opacidad;\r\n });\r\n }\r\n\r\n /** Ajusta la opacidad de una subcapa concreta. */\r\n cambiarOpacidadCapa(\r\n nombreServicio: string,\r\n identificador: string,\r\n opacidad: number,\r\n ): void {\r\n const registro = this.buscar(nombreServicio);\r\n const individual = registro.construidas.individuales?.get(identificador);\r\n if (individual) {\r\n this.opacidadesCapas.get(nombreServicio)?.set(identificador, opacidad);\r\n individual.opacity = opacidad;\r\n return;\r\n }\r\n\r\n // Con una sola capa raíz (p. ej. WMS) la opacidad afecta a todas las\r\n // subcapas: se refleja en cada una para que el estado coincida con lo pintado.\r\n const opacidadesCapas = this.opacidadesCapas.get(nombreServicio);\r\n opacidadesCapas?.forEach((_valor, clave) => opacidadesCapas.set(clave, opacidad));\r\n registro.construidas.subcapas?.establecerOpacidad(identificador, opacidad);\r\n }\r\n\r\n /** Muestra u oculta una subcapa concreta de un servicio. */\r\n cambiarVisibilidadCapa(\r\n nombreServicio: string,\r\n identificador: string,\r\n visible: boolean,\r\n ): void {\r\n this.visibilidadCapas.get(nombreServicio)?.set(identificador, visible);\r\n this.aplicarVisibilidad(this.buscar(nombreServicio));\r\n }\r\n\r\n /** Renueva las credenciales sin reconstruir las capas ni perder su estado. */\r\n actualizarCredenciales(servicios: readonly ServicioGis[]): void {\r\n for (const servicio of servicios) {\r\n const registro = this.registros.find(\r\n (candidato) => candidato.servicio.nombre === servicio.nombre,\r\n );\r\n if (!registro) continue;\r\n\r\n const cambiaron =\r\n registro.servicio.token !== servicio.token ||\r\n registro.servicio.expires !== servicio.expires ||\r\n registro.servicio.ssl !== servicio.ssl;\r\n registro.servicio = servicio;\r\n if (!cambiaron) continue;\r\n\r\n // La leyenda/capabilities cacheadas quedaron pedidas con el token\r\n // anterior: purgarlas evita servir datos de una credencial ya vencida\r\n // (o negarlos si la nueva ya no tiene acceso a lo que la vieja sí tenía).\r\n this.consultas.invalidarCache(servicio.url);\r\n\r\n registrarTokenArcgis(servicio);\r\n registro.construidas.capasRaiz.forEach((capa) => {\r\n if (!(capa instanceof WMSLayer)) return;\r\n const parametros = { ...(capa.customParameters ?? {}) };\r\n if (servicio.token) parametros.token = servicio.token;\r\n else delete parametros.token;\r\n capa.customParameters = parametros;\r\n capa.refresh();\r\n });\r\n }\r\n }\r\n\r\n /** Descubre y devuelve por servicio las subcapas que el contrato no declara. */\r\n async descubrirCapasNoDeclaradas(): Promise<Map<string, CapaServicio[]>> {\r\n const porServicio = new Map<string, CapaServicio[]>();\r\n\r\n await Promise.all(\r\n this.registros.map(async (registro) => {\r\n const { servicio, construidas } = registro;\r\n const yaDeclaradas = (servicio.configuracionCapas.capas?.length ?? 0) > 0;\r\n const raiz = construidas.capasRaiz[0];\r\n const admiteDescubrimiento =\r\n raiz instanceof MapImageLayer || raiz instanceof WMSLayer;\r\n if (yaDeclaradas || !admiteDescubrimiento) return;\r\n\r\n try {\r\n await raiz.load();\r\n } catch (error: unknown) {\r\n console.warn(\r\n `No fue posible descubrir las subcapas de \"${servicio.nombre}\".`,\r\n error,\r\n );\r\n return;\r\n }\r\n\r\n const capas =\r\n raiz instanceof WMSLayer\r\n ? raiz.allSublayers\r\n .filter((sub) => (sub.sublayers?.length ?? 0) === 0)\r\n .toArray()\r\n .map((sub) => ({\r\n identificador: sub.name,\r\n titulo: sub.title ?? sub.name,\r\n visible: sub.visible,\r\n opacidad: servicio.opacidad,\r\n minScale: sub.minScale,\r\n maxScale: sub.maxScale,\r\n }))\r\n : raiz.allSublayers\r\n .filter((sub) => (sub.sublayers?.length ?? 0) === 0)\r\n .toArray()\r\n .map((sub) => ({\r\n identificador: String(sub.id),\r\n titulo: sub.title ?? `Capa ${sub.id}`,\r\n visible: sub.visible,\r\n opacidad: servicio.opacidad,\r\n minScale: sub.minScale,\r\n maxScale: sub.maxScale,\r\n }));\r\n if (capas.length === 0) return;\r\n\r\n porServicio.set(servicio.nombre, capas);\r\n if (raiz instanceof WMSLayer) {\r\n const reemplazo = crearWms({\r\n ...servicio,\r\n configuracionCapas: { ...servicio.configuracionCapas, capas },\r\n });\r\n const capasAnteriores = [...construidas.capasRaiz];\r\n this.mapa.removeMany(capasAnteriores);\r\n // Libera listeners/recursos de la capa reemplazada: sin esto, cada\r\n // descubrimiento de subcapas deja atrás una capa \"huérfana\" pero\r\n // viva, degradando el rendimiento poco a poco.\r\n for (const capaAnterior of capasAnteriores) capaAnterior.destroy();\r\n this.mapa.addMany([...reemplazo.capasRaiz]);\r\n registro.construidas = reemplazo;\r\n }\r\n // Respeta la visibilidad del servicio; las capas descubiertas arrancan apagadas.\r\n this.sembrarEstadoCapas(servicio, capas);\r\n this.aplicarVisibilidad(this.buscar(servicio.nombre));\r\n }),\r\n );\r\n\r\n return porServicio;\r\n }\r\n\r\n /** Retira del mapa todas las capas administradas por esta instancia. */\r\n destruir(): void {\r\n this.limpiar();\r\n }\r\n\r\n /** Extensión para \"zoom a la capa\" (ver `ConsultaCapaActiva.extentDeCapa`). */\r\n async extentDeCapa(\r\n nombreServicio: string,\r\n identificador: string,\r\n outSpatialReference?: SpatialReference,\r\n ): Promise<Extent | null> {\r\n const { servicio, construidas } = this.buscar(nombreServicio);\r\n return this.consultas.extentDeCapa(\r\n servicio,\r\n construidas,\r\n identificador,\r\n outSpatialReference,\r\n );\r\n }\r\n\r\n /** Descarga en GeoJSON una subcapa (ver `ConsultaCapaActiva.descargarCapa`). */\r\n async descargarCapa(\r\n nombreServicio: string,\r\n identificador: string,\r\n extent: Extent,\r\n parametros: ParametrosDescarga,\r\n /** Solo WFS: pregunta si continuar cuando el conteo previo indica una zona densa. */\r\n onDescargaGrande?: (cantidad: number) => Promise<boolean>,\r\n ): Promise<ResultadoDescargaCapa> {\r\n const { servicio, construidas } = this.buscar(nombreServicio);\r\n return this.consultas.descargarCapa(\r\n servicio,\r\n construidas,\r\n identificador,\r\n extent,\r\n parametros,\r\n onDescargaGrande,\r\n );\r\n }\r\n\r\n /** Leyenda de una capa activa (ver `ConsultaCapaActiva.leyendaDeCapa`). */\r\n async leyendaDeCapa(\r\n nombreServicio: string,\r\n identificador: string,\r\n etiquetaCapa: string,\r\n ): Promise<ItemLeyenda[]> {\r\n const { servicio, construidas } = this.buscar(nombreServicio);\r\n return this.consultas.leyendaDeCapa(servicio, construidas, identificador, etiquetaCapa);\r\n }\r\n\r\n /** Campos consultables de una capa activa (ver `ConsultaCapaActiva.camposDeCapa`). */\r\n async camposDeCapa(\r\n nombreServicio: string,\r\n identificador: string,\r\n ): Promise<CampoConsulta[]> {\r\n const { servicio, construidas } = this.buscar(nombreServicio);\r\n return this.consultas.camposDeCapa(servicio, construidas, identificador);\r\n }\r\n\r\n /** Valores distintos de un campo (ver `ConsultaCapaActiva.valoresDistintosDeCampo`). */\r\n async valoresDistintosDeCampo(\r\n nombreServicio: string,\r\n identificador: string,\r\n campo: string,\r\n parametros: ParametrosConsulta,\r\n ): Promise<ValoresDistintosCampo> {\r\n const { servicio, construidas } = this.buscar(nombreServicio);\r\n return this.consultas.valoresDistintosDeCampo(\r\n servicio,\r\n construidas,\r\n identificador,\r\n campo,\r\n parametros,\r\n );\r\n }\r\n\r\n /** Consulta por atributos (ver `ConsultaCapaActiva.ejecutarConsulta`). */\r\n async ejecutarConsulta(\r\n nombreServicio: string,\r\n identificador: string,\r\n filtro: FiltroConsulta,\r\n parametros: ParametrosConsulta,\r\n outSpatialReference?: SpatialReference,\r\n ): Promise<ResultadoConsultaCapa> {\r\n const { servicio, construidas } = this.buscar(nombreServicio);\r\n return this.consultas.ejecutarConsulta(\r\n servicio,\r\n construidas,\r\n identificador,\r\n filtro,\r\n parametros,\r\n outSpatialReference,\r\n );\r\n }\r\n\r\n /** Siembra el estado de las subcapas de un servicio: todas arrancan desactivadas. */\r\n private sembrarEstadoCapas(\r\n servicio: ServicioGis,\r\n capas: readonly CapaServicio[],\r\n ): void {\r\n this.visibilidadCapas.set(\r\n servicio.nombre,\r\n new Map(capas.map((capa) => [capa.identificador, false])),\r\n );\r\n // Las capas descubiertas siempre traen su opacidad; el `??` solo cubre el\r\n // tipo opcional de `CapaServicio`, para heredar la del servicio.\r\n this.opacidadesCapas.set(\r\n servicio.nombre,\r\n new Map(\r\n capas.map((capa) => [\r\n capa.identificador,\r\n capa.opacidad ?? /* istanbul ignore next */ servicio.opacidad,\r\n ]),\r\n ),\r\n );\r\n }\r\n\r\n /** Devuelve el registro de un servicio administrado o lanza si no existe. */\r\n private buscar(nombre: string): RegistroServicio {\r\n const registro = this.registros.find(\r\n (candidato) => candidato.servicio.nombre === nombre,\r\n );\r\n if (!registro) {\r\n throw new Error(`El servicio \"${nombre}\" no está administrado.`);\r\n }\r\n return registro;\r\n }\r\n\r\n /** Aplica a las capas del servicio la combinación de su estado y el de cada subcapa. */\r\n private aplicarVisibilidad(registro: RegistroServicio): void {\r\n const nombre = registro.servicio.nombre;\r\n const visibleServicio =\r\n this.visibilidadServicios.get(nombre) ??\r\n /* istanbul ignore next -- respaldo defensivo: el estado siempre se siembra en `establecer` */\r\n registro.servicio.visible;\r\n /* istanbul ignore next -- respaldo defensivo: la opacidad siempre se siembra en `establecer` */\r\n const opacidad = this.opacidades.get(nombre) ?? 1;\r\n const estados = this.visibilidadCapas.get(nombre);\r\n const opacidadesCapas = this.opacidadesCapas.get(nombre);\r\n\r\n if (registro.construidas.individuales) {\r\n registro.construidas.individuales.forEach((capa, identificador) => {\r\n capa.visible = visibleServicio && (estados?.get(identificador) ?? true);\r\n capa.opacity = opacidadesCapas?.get(identificador) ?? opacidad;\r\n });\r\n return;\r\n }\r\n\r\n registro.construidas.capasRaiz.forEach((capa) => {\r\n capa.visible = visibleServicio;\r\n capa.opacity = estados?.size ? 1 : opacidad;\r\n });\r\n\r\n const subcapas = registro.construidas.subcapas;\r\n if (!subcapas || !estados) return;\r\n estados.forEach((visible, identificador) => {\r\n subcapas.establecerVisible(identificador, visible);\r\n subcapas.establecerOpacidad(\r\n identificador,\r\n opacidadesCapas?.get(identificador) ?? opacidad,\r\n );\r\n });\r\n }\r\n\r\n /** Quita del mapa las capas administradas y resetea el estado interno. */\r\n private limpiar(): void {\r\n const capas = this.registros.flatMap((registro) => registro.construidas.capasRaiz);\r\n if (capas.length > 0) this.mapa.removeMany(capas);\r\n this.registros = [];\r\n this.visibilidadServicios.clear();\r\n this.opacidades.clear();\r\n this.visibilidadCapas.clear();\r\n this.opacidadesCapas.clear();\r\n // Sin cota y sin esto, crecen sin límite durante la sesión (un mapa nunca\r\n // vuelve a llamar 'establecer' salvo al recargar la configuración).\r\n this.consultas.limpiarCache();\r\n }\r\n}\r\n","import type ArcGISMap from \"@arcgis/core/Map\";\r\nimport { useEffect, useReducer, useRef, useState } from \"react\";\r\nimport type { CapaServicio, ServicioGis, VistaMapa } from \"../types\";\r\nimport {\r\n GestorCapasMapa,\r\n type FalloServicio,\r\n} from \"../services/layers/gestor-capas\";\r\n\r\n/** Subcapas descubiertas en runtime, indexadas por nombre de servicio. */\r\nexport type CapasDescubiertas = ReadonlyMap<string, readonly CapaServicio[]>;\r\n\r\n/** Valor devuelto por `useGestorCapas`. */\r\ninterface GestorCapas {\r\n gestorRef: React.RefObject<GestorCapasMapa | null>;\r\n /** Subcapas leídas de la metadata del servidor para servicios que no las declaran. */\r\n capasDescubiertas: CapasDescubiertas;\r\n}\r\n\r\n/**\r\n * Instancia el gestor de capas cuando la vista está lista y lo destruye al\r\n * desmontar. Devuelve su ref y las subcapas descubiertas en runtime.\r\n */\r\nexport function useGestorCapas(\r\n vista: VistaMapa | null,\r\n servicios: readonly ServicioGis[],\r\n reportarFallos?: (fallos: readonly FalloServicio[]) => void,\r\n): GestorCapas {\r\n const gestorRef = useRef<GestorCapasMapa | null>(null);\r\n // Fuerza un render cuando la ref pasa a estar disponible.\r\n const [, forzarRender] = useReducer((contador: number) => contador + 1, 0);\r\n const [capasDescubiertas, setCapasDescubiertas] = useState<CapasDescubiertas>(\r\n () => new Map(),\r\n );\r\n\r\n useEffect(() => {\r\n if (!vista) return;\r\n\r\n // Crea el gestor y le pasa los servicios del contrato.\r\n const gestor = new GestorCapasMapa(vista.map as ArcGISMap, reportarFallos);\r\n gestor.establecer(servicios);\r\n gestorRef.current = gestor;\r\n forzarRender();\r\n\r\n // Descubre en segundo plano las subcapas no declaradas.\r\n let activo = true;\r\n void gestor.descubrirCapasNoDeclaradas().then((capas) => {\r\n if (activo && capas.size > 0) setCapasDescubiertas(capas);\r\n });\r\n\r\n // Limpieza: destruye el gestor y resetea el estado.\r\n return () => {\r\n activo = false;\r\n gestor.destruir();\r\n gestorRef.current = null;\r\n setCapasDescubiertas(new Map());\r\n };\r\n // Los cambios de credenciales se aplican abajo sin reconstruir las capas.\r\n // Nuevos servicios se incorporan únicamente al volver a cargar la aplicación.\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [vista, reportarFallos]);\r\n\r\n useEffect(() => {\r\n gestorRef.current?.actualizarCredenciales(servicios);\r\n }, [servicios]);\r\n\r\n return { gestorRef, capasDescubiertas };\r\n}\r\n","/**\n * Configuración de entorno del visor, recibida en tiempo de ejecución (no de\n * `import.meta.env`, que se fija al compilar): así la misma librería sirve a\n * cualquier proyecto anfitrión. El demo la llena con sus variables `VITE_*`.\n */\nexport interface EntornoMapa {\n /** Base URL del backend de Core ISA (p. ej. `https://back.isa.co`). */\n apiBaseUrl?: string;\n /** Clave opcional de ArcGIS Location Platform (basemaps vectoriales). */\n arcgisApiKey?: string;\n /** Ruta de los assets del SDK de ArcGIS; por defecto, el CDN de Esri. */\n arcgisAssetsPath?: string;\n}\n\nlet entorno: Readonly<EntornoMapa> = {};\n\n/** Combina `cambios` con el entorno vigente. */\nexport function guardarEntorno(cambios: EntornoMapa): void {\n entorno = { ...entorno, ...cambios };\n}\n\n/** Entorno vigente del visor. */\nexport function obtenerEntorno(): Readonly<EntornoMapa> {\n return entorno;\n}\n\n/** Vuelve al entorno vacío (solo para pruebas). */\nexport function reiniciarEntorno(): void {\n entorno = {};\n}\n","import { obtenerEntorno } from \"@/shared/entorno\";\r\n\r\n/** Error normalizado para respuestas HTTP no satisfactorias. */\r\nexport class HttpError extends Error {\r\n readonly status: number;\r\n\r\n constructor(status: number, mensaje: string) {\r\n super(mensaje);\r\n this.name = \"HttpError\";\r\n this.status = status;\r\n }\r\n}\r\n\r\n/** Cuánto se espera como máximo una respuesta antes de abortar la petición. */\r\nconst TIEMPO_ESPERA_MS = 15_000;\r\n\r\n/** Compone la URL final respetando la base del backend si la hay. */\r\nfunction construirUrl(url: string): string {\r\n const base = obtenerEntorno().apiBaseUrl;\r\n if (!base || /^https?:\\/\\//i.test(url)) return url;\r\n return `${base.replace(/\\/$/, \"\")}/${url.replace(/^\\//, \"\")}`;\r\n}\r\n\r\n/** Combina, si existe, el signal del llamador con un límite de tiempo propio. */\r\nfunction combinarSenal(senalLlamador?: AbortSignal | null): AbortSignal {\r\n const senalTiempo = AbortSignal.timeout(TIEMPO_ESPERA_MS);\r\n return senalLlamador ? AbortSignal.any([senalLlamador, senalTiempo]) : senalTiempo;\r\n}\r\n\r\n/** Único punto de acceso HTTP: normaliza errores, tipa la respuesta y aplica un timeout. */\r\nexport async function fetchJson<T>(url: string, init?: RequestInit): Promise<T> {\r\n const { signal, ...restoInit } = init ?? {};\r\n const respuesta = await fetch(construirUrl(url), {\r\n ...restoInit,\r\n signal: combinarSenal(signal),\r\n });\r\n if (!respuesta.ok) {\r\n throw new HttpError(\r\n respuesta.status,\r\n `La solicitud a ${url} falló (${respuesta.status}).`,\r\n );\r\n }\r\n return (await respuesta.json()) as T;\r\n}\r\n","import type {\n GrupoParametros,\n ParametrosConsulta,\n ParametrosDescarga,\n ParametrosIdentificar,\n ParametrosProyeccion,\n} from \"../types\";\nimport { fetchJson } from \"@/shared/helpers/http\";\n\n/** Endpoint público (sin JWT) que devuelve los parámetros generales desde BD. */\nconst RUTA_PARAMETROS_GENERALES = \"/api/Aplicaciones/consultar-parametros-generales\";\n\n// Llaves que cada herramienta exige a su grupo. El `Record` obliga a listar todas\n// las del contrato: si se agrega una a la interfaz, no compila hasta sumarla aquí.\n\nconst LLAVES_DESCARGA: Record<keyof ParametrosDescarga, true> = {\n wkid: true,\n limiteGeoJson: true,\n tamanoPaginaDescarga: true,\n tamanoPaginaMinimoDescarga: true,\n reintentosPaginaDescarga: true,\n timeoutPaginaDescargaMs: true,\n tiempoMaximoDescargaMs: true,\n umbralAvisoDescargaWfs: true,\n tiempoEsperaDescargaWfsMs: true,\n tiempoEsperaConteoWfsMs: true,\n};\n\nconst LLAVES_CONSULTA: Record<keyof ParametrosConsulta, true> = {\n topeValoresConsulta: true,\n topeFilasConsulta: true,\n topeCrudoValoresWfs: true,\n};\n\nconst LLAVES_IDENTIFICAR: Record<keyof ParametrosIdentificar, true> = {\n toleranciaIdentificarPx: true,\n maxEntidadesIdentificar: true,\n};\n\nconst LLAVES_PROYECCION: Record<keyof ParametrosProyeccion, true> = {\n escalaZoomMarcador: true,\n};\n\n/** No se pudieron obtener los parámetros generales: el endpoint falló o el JSON es inválido. */\nexport class ParametrosGeneralesError extends Error {}\n\n/** `true` si `valor` es un objeto JSON (no `null` ni arreglo). */\nfunction esObjeto(valor: unknown): valor is Record<string, unknown> {\n return typeof valor === \"object\" && valor !== null && !Array.isArray(valor);\n}\n\n/**\n * Toma `respuesta[grupo]` y exige cada llave como entero > 0; sin valores por\n * defecto, la única fuente es BD. Solo devuelve las llaves del grupo pedido.\n */\nfunction validarGrupo<T>(\n respuesta: unknown,\n grupo: GrupoParametros,\n llaves: Record<keyof T, true>,\n): T {\n if (!esObjeto(respuesta)) {\n throw new ParametrosGeneralesError(\"Los parámetros generales no llegaron como objeto JSON.\");\n }\n const valores = respuesta[grupo];\n if (!esObjeto(valores)) {\n throw new ParametrosGeneralesError(\n `El grupo \"${grupo}\" de los parámetros generales está ausente o no es un objeto.`,\n );\n }\n const parametros = Object.keys(llaves).map((llave) => {\n const valor = valores[llave];\n if (typeof valor !== \"number\" || !Number.isInteger(valor) || valor <= 0) {\n throw new ParametrosGeneralesError(\n `El parámetro general \"${grupo}.${llave}\" falta o no es un entero positivo (recibido: ${JSON.stringify(valor)}).`,\n );\n }\n return [llave, valor] as const;\n });\n return Object.fromEntries(parametros) as T;\n}\n\n/**\n * Consulta los parámetros generales y devuelve el `grupo` validado. Se llama en\n * cada uso (sin caché) para que un cambio en BD aplique sin redesplegar ni recargar.\n * Lanza `ParametrosGeneralesError` si el endpoint falla o el grupo es inválido.\n */\nasync function obtenerParametros<T>(\n grupo: GrupoParametros,\n llaves: Record<keyof T, true>,\n): Promise<T> {\n let respuesta: unknown;\n try {\n respuesta = await fetchJson<unknown>(RUTA_PARAMETROS_GENERALES);\n } catch (error: unknown) {\n throw new ParametrosGeneralesError(\n \"No se pudieron consultar los parámetros generales en el backend.\",\n { cause: error },\n );\n }\n return validarGrupo(respuesta, grupo, llaves);\n}\n\n/** Parámetros de la herramienta Descargar (grupo `descarga`). */\nexport function obtenerParametrosDescarga(): Promise<ParametrosDescarga> {\n return obtenerParametros<ParametrosDescarga>(\"descarga\", LLAVES_DESCARGA);\n}\n\n/** Parámetros de la consulta por atributos (grupo `consulta`). */\nexport function obtenerParametrosConsulta(): Promise<ParametrosConsulta> {\n return obtenerParametros<ParametrosConsulta>(\"consulta\", LLAVES_CONSULTA);\n}\n\n/** Parámetros de la herramienta Identificar (grupo `identificar`). */\nexport function obtenerParametrosIdentificar(): Promise<ParametrosIdentificar> {\n return obtenerParametros<ParametrosIdentificar>(\"identificar\", LLAVES_IDENTIFICAR);\n}\n\n/** Parámetros de la herramienta Proyectar (grupo `proyeccion`). */\nexport function obtenerParametrosProyeccion(): Promise<ParametrosProyeccion> {\n return obtenerParametros<ParametrosProyeccion>(\"proyeccion\", LLAVES_PROYECCION);\n}\n","import Graphic from \"@arcgis/core/Graphic\";\r\nimport PopupTemplate from \"@arcgis/core/PopupTemplate\";\r\nimport esriRequest from \"@arcgis/core/request\";\r\nimport * as identifyRest from \"@arcgis/core/rest/identify\";\r\nimport IdentifyParameters from \"@arcgis/core/rest/support/IdentifyParameters\";\r\nimport type Point from \"@arcgis/core/geometry/Point\";\r\nimport type Layer from \"@arcgis/core/layers/Layer\";\r\nimport type FeatureLayer from \"@arcgis/core/layers/FeatureLayer\";\r\nimport type MapImageLayer from \"@arcgis/core/layers/MapImageLayer\";\r\nimport type WMSLayer from \"@arcgis/core/layers/WMSLayer\";\r\nimport type { GraphicHit } from \"@arcgis/core/views/types\";\r\nimport type { ParametrosIdentificar, VistaMapa } from \"@/features/maps/types\";\r\nimport { obtenerParametrosIdentificar } from \"../parametros-generales\";\r\nimport type {\r\n ContextoHerramienta,\r\n ControladorHerramienta,\r\n ManejadorEvento,\r\n} from \"./types\";\r\n\r\n/** WKID legado de Web Mercator que GeoServer no reconoce (solo entiende 3857). */\r\nconst WKID_WEB_MERCATOR_LEGADO = new Set([102100, 102113]);\r\n\r\n/** Resuelve el EPSG estándar a enviar a GeoServer, evitando los códigos Esri. */\r\nfunction wkidEpsg(spatialReference: { wkid?: number | null; latestWkid?: number | null }): number {\r\n const wkid = spatialReference.latestWkid ?? spatialReference.wkid ?? 3857;\r\n return WKID_WEB_MERCATOR_LEGADO.has(wkid) ? 3857 : wkid;\r\n}\r\n\r\n/** Etiquetas que se eliminan por completo del HTML que llega a un popup. */\r\nconst ETIQUETAS_PELIGROSAS = new Set([\r\n \"script\",\r\n \"style\",\r\n \"iframe\",\r\n \"object\",\r\n \"embed\",\r\n \"link\",\r\n \"meta\",\r\n \"base\",\r\n \"form\",\r\n \"input\",\r\n \"button\",\r\n \"textarea\",\r\n \"select\",\r\n \"option\",\r\n \"svg\",\r\n \"math\",\r\n \"frameset\",\r\n \"frame\",\r\n \"template\",\r\n \"noscript\",\r\n]);\r\n\r\n/** `href`/`src` con esquema explícito: solo estos tres se dejan navegar/cargar. */\r\nconst ESQUEMAS_URL_PERMITIDOS = new Set([\"http:\", \"https:\", \"mailto:\"]);\r\n/** Atributos que cargan o navegan a una URL: los únicos donde importa el esquema. */\r\nconst ATRIBUTOS_URL = new Set([\"href\", \"src\"]);\r\n\r\n/** true si el valor trae un esquema distinto de http/https/mailto (las URL relativas pasan). */\r\nfunction esquemaPeligroso(valorCrudo: string): boolean {\r\n const coincidencia = /^([a-z][a-z0-9+.-]*):/i.exec(valorCrudo.trim());\r\n if (!coincidencia) return false;\r\n return !ESQUEMAS_URL_PERMITIDOS.has(coincidencia[1].toLowerCase() + \":\");\r\n}\r\n\r\n/** Elimina handlers de eventos y URLs activas; deja el layout de la tabla. */\r\nfunction limpiarNodo(nodo: Element): void {\r\n const etiqueta = nodo.tagName.toLowerCase();\r\n if (ETIQUETAS_PELIGROSAS.has(etiqueta)) {\r\n nodo.remove();\r\n return;\r\n }\r\n [...nodo.attributes].forEach((atributo) => {\r\n const nombre = atributo.name.toLowerCase();\r\n if (nombre.startsWith(\"on\")) {\r\n nodo.removeAttribute(atributo.name);\r\n } else if (ATRIBUTOS_URL.has(nombre) && esquemaPeligroso(atributo.value)) {\r\n nodo.removeAttribute(atributo.name);\r\n }\r\n });\r\n // Un enlace que se quedó sin href (era javascript:/vbscript: o venía vacío)\r\n // no navega: se quita entero para no dejar texto muerto en el popup.\r\n if (etiqueta === \"a\" && !nodo.getAttribute(\"href\")) {\r\n nodo.remove();\r\n return;\r\n }\r\n Array.from(nodo.children).forEach(limpiarNodo);\r\n}\r\n\r\n/** Sanea el HTML de `GetFeatureInfo` (scripts, iframes, `on*`, URLs ejecutables…). */\r\nexport function sanitizarHtml(html: string): string {\r\n const documento = new DOMParser().parseFromString(html, \"text/html\");\r\n Array.from(documento.body.children).forEach(limpiarNodo);\r\n return documento.body.innerHTML;\r\n}\r\n\r\n/** Punto en pantalla, tal como lo entrega el evento de clic de la vista. */\r\ninterface PuntoPantalla {\r\n readonly x: number;\r\n readonly y: number;\r\n}\r\n\r\n/**\r\n * Convierte las tablas HTML de GeoServer en atributos: un array por tabla (una\r\n * por capa, en el orden de `LAYERS`) para titular cada popup con su subcapa.\r\n */\r\nfunction analizarTablasHtml(html: string): Record<string, unknown>[][] {\r\n const documento = new DOMParser().parseFromString(html, \"text/html\");\r\n return Array.from(documento.querySelectorAll(\"table\")).map((tabla) => {\r\n const filas = Array.from(tabla.querySelectorAll(\"tr\"));\r\n const filaEncabezado = filas.find((fila) => fila.querySelector(\"th\"));\r\n const nombres = Array.from(filaEncabezado?.querySelectorAll(\"th\") ?? []).map(\r\n (th) => th.textContent?.trim() || \"\",\r\n );\r\n if (!nombres.length) return [];\r\n\r\n return filas\r\n .filter((fila) => fila.querySelectorAll(\"td\").length === nombres.length)\r\n .map((fila) => {\r\n const valores = fila.querySelectorAll(\"td\");\r\n const atributos: Record<string, unknown> = {};\r\n nombres.forEach((nombre, indice) => {\r\n atributos[nombre] = valores[indice]?.textContent?.trim() || \"\";\r\n });\r\n return atributos;\r\n });\r\n });\r\n}\r\n\r\n/** Plantilla con todos los atributos (`FieldsContent` no muestra nada sin `fieldInfos`). */\r\nfunction plantillaCampos(\r\n titulo: string,\r\n atributos: Record<string, unknown> | null | undefined,\r\n): PopupTemplate {\r\n const fieldInfos = Object.keys(atributos ?? {}).map((nombre) => ({\r\n fieldName: nombre,\r\n label: nombre,\r\n visible: true,\r\n }));\r\n return new PopupTemplate({\r\n title: titulo,\r\n outFields: [\"*\"],\r\n content: fieldInfos.length\r\n ? [{ type: \"fields\", fieldInfos }]\r\n : \"Sin atributos.\",\r\n });\r\n}\r\n\r\n/**\r\n * Identificar: consulta las capas visibles en el punto clicado y muestra el\r\n * resultado en el popup (`identify` REST, GetFeatureInfo o `hitTest`).\r\n */\r\nexport class HerramientaIdentificar implements ControladorHerramienta {\r\n private vista: VistaMapa | null = null;\r\n // Listeners de ArcGIS a liberar al desactivar.\r\n private manejadores: ManejadorEvento[] = [];\r\n\r\n activar(contexto: ContextoHerramienta): void {\r\n const vista = contexto.vista;\r\n this.vista = vista;\r\n\r\n this.manejadores.push(\r\n vista.on(\"click\", (evento) => {\r\n if (!evento.mapPoint) return;\r\n void this.identificar(vista, evento.mapPoint, {\r\n x: evento.x,\r\n y: evento.y,\r\n });\r\n }),\r\n );\r\n }\r\n\r\n desactivar(): void {\r\n this.manejadores.splice(0).forEach((manejador) => manejador.remove());\r\n this.vista?.closePopup();\r\n this.vista = null;\r\n }\r\n\r\n /**\r\n * Lanza una consulta por capa y abre el popup con las promesas pendientes. La\r\n * tolerancia y el tope de entidades se piden a BD en cada clic (sin caché).\r\n */\r\n private async identificar(\r\n vista: VistaMapa,\r\n punto: Point,\r\n pantalla: PuntoPantalla,\r\n ): Promise<void> {\r\n let parametros: ParametrosIdentificar;\r\n try {\r\n parametros = await obtenerParametrosIdentificar();\r\n } catch (error: unknown) {\r\n // Sin parámetros de BD no se identifica: se avisa en el propio popup.\r\n console.error(\"[identify] No se pudieron obtener los parámetros de Identificar.\", error);\r\n vista.openPopup({\r\n location: punto,\r\n title: \"Identificar no disponible\",\r\n content: \"No se pudieron obtener los parámetros de Identificar. Inténtalo más tarde.\",\r\n });\r\n return;\r\n }\r\n\r\n const capas: Layer[] = vista.map?.allLayers.toArray() ?? [];\r\n const consultas: Promise<Graphic[]>[] = [\r\n // Una sola pasada de hitTest cubre todas las FeatureLayer del cliente.\r\n this.consultarFeatureLayers(vista, pantalla, parametros),\r\n ];\r\n\r\n for (const capa of capas) {\r\n if (!capa.visible) continue;\r\n if (capa.type === \"map-image\") {\r\n consultas.push(\r\n this.consultarMapImage(capa as MapImageLayer, vista, punto, parametros),\r\n );\r\n } else if (capa.type === \"wms\") {\r\n consultas.push(this.consultarWms(capa as WMSLayer, vista, punto, parametros));\r\n }\r\n }\r\n\r\n try {\r\n await vista.openPopup({ location: punto, promises: consultas });\r\n } catch {\r\n // `openPopup` rechaza si otro clic la vuelve a abrir: sin efecto.\r\n }\r\n }\r\n\r\n /** FeatureLayer: entidades ya dibujadas bajo el puntero (hitTest en cliente). */\r\n private async consultarFeatureLayers(\r\n vista: VistaMapa,\r\n pantalla: PuntoPantalla,\r\n parametros: ParametrosIdentificar,\r\n ): Promise<Graphic[]> {\r\n try {\r\n const { results } = await vista.hitTest(pantalla);\r\n return results\r\n .filter((resultado): resultado is GraphicHit => resultado.type === \"graphic\")\r\n .map((resultado) => resultado.graphic)\r\n .filter(\r\n (grafico) =>\r\n grafico.layer?.type === \"feature\" && grafico.layer.visible === true,\r\n )\r\n .slice(0, parametros.maxEntidadesIdentificar)\r\n .map((grafico) => {\r\n if (!grafico.popupTemplate) {\r\n const capa = grafico.layer as FeatureLayer;\r\n grafico.popupTemplate =\r\n capa.createPopupTemplate?.() ??\r\n plantillaCampos(capa.title ?? \"Entidad\", grafico.attributes);\r\n }\r\n return grafico;\r\n });\r\n } catch (error: unknown) {\r\n console.warn(\"[identify] hitTest de FeatureLayer falló\", error);\r\n return [];\r\n }\r\n }\r\n\r\n /** MapImageLayer: identify REST sobre las subcapas encendidas en el cliente. */\r\n private async consultarMapImage(\r\n capa: MapImageLayer,\r\n vista: VistaMapa,\r\n punto: Point,\r\n parametros: ParametrosIdentificar,\r\n ): Promise<Graphic[]> {\r\n try {\r\n if (!capa.url) return [];\r\n\r\n // Sin `layerIds`, `identify()` ignora las subcapas apagadas en el panel.\r\n const todasLasSubcapas = capa.allSublayers?.toArray() ?? [];\r\n const idsVisibles =\r\n todasLasSubcapas.length > 0\r\n ? todasLasSubcapas.filter((sub) => sub.visible).map((sub) => sub.id)\r\n : null;\r\n if (idsVisibles?.length === 0) return [];\r\n\r\n const peticion = new IdentifyParameters();\r\n peticion.geometry = punto;\r\n peticion.mapExtent = vista.extent;\r\n peticion.width = Math.round(vista.width);\r\n peticion.height = Math.round(vista.height);\r\n peticion.tolerance = parametros.toleranciaIdentificarPx;\r\n peticion.returnGeometry = true;\r\n peticion.layerOption = \"visible\";\r\n if (idsVisibles) peticion.layerIds = idsVisibles;\r\n\r\n const { results } = await identifyRest.identify(capa.url, peticion);\r\n // Igual que en WMS: una subcapa que coincide con el clic pero no tiene\r\n // atributos no debe dejar una página vacía en el popup.\r\n const conAtributos = results.filter(\r\n (resultado) => Object.keys(resultado.feature.attributes ?? {}).length > 0,\r\n );\r\n return conAtributos.slice(0, parametros.maxEntidadesIdentificar).map((resultado) => {\r\n const grafico = resultado.feature;\r\n grafico.popupTemplate = plantillaCampos(\r\n resultado.layerName || capa.title || \"Entidad\",\r\n grafico.attributes,\r\n );\r\n return grafico;\r\n });\r\n } catch (error: unknown) {\r\n console.warn(`[identify] identify falló en \"${capa.title}\"`, error);\r\n return [];\r\n }\r\n }\r\n\r\n /**\r\n * WMSLayer (GeoServer): GetFeatureInfo en HTML. Se muestra como lista de campos\r\n * y, si la tabla no calza, como HTML saneado.\r\n */\r\n private async consultarWms(\r\n capa: WMSLayer,\r\n vista: VistaMapa,\r\n punto: Point,\r\n parametros: ParametrosIdentificar,\r\n ): Promise<Graphic[]> {\r\n try {\r\n const url = capa.featureInfoUrl ?? capa.url;\r\n if (!url) return [];\r\n\r\n const nombres = (capa.sublayers?.toArray() ?? [])\r\n .filter((sub) => sub.visible)\r\n .map((sub) => sub.name)\r\n .filter((nombre): nombre is string => Boolean(nombre))\r\n .join(\",\");\r\n if (!nombres) return [];\r\n\r\n const extent = vista.extent;\r\n const ancho = Math.round(vista.width);\r\n const alto = Math.round(vista.height);\r\n const version = capa.version || \"1.3.0\";\r\n const es13 = version.startsWith(\"1.3\");\r\n const wkid = wkidEpsg(extent.spatialReference);\r\n // Píxel del clic dentro del lienzo actual.\r\n const i = Math.round(((punto.x - extent.xmin) / extent.width) * ancho);\r\n const j = Math.round(((extent.ymax - punto.y) / extent.height) * alto);\r\n\r\n const query: Record<string, string | number> = {\r\n SERVICE: \"WMS\",\r\n VERSION: version,\r\n REQUEST: \"GetFeatureInfo\",\r\n LAYERS: nombres,\r\n QUERY_LAYERS: nombres,\r\n STYLES: \"\",\r\n INFO_FORMAT: \"text/html\",\r\n FEATURE_COUNT: parametros.maxEntidadesIdentificar,\r\n WIDTH: ancho,\r\n HEIGHT: alto,\r\n BBOX: `${extent.xmin},${extent.ymin},${extent.xmax},${extent.ymax}`,\r\n ...(es13\r\n ? { CRS: `EPSG:${wkid}`, I: i, J: j }\r\n : { SRS: `EPSG:${wkid}`, X: i, Y: j }),\r\n };\r\n // El WMSLayer se creó con `customParameters: { token }` (fábrica WMS);\r\n // esta llamada manual de GetFeatureInfo lo replica para que las capas\r\n // WMS protegidas respondan igual que GetMap/leyenda.\r\n const token = (capa.customParameters as Record<string, unknown> | undefined)\r\n ?.token;\r\n if (typeof token === \"string\" && token) query.token = token;\r\n\r\n const { data } = await esriRequest(url, { query, responseType: \"text\" });\r\n const html = typeof data === \"string\" ? data.trim() : \"\";\r\n if (!html) return [];\r\n\r\n // Una tabla por capa, en el orden de `LAYERS`: titula cada popup con su subcapa.\r\n const nombresSubcapas = nombres.split(\",\");\r\n const tablas = analizarTablasHtml(html);\r\n const entidadesConTitulo = tablas.flatMap((filas, indice) =>\r\n filas.map((atributos) => ({\r\n atributos,\r\n titulo: nombresSubcapas[indice] || capa.title || \"Información\",\r\n })),\r\n );\r\n if (entidadesConTitulo.length > 0) {\r\n return entidadesConTitulo\r\n .slice(0, parametros.maxEntidadesIdentificar)\r\n .map(({ atributos, titulo }) => {\r\n // El contenido \"fields\" lee los valores de `attributes`; sin esto sale vacío.\r\n const grafico = new Graphic({ geometry: punto, attributes: atributos });\r\n grafico.popupTemplate = plantillaCampos(titulo, atributos);\r\n return grafico;\r\n });\r\n }\r\n\r\n // Se valida el HTML ya saneado: el envoltorio no queda vacío aunque el body sí.\r\n const contenido = sanitizarHtml(html);\r\n if (!contenido.trim()) return [];\r\n\r\n const grafico = new Graphic({ geometry: punto });\r\n grafico.popupTemplate = new PopupTemplate({\r\n title: capa.title ?? \"Información\",\r\n content: contenido,\r\n });\r\n return [grafico];\r\n } catch (error: unknown) {\r\n console.warn(`[identify] GetFeatureInfo falló en \"${capa.title}\"`, error);\r\n return [];\r\n }\r\n }\r\n}\r\n","import AreaMeasurement2D from \"@arcgis/core/widgets/AreaMeasurement2D\";\r\nimport DistanceMeasurement2D from \"@arcgis/core/widgets/DistanceMeasurement2D\";\r\nimport * as reactiveUtils from \"@arcgis/core/core/reactiveUtils\";\r\nimport type MapView from \"@arcgis/core/views/MapView\";\r\nimport type { ControladorHerramienta, ContextoHerramienta } from \"./types\";\r\n\r\n/** Estados del `viewModel` de un widget de medición de ArcGIS. */\r\ntype EstadoMedicion = \"disabled\" | \"ready\" | \"measuring\" | \"measured\";\r\n\r\n/** Medición cruda que publica el `viewModel` (valores en la unidad activa). */\r\nexport type MedicionCruda =\r\n | { readonly length: number }\r\n | { readonly area: number; readonly perimeter: number }\r\n | null;\r\n\r\n/** Lectura normalizada para la UI. */\r\nexport interface LecturaMedicion {\r\n readonly distancia?: number;\r\n readonly area?: number;\r\n readonly perimetro?: number;\r\n}\r\n\r\n/** Superficie del `viewModel` de un widget de medición que consume la modal. */\r\ninterface ViewModelMedicion {\r\n state: EstadoMedicion;\r\n unit: string;\r\n unitOptions: readonly string[];\r\n // El `viewModel` de ArcGIS publica `undefined` mientras no hay medición.\r\n measurement: MedicionCruda | undefined;\r\n start(): unknown;\r\n clear(): void;\r\n}\r\n\r\n/** Superficie mínima que se usa de los widgets de medición 2D. */\r\ninterface WidgetMedicion {\r\n viewModel: ViewModelMedicion;\r\n destroy(): void;\r\n}\r\n\r\n/** Sub-herramienta de medición activa. */\r\ntype SubMedicion = \"measure-distance\" | \"measure-area\";\r\n\r\n/**\r\n * Medición de distancia y área (solo 2D). Al alternar oculta/muestra los widgets\r\n * sin destruirlos, así se conserva la medición previa.\r\n */\r\nexport class MeasurementTools implements ControladorHerramienta {\r\n private vista: MapView | null = null;\r\n private contenedorUI: HTMLDivElement | null = null;\r\n // Widgets de medición y sus contenedores (se crean bajo demanda).\r\n private distancia: WidgetMedicion | null = null;\r\n private area: WidgetMedicion | null = null;\r\n private containerDistancia: HTMLDivElement | null = null;\r\n private containerArea: HTMLDivElement | null = null;\r\n // Sub-herramienta visible actualmente.\r\n private activo: SubMedicion | null = null;\r\n\r\n /** Crea el `div` contenedor de un widget. */\r\n private static crearContainer(): HTMLDivElement {\r\n const div = document.createElement(\"div\");\r\n div.className = \"h-full w-full\";\r\n return div;\r\n }\r\n\r\n /** Devuelve el widget de distancia, creándolo la primera vez. */\r\n private obtenerDistancia(\r\n vista: MapView,\r\n contenedorUI: HTMLDivElement,\r\n ): WidgetMedicion {\r\n if (!this.distancia) {\r\n this.containerDistancia = MeasurementTools.crearContainer();\r\n contenedorUI.appendChild(this.containerDistancia);\r\n this.distancia = new DistanceMeasurement2D({\r\n view: vista,\r\n container: this.containerDistancia,\r\n });\r\n }\r\n return this.distancia;\r\n }\r\n\r\n /** Devuelve el widget de área, creándolo la primera vez. */\r\n private obtenerArea(vista: MapView, contenedorUI: HTMLDivElement): WidgetMedicion {\r\n if (!this.area) {\r\n this.containerArea = MeasurementTools.crearContainer();\r\n contenedorUI.appendChild(this.containerArea);\r\n this.area = new AreaMeasurement2D({\r\n view: vista,\r\n container: this.containerArea,\r\n });\r\n }\r\n return this.area;\r\n }\r\n\r\n /** Muestra la sub-herramienta indicada (distancia por defecto). */\r\n activar(contexto: ContextoHerramienta, subCodigo?: string): void {\r\n // Los widgets de medición son 2D: sin `MapView` no hay nada que montar.\r\n if (contexto.vista.type !== \"2d\") return;\r\n this.vista = contexto.vista;\r\n this.contenedorUI = contexto.contenedorUI;\r\n\r\n if (subCodigo === \"measure-area\") {\r\n this.mostrarArea();\r\n } else {\r\n this.mostrarDistancia();\r\n }\r\n }\r\n\r\n /** Cambia entre distancia y área sin destruir los widgets. */\r\n alternarSubHerramienta(subCodigo: string): void {\r\n if (!this.vista || !this.contenedorUI) return;\r\n\r\n if (subCodigo === \"measure-area\") {\r\n this.ocultarDistancia();\r\n this.mostrarArea();\r\n } else {\r\n this.ocultarArea();\r\n this.mostrarDistancia();\r\n }\r\n }\r\n\r\n /** Reinicia la medición del sub-widget activo (botón «Restablecer medida»). */\r\n restablecerMedida(): void {\r\n const w = this.widgetActivo();\r\n if (!w) return;\r\n w.viewModel.clear();\r\n void w.viewModel.start();\r\n }\r\n\r\n /** Widget de la sub-herramienta activa (o `null` si no hay ninguna). */\r\n private widgetActivo(): WidgetMedicion | null {\r\n if (this.activo === \"measure-area\") return this.area;\r\n if (this.activo === \"measure-distance\") return this.distancia;\r\n return null;\r\n }\r\n\r\n /** Unidades disponibles para la sub-herramienta activa (códigos ArcGIS). */\r\n unidades(): readonly string[] {\r\n return this.widgetActivo()?.viewModel.unitOptions ?? [];\r\n }\r\n\r\n /** Unidad seleccionada en la sub-herramienta activa. */\r\n unidadActual(): string | null {\r\n return this.widgetActivo()?.viewModel.unit ?? null;\r\n }\r\n\r\n /** Cambia la unidad de la sub-herramienta activa. */\r\n establecerUnidad(codigo: string): void {\r\n const w = this.widgetActivo();\r\n if (w) w.viewModel.unit = codigo;\r\n }\r\n\r\n /** Valores de la medición en curso, normalizados; `null` si aún no hay. */\r\n lectura(): LecturaMedicion | null {\r\n const m = this.widgetActivo()?.viewModel.measurement;\r\n if (!m) return null;\r\n if (\"length\" in m) return { distancia: m.length };\r\n return { area: m.area, perimetro: m.perimeter };\r\n }\r\n\r\n /**\r\n * Observa cambios de medición y de unidad de la sub-herramienta activa.\r\n * Devuelve una función para cancelar la observación.\r\n */\r\n observar(callback: () => void): () => void {\r\n const w = this.widgetActivo();\r\n if (!w) return () => {};\r\n const manejador = reactiveUtils.watch(\r\n () => [w.viewModel.measurement, w.viewModel.unit] as const,\r\n () => callback(),\r\n { initial: true },\r\n );\r\n return () => manejador.remove();\r\n }\r\n\r\n /** Muestra el widget de distancia e inicia una medición si hace falta. */\r\n private mostrarDistancia(): void {\r\n /* istanbul ignore next -- guarda de tipos: solo se invoca con vista y contenedorUI ya asignados */\r\n if (!this.vista || !this.contenedorUI) return;\r\n const w = this.obtenerDistancia(this.vista, this.contenedorUI);\r\n /* istanbul ignore next -- `containerDistancia` queda asignado dentro de `obtenerDistancia` */\r\n if (this.containerDistancia) this.containerDistancia.style.display = \"\";\r\n this.activo = \"measure-distance\";\r\n MeasurementTools.iniciarSiHaceFalta(w);\r\n }\r\n\r\n /** Oculta el contenedor del widget de distancia. */\r\n private ocultarDistancia(): void {\r\n if (this.containerDistancia) this.containerDistancia.style.display = \"none\";\r\n }\r\n\r\n /** Muestra el widget de área e inicia una medición si hace falta. */\r\n private mostrarArea(): void {\r\n /* istanbul ignore next -- guarda de tipos: solo se invoca con vista y contenedorUI ya asignados */\r\n if (!this.vista || !this.contenedorUI) return;\r\n const w = this.obtenerArea(this.vista, this.contenedorUI);\r\n /* istanbul ignore next -- `containerArea` queda asignado dentro de `obtenerArea` */\r\n if (this.containerArea) this.containerArea.style.display = \"\";\r\n this.activo = \"measure-area\";\r\n MeasurementTools.iniciarSiHaceFalta(w);\r\n }\r\n\r\n /**\r\n * Inicia una medición solo si el widget no tiene una en curso ni terminada,\r\n * para conservar lo ya dibujado al volver a esta sub-herramienta.\r\n */\r\n private static iniciarSiHaceFalta(widget: WidgetMedicion): void {\r\n const estado = widget.viewModel.state;\r\n if (estado === \"ready\" || estado === \"disabled\") {\r\n void widget.viewModel.start();\r\n }\r\n }\r\n\r\n /** Oculta el contenedor del widget de área. */\r\n private ocultarArea(): void {\r\n if (this.containerArea) this.containerArea.style.display = \"none\";\r\n }\r\n\r\n /** Destruye ambos widgets y limpia referencias. */\r\n desactivar(): void {\r\n this.ocultarDistancia();\r\n this.ocultarArea();\r\n this.distancia?.destroy();\r\n this.area?.destroy();\r\n this.distancia = null;\r\n this.area = null;\r\n this.containerDistancia?.remove();\r\n this.containerArea?.remove();\r\n this.containerDistancia = null;\r\n this.containerArea = null;\r\n this.activo = null;\r\n this.vista = null;\r\n this.contenedorUI = null;\r\n }\r\n}\r\n","import type { CodigoHerramienta, HerramientaMapa } from \"@/features/maps/types\";\r\nimport { HerramientaIdentificar } from \"./identify.tool\";\r\nimport { MeasurementTools } from \"./medicion.tool\";\r\nimport type { ControladorHerramienta, FabricaHerramienta } from \"./types\";\r\n\r\n/**\r\n * Controlador vacío para herramientas sin lógica imperativa (p. ej. `get-coordinates`,\r\n * que usa `useCoordenadasSeleccion`). `project` y `query` no van aquí: son acciones\r\n * (`acciones.registry.ts`) y sus modales conviven con cualquier herramienta.\r\n */\r\nconst crearControladorNulo: FabricaHerramienta = () => ({\r\n activar() {},\r\n desactivar() {},\r\n});\r\n\r\n/** Implementación por código de herramienta: una herramienta nueva = una entrada aquí. */\r\nconst REGISTRO_HERRAMIENTAS: Partial<Record<CodigoHerramienta, FabricaHerramienta>> = {\r\n identify: () => new HerramientaIdentificar(),\r\n \"get-coordinates\": crearControladorNulo,\r\n \"measurement-tools\": () => new MeasurementTools(),\r\n};\r\n\r\n/** Indica si un código de herramienta tiene implementación registrada. */\r\nexport function estaSoportada(codigo: string): boolean {\r\n return codigo in REGISTRO_HERRAMIENTAS;\r\n}\r\n\r\n/** Si un código es soportado, directo o como sub-herramienta de un padre registrado. */\r\nexport function estaSoportadaConHijos(\r\n codigo: string,\r\n herramientas: readonly HerramientaMapa[],\r\n): boolean {\r\n if (estaSoportada(codigo)) return true;\r\n return herramientas.some((h) => h.hijos?.some((hijo) => hijo.codigo === codigo));\r\n}\r\n\r\n/** Crea el controlador de la herramienta; undefined (con aviso) si no tiene implementación. */\r\nexport function crearControlador(\r\n herramienta: HerramientaMapa,\r\n): ControladorHerramienta | undefined {\r\n const fabrica = REGISTRO_HERRAMIENTAS[herramienta.codigo as CodigoHerramienta];\r\n if (!fabrica) return undefined;\r\n\r\n try {\r\n return fabrica(herramienta.configuracion);\r\n } catch (error: unknown) {\r\n console.error(\r\n `No fue posible crear la herramienta \"${herramienta.codigo}\".`,\r\n error,\r\n );\r\n return undefined;\r\n }\r\n}\r\n","import { useCallback, useEffect, useRef, useState } from \"react\";\r\nimport type { HerramientaMapa, VistaMapa } from \"../types\";\r\nimport {\r\n crearControlador,\r\n estaSoportada,\r\n} from \"../services/tools/herramientas.registry\";\r\nimport type { ControladorHerramienta } from \"../services/tools/types\";\r\n\r\n/** Valor devuelto por `useHerramientaActiva`. */\r\ninterface EstadoHerramienta {\r\n codigoActivo: string | undefined;\r\n codigoPadreActivo: string | undefined;\r\n alternar: (codigo: string) => void;\r\n alternarSubHerramienta: (subCodigo: string) => void;\r\n}\r\n\r\n/** Busca la herramienta padre que contiene a la sub-herramienta indicada. */\r\nfunction encontrarPadre(\r\n codigo: string,\r\n herramientas: readonly HerramientaMapa[],\r\n): HerramientaMapa | undefined {\r\n return herramientas.find((h) => h.hijos?.some((hijo) => hijo.codigo === codigo));\r\n}\r\n\r\n/**\r\n * Gestiona qué herramienta está activa y monta/desmonta su controlador de\r\n * ArcGIS, reutilizándolo cuando solo cambia la sub-herramienta del mismo grupo.\r\n */\r\nexport function useHerramientaActiva(\r\n vista: VistaMapa | null,\r\n herramientas: readonly HerramientaMapa[],\r\n obtenerContenedorUI: () => HTMLDivElement | null,\r\n): EstadoHerramienta {\r\n // Código activo y refs al controlador montado y a su herramienta padre.\r\n const [codigoActivo, setCodigoActivo] = useState<string | undefined>(undefined);\r\n const controladorRef = useRef<ControladorHerramienta | null>(null);\r\n const padreRef = useRef<string | undefined>(undefined);\r\n // Vista a la que está ligado el controlador vigente; si cambia (p. ej. al\r\n // alternar 2D/3D) hay que recrearlo aunque la herramienta sea la misma.\r\n const vistaMontadaRef = useRef<VistaMapa | null>(null);\r\n\r\n useEffect(() => {\r\n // Nada activo (o sin vista) → desmontar el controlador vigente.\r\n if (!vista || !codigoActivo) {\r\n controladorRef.current?.desactivar();\r\n controladorRef.current = null;\r\n padreRef.current = undefined;\r\n vistaMontadaRef.current = null;\r\n return;\r\n }\r\n\r\n const contenedor = obtenerContenedorUI();\r\n if (!contenedor) return;\r\n\r\n const padre = encontrarPadre(codigoActivo, herramientas);\r\n const claveMontada = padreRef.current;\r\n const claveNueva = padre?.codigo ?? codigoActivo;\r\n\r\n // Mismo controlador montado sobre la misma vista (misma herramienta, o\r\n // sub-herramienta del mismo padre) → solo alternar sin destruir, para\r\n // conservar lo dibujado.\r\n if (\r\n controladorRef.current &&\r\n claveMontada === claveNueva &&\r\n vistaMontadaRef.current === vista\r\n ) {\r\n if (padre) controladorRef.current.alternarSubHerramienta?.(codigoActivo);\r\n return;\r\n }\r\n\r\n // Cambió la herramienta o la vista → desmontar la anterior antes de montar.\r\n controladorRef.current?.desactivar();\r\n controladorRef.current = null;\r\n padreRef.current = undefined;\r\n vistaMontadaRef.current = null;\r\n\r\n const definicion = padre ?? herramientas.find((h) => h.codigo === codigoActivo);\r\n\r\n if (!definicion) return;\r\n\r\n const controlador = crearControlador(definicion);\r\n if (!controlador) {\r\n console.error(`No fue posible activar la herramienta \"${codigoActivo}\".`);\r\n return;\r\n }\r\n\r\n const subCodigo = padre ? codigoActivo : undefined;\r\n controlador.activar({ vista, contenedorUI: contenedor }, subCodigo);\r\n controladorRef.current = controlador;\r\n padreRef.current = claveNueva;\r\n vistaMontadaRef.current = vista;\r\n }, [vista, codigoActivo, herramientas, obtenerContenedorUI]);\r\n\r\n // Desmontaje del componente: liberar el controlador vigente una sola vez.\r\n useEffect(() => {\r\n return () => {\r\n controladorRef.current?.desactivar();\r\n controladorRef.current = null;\r\n padreRef.current = undefined;\r\n vistaMontadaRef.current = null;\r\n };\r\n }, []);\r\n\r\n // Activa la herramienta, o la desactiva si ya estaba activa.\r\n const alternar = useCallback((codigo: string) => {\r\n setCodigoActivo((actual) => {\r\n if (actual === codigo) return undefined;\r\n // Soporta tanto herramientas directas como sub-herramientas.\r\n return estaSoportada(codigo) ? codigo : undefined;\r\n });\r\n }, []);\r\n\r\n // Igual que `alternar` pero para una sub-herramienta de un submenú.\r\n const alternarSubHerramienta = useCallback((subCodigo: string) => {\r\n setCodigoActivo((actual) => {\r\n if (actual === subCodigo) return undefined;\r\n return subCodigo;\r\n });\r\n }, []);\r\n\r\n // Herramienta padre de la activa (si la activa es una sub-herramienta).\r\n const padreActivo = codigoActivo\r\n ? encontrarPadre(codigoActivo, herramientas)\r\n : undefined;\r\n\r\n return {\r\n codigoActivo,\r\n codigoPadreActivo: padreActivo?.codigo,\r\n alternar,\r\n alternarSubHerramienta,\r\n };\r\n}\r\n","import { useEffect, useState } from \"react\";\n\n/** Parámetros de `useObservadorTamano`. */\ninterface OpcionesObservadorTamano {\n /** Reacciona también a `window.resize` (cuando lo que cambia es el viewport). */\n readonly escucharResizeVentana?: boolean;\n}\n\n/**\n * Llama a `medir(elemento)` al enlazarlo (tras un `requestAnimationFrame`) y cada\n * vez que cambia su tamaño (`ResizeObserver`). Devuelve el `ref` callback.\n */\nexport function useObservadorTamano<T extends HTMLElement>(\n medir: (elemento: T) => void,\n { escucharResizeVentana = false }: OpcionesObservadorTamano = {},\n): (elemento: T | null) => void {\n const [elemento, setElemento] = useState<T | null>(null);\n\n useEffect(() => {\n if (!elemento) return;\n\n const medirAhora = () => medir(elemento);\n const cuadro = requestAnimationFrame(medirAhora);\n const observador =\n typeof ResizeObserver !== \"undefined\" ? new ResizeObserver(medirAhora) : null;\n observador?.observe(elemento);\n if (escucharResizeVentana) window.addEventListener(\"resize\", medirAhora);\n\n return () => {\n cancelAnimationFrame(cuadro);\n observador?.disconnect();\n if (escucharResizeVentana) window.removeEventListener(\"resize\", medirAhora);\n };\n // `medir` se lee en cada medición: no hace falta relanzar el efecto.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [elemento, escucharResizeVentana]);\n\n return setElemento;\n}\n","import { useState } from \"react\";\nimport { useObservadorTamano } from \"./useObservadorTamano\";\n\n/** Mide el ancho y alto real de un elemento; `null` mientras no se ha medido. */\nexport function useTamanoContenedor<T extends HTMLElement>() {\n const [ancho, setAncho] = useState<number | null>(null);\n const [alto, setAlto] = useState<number | null>(null);\n\n const ref = useObservadorTamano<T>((el) => {\n setAncho(el.clientWidth);\n setAlto(el.clientHeight);\n });\n\n return [ref, ancho, alto] as const;\n}\n","/** Realce de los botones del visor: se elevan en hover y vuelven al pulsar. */\r\nexport const CLASES_REALCE_BOTON =\r\n \"transition duration-200 ease-out hover:-translate-y-0.5 active:translate-y-0\";\r\n\r\n/** Botón flotante de control (mapa base y 3D); sin borde, el fondo lo aporta el estado. */\r\nexport const CLASES_BOTON_CONTROL = `grid size-10 place-items-center rounded-xl text-[#9EA0A2] ${CLASES_REALCE_BOTON}`;\r\n\r\n/** Botón de control en reposo: sombra difusa que se nota y, al pasar el puntero, azul como el activo. */\r\nexport const CLASES_BOTON_CONTROL_REPOSO =\r\n \"bg-white shadow-[0px_4px_20px_0px_rgba(0,0,0,0.35)] hover:bg-[#8DCEFF] hover:text-slate-600\";\r\n\r\n/** Botón de la barra en estado seleccionado (chip 30×30, radio 8, azul claro). */\r\nexport const CLASES_BOTON_BARRA_SELECCIONADO =\r\n \"rounded-lg bg-[#8DCEFF] shadow-inner hover:bg-[#8DCEFF]\";\r\n\r\n/** Botón de control en estado seleccionado. */\r\nexport const CLASES_BOTON_CONTROL_SELECCIONADO = CLASES_BOTON_BARRA_SELECCIONADO;\r\n\r\n/** Botón redondo de cierre («X») de paneles y modales. */\r\nexport const CLASES_BOTON_CERRAR = `grid size-6 shrink-0 place-items-center rounded-full text-slate-400 ${CLASES_REALCE_BOTON} hover:bg-slate-100 hover:text-slate-600`;\r\n\r\n/** Ancho mínimo (px) del contenedor para el layout de escritorio (ver `useModoResponsive`). */\r\nexport const ANCHO_MINIMO_ESCRITORIO_PX = 640;\r\n\r\n/** Puntos de anclaje (fracción del alto del mapa) de la hoja inferior responsive. */\r\nexport const PUNTOS_ANCLAJE_HOJA_INFERIOR = [0.18, 0.5, 0.9] as const;\r\n\r\n/** Asa de arrastre superior de la hoja inferior. */\r\nexport const CLASES_ASA_HOJA_INFERIOR =\r\n \"flex w-full shrink-0 cursor-grab touch-none items-center justify-center py-2 active:cursor-grabbing\";\r\n\r\n/** Contenedor de la hoja inferior fija (mapa base / capas en responsive). */\r\nexport const CLASES_HOJA_INFERIOR =\r\n \"absolute inset-x-0 bottom-0 z-20 flex flex-col overflow-hidden rounded-t-[15px] \" +\r\n \"border border-b-0 border-slate-200 bg-white shadow-2xl\";\r\n","import { useTamanoContenedor } from \"@/shared/hooks/useTamanoContenedor\";\nimport { ANCHO_MINIMO_ESCRITORIO_PX } from \"../styles/controles.estilos\";\n\n/** Valor devuelto por `useModoResponsive`. */\ninterface ModoResponsive<T extends HTMLElement> {\n /** `ref` callback a enlazar en el contenedor del mapa (normalmente su `<section>` raíz). */\n readonly ref: (elemento: T | null) => void;\n /** Ancho medido del contenedor (px), `null` hasta la primera medición. */\n readonly ancho: number | null;\n /** Alto medido del contenedor (px), `null` hasta la primera medición. */\n readonly alto: number | null;\n /** `true` si el contenedor es más angosto que el mínimo; sin medición, se asume escritorio. */\n readonly responsive: boolean;\n}\n\n/** Modo de layout según el ancho del contenedor (no del viewport); expone también el alto. */\nexport function useModoResponsive<T extends HTMLElement>(): ModoResponsive<T> {\n const [ref, ancho, alto] = useTamanoContenedor<T>();\n return {\n ref,\n ancho,\n alto,\n responsive: !!ancho && ancho < ANCHO_MINIMO_ESCRITORIO_PX,\n };\n}\n","import { useCallback, useMemo, useState } from \"react\";\nimport type { CodigoPanelInferior } from \"../types\";\n\n/** Valor devuelto por `usePanelesInferiores`. */\ninterface PanelesInferiores {\n readonly panelCapasAbierto: boolean;\n readonly panelBaseMapAbierto: boolean;\n readonly togglePanelCapas: () => void;\n readonly togglePanelBaseMap: () => void;\n}\n\n/** Paneles \"Capas\" y \"Mapa base\": independientes en escritorio, excluyentes en responsive. */\nexport function usePanelesInferiores(modoResponsive: boolean): PanelesInferiores {\n const [capasAbierto, setCapasAbierto] = useState(false);\n const [baseMapAbierto, setBaseMapAbierto] = useState(false);\n const [panelActivo, setPanelActivo] = useState<CodigoPanelInferior | null>(null);\n\n const togglePanelCapas = useCallback(() => {\n if (modoResponsive) {\n setPanelActivo((actual) => (actual === \"layer\" ? null : \"layer\"));\n } else {\n setCapasAbierto((abierto) => !abierto);\n }\n }, [modoResponsive]);\n\n const togglePanelBaseMap = useCallback(() => {\n if (modoResponsive) {\n setPanelActivo((actual) => (actual === \"base-map\" ? null : \"base-map\"));\n } else {\n setBaseMapAbierto((abierto) => !abierto);\n }\n }, [modoResponsive]);\n\n return useMemo(\n () => ({\n panelCapasAbierto: modoResponsive ? panelActivo === \"layer\" : capasAbierto,\n panelBaseMapAbierto: modoResponsive\n ? panelActivo === \"base-map\"\n : baseMapAbierto,\n togglePanelCapas,\n togglePanelBaseMap,\n }),\n [\n modoResponsive,\n panelActivo,\n capasAbierto,\n baseMapAbierto,\n togglePanelCapas,\n togglePanelBaseMap,\n ],\n );\n}\n","import SimpleFillSymbol from \"@arcgis/core/symbols/SimpleFillSymbol\";\nimport SimpleLineSymbol from \"@arcgis/core/symbols/SimpleLineSymbol\";\nimport SimpleMarkerSymbol from \"@arcgis/core/symbols/SimpleMarkerSymbol\";\n\n/**\n * Símbolos (ámbar) con los que `useResaltadoConsulta` dibuja los resultados de\n * Consultar, distintos del marcador azul de \"Proyectar\".\n */\n\n/** Geometrías a las que se les puede dibujar un símbolo de estos. */\ntype SimboloConsulta = SimpleMarkerSymbol | SimpleLineSymbol | SimpleFillSymbol;\n\nexport const SIMBOLO_CONSULTA_PUNTO = new SimpleMarkerSymbol({\n color: [245, 158, 11],\n size: 10,\n outline: { color: [255, 255, 255], width: 1.5 },\n});\n\nexport const SIMBOLO_CONSULTA_LINEA = new SimpleLineSymbol({\n color: [245, 158, 11],\n width: 3,\n});\n\nexport const SIMBOLO_CONSULTA_POLIGONO = new SimpleFillSymbol({\n color: [245, 158, 11, 0.3],\n outline: { color: [245, 158, 11], width: 2 },\n});\n\n/** Variantes \"seleccionadas\" (rojo, más gruesas), para la fila activa de la tabla. */\nexport const SIMBOLO_CONSULTA_PUNTO_SELECCIONADO = new SimpleMarkerSymbol({\n color: [220, 38, 38],\n size: 13,\n outline: { color: [255, 255, 255], width: 2 },\n});\n\nexport const SIMBOLO_CONSULTA_LINEA_SELECCIONADA = new SimpleLineSymbol({\n color: [220, 38, 38],\n width: 4.5,\n});\n\nexport const SIMBOLO_CONSULTA_POLIGONO_SELECCIONADO = new SimpleFillSymbol({\n color: [220, 38, 38, 0.35],\n outline: { color: [220, 38, 38], width: 3 },\n});\n\n/** Símbolo por tipo de geometría (`multipoint` usa el de punto), o `null` si no se dibuja. */\nexport function simboloConsultaPara(\n tipoGeometria: string | undefined,\n seleccionado: boolean,\n): SimboloConsulta | null {\n switch (tipoGeometria) {\n case \"point\":\n case \"multipoint\":\n return seleccionado ? SIMBOLO_CONSULTA_PUNTO_SELECCIONADO : SIMBOLO_CONSULTA_PUNTO;\n case \"polyline\":\n return seleccionado\n ? SIMBOLO_CONSULTA_LINEA_SELECCIONADA\n : SIMBOLO_CONSULTA_LINEA;\n case \"polygon\":\n return seleccionado\n ? SIMBOLO_CONSULTA_POLIGONO_SELECCIONADO\n : SIMBOLO_CONSULTA_POLIGONO;\n default:\n return null;\n }\n}\n","import type ArcGISMap from \"@arcgis/core/Map\";\r\nimport type Graphic from \"@arcgis/core/Graphic\";\r\nimport GraphicsLayer from \"@arcgis/core/layers/GraphicsLayer\";\r\nimport { useCallback, useEffect, useMemo, useRef } from \"react\";\r\nimport { simboloConsultaPara } from \"../services/layers/simbolos-consulta\";\r\nimport type { VistaMapa } from \"../types\";\r\n\r\n/** Un grupo de clones resaltados, para una clave de capa (ver `mostrarCapa`). */\r\ninterface GrupoResaltado {\r\n mapa: WeakMap<Graphic, Graphic>;\r\n graficos: readonly Graphic[];\r\n}\r\n\r\n/** Valor devuelto por `useResaltadoConsulta`. */\r\ninterface ResaltadoConsulta {\r\n /** Reemplaza el resaltado de una clave de capa sin afectar el de las demás (ej. Línea y Torre a la vez). */\r\n mostrarCapa: (clave: string, graficos: readonly Graphic[]) => void;\r\n /** Quita del resaltado solo los clones de una clave (cerrar su pestaña). */\r\n quitarCapa: (clave: string) => void;\r\n /** Repinta todas las entidades resaltadas según qué filas están marcadas. */\r\n sincronizarSeleccion: (seleccionados: ReadonlySet<Graphic>) => void;\r\n /** Vacía el resaltado (acción \"clear\" o al cerrar los resultados). */\r\n limpiar: () => void;\r\n}\r\n\r\n/**\r\n * Capa de resaltado de Consultar en `vista.map` (no en `vista.graphics`, que usan\r\n * otras herramientas). La selección vive en `MapaView`.\r\n */\r\nexport function useResaltadoConsulta(vista: VistaMapa | null): ResaltadoConsulta {\r\n const capaRef = useRef<GraphicsLayer | null>(null);\r\n // Un grupo por clave de capa, para reemplazar/quitar uno sin tocar los demás.\r\n // Guarda la vista a la que pertenecen: si se recrea, queda invalidado por comparación.\r\n const gruposRef = useRef<{\r\n vista: VistaMapa | null;\r\n grupos: Map<string, GrupoResaltado>;\r\n }>({ vista: null, grupos: new Map() });\r\n\r\n /** Crea la capa de resaltado la primera vez; `null` si aún no hay vista. */\r\n const obtenerCapa = useCallback((): GraphicsLayer | null => {\r\n if (!vista) return null;\r\n if (!capaRef.current) {\r\n capaRef.current = new GraphicsLayer({ title: \"Resultados de consulta\" });\r\n (vista.map as ArcGISMap).add(capaRef.current);\r\n }\r\n return capaRef.current;\r\n }, [vista]);\r\n\r\n useEffect(\r\n () => () => {\r\n if (capaRef.current && vista) (vista.map as ArcGISMap).remove(capaRef.current);\r\n capaRef.current = null;\r\n },\r\n [vista],\r\n );\r\n\r\n /** Si la vista cambió desde el último grupo guardado, empieza de cero. */\r\n const grupos = useCallback((): Map<string, GrupoResaltado> => {\r\n if (gruposRef.current.vista !== vista) {\r\n gruposRef.current = { vista, grupos: new Map() };\r\n }\r\n return gruposRef.current.grupos;\r\n }, [vista]);\r\n\r\n const mostrarCapa = useCallback(\r\n (clave: string, graficos: readonly Graphic[]) => {\r\n const capa = obtenerCapa();\r\n if (!capa) return;\r\n const mapaGrupos = grupos();\r\n\r\n const anterior = mapaGrupos.get(clave);\r\n if (anterior) {\r\n for (const original of anterior.graficos) {\r\n const clon = anterior.mapa.get(original);\r\n if (clon) capa.remove(clon);\r\n }\r\n }\r\n\r\n const nuevos = new WeakMap<Graphic, Graphic>();\r\n for (const grafico of graficos) {\r\n const simbolo = simboloConsultaPara(grafico.geometry?.type, false);\r\n if (!simbolo || !grafico.geometry) continue;\r\n const clon = grafico.clone().set({ symbol: simbolo });\r\n capa.add(clon);\r\n nuevos.set(grafico, clon);\r\n }\r\n mapaGrupos.set(clave, { mapa: nuevos, graficos });\r\n },\r\n [obtenerCapa, grupos],\r\n );\r\n\r\n const quitarCapa = useCallback(\r\n (clave: string) => {\r\n const capa = capaRef.current;\r\n const mapaGrupos = grupos();\r\n const grupo = mapaGrupos.get(clave);\r\n if (!grupo) return;\r\n if (capa) {\r\n for (const original of grupo.graficos) {\r\n const clon = grupo.mapa.get(original);\r\n if (clon) capa.remove(clon);\r\n }\r\n }\r\n mapaGrupos.delete(clave);\r\n },\r\n [grupos],\r\n );\r\n\r\n const sincronizarSeleccion = useCallback(\r\n (seleccionados: ReadonlySet<Graphic>) => {\r\n // Si la vista se recreó, sus clones se fueron con ella: no hay nada\r\n // vigente que resimbolizar.\r\n if (gruposRef.current.vista !== vista) return;\r\n for (const grupo of gruposRef.current.grupos.values()) {\r\n for (const original of grupo.graficos) {\r\n const clon = grupo.mapa.get(original);\r\n if (!clon) continue;\r\n const simbolo = simboloConsultaPara(\r\n clon.geometry?.type,\r\n seleccionados.has(original),\r\n );\r\n if (simbolo) clon.symbol = simbolo;\r\n }\r\n }\r\n },\r\n [vista],\r\n );\r\n\r\n const limpiar = useCallback(() => {\r\n capaRef.current?.removeAll();\r\n gruposRef.current = { vista, grupos: new Map() };\r\n }, [vista]);\r\n\r\n // Identidad estable entre renders (solo cambia si cambian las funciones\r\n // devueltas, es decir si cambia `vista`): permite usar el objeto completo\r\n // como dependencia sin invalidar memoización.\r\n return useMemo(\r\n () => ({ mostrarCapa, quitarCapa, sincronizarSeleccion, limpiar }),\r\n [mostrarCapa, quitarCapa, sincronizarSeleccion, limpiar],\r\n );\r\n}\r\n","import type { CapaConsultable, ClaveCapaConsultable } from \"../types\";\r\n\r\n/** Clave estable de una capa consultable (pestañas de resultados, combo \"Capas\" de Consultar). */\r\nexport function claveCapaConsultable(item: CapaConsultable): ClaveCapaConsultable {\r\n return `${item.servicio.nombre}::${item.capa.identificador}`;\r\n}\r\n\r\nconst ANCHO_REFERENCIA_PX = 1920;\r\n\r\n/** Factor de escala de la interfaz según el ancho del contenedor (clase `.escala-interfaz`). */\r\nexport function useEscalaInterfaz(anchoContenedor: number | null): number {\r\n return anchoContenedor ? Math.max(1, anchoContenedor / ANCHO_REFERENCIA_PX) : 1;\r\n}\r\n","import type Graphic from \"@arcgis/core/Graphic\";\r\nimport { useCallback, useMemo, useState } from \"react\";\r\nimport type {\r\n CapaConsultable,\r\n ResultadoConsultaCapa,\r\n ResultadosConsultaCapas,\r\n VistaMapa,\r\n} from \"../types\";\r\nimport { claveCapaConsultable } from \"../utils/mapa-helpers\";\r\nimport type { useResaltadoConsulta } from \"./useResaltadoConsulta\";\r\n\r\n/** Valor devuelto por `useResultadosConsulta`. */\r\ninterface ResultadosConsulta {\r\n resultados: ResultadosConsultaCapas;\r\n /** Filas marcadas (checkbox) de la pestaña activa. Un único `Set` global\r\n * (no uno por capa): los `Graphic` de capas distintas nunca son el mismo\r\n * objeto, así que no hay ambigüedad. */\r\n seleccionados: ReadonlySet<Graphic>;\r\n /** Agrega o actualiza la pestaña de esa capa sin tocar las demás. */\r\n onResultado: (resultado: ResultadoConsultaCapa, capa: CapaConsultable) => void;\r\n /** Cierra una pestaña de resultados sin afectar las demás. */\r\n onQuitarPestana: (clave: string) => void;\r\n /** Cambia la pestaña activa y centra el mapa en esa capa. */\r\n onCambiarPestana: (clave: string) => void;\r\n /** Marca/desmarca una fila; acerca la vista a la entidad al marcarla. */\r\n onAlternarFila: (grafico: Graphic) => void;\r\n /** Lupa por fila: acerca la vista sin alterar la selección. */\r\n onZoomFila: (grafico: Graphic) => void;\r\n /** Checkbox \"marcar todas\" de la pestaña activa. */\r\n onAlternarTodos: () => void;\r\n /** Vacía todos los resultados, la selección y su resaltado en el mapa. */\r\n limpiar: () => void;\r\n}\r\n\r\n/**\r\n * Estado de \"Consultar\": una pestaña por capa, filas marcadas y resaltado. Vive en\r\n * `MapaView` para sobrevivir al cierre del formulario.\r\n */\r\nexport function useResultadosConsulta(\r\n vista: VistaMapa | null,\r\n resaltadoConsulta: ReturnType<typeof useResaltadoConsulta>,\r\n): ResultadosConsulta {\r\n const [resultados, setResultados] = useState<ResultadosConsultaCapas>(() => ({\r\n entradas: [],\r\n activa: null,\r\n }));\r\n const [seleccionados, setSeleccionados] = useState<ReadonlySet<Graphic>>(\r\n () => new Set(),\r\n );\r\n\r\n const onResultado = useCallback(\r\n (resultado: ResultadoConsultaCapa, capa: CapaConsultable) => {\r\n const clave = claveCapaConsultable(capa);\r\n // La limpieza de seleccionados se calcula antes: el updater de setResultados debe ser puro.\r\n const anteriorEntrada = resultados.entradas.find(\r\n (entrada) => entrada.clave === clave,\r\n );\r\n if (anteriorEntrada) {\r\n setSeleccionados((seleccion) => {\r\n if (seleccion.size === 0) return seleccion;\r\n const nuevo = new Set(seleccion);\r\n for (const grafico of anteriorEntrada.resultado.graficos) nuevo.delete(grafico);\r\n return nuevo;\r\n });\r\n }\r\n setResultados((anterior) => {\r\n const entradas = anterior.entradas.filter((entrada) => entrada.clave !== clave);\r\n entradas.push({ clave, capa, resultado });\r\n return { entradas, activa: clave };\r\n });\r\n resaltadoConsulta.mostrarCapa(clave, resultado.graficos);\r\n if (resultado.extent) void vista?.goTo(resultado.extent);\r\n },\r\n [vista, resaltadoConsulta, resultados],\r\n );\r\n\r\n const onQuitarPestana = useCallback(\r\n (clave: string) => {\r\n const entradaQuitada = resultados.entradas.find(\r\n (entrada) => entrada.clave === clave,\r\n );\r\n /* istanbul ignore next -- la \"x\" solo se pinta en una pestaña existente */\r\n if (!entradaQuitada) return;\r\n\r\n setSeleccionados((seleccion) => {\r\n if (seleccion.size === 0) return seleccion;\r\n const nuevo = new Set(seleccion);\r\n for (const grafico of entradaQuitada.resultado.graficos) nuevo.delete(grafico);\r\n return nuevo;\r\n });\r\n setResultados((anterior) => {\r\n const entradas = anterior.entradas.filter((entrada) => entrada.clave !== clave);\r\n const activa =\r\n anterior.activa === clave\r\n ? (entradas[entradas.length - 1]?.clave ?? null)\r\n : anterior.activa;\r\n return { entradas, activa };\r\n });\r\n resaltadoConsulta.quitarCapa(clave);\r\n },\r\n [resaltadoConsulta, resultados],\r\n );\r\n\r\n const onCambiarPestana = useCallback(\r\n (clave: string) => {\r\n setResultados((anterior) => ({ ...anterior, activa: clave }));\r\n const entrada = resultados.entradas.find((item) => item.clave === clave);\r\n /* istanbul ignore next -- el botón se pinta desde la misma lista de entradas que se busca aquí */\r\n if (!entrada) return;\r\n const marcados = entrada.resultado.graficos.filter(\r\n (grafico) => seleccionados.has(grafico) && grafico.geometry,\r\n );\r\n if (marcados.length > 0) void vista?.goTo(marcados);\r\n else if (entrada.resultado.extent) void vista?.goTo(entrada.resultado.extent);\r\n },\r\n [resultados, seleccionados, vista],\r\n );\r\n\r\n const onAlternarFila = useCallback(\r\n (grafico: Graphic) => {\r\n const nuevo = new Set(seleccionados);\r\n const seMarca = !nuevo.has(grafico);\r\n if (seMarca) nuevo.add(grafico);\r\n else nuevo.delete(grafico);\r\n setSeleccionados(nuevo);\r\n resaltadoConsulta.sincronizarSeleccion(nuevo);\r\n if (seMarca && grafico.geometry) void vista?.goTo(grafico.geometry);\r\n },\r\n [seleccionados, resaltadoConsulta, vista],\r\n );\r\n\r\n const onZoomFila = useCallback(\r\n (grafico: Graphic) => {\r\n if (grafico.geometry) void vista?.goTo(grafico.geometry);\r\n },\r\n [vista],\r\n );\r\n\r\n const onAlternarTodos = useCallback(() => {\r\n const entradaActiva = resultados.entradas.find(\r\n (entrada) => entrada.clave === resultados.activa,\r\n );\r\n /* istanbul ignore next -- guarda de tipos: la tabla solo se monta con una pestaña activa */\r\n if (!entradaActiva) return;\r\n const graficos = entradaActiva.resultado.graficos;\r\n const algunaMarcada = graficos.some((grafico) => seleccionados.has(grafico));\r\n const nuevo = new Set(seleccionados);\r\n for (const grafico of graficos) {\r\n if (algunaMarcada) nuevo.delete(grafico);\r\n else nuevo.add(grafico);\r\n }\r\n setSeleccionados(nuevo);\r\n resaltadoConsulta.sincronizarSeleccion(nuevo);\r\n }, [resultados, seleccionados, resaltadoConsulta]);\r\n\r\n const limpiar = useCallback(() => {\r\n resaltadoConsulta.limpiar();\r\n setResultados({ entradas: [], activa: null });\r\n setSeleccionados(new Set());\r\n }, [resaltadoConsulta]);\r\n\r\n // Identidad estable entre renders salvo que cambie algo de lo que expone,\r\n // igual que `useResaltadoConsulta`: permite pasar el objeto completo como\r\n // dependencia sin invalidar memoización innecesariamente.\r\n return useMemo(\r\n () => ({\r\n resultados,\r\n seleccionados,\r\n onResultado,\r\n onQuitarPestana,\r\n onCambiarPestana,\r\n onAlternarFila,\r\n onZoomFila,\r\n onAlternarTodos,\r\n limpiar,\r\n }),\r\n [\r\n resultados,\r\n seleccionados,\r\n onResultado,\r\n onQuitarPestana,\r\n onCambiarPestana,\r\n onAlternarFila,\r\n onZoomFila,\r\n onAlternarTodos,\r\n limpiar,\r\n ],\r\n );\r\n}\r\n","import ArcGISMap from \"@arcgis/core/Map\";\nimport type Viewpoint from \"@arcgis/core/Viewpoint\";\nimport MapView from \"@arcgis/core/views/MapView\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { ConfiguracionVisualMapa, VistaMapa } from \"../types\";\n\n/** Valor devuelto por `useVistaArcgis`. */\ninterface VistaArcgis {\n contenedorRef: React.RefObject<HTMLDivElement | null>;\n vista: VistaMapa | null;\n /** Error de inicialización del mapa; `null` mientras carga o si tuvo éxito. */\n error: Error | null;\n cambiarBasemap: (codigo: string) => void;\n /** Regresa el mapa al viewpoint con el que se inicializó. */\n irAInicio: () => void;\n}\n\n/** Compara dos configuraciones por valor, para ignorar objetos nuevos con los mismos datos. */\nfunction mismaConfiguracion(\n a: ConfiguracionVisualMapa,\n b: ConfiguracionVisualMapa,\n): boolean {\n return (\n a.basemap === b.basemap &&\n a.zoom === b.zoom &&\n a.width === b.width &&\n a.height === b.height &&\n a.center[0] === b.center[0] &&\n a.center[1] === b.center[1]\n );\n}\n\n/**\n * Crea y destruye la vista de ArcGIS (`MapView` o `SceneView`, cargado en diferido),\n * conservando el encuadre al alternar y aplicando el cambio de mapa base.\n */\nexport function useVistaArcgis(\n configuracion: ConfiguracionVisualMapa | undefined,\n tridimensional: boolean,\n): VistaArcgis {\n // Refs a los objetos de ArcGIS y estado expuesto a la UI.\n const contenedorRef = useRef<HTMLDivElement | null>(null);\n const mapaRef = useRef<ArcGISMap | null>(null);\n const vistaRef = useRef<VistaMapa | null>(null);\n const inicioRef = useRef<Viewpoint | null>(null);\n\n // Conserva la configuración anterior si llega una igual por valor, para no\n // recrear la vista (ajuste en render con `useState`, no con un `ref`).\n const [configuracionEstable, setConfiguracionEstable] = useState(configuracion);\n if (\n configuracionEstable !== configuracion &&\n !(\n configuracionEstable &&\n configuracion &&\n mismaConfiguracion(configuracionEstable, configuracion)\n )\n ) {\n setConfiguracionEstable(configuracion);\n }\n\n // Contrato y viewpoint de la vista anterior: permiten restaurar el encuadre\n // al recrear la vista solo por alternar 2D/3D (no al cambiar de contrato).\n const contratoPrevioRef = useRef(configuracionEstable);\n const viewpointPrevioRef = useRef<Viewpoint | null>(null);\n const [vista, setVista] = useState<VistaMapa | null>(null);\n const [error, setError] = useState<Error | null>(null);\n\n useEffect(() => {\n const contenedor = contenedorRef.current;\n if (!contenedor || !configuracionEstable) return;\n\n // Solo se conserva el encuadre si seguimos en el mismo contrato de mapa.\n const mismoContrato = contratoPrevioRef.current === configuracionEstable;\n contratoPrevioRef.current = configuracionEstable;\n if (!mismoContrato) viewpointPrevioRef.current = null;\n\n setError(null);\n const mapa = new ArcGISMap({ basemap: configuracionEstable.basemap });\n const propiedades = {\n map: mapa,\n container: contenedor,\n zoom: configuracionEstable.zoom,\n center: configuracionEstable.center,\n // Sin widgets nativos (zoom, brújula, navegación 3D): el visor aporta\n // los suyos en `BarraHerramientas`.\n ui: { components: [] },\n // Oculta la atribución de Esri (decisión explícita del producto: los\n // términos de Esri piden mostrarla al usar sus basemaps, pero se optó\n // por quitarla igual porque ocupaba espacio en el visor).\n attributionVisible: false,\n // Los popups nativos arrancan apagados: solo la herramienta «Identificar»\n // los enciende. Sin plantilla propia, el popup muestra todos los campos.\n popupEnabled: false,\n popup: { defaultPopupTemplateEnabled: true },\n };\n mapaRef.current = mapa;\n\n let cancelado = false;\n let creada: VistaMapa | null = null;\n\n // Instancia la vista (cargando `SceneView` bajo demanda), restaura el\n // encuadre previo si lo hay (alternancia 2D/3D) y la publica.\n const iniciar = async (): Promise<void> => {\n let nueva: VistaMapa;\n if (tridimensional) {\n const { default: SceneView } = await import(\n \"@arcgis/core/views/SceneView\"\n );\n nueva = new SceneView(propiedades);\n } else {\n nueva = new MapView(propiedades);\n }\n if (cancelado) {\n nueva.destroy();\n return;\n }\n creada = nueva;\n vistaRef.current = nueva;\n\n await nueva.when();\n if (cancelado) return;\n inicioRef.current = nueva.viewpoint.clone();\n const previo = viewpointPrevioRef.current;\n if (previo) void nueva.goTo(previo);\n setVista(nueva);\n };\n\n void iniciar().catch((causa: unknown) => {\n if (cancelado) return;\n const fallo =\n causa instanceof Error\n ? causa\n : new Error(\"No fue posible inicializar el mapa.\");\n console.error(\"No fue posible inicializar el mapa.\", fallo);\n setError(fallo);\n });\n\n // Limpieza: recuerda el encuadre, destruye la vista y resetea refs y estado.\n return () => {\n cancelado = true;\n viewpointPrevioRef.current = vistaRef.current?.viewpoint?.clone() ?? null;\n mapaRef.current = null;\n vistaRef.current = null;\n inicioRef.current = null;\n setVista(null);\n setError(null);\n creada?.destroy();\n };\n }, [configuracionEstable, tridimensional]);\n\n // Cambia el mapa base sobre la instancia viva.\n const cambiarBasemap = useCallback((codigo: string) => {\n const mapa = mapaRef.current;\n if (mapa && codigo) mapa.basemap = codigo;\n }, []);\n\n // Vuelve al viewpoint inicial.\n const irAInicio = useCallback(() => {\n const inicio = inicioRef.current;\n if (vistaRef.current && inicio) void vistaRef.current.goTo(inicio);\n }, []);\n\n return { contenedorRef, vista, error, cambiarBasemap, irAInicio };\n}\n","/** Lee el mensaje que el proxy devuelve dentro del error de ArcGIS. */\r\nfunction mensajeDelBackend(fallo: unknown): string | undefined {\r\n if (!fallo || typeof fallo !== \"object\") return undefined;\r\n\r\n const detalles = (fallo as { details?: unknown }).details;\r\n const bruto =\r\n detalles && typeof detalles === \"object\"\r\n ? (detalles as { raw?: unknown }).raw\r\n : undefined;\r\n let respuesta: unknown = bruto;\r\n\r\n if (typeof bruto === \"string\") {\r\n try {\r\n respuesta = JSON.parse(bruto);\r\n } catch {\r\n return undefined;\r\n }\r\n }\r\n\r\n if (!respuesta || typeof respuesta !== \"object\") return undefined;\r\n const cuerpo = respuesta as { mensaje?: unknown; message?: unknown };\r\n const mensaje = cuerpo.mensaje ?? cuerpo.message;\r\n if (typeof mensaje !== \"string\" || !mensaje.trim()) return undefined;\r\n // Tope de longitud: un backend hablador no debe poder inundar la UI de texto.\r\n return mensaje.trim().slice(0, 300);\r\n}\r\n\r\n/** Palabras/códigos que indican un token de ArcGIS inválido o vencido, ancladas\r\n * a límite de palabra para no disparar con un número de otro tipo que\r\n * contenga \"498\"/\"499\" como subcadena (p. ej. un tamaño en bytes). */\r\nconst PATRON_ERROR_TOKEN = /\\btoken\\b|\\bcredential\\w*\\b|\\b498\\b|\\b499\\b|\\bunauthor\\w*\\b/i;\r\n\r\n/** Convierte un fallo técnico de carga en el mensaje visible del servicio. */\r\nexport function mensajeErrorServicio(fallo: unknown): string {\r\n const mensaje = mensajeDelBackend(fallo);\r\n if (mensaje) return mensaje;\r\n\r\n const detalle = fallo instanceof Error ? fallo.message : \"\";\r\n if (PATRON_ERROR_TOKEN.test(detalle)) {\r\n return \"El token de ArcGIS no es válido o está vencido.\";\r\n }\r\n return detalle || \"No fue posible cargar el servicio.\";\r\n}\r\n","import type { CodigoHerramienta, HerramientaMapa } from \"@/features/maps/types\";\r\n\r\n/** Anida las mediciones como `hijos` de `measurement-tools` para mostrarlas en un desplegable. */\r\nexport function agruparHerramientasMedicion(\r\n herramientas: readonly HerramientaMapa[],\r\n): HerramientaMapa[] {\r\n // Localiza las tres herramientas implicadas.\r\n const padre = herramientas.find(\r\n (h) => h.codigo === (\"measurement-tools\" satisfies CodigoHerramienta),\r\n );\r\n const distancia = herramientas.find(\r\n (h) => h.codigo === (\"measure-distance\" satisfies CodigoHerramienta),\r\n );\r\n const area = herramientas.find(\r\n (h) => h.codigo === (\"measure-area\" satisfies CodigoHerramienta),\r\n );\r\n // Si falta alguna, no se reagrupa nada.\r\n if (!padre || !distancia || !area) return [...herramientas];\r\n\r\n // Reemplaza el padre por su versión con hijos y quita las sueltas.\r\n const grupoMedicion: HerramientaMapa = { ...padre, hijos: [distancia, area] };\r\n\r\n return herramientas\r\n .filter((h) => h !== distancia && h !== area)\r\n .map((h) => (h === padre ? grupoMedicion : h));\r\n}\r\n","import type {\r\n CodigoHerramienta,\r\n ConfiguracionHerramienta,\r\n VistaMapa,\r\n} from \"@/features/maps/types\";\r\n\r\n/** Recursos que el visor entrega a una acción instantánea del mapa. */\r\nexport interface ContextoAccion {\r\n readonly vista: VistaMapa;\r\n /** Regresa el mapa a la vista inicial configurada. */\r\n readonly irAInicio: () => void;\r\n /** Cancela la herramienta activa y limpia dibujos/mediciones/selecciones. */\r\n readonly limpiar: () => void;\r\n /** Alterna la visibilidad del panel de capas. */\r\n readonly togglePanelCapas: () => void;\r\n /** Alterna la visibilidad de la modal de herramientas de medición. */\r\n readonly toggleModalMedicion: () => void;\r\n /** Alterna la visibilidad de la modal de proyección de coordenadas. */\r\n readonly toggleModalProyeccion: () => void;\r\n /** Alterna la visibilidad de la modal de consulta por atributos. */\r\n readonly toggleModalConsulta: () => void;\r\n /** Alterna la visibilidad del panel de metadatos del mapa. */\r\n readonly togglePanelMetadata: () => void;\r\n /** Alterna entre la vista 2D (`MapView`) y la vista 3D (`SceneView`). */\r\n readonly alternarTridimensional: () => void;\r\n}\r\n\r\n/** Función que ejecuta una acción instantánea con su contexto y configuración. */\r\ntype EjecutorAccion = (\r\n contexto: ContextoAccion,\r\n configuracion: ConfiguracionHerramienta,\r\n) => void;\r\n\r\n/** Lee `delta` de la configuración o usa el valor por defecto. */\r\nfunction leerDelta(\r\n configuracion: ConfiguracionHerramienta,\r\n porDefecto: number,\r\n): number {\r\n return configuracion.delta ?? porDefecto;\r\n}\r\n\r\n/**\r\n * Acciones instantáneas por código de herramienta: se ejecutan una vez al\r\n * hacer clic, sin estado activo/inactivo.\r\n */\r\nconst REGISTRO_ACCIONES: Partial<Record<CodigoHerramienta, EjecutorAccion>> = {\r\n home: (contexto) => contexto.irAInicio(),\r\n \"zoom-in\": (contexto, configuracion) => {\r\n void contexto.vista.goTo({\r\n zoom: contexto.vista.zoom + leerDelta(configuracion, 1),\r\n });\r\n },\r\n \"zoom-out\": (contexto, configuracion) => {\r\n void contexto.vista.goTo({\r\n zoom: contexto.vista.zoom + leerDelta(configuracion, -1),\r\n });\r\n },\r\n clear: (contexto) => contexto.limpiar(),\r\n layer: (contexto) => contexto.togglePanelCapas(),\r\n // Abre/cierra la modal que contiene las sub-herramientas de medición.\r\n \"measurement-tools\": (contexto) => contexto.toggleModalMedicion(),\r\n \"three-dimensional\": (contexto) => contexto.alternarTridimensional(),\r\n // Abre/cierra el panel con los metadatos del mapa y sus servicios.\r\n metadata: (contexto) => contexto.togglePanelMetadata(),\r\n // Abre/cierra la modal de proyección; independiente de las demás\r\n // herramientas (p. ej. \"get-coordinates\") para que ambas puedan estar\r\n // abiertas a la vez, hasta que el usuario las cierre.\r\n project: (contexto) => contexto.toggleModalProyeccion(),\r\n // Abre/cierra la modal de consulta; mismo criterio de independencia que\r\n // \"project\" (no dibuja sobre el mapa, así que puede convivir con cualquier\r\n // otra herramienta activa hasta que el usuario la cierre).\r\n query: (contexto) => contexto.toggleModalConsulta(),\r\n};\r\n\r\n/** Indica si un código de herramienta es una acción instantánea soportada. */\r\nexport function esAccion(codigo: string): boolean {\r\n return codigo in REGISTRO_ACCIONES;\r\n}\r\n\r\n/** Ejecuta la acción asociada al código; no hace nada si no está registrada. */\r\nexport function ejecutarAccion(\r\n codigo: string,\r\n contexto: ContextoAccion,\r\n configuracion: ConfiguracionHerramienta,\r\n): void {\r\n REGISTRO_ACCIONES[codigo as CodigoHerramienta]?.(contexto, configuracion);\r\n}\r\n","import type { CapaConsultable, EstadosCapas, ServicioGis } from \"../types\";\n\n/**\n * Tipos con consulta por atributos. Es lista blanca para que un tipo nuevo no\n * aparezca en \"Capas\" sin mecanismo; `ARCGIS_TILE` queda fuera (solo teselas).\n */\nconst TIPOS_CONSULTABLES: ReadonlySet<string> = new Set([\n \"ARCGIS_FEATURE\",\n \"ARCGIS_MAP\",\n \"OGC_WMS\",\n]);\n\n/**\n * Capas visibles consultables por atributos (combo \"Capas\" de Consultar). Exige\n * servicio activo e `identificador`.\n */\nexport function capasActivasConsultables(\n servicios: readonly ServicioGis[],\n estados: EstadosCapas,\n): CapaConsultable[] {\n return servicios.flatMap((servicio) => {\n if (!TIPOS_CONSULTABLES.has(servicio.tipoServicio)) return [];\n if (!estados.servicios[servicio.nombre]) return [];\n\n const capas = servicio.configuracionCapas.capas ?? [];\n const visibilidadCapas = estados.capas[servicio.nombre] ?? {};\n\n return capas\n .filter((capa) => capa.identificador !== \"\")\n .filter((capa) => Boolean(visibilidadCapas[capa.identificador]))\n .map((capa) => ({ servicio, capa }));\n });\n}\n","import type { CodigoHerramienta } from \"@/features/maps/types\";\n\n/** Grupo de herramientas contiguas dentro de la barra. */\nexport interface GrupoBarra {\n codigos: readonly CodigoHerramienta[];\n /** Se dibuja dentro de su propia píldora tenue, separada del resto. */\n encapsulado?: boolean;\n}\n\n/** Orden y agrupación visual de las herramientas en la barra de escritorio. */\nexport const GRUPOS_BARRA_ESCRITORIO: readonly GrupoBarra[] = [\n {\n codigos: [\n \"layer\",\n \"measurement-tools\",\n \"identify\",\n \"get-coordinates\",\n \"project\",\n \"query\",\n \"clear\",\n ],\n },\n { codigos: [\"home\", \"zoom-in\", \"zoom-out\"], encapsulado: true },\n];\n\n/** Barra reducida (responsive): capas, home y zoom. \"Mapa base\" y \"3D\" van aparte. */\nexport const GRUPOS_BARRA_RESPONSIVE: readonly GrupoBarra[] = [\n { codigos: [\"layer\"] },\n { codigos: [\"home\", \"zoom-in\", \"zoom-out\"], encapsulado: true },\n];\n\n/** Códigos de la barra reducida, derivados de `GRUPOS_BARRA_RESPONSIVE`. */\nexport const CODIGOS_BARRA_RESPONSIVE: ReadonlySet<CodigoHerramienta> = new Set(\n GRUPOS_BARRA_RESPONSIVE.flatMap((grupo) => grupo.codigos),\n);\n","import type { CodigoHerramienta, HerramientaMapa } from \"../types\";\r\nimport { CODIGOS_BARRA_RESPONSIVE } from \"../services/tools/grupos-barra\";\r\n\r\n/**\r\n * Herramientas de la barra genérica: sin 3D, mapa base ni metadata (van aparte),\r\n * sin medición en 3D y, en responsive, solo `CODIGOS_BARRA_RESPONSIVE`.\r\n */\r\nexport function filtrarHerramientasBarra(\r\n herramientas: readonly HerramientaMapa[],\r\n tridimensional: boolean,\r\n modoResponsive: boolean,\r\n): HerramientaMapa[] {\r\n return herramientas\r\n .filter(\r\n (herramienta) =>\r\n herramienta.codigo !== \"three-dimensional\" &&\r\n herramienta.codigo !== \"base-map\" &&\r\n herramienta.codigo !== \"metadata\" &&\r\n !(tridimensional && herramienta.codigo === \"measurement-tools\") &&\r\n !(\r\n modoResponsive &&\r\n !CODIGOS_BARRA_RESPONSIVE.has(\r\n herramienta.codigo as CodigoHerramienta,\r\n )\r\n ),\r\n )\r\n .map((herramienta) =>\r\n herramienta.codigo === \"measurement-tools\"\r\n ? { ...herramienta, hijos: undefined }\r\n : herramienta,\r\n );\r\n}","import type { CapaServicio, GrupoServicios, ServicioGis } from \"../types\";\r\n\r\n/** Completa las subcapas de los servicios que no las declaran con las descubiertas en runtime. */\r\nexport function resolverServicios(\r\n servicios: readonly ServicioGis[],\r\n capasDescubiertas: ReadonlyMap<string, readonly CapaServicio[]>,\r\n): ServicioGis[] {\r\n return servicios.map((servicio) => {\r\n const descubiertas = capasDescubiertas.get(servicio.nombre);\r\n const yaDeclaradas = (servicio.configuracionCapas.capas?.length ?? 0) > 0;\r\n if (!descubiertas || yaDeclaradas) return servicio;\r\n return {\r\n ...servicio,\r\n configuracionCapas: {\r\n ...servicio.configuracionCapas,\r\n capas: [...descubiertas],\r\n },\r\n };\r\n });\r\n}\r\n\r\n/** Restaura la estructura grupos → servicios con las versiones resueltas. */\r\nexport function reagruparServicios(\r\n grupos: readonly GrupoServicios[],\r\n serviciosResueltos: readonly ServicioGis[],\r\n): GrupoServicios[] {\r\n const porNombre = new Map(\r\n serviciosResueltos.map((servicio) => [servicio.nombre, servicio]),\r\n );\r\n return grupos.map((grupo) => ({\r\n ...grupo,\r\n servicios: grupo.servicios.map(\r\n (servicio) => porNombre.get(servicio.nombre) ?? servicio,\r\n ),\r\n }));\r\n}","export default \"data:image/svg+xml,%3csvg%20width='30'%20height='30'%20viewBox='0%200%2030%2030'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M24.0406%2010.19L15.0006%2015.42L5.96057%2010.19C6.36057%209.45002%206.94057%208.80002%207.59057%208.44002L12.9306%205.48002C14.0706%204.84002%2015.9306%204.84002%2017.0706%205.48002L22.4106%208.44002C23.0606%208.80002%2023.6406%209.45002%2024.0406%2010.19Z'%20fill='white'/%3e%3cpath%20d='M15.0006%2015.42V25C14.2506%2025%2013.5006%2024.84%2012.9306%2024.52L7.59063%2021.56C6.38063%2020.89%205.39062%2019.21%205.39062%2017.83V12.17C5.39062%2011.53%205.61062%2010.83%205.96062%2010.19L15.0006%2015.42Z'%20fill='%23E8E8E8'/%3e%3cpath%20d='M24.6106%2012.17V17.83C24.6106%2019.21%2023.6206%2020.89%2022.4106%2021.56L17.0706%2024.52C16.5006%2024.84%2015.7506%2025%2015.0006%2025V15.42L24.0406%2010.19C24.3906%2010.83%2024.6106%2011.53%2024.6106%2012.17Z'%20fill='%23CCCCCC'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='30'%20height='30'%20viewBox='0%200%2030%2030'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M24.0406%2010.19L15.0006%2015.42L5.96057%2010.19C6.36057%209.45%206.94057%208.8%207.59057%208.44L12.9306%205.48C14.0706%204.84%2015.9306%204.84%2017.0706%205.48L22.4106%208.44C23.0606%208.8%2023.6406%209.45%2024.0406%2010.19Z'%20fill='%239EA0A2'/%3e%3cpath%20d='M15.0006%2015.4199V24.9999C14.2506%2024.9999%2013.5006%2024.8399%2012.9306%2024.5199L7.59063%2021.5599C6.38063%2020.8899%205.39062%2019.2099%205.39062%2017.8299V12.1699C5.39062%2011.5299%205.61062%2010.8299%205.96062%2010.1899L15.0006%2015.4199Z'%20fill='%23787A7D'/%3e%3cpath%20d='M24.6106%2012.1699V17.8299C24.6106%2019.2099%2023.6206%2020.8899%2022.4106%2021.5599L17.0706%2024.5199C16.5006%2024.8399%2015.7506%2024.9999%2015.0006%2024.9999V15.4199L24.0406%2010.1899C24.3906%2010.8299%2024.6106%2011.5299%2024.6106%2012.1699Z'%20fill='%23292D32'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='27'%20height='27'%20viewBox='0%200%2027%2027'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M13.1708%202.19507C7.12319%202.19507%202.19508%207.12318%202.19508%2013.1708C2.19508%2019.2185%207.12319%2024.1466%2013.1708%2024.1466C19.2185%2024.1466%2024.1466%2019.2185%2024.1466%2013.1708C24.1466%207.12318%2019.2185%202.19507%2013.1708%202.19507ZM12.3477%208.78052C12.3477%208.33051%2012.7208%207.95734%2013.1708%207.95734C13.6208%207.95734%2013.994%208.33051%2013.994%208.78052V14.2684C13.994%2014.7184%2013.6208%2015.0916%2013.1708%2015.0916C12.7208%2015.0916%2012.3477%2014.7184%2012.3477%2014.2684V8.78052ZM14.1806%2017.9782C14.1257%2018.1209%2014.0489%2018.2306%2013.9501%2018.3404C13.8404%2018.4392%2013.7196%2018.516%2013.5879%2018.5709C13.4562%2018.6258%2013.3135%2018.6587%2013.1708%2018.6587C13.0281%2018.6587%2012.8855%2018.6258%2012.7538%2018.5709C12.622%2018.516%2012.5013%2018.4392%2012.3916%2018.3404C12.2928%2018.2306%2012.2159%2018.1209%2012.1611%2017.9782C12.1062%2017.8465%2012.0733%2017.7038%2012.0733%2017.5611C12.0733%2017.4184%2012.1062%2017.2757%2012.1611%2017.144C12.2159%2017.0123%2012.2928%2016.8916%2012.3916%2016.7818C12.5013%2016.6831%2012.622%2016.6062%2012.7538%2016.5513C13.0172%2016.4416%2013.3245%2016.4416%2013.5879%2016.5513C13.7196%2016.6062%2013.8404%2016.6831%2013.9501%2016.7818C14.0489%2016.8916%2014.1257%2017.0123%2014.1806%2017.144C14.2355%2017.2757%2014.2684%2017.4184%2014.2684%2017.5611C14.2684%2017.7038%2014.2355%2017.8465%2014.1806%2017.9782Z'%20fill='%23005899'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='28'%20height='4'%20viewBox='0%200%2028%204'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3crect%20width='28'%20height='4'%20rx='2'%20fill='%239EA0A2'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='20'%20height='20'%20viewBox='0%200%2020%2020'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M17.7083%207.625C15.7833%204.6%2012.9667%202.85834%209.99999%202.85834C8.51666%202.85834%207.07499%203.29167%205.75832%204.1C4.44166%204.91667%203.25832%206.10834%202.29166%207.625C1.45832%208.93334%201.45832%2011.0583%202.29166%2012.3667C4.21666%2015.4%207.03332%2017.1333%209.99999%2017.1333C11.4833%2017.1333%2012.925%2016.7%2014.2417%2015.8917C15.5583%2015.075%2016.7417%2013.8833%2017.7083%2012.3667C18.5417%2011.0667%2018.5417%208.93334%2017.7083%207.625ZM9.99999%2013.3667C8.13332%2013.3667%206.63332%2011.8583%206.63332%2010C6.63332%208.14167%208.13332%206.63334%209.99999%206.63334C11.8667%206.63334%2013.3667%208.14167%2013.3667%2010C13.3667%2011.8583%2011.8667%2013.3667%209.99999%2013.3667Z'%20fill='%230CBD03'/%3e%3cpath%20d='M10%207.61667C8.69167%207.61667%207.625%208.68334%207.625%2010C7.625%2011.3083%208.69167%2012.375%2010%2012.375C11.3083%2012.375%2012.3833%2011.3083%2012.3833%2010C12.3833%208.69167%2011.3083%207.61667%2010%207.61667Z'%20fill='%23297825'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='30'%20height='30'%20viewBox='0%200%2030%2030'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M12.1333%207.78333V19.725C11.85%2019.7333%2011.5667%2019.8%2011.3583%2019.925L9.39999%2021.0417C8.03333%2021.825%206.90833%2021.175%206.90833%2019.5917V11.4833C6.90833%2010.9583%207.28333%2010.3083%207.74999%2010.0417L11.3583%207.97499C11.5667%207.85833%2011.85%207.79166%2012.1333%207.78333Z'%20fill='%239EA0A2'/%3e%3cpath%20d='M18.1083%2010.275V22.2167C17.8166%2022.225%2017.5333%2022.175%2017.3083%2022.0667L12.9333%2019.875C12.7083%2019.7667%2012.425%2019.7167%2012.1333%2019.725V7.78336C12.425%207.77503%2012.7083%207.82503%2012.9333%207.93336L17.3083%2010.125C17.5333%2010.2334%2017.8166%2010.2834%2018.1083%2010.275Z'%20fill='%23292D32'/%3e%3cpath%20d='M23.3333%2010.4083V18.5166C23.3333%2019.0416%2022.9583%2019.6916%2022.4917%2019.9583L18.8833%2022.025C18.675%2022.1416%2018.3917%2022.2083%2018.1083%2022.2166V10.275C18.3917%2010.2666%2018.675%2010.2%2018.8833%2010.075L20.8417%208.95831C22.2083%208.17497%2023.3333%208.82497%2023.3333%2010.4083Z'%20fill='%239EA0A2'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='18'%20height='18'%20viewBox='0%200%2018%2018'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M10.3329%208.99843L13.2249%206.10636C13.5896%205.7417%2013.5896%205.13814%2013.2249%204.77349C12.8603%204.40884%2012.2567%204.40884%2011.8921%204.77349L9%207.66556L6.10793%204.77349C5.74328%204.40884%205.13971%204.40884%204.77506%204.77349C4.41041%205.13814%204.41041%205.7417%204.77506%206.10636L7.66713%208.99843L4.77506%2011.8905C4.41041%2012.2552%204.41041%2012.8587%204.77506%2013.2234C4.96367%2013.412%205.20258%2013.5%205.44149%2013.5C5.6804%2013.5%205.91931%2013.412%206.10793%2013.2234L9%2010.3313L11.8921%2013.2234C12.0807%2013.412%2012.3196%2013.5%2012.5585%2013.5C12.7974%2013.5%2013.0363%2013.412%2013.2249%2013.2234C13.5896%2012.8587%2013.5896%2012.2552%2013.2249%2011.8905L10.3329%208.99843Z'%20fill='%23292D32'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='30'%20height='30'%20viewBox='0%200%2030%2030'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cg%20transform='translate(6.71%204.5)%20scale(1.105)'%3e%3cpath%20d='M10.833%202.05762C13.7497%202.05762%2015%203.72461%2015%206.22461V14.5576C15%2017.0576%2013.7497%2018.7246%2010.833%2018.7246H4.16699C1.25035%2018.7246%202.03458e-05%2017.0576%200%2014.5576V6.22461C0%205.27848%200.178917%204.45131%200.55957%203.78906L2.23047%209.03906C2.29999%209.25742%202.41301%209.45414%202.55762%209.62109C1.87679%2010.1339%201.51432%2011.0094%201.70215%2011.8984L1.71973%2011.9814C1.97907%2013.205%203.18062%2013.9864%204.4043%2013.7275C5.628%2013.4683%206.41027%2012.2668%206.15137%2011.043L6.13477%2010.9609C6.00376%2010.3425%205.63048%209.837%205.13672%209.52148C5.22316%209.39932%205.29459%209.26397%205.34473%209.11719L7.24316%203.55566C7.36977%203.18439%207.35467%202.77858%207.20215%202.41211C7.19602%202.39655%207.19048%202.37953%207.18359%202.36426C7.18015%202.35671%207.17597%202.34939%207.17285%202.34277C7.17029%202.33714%207.16733%202.33023%207.16406%202.32324L7.15527%202.30566C7.14773%202.28947%207.13577%202.26423%207.12402%202.24023C7.09989%202.19097%207.06802%202.1293%207.03027%202.05762H10.833ZM4.63672%202.45215C4.78241%202.6538%204.90358%202.85835%204.98828%203.01465C4.99419%203.02558%205.00034%203.03749%205.00586%203.04785H5.00488C4.99943%203.03761%204.99314%203.02642%204.9873%203.01562C4.90257%202.85927%204.78154%202.65392%204.63574%202.45215C4.59875%202.40098%204.56158%202.35045%204.52344%202.30273L4.63672%202.45215ZM1.35449%202.99316L1.33691%202.9248C1.33642%202.92232%201.33636%202.91949%201.33594%202.91699C1.34068%202.94243%201.34656%202.9682%201.35449%202.99316Z'%20fill='%239EA0A2'/%3e%3cpath%20d='M12.0832%2012.6826H8.5415C8.19984%2012.6826%207.9165%2012.3993%207.9165%2012.0576C7.9165%2011.716%208.19984%2011.4326%208.5415%2011.4326H12.0832C12.4248%2011.4326%2012.7082%2011.716%2012.7082%2012.0576C12.7082%2012.3993%2012.4248%2012.6826%2012.0832%2012.6826Z'%20fill='%23292D32'/%3e%3cpath%20d='M12.0832%2016.0159H4.99988C4.65821%2016.0159%204.37488%2015.7325%204.37488%2015.3909C4.37488%2015.0492%204.65821%2014.7659%204.99988%2014.7659H12.0832C12.4249%2014.7659%2012.7082%2015.0492%2012.7082%2015.3909C12.7082%2015.7325%2012.4249%2016.0159%2012.0832%2016.0159Z'%20fill='%23292D32'/%3e%3cpath%20d='M3.89413%200.485185C3.46043%200.472759%203.08687%200.648246%202.80337%200.844719C2.51646%201.04361%202.27099%201.29933%202.07773%201.53315C1.88201%201.76995%201.7233%202.00418%201.61473%202.17768C1.56003%202.26508%201.51746%202.33903%201.48746%202.39178C1.47243%202.41818%201.46034%202.43948%201.45197%202.45482C1.44781%202.46244%201.44408%202.46901%201.44163%202.47358C1.44052%202.47566%201.43934%202.47782%201.43861%202.4792L1.43814%202.48097L1.43733%202.48112L1.4375%202.48193L1.39105%202.59657C1.35656%202.71473%201.35781%202.84201%201.39604%202.96217L3.22819%208.72226C3.31127%208.98341%203.5532%209.16504%203.8277%209.17207C4.10224%209.17906%204.34752%209.00983%204.43525%208.753L6.3343%203.19144C6.38549%203.04155%206.37755%202.87722%206.31178%202.73108L5.73309%202.98018L6.31161%202.73027L6.31144%202.72947C6.31118%202.72889%206.31048%202.728%206.31012%202.7272C6.3094%202.72563%206.30824%202.72347%206.30714%202.72107C6.30488%202.71616%206.30166%202.70918%206.29785%202.70105C6.29013%202.6846%206.27967%202.66164%206.26585%202.6334C6.23791%202.57636%206.19748%202.49644%206.14604%202.4015C6.04392%202.213%205.8938%201.95742%205.70564%201.69706C5.51994%201.44013%205.28194%201.15669%204.99774%200.930105C4.71656%200.70593%204.3408%200.498042%203.89413%200.485185ZM3.87887%201.74549C3.94212%201.7474%204.05264%201.7805%204.21307%201.9084C4.37065%202.0341%204.53009%202.21557%204.67853%202.42095C4.82445%202.62288%204.94531%202.82755%205.03007%202.98398C5.03606%202.99504%205.04151%203.00627%205.04711%203.01676L3.85162%206.51683L2.69075%202.86613C2.69267%202.86305%202.69437%202.8598%202.69632%202.85667C2.78592%202.71351%202.91284%202.52593%203.06409%202.3429C3.21792%202.15678%203.38196%201.99334%203.54167%201.88262C3.70473%201.7696%203.81587%201.74369%203.87887%201.74549Z'%20fill='%23292D32'/%3e%3cpath%20d='M5.21498%2011.219L5.19758%2011.1368C5.05286%2010.4532%204.38132%2010.0162%203.69765%2010.161C3.01397%2010.3057%202.57706%2010.9772%202.72177%2011.6609L2.73917%2011.7431C2.88389%2012.4268%203.55543%2012.8637%204.23911%2012.719C4.92278%2012.5742%205.35969%2011.9027%205.21498%2011.219Z'%20fill='%23292D32'/%3e%3c/g%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='18'%20height='18'%20viewBox='0%200%2018%2018'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20opacity='0.4'%20d='M12.6%206.75H5.4C3%206.75%201.5%208.25%201.5%2010.65V12.5925C1.5%2015%203%2016.5%205.4%2016.5H12.5925C14.9925%2016.5%2016.4925%2015%2016.4925%2012.6V10.65C16.5%208.25%2015%206.75%2012.6%206.75Z'%20fill='%23292D32'/%3e%3cpath%20d='M11.91%209.3225L9.3975%2011.835C9.18%2012.0525%208.82%2012.0525%208.6025%2011.835L6.09%209.3225C5.8725%209.105%205.8725%208.745%206.09%208.5275C6.3075%208.31%206.6675%208.31%206.885%208.5275L8.4375%2010.08V2.0625C8.4375%201.755%208.6925%201.5%209%201.5C9.3075%201.5%209.5625%201.755%209.5625%202.0625V10.08L11.115%208.5275C11.2275%208.415%2011.37%208.3625%2011.5125%208.3625C11.655%208.3625%2011.7975%208.415%2011.91%208.5275C12.135%208.745%2012.135%209.0975%2011.91%209.3225Z'%20fill='%23292D32'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='20'%20height='20'%20viewBox='0%200%2020%2020'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cg%20transform='translate(-14%20-70)'%3e%3cpath%20opacity='0.4'%20d='M31.5%2075.8333V84.1666C31.5%2086.6666%2030.25%2088.3333%2027.3333%2088.3333H20.6667C17.75%2088.3333%2016.5%2086.6666%2016.5%2084.1666V75.8333C16.5%2073.3333%2017.75%2071.6666%2020.6667%2071.6666H27.3333C30.25%2071.6666%2031.5%2073.3333%2031.5%2075.8333Z'%20fill='%23292D32'/%3e%3cpath%20d='M29.4167%2077.7083H27.75C26.4833%2077.7083%2025.4583%2076.6833%2025.4583%2075.4167V73.75C25.4583%2073.4083%2025.7417%2073.125%2026.0833%2073.125C26.425%2073.125%2026.7083%2073.4083%2026.7083%2073.75V75.4167C26.7083%2075.9917%2027.175%2076.4583%2027.75%2076.4583H29.4167C29.7583%2076.4583%2030.0417%2076.7417%2030.0417%2077.0833C30.0417%2077.425%2029.7583%2077.7083%2029.4167%2077.7083Z'%20fill='%23292D32'/%3e%3cpath%20d='M24%2081.4584H20.6667C20.325%2081.4584%2020.0417%2081.175%2020.0417%2080.8334C20.0417%2080.4917%2020.325%2080.2084%2020.6667%2080.2084H24C24.3417%2080.2084%2024.625%2080.4917%2024.625%2080.8334C24.625%2081.175%2024.3417%2081.4584%2024%2081.4584Z'%20fill='%23292D32'/%3e%3cpath%20d='M27.3333%2084.7916H20.6667C20.325%2084.7916%2020.0417%2084.5083%2020.0417%2084.1666C20.0417%2083.825%2020.325%2083.5416%2020.6667%2083.5416H27.3333C27.675%2083.5416%2027.9583%2083.825%2027.9583%2084.1666C27.9583%2084.5083%2027.675%2084.7916%2027.3333%2084.7916Z'%20fill='%23292D32'/%3e%3c/g%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='30'%20height='30'%20viewBox='0%200%2030%2030'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M15.0039%2023.487C14.7059%2023.487%2014.4078%2023.4243%2014.1333%2023.3066L8.84714%2020.9537C8.03931%2020.593%207.41187%2019.6283%207.41187%2018.742C7.41187%2018.4204%207.67069%2018.1616%207.99225%2018.1616C8.31381%2018.1616%208.57263%2018.4204%208.57263%2018.742C8.57263%2019.1655%208.92557%2019.7145%209.31772%2019.8871L14.6039%2022.24C14.8549%2022.3498%2015.1451%2022.3498%2015.3961%2022.24L20.6823%2019.8871C21.0744%2019.7145%2021.4274%2019.1734%2021.4274%2018.742C21.4274%2018.4204%2021.6862%2018.1616%2022.0077%2018.1616C22.3293%2018.1616%2022.5881%2018.4204%2022.5881%2018.742C22.5881%2019.6204%2021.9607%2020.593%2021.1528%2020.9537L15.8666%2023.3066C15.6%2023.4243%2015.3019%2023.487%2015.0039%2023.487Z'%20fill='%23292D32'/%3e%3cpath%20d='M15.0039%2013.5291C15.4464%2013.5291%2015.8134%2013.1621%2015.8134%2012.7195V7.32255C15.8134%206.88%2015.4464%206.513%2015.0039%206.513C14.5613%206.513%2014.1943%206.88%2014.1943%207.32255V12.7195C14.1943%2013.1621%2014.5613%2013.5291%2015.0039%2013.5291Z'%20fill='%23292D32'/%3e%3cpath%20d='M15.9969%2015.0157C15.943%2014.8862%2015.8674%2014.7674%2015.7703%2014.6595C15.6623%2014.5624%2015.5436%2014.4868%2015.4141%2014.4328C15.155%2014.3249%2014.8528%2014.3249%2014.5937%2014.4328C14.4642%2014.4868%2014.3455%2014.5624%2014.2375%2014.6595C14.1404%2014.7674%2014.0648%2014.8862%2014.0109%2015.0157C13.9569%2015.1452%2013.9245%2015.2855%2013.9245%2015.4259C13.9245%2015.5662%2013.9569%2015.7065%2014.0109%2015.836C14.0648%2015.9764%2014.1404%2016.0843%2014.2375%2016.1922C14.3455%2016.2894%2014.4642%2016.3649%2014.5937%2016.4189C14.7233%2016.4729%2014.8636%2016.5053%2015.0039%2016.5053C15.1442%2016.5053%2015.2845%2016.4729%2015.4141%2016.4189C15.5436%2016.3649%2015.6623%2016.2894%2015.7703%2016.1922C15.8674%2016.0843%2015.943%2015.9764%2015.9969%2015.836C16.0509%2015.7065%2016.0833%2015.5662%2016.0833%2015.4259C16.0833%2015.2855%2016.0509%2015.1452%2015.9969%2015.0157Z'%20fill='%23292D32'/%3e%3cpath%20d='M20.7844%2013.9579C21.9526%2014.4755%2022.1173%2015.1811%2022.1174%2015.5576C22.1174%2015.934%2021.9451%2016.6405%2020.7844%2017.1581L16.1887%2019.205C15.8515%2019.354%2015.4275%2019.4325%2015.0041%2019.4326C14.5806%2019.4326%2014.1568%2019.354%2013.8195%2019.205L9.22382%2017.1581C8.06305%2016.6405%207.88983%2015.934%207.88983%2015.5576C7.88988%2015.181%208.06322%2014.4755%209.22382%2013.9579L13.1945%2012.1894V12.5947C13.1946%2013.0338%2013.3534%2013.4376%2013.6164%2013.7519C13.6008%2013.7652%2013.5848%2013.7782%2013.5695%2013.7919L13.5295%2013.8271L13.4943%2013.8661C13.3244%2014.055%2013.187%2014.2695%2013.0881%2014.5068C13.0157%2014.6806%2012.96%2014.8767%2012.9367%2015.0869L12.925%2015.3017L12.9367%2015.5165C12.96%2015.7265%2013.0157%2015.923%2013.0881%2016.0966L13.09%2016.0956C13.1993%2016.3686%2013.3466%2016.5731%2013.4943%2016.7372L13.5295%2016.7763L13.5695%2016.8115C13.7581%2016.981%2013.9723%2017.119%2014.2092%2017.2177C14.4408%2017.3141%2014.7124%2017.3808%2015.0041%2017.3808C15.2959%2017.3807%2015.5674%2017.3142%2015.799%2017.2177C16.0362%2017.1188%2016.2508%2016.9813%2016.4396%2016.8115L16.4787%2016.7763L16.5139%2016.7372C16.6617%2016.573%2016.8098%2016.3688%2016.9191%2016.0956L16.9201%2016.0966C16.9218%2016.0925%2016.9224%2016.0871%2016.924%2016.0829C16.9257%2016.0787%2016.9291%2016.0745%2016.9308%2016.0703L16.9299%2016.0693C17.0205%2015.8436%2017.0841%2015.5824%2017.0842%2015.3017C17.0842%2015.0099%2017.0166%2014.7385%2016.9201%2014.5068C16.8213%2014.2696%2016.6837%2014.0549%2016.5139%2013.8661L16.4787%2013.8271L16.4396%2013.7919C16.424%2013.7778%2016.4068%2013.7645%2016.3908%2013.7509C16.6536%2013.4367%2016.8136%2013.0336%2016.8137%2012.5947V12.1894L20.7844%2013.9579Z'%20fill='%239EA0A2'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='20'%20height='20'%20viewBox='0%200%2020%2020'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M7%2016V4M4%207L7%204L10%207M13%204V16M16%2013L13%2016L10%2013'%20stroke='%23292D32'%20stroke-width='1.5'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='30'%20height='30'%20viewBox='0%200%2030%2030'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M22.525%2023.3333H16.6583C16.3083%2023.3333%2016.0333%2023.05%2016.0333%2022.7083C16.0333%2022.3666%2016.3167%2022.0833%2016.6583%2022.0833H22.525C22.875%2022.0833%2023.15%2022.3666%2023.15%2022.7083C23.15%2023.05%2022.875%2023.3333%2022.525%2023.3333Z'%20fill='%23292D32'/%3e%3cpath%20d='M17.8417%2018.6167L13.8833%2022.575C12.9583%2023.5%2011.475%2023.55%2010.4917%2022.725C10.4334%2022.675%2010.3834%2022.625%2010.3334%2022.575L9.60836%2021.85L8.11667%2020.3584L7.40001%2019.6417C7.34168%2019.5834%207.29168%2019.525%207.24168%2019.4667C6.42501%2018.4834%206.48334%2017.0167%207.40001%2016.1L10.475%2013.0334L11.3583%2012.15L17.8417%2018.6167Z'%20fill='%239EA0A2'/%3e%3cpath%20d='M22.6%2013.8667L17.8416%2018.6167L11.3583%2012.15L16.1167%207.40001C17.0917%206.42501%2018.6916%206.42501%2019.6666%207.40001L22.6%2010.325C23.575%2011.3%2023.575%2012.8917%2022.6%2013.8667Z'%20fill='%23292D32'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='30'%20height='30'%20viewBox='0%200%2030%2030'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M9.16669%2019.1666H20.8334C22.2167%2019.1666%2023.3334%2018.05%2023.3334%2016.6666V13.3333C23.3334%2011.95%2022.2167%2010.8333%2020.8334%2010.8333H9.16669C7.78335%2010.8333%206.66669%2011.95%206.66669%2013.3333V16.6666C6.66669%2018.05%207.78335%2019.1666%209.16669%2019.1666Z'%20fill='%239EA0A2'/%3e%3cpath%20d='M20.625%2010.8333V15C20.625%2015.3416%2020.3417%2015.625%2020%2015.625C19.6583%2015.625%2019.375%2015.3416%2019.375%2015V10.8333H20.625Z'%20fill='%23292D32'/%3e%3cpath%20d='M10.625%2010.8333V14C10.625%2014.3416%2010.3417%2014.625%2010%2014.625C9.65833%2014.625%209.375%2014.3416%209.375%2014V10.8333H10.625Z'%20fill='%23292D32'/%3e%3cpath%20d='M13.9916%2010.8333L13.9583%2015.0083C13.9583%2015.35%2013.675%2015.625%2013.3333%2015.625C13.3333%2015.625%2013.3333%2015.625%2013.325%2015.625C12.9833%2015.625%2012.7083%2015.3416%2012.7083%2014.9916L12.7416%2010.8333H13.9916Z'%20fill='%23292D32'/%3e%3cpath%20d='M17.2917%2010.8333V13C17.2917%2013.3416%2017.0084%2013.625%2016.6667%2013.625C16.325%2013.625%2016.0417%2013.3416%2016.0417%2013V10.8333H17.2917Z'%20fill='%23292D32'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='20'%20height='20'%20viewBox='0%200%2020%2020'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M4.1665%2016.3408H15.8332C17.2165%2016.3408%2018.3332%2015.2241%2018.3332%2013.8408V10.5074C18.3332%209.12411%2017.2165%208.00745%2015.8332%208.00745H4.1665C2.78317%208.00745%201.6665%209.12411%201.6665%2010.5074V13.8408C1.6665%2015.2241%202.78317%2016.3408%204.1665%2016.3408Z'%20fill='%239EA0A2'/%3e%3cpath%20d='M15.625%208.00745V12.1741C15.625%2012.5158%2015.3417%2012.7991%2015%2012.7991C14.6583%2012.7991%2014.375%2012.5158%2014.375%2012.1741V8.00745H15.625Z'%20fill='%23292D32'/%3e%3cpath%20d='M5.625%208.00745V11.1741C5.625%2011.5158%205.34167%2011.7991%205%2011.7991C4.65833%2011.7991%204.375%2011.5158%204.375%2011.1741V8.00745H5.625Z'%20fill='%23292D32'/%3e%3cpath%20d='M8.99159%208.00745L8.95825%2012.1824C8.95825%2012.5241%208.67492%2012.7991%208.33325%2012.7991C8.33325%2012.7991%208.33325%2012.7991%208.32492%2012.7991C7.98325%2012.7991%207.70825%2012.5158%207.70825%2012.1658L7.74159%208.00745H8.99159Z'%20fill='%23292D32'/%3e%3cpath%20d='M2.57227%203.61453C2.57227%203.61453%205.1324%201.70386%209.98544%201.70386C14.8385%201.70386%2017.3527%203.61453%2017.3527%203.61453'%20stroke='%23292D32'%20stroke-linecap='round'%20stroke-linejoin='round'%20stroke-dasharray='2%203'/%3e%3cpath%20d='M12.2915%208.00745V10.1741C12.2915%2010.5158%2012.0082%2010.7991%2011.6665%2010.7991C11.3248%2010.7991%2011.0415%2010.5158%2011.0415%2010.1741V8.00745H12.2915Z'%20fill='%23292D32'/%3e%3cpath%20d='M2.57251%203.64697L2.57251%205.67273L17.3529%205.67273L17.3529%203.64697'%20stroke='%23292D32'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='20'%20height='20'%20viewBox='0%200%2020%2020'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M4.1665%2016.3408H15.8332C17.2165%2016.3408%2018.3332%2015.2241%2018.3332%2013.8408V10.5074C18.3332%209.12411%2017.2165%208.00745%2015.8332%208.00745H4.1665C2.78317%208.00745%201.6665%209.12411%201.6665%2010.5074V13.8408C1.6665%2015.2241%202.78317%2016.3408%204.1665%2016.3408Z'%20fill='%239EA0A2'/%3e%3cpath%20d='M15.625%208.00745V12.1741C15.625%2012.5158%2015.3417%2012.7991%2015%2012.7991C14.6583%2012.7991%2014.375%2012.5158%2014.375%2012.1741V8.00745H15.625Z'%20fill='%23292D32'/%3e%3cpath%20d='M5.625%208.00745V11.1741C5.625%2011.5158%205.34167%2011.7991%205%2011.7991C4.65833%2011.7991%204.375%2011.5158%204.375%2011.1741V8.00745H5.625Z'%20fill='%23292D32'/%3e%3cpath%20d='M8.99159%208.00745L8.95825%2012.1824C8.95825%2012.5241%208.67492%2012.7991%208.33325%2012.7991C8.33325%2012.7991%208.33325%2012.7991%208.32492%2012.7991C7.98325%2012.7991%207.70825%2012.5158%207.70825%2012.1658L7.74159%208.00745H8.99159Z'%20fill='%23292D32'/%3e%3cpath%20d='M3.09058%203.65918C3.09058%203.38304%202.86672%203.15918%202.59058%203.15918C2.31443%203.15918%202.09058%203.38304%202.09058%203.65918H2.59058H3.09058ZM2.09058%206.60007C2.09058%206.87622%202.31443%207.10007%202.59058%207.10007C2.86672%207.10007%203.09058%206.87622%203.09058%206.60007H2.59058H2.09058ZM17.4094%205.12963V5.62963H17.9094V5.12963H17.4094ZM17.9094%203.65918C17.9094%203.38304%2017.6855%203.15918%2017.4094%203.15918C17.1332%203.15918%2016.9094%203.38304%2016.9094%203.65918H17.4094H17.9094ZM16.9094%206.60007C16.9094%206.87622%2017.1332%207.10007%2017.4094%207.10007C17.6855%207.10007%2017.9094%206.87622%2017.9094%206.60007H17.4094H16.9094ZM2.59058%203.65918H2.09058V5.12963H2.59058H3.09058V3.65918H2.59058ZM2.59058%205.12963H2.09058V6.60007H2.59058H3.09058V5.12963H2.59058ZM2.59058%205.12963V5.62963H17.4094V5.12963V4.62963H2.59058V5.12963ZM17.4094%205.12963H17.9094V3.65918H17.4094H16.9094V5.12963H17.4094ZM17.4094%203.65918H16.9094V6.60007H17.4094H17.9094V3.65918H17.4094Z'%20fill='%23292D32'/%3e%3cpath%20d='M12.2915%208.00745V10.1741C12.2915%2010.5158%2012.0082%2010.7991%2011.6665%2010.7991C11.3248%2010.7991%2011.0415%2010.5158%2011.0415%2010.1741V8.00745H12.2915Z'%20fill='%23292D32'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='30'%20height='30'%20viewBox='0%200%2030%2030'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M15.295%2017.3076C15.6501%2017.0984%2015.7667%2016.638%2015.5555%2016.2793C15.3442%2015.9206%2014.8851%2015.7994%2014.53%2016.0086L14.9125%2016.6581L15.295%2017.3076ZM6.41087%2020.792C6.05579%2021.0011%205.9392%2021.4615%206.15046%2021.8202C6.36171%2022.179%206.82081%2022.3002%207.17588%2022.091L6.79337%2021.4415L6.41087%2020.792ZM14.9125%2016.6581L14.53%2016.0086L6.41087%2020.792L6.79337%2021.4415L7.17588%2022.091L15.295%2017.3076L14.9125%2016.6581Z'%20fill='%23292D32'/%3e%3cpath%20d='M14.705%2017.3076C14.3499%2017.0984%2014.2333%2016.638%2014.4445%2016.2793C14.6558%2015.9206%2015.1149%2015.7994%2015.47%2016.0086L15.0875%2016.6581L14.705%2017.3076ZM23.5891%2020.792C23.9442%2021.0011%2024.0608%2021.4615%2023.8495%2021.8202C23.6383%2022.179%2023.1792%2022.3002%2022.8241%2022.091L23.2066%2021.4415L23.5891%2020.792ZM15.0875%2016.6581L15.47%2016.0086L23.5891%2020.792L23.2066%2021.4415L22.8241%2022.091L14.705%2017.3076L15.0875%2016.6581Z'%20fill='%23292D32'/%3e%3cpath%20d='M7.73406%2018.2571C7.83926%2017.8564%207.60065%2017.4431%207.2011%2017.3339C6.80155%2017.2246%206.39237%2017.4608%206.28718%2017.8615L7.01062%2018.0593L7.73406%2018.2571ZM5.99998%2021.9081L5.27654%2021.7103C5.17134%2022.1109%205.40996%2022.5243%205.8095%2022.6335L5.99998%2021.9081ZM9.58125%2023.6648C9.9808%2023.774%2010.39%2023.5378%2010.4952%2023.1372C10.6004%2022.7366%2010.3618%2022.3232%209.96221%2022.214L9.77173%2022.9394L9.58125%2023.6648ZM7.01062%2018.0593L6.28718%2017.8615L5.27654%2021.7103L5.99998%2021.9081L6.72343%2022.1059L7.73406%2018.2571L7.01062%2018.0593ZM5.99998%2021.9081L5.8095%2022.6335L9.58125%2023.6648L9.77173%2022.9394L9.96221%2022.214L6.19046%2021.1827L5.99998%2021.9081Z'%20fill='%23292D32'/%3e%3cpath%20d='M22.2659%2018.2571C22.1607%2017.8564%2022.3994%2017.4431%2022.7989%2017.3339C23.1984%2017.2246%2023.6076%2017.4608%2023.7128%2017.8615L22.9894%2018.0593L22.2659%2018.2571ZM24%2021.9081L24.7235%2021.7103C24.8287%2022.1109%2024.59%2022.5243%2024.1905%2022.6335L24%2021.9081ZM20.4187%2023.6648C20.0192%2023.774%2019.61%2023.5378%2019.5048%2023.1372C19.3996%2022.7366%2019.6382%2022.3232%2020.0378%2022.214L20.2283%2022.9394L20.4187%2023.6648ZM22.9894%2018.0593L23.7128%2017.8615L24.7235%2021.7103L24%2021.9081L23.2766%2022.1059L22.2659%2018.2571L22.9894%2018.0593ZM24%2021.9081L24.1905%2022.6335L20.4187%2023.6648L20.2283%2022.9394L20.0378%2022.214L23.8095%2021.1827L24%2021.9081Z'%20fill='%23292D32'/%3e%3cpath%20d='M15.7412%2017.3081C15.7412%2017.7264%2015.4088%2018.0656%2014.9988%2018.0656C14.5888%2018.0656%2014.2564%2017.7264%2014.2564%2017.3081L14.9988%2017.3081L15.7412%2017.3081ZM14.2564%207.74126C14.2564%207.32288%2014.5888%206.98371%2014.9988%206.98371C15.4088%206.98371%2015.7412%207.32288%2015.7412%207.74126L14.9988%207.74126L14.2564%207.74126ZM14.9988%2017.3081L14.2564%2017.3081V7.74126L14.9988%207.74126L15.7412%207.74126V17.3081L14.9988%2017.3081Z'%20fill='%23292D32'/%3e%3cpath%20d='M12.7627%2010.161C12.4728%2010.4568%2012.0028%2010.4568%2011.7129%2010.161C11.4229%209.86513%2011.4229%209.38548%2011.7129%209.08964L12.2378%209.62531L12.7627%2010.161ZM14.9989%206.80777L14.474%206.2721C14.7639%205.97626%2015.2339%205.97626%2015.5238%206.2721L14.9989%206.80777ZM18.285%209.08964C18.5749%209.38548%2018.5749%209.86513%2018.285%2010.161C17.995%2010.4568%2017.525%2010.4568%2017.2351%2010.161L17.76%209.62531L18.285%209.08964ZM12.2378%209.62531L11.7129%209.08964L14.474%206.2721L14.9989%206.80777L15.5238%207.34343L12.7627%2010.161L12.2378%209.62531ZM14.9989%206.80777L15.5238%206.2721L18.285%209.08964L17.76%209.62531L17.2351%2010.161L14.474%207.34343L14.9989%206.80777Z'%20fill='%23292D32'/%3e%3cellipse%20cx='14.9915'%20cy='16.9581'%20rx='4.15556'%20ry='4.24049'%20fill='%239EA0A2'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='18'%20height='18'%20viewBox='0%200%2018%2018'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20fill-rule='evenodd'%20clip-rule='evenodd'%20d='M5.23819%208.8294C5.23819%206.75463%206.92182%205.07324%208.99934%205.07324C11.0769%205.07324%2012.7605%206.75463%2012.7605%208.8294C12.7605%209.65439%2012.4938%2010.4186%2012.0418%2011.038L11.4591%2012.7843C11.2259%2013.4809%2010.5729%2013.9514%209.83704%2013.9514H8.16165C7.42583%2013.9514%206.77207%2013.4809%206.53956%2012.7843L5.95693%2011.038C5.50491%2010.4186%205.23819%209.65439%205.23819%208.8294Z'%20fill='%239EA0A2'/%3e%3cpath%20fill-rule='evenodd'%20clip-rule='evenodd'%20d='M12.8613%204.49072L14.229%203.12485L14.7132%203.60837L13.3455%204.97425L12.8613%204.49072Z'%20fill='%23292D32'/%3e%3cpath%20fill-rule='evenodd'%20clip-rule='evenodd'%20d='M14.4709%208.48776H15.8386V9.1712H14.4709V8.48776Z'%20fill='%23292D32'/%3e%3cpath%20fill-rule='evenodd'%20clip-rule='evenodd'%20d='M2.16138%208.48776H3.52907V9.1712H2.16138V8.48776Z'%20fill='%23292D32'/%3e%3cpath%20fill-rule='evenodd'%20clip-rule='evenodd'%20d='M3.77186%203.12485L5.13955%204.49072L4.65538%204.97425L3.28769%203.60837L3.77186%203.12485Z'%20fill='%23292D32'/%3e%3cpath%20fill-rule='evenodd'%20clip-rule='evenodd'%20d='M9.34119%202V3.36687H8.65735V2H9.34119Z'%20fill='%23292D32'/%3e%3cpath%20fill-rule='evenodd'%20clip-rule='evenodd'%20d='M7.29047%2014.2926C7.29047%2015.2358%208.05569%2016%209.00008%2016C9.94447%2016%2010.7097%2015.2358%2010.7097%2014.2926V13.6097C10.7097%2013.4212%2010.5565%2013.2682%2010.3678%2013.2682H7.63239C7.44365%2013.2682%207.29047%2013.4212%207.29047%2013.6097V14.2926Z'%20fill='%23292D32'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='20'%20height='20'%20viewBox='0%200%2020%2020'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20opacity='0.4'%20d='M15.7688%207.26249H12.3062C12.0687%207.26249%2011.875%207.06874%2011.875%206.82499C11.875%206.58749%2012.0687%206.39374%2012.3062%206.39374H15.7688C16.0062%206.39374%2016.2%206.58749%2016.2%206.82499C16.2%207.06874%2016.0062%207.26249%2015.7688%207.26249Z'%20fill='%23292D32'/%3e%3cpath%20opacity='0.4'%20d='M6.5375%207.26252H4.23125C3.99375%207.26252%203.8%207.06877%203.8%206.83127C3.8%206.59377%203.99375%206.40002%204.23125%206.40002H6.5375C6.775%206.40002%206.96875%206.59377%206.96875%206.83127C6.96875%207.06877%206.775%207.26252%206.5375%207.26252Z'%20fill='%23292D32'/%3e%3cpath%20d='M8.84375%209.275C10.1969%209.275%2011.2938%208.1781%2011.2938%206.825C11.2938%205.4719%2010.1969%204.375%208.84375%204.375C7.49066%204.375%206.39375%205.4719%206.39375%206.825C6.39375%208.1781%207.49066%209.275%208.84375%209.275Z'%20fill='%23292D32'/%3e%3cpath%20opacity='0.4'%20d='M15.7687%2013.6062H13.4625C13.225%2013.6062%2013.0312%2013.4125%2013.0312%2013.175C13.0312%2012.9375%2013.225%2012.7437%2013.4625%2012.7437H15.7687C16.0062%2012.7437%2016.2%2012.9375%2016.2%2013.175C16.2%2013.4125%2016.0062%2013.6062%2015.7687%2013.6062Z'%20fill='%23292D32'/%3e%3cpath%20opacity='0.4'%20d='M7.69375%2013.6062H4.23125C3.99375%2013.6062%203.8%2013.4125%203.8%2013.175C3.8%2012.9375%203.99375%2012.7437%204.23125%2012.7437H7.69375C7.93125%2012.7437%208.125%2012.9375%208.125%2013.175C8.125%2013.4125%207.93125%2013.6062%207.69375%2013.6062Z'%20fill='%23292D32'/%3e%3cpath%20d='M11.1562%2015.625C12.5093%2015.625%2013.6062%2014.5281%2013.6062%2013.175C13.6062%2011.8219%2012.5093%2010.725%2011.1562%2010.725C9.80314%2010.725%208.70624%2011.8219%208.70624%2013.175C8.70624%2014.5281%209.80314%2015.625%2011.1562%2015.625Z'%20fill='%23292D32'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='30'%20height='30'%20viewBox='0%200%2030%2030'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M22.1833%2012.25C21.3167%208.39169%2017.95%206.66669%2015%206.66669C15%206.66669%2015%206.66669%2014.9917%206.66669C12.05%206.66669%208.69167%208.39169%207.81667%2012.2417C6.83334%2016.5417%209.46667%2019.35%2011.85%2021.65C12.7333%2022.5%2013.8667%2023.7584%2015%2023.7584C16.1333%2023.7584%2017.2667%2022.5%2018.1417%2021.65C20.525%2019.35%2023.1583%2016.55%2022.1833%2012.25Z'%20fill='%239EA0A2'/%3e%3cpath%20d='M12.055%2014.7627H17.7262'%20stroke='%23292D32'%20stroke-width='1.5'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3cpath%20d='M15.8358%2017.5983L18.6715%2014.7627L15.8358%2011.9271'%20stroke='%23292D32'%20stroke-width='1.5'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='20'%20height='20'%20viewBox='0%200%2020%2020'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M3.78325%209.61655L6.14992%207.24155C6.39158%206.99989%206.79159%206.99989%207.03325%207.24155C7.27492%207.48322%207.27492%207.88322%207.03325%208.12489L5.73325%209.42489H13.7083C14.0499%209.42489%2014.3333%209.70822%2014.3333%2010.0499C14.3333%2010.3916%2014.0499%2010.6749%2013.7083%2010.6749H5.73325L7.03325%2011.9832C7.27492%2012.2249%207.27492%2012.6249%207.03325%2012.8666C6.90825%2012.9916%206.74992%2013.0499%206.59159%2013.0499C6.43325%2013.0499%206.27492%2012.9916%206.14992%2012.8666L3.78325%2010.4916C3.53325%2010.2499%203.53325%209.85822%203.78325%209.61655Z'%20fill='%235B5D60'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='20'%20height='20'%20viewBox='0%200%2020%2020'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M15.5%206.5A6%206%200%200%200%204.5%208m0%200V4.5m0%203.5H8M4.5%2013.5A6%206%200%200%200%2015.5%2012m0%200v3.5m0-3.5H12'%20stroke='%23292D32'%20stroke-width='1.5'%20stroke-linecap='round'%20stroke-linejoin='round'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='20'%20height='20'%20viewBox='0%200%2020%2020'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M18.1818%205.28182V12.4546C18.1818%2012.4455%2018.1727%2012.4363%2018.1636%2012.4273C18.1273%2012.3727%2018.0818%2012.3182%2018.0364%2012.2727C18.0273%2012.2636%2018.0182%2012.2455%2018.0091%2012.2364C17.2727%2011.4182%2016.1909%2010.9091%2015%2010.9091C13.8545%2010.9091%2012.8091%2011.3818%2012.0636%2012.1454C11.3454%2012.8818%2010.9091%2013.8909%2010.9091%2015C10.9091%2015.7636%2011.1273%2016.4909%2011.5%2017.1091C11.7%2017.4455%2011.9545%2017.7545%2012.2455%2018.0091C12.2636%2018.0182%2012.2727%2018.0273%2012.2818%2018.0364C12.3273%2018.0818%2012.3727%2018.1182%2012.4273%2018.1636C12.4273%2018.1636%2012.4273%2018.1636%2012.4364%2018.1636C12.4454%2018.1727%2012.4545%2018.1818%2012.4636%2018.1818H5.28182C1.97272%2018.1818%200%2016.2091%200%2012.9V5.28182C0%204.81818%200.0363681%204.37271%200.118186%203.96362C0.581823%201.46362%202.42726%200.00909091%205.24544%200H12.9364C15.7546%200.00909091%2017.6%201.46362%2018.0636%203.96362C18.1454%204.37271%2018.1818%204.81818%2018.1818%205.28182Z'%20fill='%239EA0A2'/%3e%3cpath%20d='M18.1818%205.28182V5.32726H0V5.28182C0%204.81818%200.0363681%204.37271%200.118186%203.96362H5.24544V0H6.60908V3.96362H11.5727V0H12.9364V3.96362H18.0636C18.1454%204.37271%2018.1818%204.81818%2018.1818%205.28182Z'%20fill='%23292D32'/%3e%3cpath%20d='M19.5391%2012.1899C18.1197%209.9593%2016.0427%208.67505%2013.8552%208.67505C12.7614%208.67505%2011.6984%208.99458%2010.7275%209.59062C9.75666%2010.1928%208.8841%2011.0715%208.17131%2012.1899C7.55683%2013.1546%207.55683%2014.7215%208.17131%2015.6862C9.59075%2017.9229%2011.6677%2019.201%2013.8552%2019.201C14.949%2019.201%2016.012%2018.8815%2016.9829%2018.2855C17.9538%2017.6833%2018.8263%2016.8046%2019.5391%2015.6862C20.1536%2014.7276%2020.1536%2013.1546%2019.5391%2012.1899ZM13.8552%2016.4236C12.4788%2016.4236%2011.3727%2015.3114%2011.3727%2013.9411C11.3727%2012.5708%2012.4788%2011.4586%2013.8552%2011.4586C15.2316%2011.4586%2016.3377%2012.5708%2016.3377%2013.9411C16.3377%2015.3114%2015.2316%2016.4236%2013.8552%2016.4236Z'%20fill='%23292D32'/%3e%3cpath%20d='M13.8553%2012.1833C12.8905%2012.1833%2012.104%2012.9699%2012.104%2013.9408C12.104%2014.9055%2012.8905%2015.692%2013.8553%2015.692C14.82%2015.692%2015.6127%2014.9055%2015.6127%2013.9408C15.6127%2012.976%2014.82%2012.1833%2013.8553%2012.1833Z'%20fill='%23292D32'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='20'%20height='20'%20viewBox='0%200%2020%2020'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M9.70834%2015.25C12.7689%2015.25%2015.25%2012.7689%2015.25%209.70835C15.25%206.64778%2012.7689%204.16669%209.70834%204.16669C6.64776%204.16669%204.16667%206.64778%204.16667%209.70835C4.16667%2012.7689%206.64776%2015.25%209.70834%2015.25Z'%20fill='%239EA0A2'/%3e%3cpath%20d='M15.425%2015.8334C15.32%2015.8334%2015.215%2015.7926%2015.1392%2015.7167L14.0542%2014.6317C13.8967%2014.4742%2013.8967%2014.2176%2014.0542%2014.0542C14.2117%2013.8967%2014.4684%2013.8967%2014.6317%2014.0542L15.7167%2015.1392C15.8742%2015.2967%2015.8742%2015.5534%2015.7167%2015.7167C15.635%2015.7926%2015.53%2015.8334%2015.425%2015.8334Z'%20fill='%23292D32'/%3e%3cpath%20d='M11.2833%209.38747H10.2625V8.36664C10.2625%208.12747%2010.0642%207.92914%209.825%207.92914C9.58584%207.92914%209.3875%208.12747%209.3875%208.36664V9.38747H8.36667C8.1275%209.38747%207.92917%209.5858%207.92917%209.82497C7.92917%2010.0641%208.1275%2010.2625%208.36667%2010.2625H9.3875V11.2833C9.3875%2011.5225%209.58584%2011.7208%209.825%2011.7208C10.0642%2011.7208%2010.2625%2011.5225%2010.2625%2011.2833V10.2625H11.2833C11.5225%2010.2625%2011.7208%2010.0641%2011.7208%209.82497C11.7208%209.5858%2011.5225%209.38747%2011.2833%209.38747Z'%20fill='%23292D32'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='30'%20height='30'%20viewBox='0%200%2030%2030'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M15%2023.3334C19.6024%2023.3334%2023.3333%2019.6024%2023.3333%2015C23.3333%2010.3976%2019.6024%206.66669%2015%206.66669C10.3976%206.66669%206.66666%2010.3976%206.66666%2015C6.66666%2019.6024%2010.3976%2023.3334%2015%2023.3334Z'%20fill='%239EA0A2'/%3e%3cpath%20d='M18.3333%2014.375H15.625V11.6667C15.625%2011.325%2015.3417%2011.0417%2015%2011.0417C14.6583%2011.0417%2014.375%2011.325%2014.375%2011.6667V14.375H11.6667C11.325%2014.375%2011.0417%2014.6584%2011.0417%2015C11.0417%2015.3417%2011.325%2015.625%2011.6667%2015.625H14.375V18.3334C14.375%2018.675%2014.6583%2018.9584%2015%2018.9584C15.3417%2018.9584%2015.625%2018.675%2015.625%2018.3334V15.625H18.3333C18.675%2015.625%2018.9583%2015.3417%2018.9583%2015C18.9583%2014.6584%2018.675%2014.375%2018.3333%2014.375Z'%20fill='%23292D32'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='30'%20height='30'%20viewBox='0%200%2030%2030'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M21.7%2010.6834L16.9%207.32503C15.5917%206.40836%2013.5833%206.45836%2012.325%207.43336L8.14999%2010.6917C7.31666%2011.3417%206.65833%2012.675%206.65833%2013.725V19.475C6.65833%2021.6%208.38333%2023.3334%2010.5083%2023.3334H19.4917C21.6167%2023.3334%2023.3417%2021.6084%2023.3417%2019.4834V13.8334C23.3417%2012.7084%2022.6167%2011.325%2021.7%2010.6834Z'%20fill='%239EA0A2'/%3e%3cpath%20d='M15%2020.625C14.6583%2020.625%2014.375%2020.3417%2014.375%2020V15.5C14.375%2015.1583%2014.6583%2014.875%2015%2014.875C15.3417%2014.875%2015.625%2015.1583%2015.625%2015.5V20C15.625%2020.3417%2015.3417%2020.625%2015%2020.625Z'%20fill='%23292D32'/%3e%3c/svg%3e\"","export default \"data:image/svg+xml,%3csvg%20width='30'%20height='30'%20viewBox='0%200%2030%2030'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M15%2023.3334C19.6024%2023.3334%2023.3333%2019.6024%2023.3333%2015C23.3333%2010.3976%2019.6024%206.66669%2015%206.66669C10.3976%206.66669%206.66667%2010.3976%206.66667%2015C6.66667%2019.6024%2010.3976%2023.3334%2015%2023.3334Z'%20fill='%239EA0A2'/%3e%3cpath%20d='M18.2667%2015.625H11.6C11.2583%2015.625%2010.975%2015.3417%2010.975%2015C10.975%2014.6583%2011.2583%2014.375%2011.6%2014.375H18.2667C18.6083%2014.375%2018.8917%2014.6583%2018.8917%2015C18.8917%2015.3417%2018.6167%2015.625%2018.2667%2015.625Z'%20fill='%23292D32'/%3e%3c/svg%3e\"","import type { ReactNode } from \"react\";\r\nimport { useState } from \"react\";\r\nimport { cn } from \"@/shared/lib/cn\";\r\n\r\ninterface PropsIcono {\r\n className?: string;\r\n}\r\n\r\n/** URLs de los SVG de `src/assets/icons`; un ícono nuevo se agrega a esa carpeta. */\r\nconst URLS_ICONOS = import.meta.glob(\"../../../assets/icons/*.svg\", {\r\n eager: true,\r\n query: \"?url\",\r\n import: \"default\",\r\n}) as Record<string, string>;\r\n\r\n/** URL del SVG cuyo nombre de archivo (sin extensión) es `nombre`. */\r\nfunction urlIcono(nombre: string): string | undefined {\r\n const sufijo = `/${nombre}.svg`;\r\n for (const [ruta, url] of Object.entries(URLS_ICONOS)) {\r\n if (ruta.endsWith(sufijo)) return url;\r\n }\r\n /* istanbul ignore next -- todos los nombres en uso tienen archivo en assets/icons */\r\n return undefined;\r\n}\r\n\r\n/** Archivo de `src/assets/icons` que ilustra cada código de herramienta. */\r\nconst ARCHIVO_ICONO: Record<string, string> = {\r\n home: \"ZoomInicial\",\r\n \"zoom-in\": \"ZoomIn\",\r\n \"zoom-out\": \"ZoomOut\",\r\n clear: \"Limpiar\",\r\n identify: \"Identificar\",\r\n \"get-coordinates\": \"ObtenerCoordenadas\",\r\n project: \"Proyectar\",\r\n query: \"Consultar\",\r\n \"measurement-tools\": \"Medir\",\r\n \"measure-distance\": \"MedirDistancia\",\r\n \"measure-area\": \"MedirArea\",\r\n layer: \"CapasYServicios\",\r\n metadata: \"OpcionesCapa\",\r\n};\r\n\r\n/** `<img>` de un SVG de `src/assets/icons`; nada si el archivo aún no existe. */\r\nfunction IconoArchivo({\r\n nombre,\r\n className = \"size-5\",\r\n}: PropsIcono & { nombre: string }) {\r\n const url = urlIcono(nombre);\r\n /* istanbul ignore next -- todos los `nombre` en uso resuelven a un archivo real */\r\n if (!url) return null;\r\n return (\r\n <img\r\n src={url}\r\n alt=\"\"\r\n aria-hidden=\"true\"\r\n className={cn(\"shrink-0 object-contain\", className)}\r\n />\r\n );\r\n}\r\n\r\n/** Envoltorio `<svg>` trazado para los pocos íconos que aún no tienen archivo propio. */\r\nfunction SvgBase({\r\n children,\r\n className = \"size-5\",\r\n}: PropsIcono & { children: ReactNode }) {\r\n return (\r\n <svg\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth={1.8}\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n aria-hidden=\"true\"\r\n className={cn(\"shrink-0\", className)}\r\n >\r\n {children}\r\n </svg>\r\n );\r\n}\r\n\r\ninterface PropsIconoHerramienta extends PropsIcono {\r\n codigo: string;\r\n /** Ícono real de la herramienta (`herramienta.rutaIcono` del contrato). */\r\n rutaIcono?: string;\r\n /** Estado activo (hoy solo `three-dimensional` cambia de ícono). */\r\n activo?: boolean;\r\n}\r\n\r\n/** Ícono de una herramienta: `rutaIcono` del backend, el propio de `assets/icons` o uno genérico. */\r\nexport function IconoHerramienta({\r\n codigo,\r\n rutaIcono,\r\n activo = false,\r\n className = \"size-5\",\r\n}: PropsIconoHerramienta) {\r\n const [fallo, setFallo] = useState(false);\r\n\r\n // 1) Ícono entregado por el backend en `rutaIcono` (tiene prioridad).\r\n if (rutaIcono && !fallo) {\r\n return (\r\n <img\r\n src={rutaIcono}\r\n alt=\"\"\r\n aria-hidden=\"true\"\r\n className={cn(\"shrink-0 object-contain\", className)}\r\n onError={() => setFallo(true)}\r\n />\r\n );\r\n }\r\n\r\n // 2) Ícono propio del visor, servido desde `src/assets/icons`.\r\n const archivo =\r\n codigo === \"three-dimensional\"\r\n ? activo\r\n ? \"3DActivo\"\r\n : \"3DInactivo\"\r\n : ARCHIVO_ICONO[codigo];\r\n const urlCarpeta = archivo ? urlIcono(archivo) : undefined;\r\n if (urlCarpeta) {\r\n return (\r\n <img\r\n src={urlCarpeta}\r\n alt=\"\"\r\n aria-hidden=\"true\"\r\n className={cn(\"shrink-0 object-contain\", className)}\r\n />\r\n );\r\n }\r\n\r\n // 3) Sin ícono propio todavía: círculo con interrogación.\r\n return (\r\n <SvgBase className={className}>\r\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\r\n <path d=\"M9.6 9.2a2.5 2.5 0 114 2.2c-.9.6-1.6 1-1.6 2.1M12 17h.01\" />\r\n </SvgBase>\r\n );\r\n}\r\n\r\n/** Aspa (X): cerrar paneles y modales. */\r\nexport function IconoCerrar({ className }: PropsIcono) {\r\n return <IconoArchivo nombre=\"Cerrar\" className={className} />;\r\n}\r\n\r\n/** Círculo con \"i\": ilustra el aviso de una modal de alerta. */\r\nexport function IconoAlerta({ className }: PropsIcono) {\r\n return <IconoArchivo nombre=\"Alerta\" className={className} />;\r\n}\r\n\r\n/** Flechas circulares: restablece la medición en curso. */\r\nexport function IconoRestablecerMedida({ className }: PropsIcono) {\r\n return <IconoArchivo nombre=\"RestablecerMedida\" className={className} />;\r\n}\r\n\r\n/** Flechas verticales opuestas: intercambia origen y destino. */\r\nexport function IconoIntercambiar({ className }: PropsIcono) {\r\n return <IconoArchivo nombre=\"Intercambiar\" className={className} />;\r\n}\r\n\r\n/** Pin de ubicación: marca en el mapa el punto de coordenadas escrito. */\r\nexport function IconoMarcarPunto({ className }: PropsIcono) {\r\n return <IconoArchivo nombre=\"Proyectar\" className={className} />;\r\n}\r\n\r\n/** Barra tenue: asa para arrastrar una modal. */\r\nexport function IconoArrastrar({ className }: PropsIcono) {\r\n return <IconoArchivo nombre=\"Arrastrar\" className={className} />;\r\n}\r\n\r\n/** Flecha hacia la izquierda: volver a la vista anterior. */\r\nexport function IconoRegresar({ className }: PropsIcono) {\r\n return <IconoArchivo nombre=\"Regresar\" className={className} />;\r\n}\r\n\r\n/** Tabla con lupa: vuelve a ver la tabla de resultados sin repetir la búsqueda. */\r\nexport function IconoVerTabla({ className }: PropsIcono) {\r\n return <IconoArchivo nombre=\"VerTabla\" className={className} />;\r\n}\r\n\r\n/** Lupa con \"+\": encuadra el mapa a la extensión de la capa. */\r\nexport function IconoZoomALaCapa({ className }: PropsIcono) {\r\n return <IconoArchivo nombre=\"ZoomALaCapa\" className={className} />;\r\n}\r\n\r\n/** Flecha hacia una bandeja: descarga en GeoJSON lo visible de la capa. */\r\nexport function IconoDescargar({ className }: PropsIcono) {\r\n return <IconoArchivo nombre=\"Descargar\" className={className} />;\r\n}\r\n\r\n/** Dos rectángulos superpuestos: copia un valor al portapapeles. */\r\nexport function IconoCopiar({ className }: PropsIcono) {\r\n return (\r\n <SvgBase className={className}>\r\n <rect x=\"8\" y=\"8\" width=\"12\" height=\"12\" rx=\"2\" />\r\n <path d=\"M16 8V6a2 2 0 00-2-2H6a2 2 0 00-2 2v8a2 2 0 002 2h2\" />\r\n </SvgBase>\r\n );\r\n}\r\n\r\n/** Palomita: confirma que el valor ya se copió al portapapeles. */\r\nexport function IconoCopiado({ className }: PropsIcono) {\r\n return (\r\n <SvgBase className={className}>\r\n <path d=\"M5 12.5l4.5 4.5L13 8.5\" />\r\n </SvgBase>\r\n );\r\n}\r\n\r\n/** Lupa: filtro de texto de un combo buscable. */\r\nexport function IconoBuscar({ className }: PropsIcono) {\r\n return (\r\n <SvgBase className={className}>\r\n <circle cx=\"11\" cy=\"11\" r=\"7\" />\r\n <path d=\"M21 21l-4.3-4.3\" />\r\n </SvgBase>\r\n );\r\n}\r\n\r\n/** Flecha \"v\": indicador de submenú desplegable. */\r\nexport function IconoChevron({ className }: PropsIcono) {\r\n return (\r\n <SvgBase className={className}>\r\n <path d=\"M6 9l6 6 6-6\" />\r\n </SvgBase>\r\n );\r\n}\r\n\r\n/** Bombillo con rayos: ícono del control de opacidad de las capas. */\r\nexport function IconoOpacidad({ className }: PropsIcono) {\r\n return <IconoArchivo nombre=\"Opacidad\" className={className} />;\r\n}\r\n\r\n/** Controles deslizantes: opciones de un servicio o capa. */\r\nexport function IconoOpcionesCapa({ className }: PropsIcono) {\r\n return <IconoArchivo nombre=\"OpcionesCapa\" className={className} />;\r\n}\r\n\r\n/** Documento con líneas: fuente de información del servicio. */\r\nexport function IconoFuenteInformacion({ className }: PropsIcono) {\r\n return <IconoArchivo nombre=\"FuenteInformacion\" className={className} />;\r\n}\r\n\r\n/** Ojo verde: indica que la capa está visible (activa). */\r\nexport function IconoOjo({ className }: PropsIcono) {\r\n return <IconoArchivo nombre=\"CapaActiva\" className={className} />;\r\n}\r\n\r\n/** Ojo tachado: indica que la capa está oculta. */\r\nexport function IconoOjoTachado({ className }: PropsIcono) {\r\n return (\r\n <svg\r\n viewBox=\"0 0 20 20\"\r\n fill=\"none\"\r\n aria-hidden=\"true\"\r\n className={cn(\"shrink-0\", className)}\r\n >\r\n <path\r\n d=\"M17.7083 7.62497C17.3 6.97497 16.8333 6.39164 16.35 5.86664L13.2083 9.00831C13.3083 9.31664 13.3667 9.64997 13.3667 9.99997C13.3667 11.8666 11.8583 13.3666 10 13.3666C9.65 13.3666 9.31667 13.3083 9.00833 13.2083L6.125 16.0916C7.34167 16.775 8.65833 17.1333 10 17.1333C11.4833 17.1333 12.925 16.7 14.2417 15.8916C15.5583 15.075 16.7417 13.8833 17.7083 12.3666C18.5417 11.0666 18.5417 8.9333 17.7083 7.62497Z\"\r\n fill=\"#9EA0A2\"\r\n />\r\n <path\r\n d=\"M11.6833 8.31667L8.31667 11.6833C7.89167 11.25 7.61667 10.65 7.61667 10C7.61667 8.69167 8.68334 7.61667 10 7.61667C10.65 7.61667 11.25 7.89167 11.6833 8.31667Z\"\r\n fill=\"#292D32\"\r\n />\r\n <path\r\n d=\"M15.2083 4.79167L12.3833 7.61667C11.775 7 10.9333 6.63334 9.99999 6.63334C8.13332 6.63334 6.63332 8.14167 6.63332 10C6.63332 10.9333 7.00832 11.775 7.61666 12.3833L4.79999 15.2083H4.79166C3.86666 14.4583 3.01666 13.5 2.29166 12.3667C1.45832 11.0583 1.45832 8.93334 2.29166 7.625C3.25832 6.10834 4.44166 4.91667 5.75832 4.1C7.07499 3.3 8.51666 2.85834 9.99999 2.85834C11.8583 2.85834 13.6583 3.54167 15.2083 4.79167Z\"\r\n fill=\"#9EA0A2\"\r\n />\r\n <path\r\n d=\"M12.3833 10C12.3833 11.3083 11.3167 12.3833 10 12.3833C9.95 12.3833 9.90834 12.3833 9.85834 12.3667L12.3667 9.85834C12.3833 9.90834 12.3833 9.95 12.3833 10Z\"\r\n fill=\"#292D32\"\r\n />\r\n <path\r\n d=\"M18.1417 1.85834C17.8917 1.60834 17.4833 1.60834 17.2333 1.85834L1.85834 17.2417C1.60834 17.4917 1.60834 17.9 1.85834 18.15C1.98334 18.2667 2.14167 18.3333 2.30834 18.3333C2.475 18.3333 2.63334 18.2667 2.75834 18.1417L18.1417 2.75834C18.4 2.50834 18.4 2.10834 18.1417 1.85834Z\"\r\n fill=\"#292D32\"\r\n />\r\n </svg>\r\n );\r\n}\r\n","/**\n * Clase raíz del visor: acota el reset y el tema de la librería (`estilos.css`)\n * para no tocar el resto de la página anfitriona. La llevan la raíz del visor\n * y cada portal a `document.body` (que queda fuera de esa raíz).\n */\nexport const CLASE_RAIZ_MAPA = \"core-isa-mapa\";\n","import type { ReactElement } from \"react\";\r\nimport { cloneElement, useEffect, useId, useRef, useState } from \"react\";\r\nimport { createPortal } from \"react-dom\";\r\nimport { cn } from \"@/shared/lib/cn\";\r\nimport { CLASE_RAIZ_MAPA } from \"../styles/raiz.estilos\";\r\n\r\n/** Lado del disparador donde se despliega el tooltip. */\r\ntype Lado = \"arriba\" | \"abajo\";\r\n\r\n/** Alineación horizontal del tooltip respecto al disparador. */\r\ntype Alineacion = \"inicio\" | \"centro\" | \"fin\";\r\n\r\n/** Props de `Tooltip`. */\r\ninterface TooltipProps {\r\n /** Primera línea, en negrita (normalmente el nombre de la herramienta). */\r\n titulo: string;\r\n /** Segunda línea, tenue y opcional (la descripción). */\r\n descripcion?: string;\r\n /** Lado donde aparece. Por defecto `\"arriba\"`. */\r\n lado?: Lado;\r\n /** Alineación horizontal. Usa `\"fin\"`/`\"inicio\"` cerca de un borde. Por defecto `\"centro\"`. */\r\n alineacion?: Alineacion;\r\n /** Milisegundos de espera antes de mostrarse al pasar el puntero. */\r\n retardo?: number;\r\n /** Si es `true` no muestra nada (p. ej. mientras el disparador abre un panel). */\r\n deshabilitado?: boolean;\r\n /** Único hijo: el elemento que dispara el tooltip (un botón, un enlace…). */\r\n children: ReactElement<{ \"aria-describedby\"?: string }>;\r\n /** Clases para el `span` envolvente. */\r\n className?: string;\r\n}\r\n\r\n/** Separación en píxeles entre el disparador y el tooltip. */\r\nconst SEPARACION = 8;\r\n\r\nconst CLASES_FLECHA: Record<Alineacion, string> = {\r\n inicio: \"left-3\",\r\n centro: \"left-1/2 -translate-x-1/2\",\r\n fin: \"right-3\",\r\n};\r\n\r\n/** Posición fija (relativa al viewport) a partir del recuadro del disparador. */\r\nfunction calcularPosicion(rect: DOMRect, lado: Lado, alineacion: Alineacion) {\r\n const top = lado === \"arriba\" ? rect.top - SEPARACION : rect.bottom + SEPARACION;\r\n const desplazamientoY = lado === \"arriba\" ? \"-100%\" : \"0\";\r\n\r\n const horizontal = {\r\n inicio: { left: rect.left, x: \"0\" },\r\n centro: { left: rect.left + rect.width / 2, x: \"-50%\" },\r\n fin: { left: rect.right, x: \"-100%\" },\r\n }[alineacion];\r\n\r\n return {\r\n top,\r\n left: horizontal.left,\r\n transform: `translate(${horizontal.x}, ${desplazamientoY})`,\r\n };\r\n}\r\n\r\n/**\r\n * Tooltip accesible en `document.body` (no lo recorta ningún `overflow`). Aparece\r\n * con hover o foco y se oculta al salir o con `Escape`.\r\n */\r\nexport function Tooltip({\r\n titulo,\r\n descripcion,\r\n lado = \"arriba\",\r\n alineacion = \"centro\",\r\n retardo = 300,\r\n deshabilitado = false,\r\n children,\r\n className,\r\n}: TooltipProps) {\r\n const id = useId();\r\n const anclaRef = useRef<HTMLSpanElement>(null);\r\n const temporizador = useRef<number | undefined>(undefined);\r\n // El puntero está sobre el disparador: sirve para no reabrir el tooltip con el\r\n // foco que deja un clic de ratón (esa era la causa de que se quedara fijo).\r\n const punteroPresente = useRef(false);\r\n const [posicion, setPosicion] = useState<ReturnType<\r\n typeof calcularPosicion\r\n > | null>(null);\r\n\r\n const medir = () => {\r\n const rect = anclaRef.current?.getBoundingClientRect();\r\n /* istanbul ignore next -- el ancla siempre está montada al medir */\r\n if (rect) setPosicion(calcularPosicion(rect, lado, alineacion));\r\n };\r\n\r\n const cerrar = () => {\r\n window.clearTimeout(temporizador.current);\r\n setPosicion(null);\r\n };\r\n\r\n const programarApertura = () => {\r\n window.clearTimeout(temporizador.current);\r\n temporizador.current = window.setTimeout(medir, retardo);\r\n };\r\n\r\n // Puntero encima: programa la apertura tras el retardo.\r\n const alEntrarPuntero = () => {\r\n punteroPresente.current = true;\r\n programarApertura();\r\n };\r\n\r\n // Puntero fuera: cierra y olvida el estado de puntero.\r\n const alSalirPuntero = () => {\r\n punteroPresente.current = false;\r\n cerrar();\r\n };\r\n\r\n // Un clic sobre el disparador cierra el tooltip en vez de dejarlo fijo.\r\n const alPulsar = () => {\r\n punteroPresente.current = true;\r\n cerrar();\r\n };\r\n\r\n // El foco por teclado lo muestra; el que proviene de un clic de ratón, no.\r\n const alEnfocar = () => {\r\n if (punteroPresente.current) return;\r\n programarApertura();\r\n };\r\n\r\n const alDesenfocar = () => {\r\n punteroPresente.current = false;\r\n cerrar();\r\n };\r\n\r\n // Cancela cualquier apertura pendiente al desmontar.\r\n useEffect(() => () => window.clearTimeout(temporizador.current), []);\r\n\r\n // Mientras está visible: `Escape` lo cierra y el scroll/resize lo recolocan.\r\n useEffect(() => {\r\n if (!posicion) return;\r\n\r\n const alTecla = (evento: KeyboardEvent) => {\r\n if (evento.key === \"Escape\") cerrar();\r\n };\r\n const recolocar = () => {\r\n const rect = anclaRef.current?.getBoundingClientRect();\r\n /* istanbul ignore next -- el ancla sigue montada mientras el tooltip es visible */\r\n if (rect) setPosicion(calcularPosicion(rect, lado, alineacion));\r\n };\r\n\r\n document.addEventListener(\"keydown\", alTecla);\r\n window.addEventListener(\"scroll\", recolocar, true);\r\n window.addEventListener(\"resize\", recolocar);\r\n return () => {\r\n document.removeEventListener(\"keydown\", alTecla);\r\n window.removeEventListener(\"scroll\", recolocar, true);\r\n window.removeEventListener(\"resize\", recolocar);\r\n };\r\n }, [posicion, lado, alineacion]);\r\n\r\n const visible = posicion !== null;\r\n\r\n // Envoltura estable: no cambia entre estados para no remontar al hijo.\r\n if (deshabilitado) {\r\n return <span className={cn(\"relative inline-flex\", className)}>{children}</span>;\r\n }\r\n\r\n return (\r\n <span\r\n ref={anclaRef}\r\n className={cn(\"relative inline-flex\", className)}\r\n onMouseEnter={alEntrarPuntero}\r\n onMouseLeave={alSalirPuntero}\r\n onPointerDown={alPulsar}\r\n onClick={cerrar}\r\n onFocus={alEnfocar}\r\n onBlur={alDesenfocar}\r\n >\r\n {cloneElement(children, {\r\n \"aria-describedby\": visible ? id : children.props[\"aria-describedby\"],\r\n })}\r\n\r\n {visible &&\r\n createPortal(\r\n <span\r\n role=\"tooltip\"\r\n id={id}\r\n style={{\r\n top: posicion.top,\r\n left: posicion.left,\r\n transform: posicion.transform,\r\n }}\r\n className={cn(\r\n CLASE_RAIZ_MAPA,\r\n \"pointer-events-none fixed z-10001 w-max max-w-60 rounded-lg\",\r\n \"bg-slate-900 px-2.5 py-1.5 text-left shadow-xl\",\r\n \"transition-opacity duration-150 ease-out starting:opacity-0\",\r\n \"motion-reduce:transition-none\",\r\n )}\r\n >\r\n <span className=\"block text-[12px] font-semibold leading-tight text-white\">\r\n {titulo}\r\n </span>\r\n {descripcion && (\r\n <span className=\"mt-0.5 block text-[11px] leading-snug text-slate-300\">\r\n {descripcion}\r\n </span>\r\n )}\r\n {/* Flecha que apunta al disparador. */}\r\n <span\r\n aria-hidden=\"true\"\r\n className={cn(\r\n \"absolute size-2 rotate-45 bg-slate-900\",\r\n lado === \"arriba\" ? \"-bottom-1\" : \"-top-1\",\r\n CLASES_FLECHA[alineacion],\r\n )}\r\n />\r\n </span>,\r\n document.body,\r\n )}\r\n </span>\r\n );\r\n}\r\n","import type { ReactNode } from \"react\";\r\nimport { Fragment, useCallback, useEffect, useRef, useState } from \"react\";\r\nimport { cn } from \"@/shared/lib/cn\";\r\nimport type { HerramientaMapa } from \"../types\";\r\nimport {\r\n GRUPOS_BARRA_ESCRITORIO,\r\n GRUPOS_BARRA_RESPONSIVE,\r\n type GrupoBarra,\r\n} from \"../services/tools/grupos-barra\";\r\nimport { CLASES_REALCE_BOTON } from \"../styles/controles.estilos\";\r\nimport { IconoChevron, IconoHerramienta } from \"./iconos\";\r\nimport { Tooltip } from \"./Tooltip\";\r\n\r\n/**\r\n * Estilo base de cada botón (30×30). El fondo de hover se dibuja 3px hacia dentro\r\n * con `::before` para que dos botones contiguos no se toquen.\r\n */\r\nconst CLASES_BOTON =\r\n `relative grid size-7.5 place-items-center ${CLASES_REALCE_BOTON} hover:text-slate-600 ` +\r\n \"before:pointer-events-none before:absolute before:inset-0.75 before:rounded-[10px] \" +\r\n \"before:transition-colors before:duration-200 hover:before:bg-black/5\";\r\n\r\n/** Fondo azul del botón de la barra cuando está seleccionado (sobre el `::before`). */\r\nconst CLASES_BOTON_SELECCIONADO =\r\n \"before:bg-[#8DCEFF] before:shadow-inner hover:before:bg-[#8DCEFF]\";\r\n\r\n/** Tamaño de cada ícono de la barra (`relative` para quedar sobre el `::before`). */\r\nconst CLASES_ICONO = \"relative size-6\";\r\n\r\n/** Estilo del contenedor de la barra (alto 47px a factor de escala 1, ref. diseño). */\r\nconst CLASES_BARRA =\r\n \"flex flex-row items-center gap-0 rounded-[15px] border border-[#1E557E]/15 \" +\r\n \"bg-white px-[calc(var(--spacing)*1.5625)] py-[calc(var(--spacing)*1.875)] text-[#9EA0A2] shadow-xl\";\r\n\r\n/** Píldora de home/zoom, del mismo alto que un botón para no agrandar la barra. */\r\nconst CLASES_PILDORA_BARRA =\r\n \"flex flex-row items-center gap-0 rounded-[10px] bg-[#F3F3F3] px-0.5\";\r\n\r\n/** Herramienta que agrupa sub-herramientas en un submenú. */\r\ntype HerramientaConHijos = HerramientaMapa & { hijos: readonly HerramientaMapa[] };\r\n\r\n/** Indica si la herramienta tiene sub-herramientas. */\r\nconst tieneHijos = (h: HerramientaMapa): h is HerramientaConHijos =>\r\n Boolean(h.hijos && h.hijos.length > 0);\r\n\r\n/** Empareja los grupos con las herramientas disponibles y descarta los vacíos. */\r\nfunction agruparParaBarra(\r\n herramientas: readonly HerramientaMapa[],\r\n soportada: (codigo: string) => boolean,\r\n gruposBarra: readonly GrupoBarra[],\r\n): { grupo: GrupoBarra; items: HerramientaMapa[] }[] {\r\n const porCodigo = new Map(herramientas.map((h) => [h.codigo, h]));\r\n return gruposBarra.map((grupo) => ({\r\n grupo,\r\n items: grupo.codigos\r\n .map((codigo) => porCodigo.get(codigo))\r\n .filter((h): h is HerramientaMapa => h != null && soportada(h.codigo)),\r\n })).filter(({ items }) => items.length > 0);\r\n}\r\n\r\n// ─── Botón de ícono reutilizable ────────────────────────────────────\r\n\r\n/** Props de `BotonIcono`. */\r\ninterface BotonIconoProps {\r\n herramienta: HerramientaMapa;\r\n activa: boolean;\r\n onClick: () => void;\r\n /** Solo para el botón que abre un submenú. */\r\n haspopup?: boolean;\r\n expanded?: boolean;\r\n /** Oculta el tooltip (p. ej. mientras el submenú del grupo está abierto). */\r\n tooltipDeshabilitado?: boolean;\r\n children?: ReactNode;\r\n}\r\n\r\n/** Botón de una herramienta: ícono, tooltip y estado activo. */\r\nfunction BotonIcono({\r\n herramienta,\r\n activa,\r\n onClick,\r\n haspopup,\r\n expanded,\r\n tooltipDeshabilitado,\r\n children,\r\n}: BotonIconoProps) {\r\n return (\r\n <Tooltip\r\n titulo={herramienta.nombre}\r\n descripcion={herramienta.descripcion}\r\n alineacion=\"fin\"\r\n deshabilitado={tooltipDeshabilitado}\r\n >\r\n <button\r\n type=\"button\"\r\n aria-label={herramienta.nombre}\r\n aria-pressed={activa}\r\n aria-haspopup={haspopup}\r\n aria-expanded={expanded}\r\n onClick={onClick}\r\n className={cn(CLASES_BOTON, activa && CLASES_BOTON_SELECCIONADO)}\r\n >\r\n <IconoHerramienta\r\n codigo={herramienta.codigo}\r\n rutaIcono={herramienta.rutaIcono}\r\n className={CLASES_ICONO}\r\n />\r\n {children}\r\n </button>\r\n </Tooltip>\r\n );\r\n}\r\n\r\n// ─── Herramienta con submenú (ej: medición) ─────────────────────────\r\n\r\n/** Props de `GrupoConSubmenu`. */\r\ninterface GrupoConSubmenuProps {\r\n herramienta: HerramientaConHijos;\r\n abierto: boolean;\r\n /** Alguna sub-herramienta del grupo está activa. */\r\n activa: boolean;\r\n codigoActivo?: string;\r\n onToggleMenu: () => void;\r\n onSeleccionarSub: (codigo: string) => void;\r\n}\r\n\r\n/** Botón con chevron que despliega un submenú con sus sub-herramientas. */\r\nfunction GrupoConSubmenu({\r\n herramienta,\r\n abierto,\r\n activa,\r\n codigoActivo,\r\n onToggleMenu,\r\n onSeleccionarSub,\r\n}: GrupoConSubmenuProps) {\r\n return (\r\n <div className=\"relative\">\r\n <BotonIcono\r\n herramienta={herramienta}\r\n activa={activa}\r\n haspopup\r\n expanded={abierto}\r\n tooltipDeshabilitado={abierto}\r\n onClick={onToggleMenu}\r\n >\r\n <IconoChevron\r\n className={cn(\r\n \"absolute -right-0.5 top-1/2 size-3.5 -translate-y-1/2 text-slate-400 transition duration-200\",\r\n abierto && \"rotate-180 text-sky-500\",\r\n )}\r\n />\r\n </BotonIcono>\r\n\r\n {/* Submenú desplegable con las sub-herramientas. */}\r\n {abierto && (\r\n <ul\r\n aria-label={`Opciones de ${herramienta.nombre}`}\r\n className=\"absolute bottom-full right-0 z-30 mb-2 flex flex-row gap-0 rounded-2xl border border-slate-200 bg-white p-2 text-[#9EA0A2] shadow-xl\"\r\n >\r\n {herramienta.hijos.map((hijo) => (\r\n <li key={hijo.codigo}>\r\n <BotonIcono\r\n herramienta={hijo}\r\n activa={codigoActivo === hijo.codigo}\r\n onClick={() => onSeleccionarSub(hijo.codigo)}\r\n />\r\n </li>\r\n ))}\r\n </ul>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n// ─── Barra principal ───────────────────────────────────────────────\r\n\r\n/** Props de `BarraHerramientas`. */\r\ninterface BarraHerramientasProps {\r\n herramientas: readonly HerramientaMapa[];\r\n codigoActivo?: string;\r\n codigoPadreActivo?: string;\r\n /** Códigos que deben verse seleccionados aunque no tengan estado activo propio. */\r\n codigosResaltados?: readonly string[];\r\n onAlternar: (codigo: string) => void;\r\n onAlternarSubHerramienta: (subCodigo: string) => void;\r\n soportada: (codigo: string) => boolean;\r\n /** Selecciona la agrupación de herramientas a mostrar. Por defecto, `\"escritorio\"`. */\r\n variante?: \"escritorio\" | \"responsive\";\r\n}\r\n\r\n/** Barra flotante de herramientas del mapa, con soporte de submenús por grupo. */\r\nexport function BarraHerramientas({\r\n herramientas,\r\n codigoActivo,\r\n codigoPadreActivo,\r\n codigosResaltados,\r\n onAlternar,\r\n onAlternarSubHerramienta,\r\n soportada,\r\n variante = \"escritorio\",\r\n}: BarraHerramientasProps) {\r\n // Código del submenú abierto (o null) y referencia al contenedor de la barra.\r\n const [menuAbierto, setMenuAbierto] = useState<string | null>(null);\r\n const barraRef = useRef<HTMLDivElement>(null);\r\n\r\n // Grupos con las herramientas disponibles ya resueltas.\r\n const grupos = agruparParaBarra(\r\n herramientas,\r\n soportada,\r\n variante === \"responsive\" ? GRUPOS_BARRA_RESPONSIVE : GRUPOS_BARRA_ESCRITORIO,\r\n );\r\n\r\n const cerrarMenu = useCallback(() => setMenuAbierto(null), []);\r\n\r\n // Cierra el submenú abierto ante un clic fuera de la barra o la tecla Escape.\r\n useEffect(() => {\r\n if (!menuAbierto) return;\r\n\r\n const alClicFuera = (evento: MouseEvent) => {\r\n if (barraRef.current && !barraRef.current.contains(evento.target as Node)) {\r\n cerrarMenu();\r\n }\r\n };\r\n const alTecla = (evento: KeyboardEvent) => {\r\n if (evento.key === \"Escape\") cerrarMenu();\r\n };\r\n\r\n document.addEventListener(\"mousedown\", alClicFuera);\r\n document.addEventListener(\"keydown\", alTecla);\r\n return () => {\r\n document.removeEventListener(\"mousedown\", alClicFuera);\r\n document.removeEventListener(\"keydown\", alTecla);\r\n };\r\n }, [menuAbierto, cerrarMenu]);\r\n\r\n // Clic en herramienta sin submenú: cierra el menú y alterna la herramienta.\r\n const alClicSimple = useCallback(\r\n (codigo: string) => {\r\n cerrarMenu();\r\n onAlternar(codigo);\r\n },\r\n [cerrarMenu, onAlternar],\r\n );\r\n\r\n // Clic en herramienta con submenú: abre o cierra su desplegable.\r\n const alToggleMenu = useCallback((codigo: string) => {\r\n setMenuAbierto((abierto) => (abierto === codigo ? null : codigo));\r\n }, []);\r\n\r\n if (grupos.length === 0) return null;\r\n\r\n // Elige entre botón con submenú o botón simple según la herramienta.\r\n const renderBoton = (herramienta: HerramientaMapa) =>\r\n tieneHijos(herramienta) ? (\r\n <GrupoConSubmenu\r\n key={herramienta.codigo}\r\n herramienta={herramienta}\r\n abierto={menuAbierto === herramienta.codigo}\r\n activa={codigoPadreActivo === herramienta.codigo}\r\n codigoActivo={codigoActivo}\r\n onToggleMenu={() => alToggleMenu(herramienta.codigo)}\r\n onSeleccionarSub={onAlternarSubHerramienta}\r\n />\r\n ) : (\r\n <BotonIcono\r\n key={herramienta.codigo}\r\n herramienta={herramienta}\r\n activa={\r\n codigoActivo === herramienta.codigo ||\r\n (codigosResaltados?.includes(herramienta.codigo) ?? false)\r\n }\r\n onClick={() => alClicSimple(herramienta.codigo)}\r\n />\r\n );\r\n\r\n return (\r\n <div\r\n ref={barraRef}\r\n role=\"toolbar\"\r\n aria-orientation=\"horizontal\"\r\n className={CLASES_BARRA}\r\n >\r\n {grupos.map(({ grupo, items }, indice) => (\r\n <Fragment key={grupo.codigos[0]}>\r\n {/* Separador vertical entre grupos. */}\r\n {indice > 0 && (\r\n <span\r\n aria-hidden=\"true\"\r\n className=\"mx-0.5 h-5 w-px shrink-0 bg-slate-200\"\r\n />\r\n )}\r\n {/* Grupo encapsulado en su píldora, o botones sueltos. */}\r\n {grupo.encapsulado ? (\r\n <div className={CLASES_PILDORA_BARRA}>\r\n {items.map(renderBoton)}\r\n </div>\r\n ) : (\r\n items.map(renderBoton)\r\n )}\r\n </Fragment>\r\n ))}\r\n </div>\r\n );\r\n}\r\n","import { cn } from \"@/shared/lib/cn\";\nimport type { HerramientaMapa } from \"../types\";\nimport {\n CLASES_BOTON_CONTROL,\n CLASES_BOTON_CONTROL_REPOSO,\n CLASES_BOTON_CONTROL_SELECCIONADO,\n} from \"../styles/controles.estilos\";\nimport { IconoHerramienta } from \"./iconos\";\nimport { Tooltip } from \"./Tooltip\";\n\n/** Props de `BotonTridimensional`. */\ninterface BotonTridimensionalProps {\n herramienta: HerramientaMapa;\n activo: boolean;\n onClick: () => void;\n}\n\n/** Botón que alterna entre la vista 2D y la vista 3D del mapa. */\nexport function BotonTridimensional({\n herramienta,\n activo,\n onClick,\n}: BotonTridimensionalProps) {\n return (\n <Tooltip titulo={herramienta.nombre} descripcion={herramienta.descripcion} alineacion=\"inicio\">\n <button\n type=\"button\"\n aria-label={herramienta.nombre}\n aria-pressed={activo}\n onClick={onClick}\n className={cn(\n CLASES_BOTON_CONTROL,\n activo ? CLASES_BOTON_CONTROL_SELECCIONADO : CLASES_BOTON_CONTROL_REPOSO,\n )}\n >\n <IconoHerramienta\n codigo=\"three-dimensional\"\n rutaIcono={herramienta.rutaIcono}\n activo={activo}\n className=\"size-6\"\n />\n </button>\n </Tooltip>\n );\n}\n","/** Un decimal de coordenada a grados/minutos/segundos, con sufijo cardinal. */\r\nfunction formatearGrados(\r\n decimal: number,\r\n sufijoPositivo: string,\r\n sufijoNegativo: string,\r\n): string {\r\n const absoluto = Math.abs(decimal);\r\n const grados = Math.floor(absoluto);\r\n const minutosDecimal = (absoluto - grados) * 60;\r\n const minutos = Math.floor(minutosDecimal);\r\n const segundos = (minutosDecimal - minutos) * 60;\r\n const sufijo = decimal >= 0 ? sufijoPositivo : sufijoNegativo;\r\n return `${grados}°${minutos}'${segundos.toFixed(3)}\" ${sufijo}`;\r\n}\r\n\r\n/** Coordenadas geográficas en grados/minutos/segundos: `longitud / latitud`. */\r\nexport function formatearCoordenadas(longitud: number, latitud: number): string {\r\n return `${formatearGrados(longitud, \"E\", \"W\")} / ${formatearGrados(latitud, \"N\", \"S\")}`;\r\n}\r\n\r\n/** Un eje WGS84 (EPSG:4326) individual en grados decimales, p. ej. `4.570868°`. */\r\nexport function formatearGradosDecimales(valor: number, decimales = 6): string {\r\n return `${valor.toFixed(decimales)}°`;\r\n}\r\n","import { cn } from \"@/shared/lib/cn\";\r\nimport type { CoordenadasPuntero } from \"../hooks/useCoordenadasPuntero\";\r\nimport { formatearCoordenadas } from \"../services/formato-coordenadas\";\r\n\r\n/** Props de `LecturaCoordenadas`. */\r\ninterface LecturaCoordenadasProps {\r\n coordenadas: CoordenadasPuntero | null;\r\n className?: string;\r\n}\r\n\r\n/** Muestra las coordenadas bajo el puntero en grados/minutos/segundos. */\r\nexport function LecturaCoordenadas({\r\n coordenadas,\r\n className,\r\n}: LecturaCoordenadasProps) {\r\n return (\r\n <span\r\n // Sin aria-live: el valor sigue al puntero del mouse (cambia en cada\r\n // pointermove), así que anunciarlo interrumpiría constantemente al\r\n // lector de pantalla. Es un indicador puramente visual.\r\n className={cn(\r\n // Píldora con fondo propio (no solo texto+sombra): se lee igual de bien\r\n // sobre un basemap oscuro que sobre uno claro, y hace juego con la\r\n // barra de herramientas y las demás modales flotantes del visor.\r\n \"rounded-[15px] border border-slate-200 bg-white/95 px-2.5 py-1 shadow-lg backdrop-blur\",\r\n \"text-[12px] font-semibold leading-none tracking-normal text-slate-900 tabular-nums\",\r\n className,\r\n )}\r\n >\r\n {/* Coordenadas formateadas o marcador de posición. */}\r\n {coordenadas\r\n ? formatearCoordenadas(coordenadas.longitud, coordenadas.latitud)\r\n : \"— —\"}\r\n </span>\r\n );\r\n}\r\n","import { useCallback, useEffect, useState } from \"react\";\r\nimport { useObservadorTamano } from \"@/shared/hooks/useObservadorTamano\";\r\n\r\n/** Punto en coordenadas del viewport. */\r\ninterface Posicion {\r\n readonly x: number;\r\n readonly y: number;\r\n}\r\n\r\n/** Parámetros de `useModalArrastrable`. */\r\ninterface OpcionesModalArrastrable {\r\n /** Ancho fijo del elemento flotante (px). */\r\n readonly ancho: number;\r\n /** Alto estimado (px) hasta medir el real con `ref`. */\r\n readonly alto: number;\r\n /** Separación mínima con el borde de la ventana (px). Por defecto `8`. */\r\n readonly margen?: number;\r\n /** Reserva inferior (px) para no tapar la barra de herramientas. Por defecto, `margen`. */\r\n readonly margenInferior?: number;\r\n /** Reserva inferior usada solo al ubicar la modal por primera vez. */\r\n readonly margenInferiorInicial?: number;\r\n}\r\n\r\n/** Valor devuelto por `useModalArrastrable`. */\r\ninterface ModalArrastrable {\r\n /** Posición actual, siempre dentro de la ventana. */\r\n readonly posicion: Posicion;\r\n /** `onPointerDown` del asa de arrastre. */\r\n readonly alArrastrar: (evento: React.PointerEvent<HTMLElement>) => void;\r\n /** `ref` del contenedor: acota el arrastre con su alto real. */\r\n readonly ref: (nodo: HTMLElement | null) => void;\r\n}\r\n\r\n/**\r\n * Posiciona un elemento flotante y lo hace arrastrable sin salir de la ventana,\r\n * con captura de puntero para que siga al cursor y no se quede pegado.\r\n */\r\nexport function useModalArrastrable({\r\n ancho,\r\n alto,\r\n margen = 8,\r\n margenInferior = margen,\r\n margenInferiorInicial = margenInferior,\r\n}: OpcionesModalArrastrable): ModalArrastrable {\r\n const [altoMedido, setAltoMedido] = useState<number | null>(null);\r\n const [anchoMedido, setAnchoMedido] = useState<number | null>(null);\r\n const altoEfectivo = altoMedido ?? alto;\r\n // Cubre modales que crecen más allá de `ancho` (p. ej. un selector con una\r\n // opción larga en `ModalProyeccion`), para que el arrastre no las saque de\r\n // la ventana.\r\n const anchoEfectivo = anchoMedido ?? ancho;\r\n\r\n const acotar = useCallback(\r\n (x: number, y: number): Posicion => {\r\n const maxX = Math.max(margen, window.innerWidth - anchoEfectivo - margen);\r\n const maxY = Math.max(\r\n margen,\r\n window.innerHeight - altoEfectivo - margenInferior,\r\n );\r\n return {\r\n x: Math.min(Math.max(margen, x), maxX),\r\n y: Math.min(Math.max(margen, y), maxY),\r\n };\r\n },\r\n [anchoEfectivo, altoEfectivo, margen, margenInferior],\r\n );\r\n\r\n const [posicion, setPosicion] = useState<Posicion>(() => {\r\n /* istanbul ignore next -- guarda SSR: el visor solo corre en el navegador */\r\n if (typeof window === \"undefined\") return { x: margen, y: margen };\r\n // Aparece en la esquina inferior derecha, con su base sobre la reserva\r\n // inferior (la barra de herramientas queda despejada).\r\n return {\r\n x: Math.max(margen, window.innerWidth - ancho - 24),\r\n y: Math.max(margen, window.innerHeight - alto - margenInferiorInicial),\r\n };\r\n });\r\n\r\n // Mide el alto y ancho reales del contenedor (variables en las modales que\r\n // crecen) y los vuelve a medir cuando cambian de tamaño.\r\n const ref = useObservadorTamano<HTMLElement>((nodo) => {\r\n setAltoMedido(nodo.offsetHeight || null);\r\n setAnchoMedido(nodo.offsetWidth || null);\r\n });\r\n\r\n // Reacomoda la modal cuando cambia el tamaño de la ventana o el alto medido.\r\n useEffect(() => {\r\n const reacomodar = () => setPosicion((previa) => acotar(previa.x, previa.y));\r\n const cuadro = requestAnimationFrame(reacomodar);\r\n window.addEventListener(\"resize\", reacomodar);\r\n return () => {\r\n cancelAnimationFrame(cuadro);\r\n window.removeEventListener(\"resize\", reacomodar);\r\n };\r\n }, [acotar]);\r\n\r\n const alArrastrar = useCallback(\r\n (evento: React.PointerEvent<HTMLElement>) => {\r\n // No arrastrar cuando se pulsa un control dentro del asa.\r\n if ((evento.target as HTMLElement).closest(\"button\")) return;\r\n\r\n const asa = evento.currentTarget;\r\n asa.setPointerCapture(evento.pointerId);\r\n\r\n const puntero0 = { x: evento.clientX, y: evento.clientY };\r\n const posicion0 = posicion;\r\n\r\n const alMover = (e: PointerEvent) => {\r\n setPosicion(\r\n acotar(\r\n posicion0.x + (e.clientX - puntero0.x),\r\n posicion0.y + (e.clientY - puntero0.y),\r\n ),\r\n );\r\n };\r\n const finalizar = (e: PointerEvent) => {\r\n asa.releasePointerCapture(e.pointerId);\r\n asa.removeEventListener(\"pointermove\", alMover);\r\n asa.removeEventListener(\"pointerup\", finalizar);\r\n asa.removeEventListener(\"pointercancel\", finalizar);\r\n };\r\n\r\n asa.addEventListener(\"pointermove\", alMover);\r\n asa.addEventListener(\"pointerup\", finalizar);\r\n asa.addEventListener(\"pointercancel\", finalizar);\r\n },\r\n [acotar, posicion],\r\n );\r\n\r\n return { posicion, alArrastrar, ref };\r\n}\r\n","/** Estilos compartidos de las modales de herramienta arrastrables. */\r\n\r\n/** Ancho fijo del diseño (px). La altura la decide cada modal. */\r\nexport const ANCHO_MODAL_HERRAMIENTA = 337.7;\r\n\r\n/** Ancho de la vista de resultados de \"Consultar\", más ancha para la tabla. */\r\nexport const ANCHO_MODAL_RESULTADOS_CONSULTA = 632;\r\n\r\n/** Alto máximo de la vista de resultados de \"Consultar\" (px): la tabla hace scroll propio dentro. */\r\nexport const ALTO_MODAL_RESULTADOS_CONSULTA = 443;\r\n\r\n/** Reserva inferior (px) para que la modal no tape la barra de herramientas. */\r\nexport const MARGEN_BARRA_HERRAMIENTAS = 110;\r\n\r\n/** Contenedor flotante de la modal. */\r\nexport const CLASES_MODAL_HERRAMIENTA =\r\n \"fixed z-40 flex flex-col overflow-hidden rounded-[10px] bg-white \" +\r\n \"shadow-[0_4px_20px_rgba(0,0,0,0.5)]\";\r\n","import { useEffect, type RefObject } from \"react\";\n\n/** Llama a `alCerrar` al hacer clic fuera de las `refs` mientras `activo` sea true. */\nexport function useCerrarAlClicFuera(\n refs: readonly RefObject<HTMLElement | null>[],\n activo: boolean,\n alCerrar: () => void,\n): void {\n useEffect(() => {\n if (!activo) return;\n const alClicFuera = (evento: MouseEvent) => {\n const destino = evento.target as Node;\n const dentroDeAlguna = refs.some((ref) => ref.current?.contains(destino));\n if (!dentroDeAlguna) alCerrar();\n };\n document.addEventListener(\"mousedown\", alClicFuera);\n return () => document.removeEventListener(\"mousedown\", alClicFuera);\n // `refs` y `alCerrar` se leen al momento del clic; no hace falta relanzar\n // el efecto cuando cambian de identidad entre renders.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [activo]);\n}\n","import { useCallback, useEffect, useState, type KeyboardEvent } from \"react\";\r\nimport { useCerrarAlClicFuera } from \"@/shared/hooks/useCerrarAlClicFuera\";\r\n\r\n/** Posición de un panel flotante, anclado por un solo borde (el otro va en `null`). */\r\nexport interface CajaPanel {\r\n top: number | null;\r\n bottom: number | null;\r\n left: number;\r\n width: number;\r\n}\r\n\r\n/** Separación en px entre el disparador y su panel. */\r\nconst SEPARACION = 4;\r\n/** Alto mínimo libre debajo del disparador para abrir el panel hacia abajo. */\r\nconst ESPACIO_MINIMO_ABAJO = 160;\r\n/** Margen inferior que se le deja a la ventana al abrir el panel. */\r\nconst MARGEN_INFERIOR_VENTANA = 8;\r\n\r\n/** Configura `manejarTeclado` para lo que cada disparador tiene de propio. */\r\nexport interface AccionesTeclado {\r\n /** Teclas extra (aparte de las flechas) que abren el panel estando cerrado. */\r\n teclasQueAbren?: readonly string[];\r\n /** Reemplaza `abrir()` al abrir por teclado (ej. para reiniciar un filtro). */\r\n alAbrir?: () => void;\r\n /** Enter (y Espacio, si `espacioConfirma`) con el panel abierto. */\r\n onEnter: () => void;\r\n /** Espacio también confirma como Enter; no usar si el disparador es un campo de texto. */\r\n espacioConfirma?: boolean;\r\n /** Reemplaza el cierre por defecto (`cerrar`) al presionar Escape. */\r\n onEscape?: () => void;\r\n /** Reemplaza el cierre por defecto (`cerrar`) al presionar Tab. */\r\n onTab?: () => void;\r\n /** Habilita Home/End para saltar a la primera/última opción. */\r\n primeraUltima?: readonly [primero: number, ultimo: number];\r\n}\r\n\r\n/** Opciones de `useListbox`. */\r\ninterface OpcionesListbox {\r\n /** Mide el disparador (getter en vez de `ref`: quien lo crea lo mide). */\r\n medir: () => DOMRect | undefined;\r\n /** Cuántas opciones tiene ahora la lista, para acotar el resaltado. */\r\n total: number;\r\n /** Opción a dejar resaltada al abrir (por defecto, la primera). */\r\n indiceInicial?: number;\r\n /** Se llama al cerrar sin elegir de la lista (permite confirmar texto escrito). */\r\n alCerrar?: () => void;\r\n}\r\n\r\n/**\r\n * Mecánica compartida de los selectores con listado en portal (`SelectorDesplegable`,\r\n * `ComboBuscable`): posición del panel, resaltado y cierre. No sabe qué es una opción;\r\n * los `ref` los posee quien monta el disparador y el panel.\r\n */\r\nexport function useListbox(\r\n disparadorRef: React.RefObject<HTMLElement | null>,\r\n panelRef: React.RefObject<HTMLUListElement | null>,\r\n { medir, total, indiceInicial = 0, alCerrar }: OpcionesListbox,\r\n) {\r\n const [abierto, setAbierto] = useState(false);\r\n const [caja, setCaja] = useState<CajaPanel | null>(null);\r\n const [indiceActivo, setIndiceActivo] = useState(indiceInicial);\r\n\r\n /** Rango válido del resaltado: `[0, total - 1]`, o `[0, 0]` si la lista está vacía. */\r\n const acotar = useCallback(\r\n (indice: number) => Math.min(Math.max(indice, 0), Math.max(total - 1, 0)),\r\n [total],\r\n );\r\n\r\n const cerrar = useCallback(() => {\r\n setAbierto(false);\r\n alCerrar?.();\r\n }, [alCerrar]);\r\n\r\n /** Cierra sin pasar por `alCerrar`: en `ComboBuscable`, Escape descarta lo escrito. */\r\n const ocultar = useCallback(() => setAbierto(false), []);\r\n\r\n const abrir = useCallback(\r\n (indice: number = indiceInicial) => {\r\n const rect = medir();\r\n if (rect) {\r\n const espacioAbajo =\r\n window.innerHeight - rect.bottom - SEPARACION - MARGEN_INFERIOR_VENTANA;\r\n const arriba = espacioAbajo < ESPACIO_MINIMO_ABAJO && rect.top > espacioAbajo;\r\n setCaja({\r\n top: arriba ? null : rect.bottom + SEPARACION,\r\n bottom: arriba ? window.innerHeight - (rect.top - SEPARACION) : null,\r\n left: rect.left,\r\n width: rect.width,\r\n });\r\n }\r\n setIndiceActivo(indice);\r\n setAbierto(true);\r\n },\r\n [medir, indiceInicial],\r\n );\r\n\r\n // Mantiene la opción resaltada dentro del panel visible.\r\n useEffect(() => {\r\n if (!abierto) return;\r\n panelRef.current\r\n ?.querySelector(`[data-indice=\"${indiceActivo}\"]`)\r\n ?.scrollIntoView({ block: \"nearest\" });\r\n }, [abierto, indiceActivo, panelRef]);\r\n\r\n // Al filtrar la lista, el resaltado puede quedar fuera de rango. Se ajusta\r\n // durante el render (no en un efecto) siguiendo el patrón que recomienda\r\n // React para \"ajustar estado cuando cambia una entrada\".\r\n const [totalPrevio, setTotalPrevio] = useState(total);\r\n if (totalPrevio !== total) {\r\n setTotalPrevio(total);\r\n if (indiceActivo > Math.max(total - 1, 0)) setIndiceActivo(acotar(indiceActivo));\r\n }\r\n\r\n // Con el panel abierto, un scroll de la ventana o un resize lo cierran (su\r\n // posición es fija). El scroll *dentro* del propio panel no debe cerrarlo.\r\n useEffect(() => {\r\n if (!abierto) return;\r\n const alDesplazar = (evento: Event) => {\r\n if (panelRef.current?.contains(evento.target as Node)) return;\r\n setAbierto(false);\r\n };\r\n window.addEventListener(\"scroll\", alDesplazar, true);\r\n window.addEventListener(\"resize\", alDesplazar);\r\n return () => {\r\n window.removeEventListener(\"scroll\", alDesplazar, true);\r\n window.removeEventListener(\"resize\", alDesplazar);\r\n };\r\n }, [abierto, panelRef]);\r\n\r\n useCerrarAlClicFuera([disparadorRef, panelRef], abierto, cerrar);\r\n\r\n const moverIndice = useCallback(\r\n (salto: number) => setIndiceActivo((i) => acotar(i + salto)),\r\n [acotar],\r\n );\r\n\r\n /** Teclado de un disparador tipo listbox; cada selector pasa sus `acciones`. */\r\n const manejarTeclado = useCallback(\r\n (evento: KeyboardEvent<HTMLElement>, acciones: AccionesTeclado) => {\r\n const { teclasQueAbren = [], alAbrir, onEnter, espacioConfirma, onEscape, onTab, primeraUltima } =\r\n acciones;\r\n\r\n if (!abierto) {\r\n if ([\"ArrowDown\", \"ArrowUp\", ...teclasQueAbren].includes(evento.key)) {\r\n evento.preventDefault();\r\n (alAbrir ?? abrir)();\r\n }\r\n return;\r\n }\r\n switch (evento.key) {\r\n case \"Escape\":\r\n evento.preventDefault();\r\n (onEscape ?? cerrar)();\r\n break;\r\n case \"Tab\":\r\n (onTab ?? cerrar)();\r\n break;\r\n case \"ArrowDown\":\r\n evento.preventDefault();\r\n moverIndice(1);\r\n break;\r\n case \"ArrowUp\":\r\n evento.preventDefault();\r\n moverIndice(-1);\r\n break;\r\n case \"Home\":\r\n if (primeraUltima) {\r\n evento.preventDefault();\r\n abrir(primeraUltima[0]);\r\n }\r\n break;\r\n case \"End\":\r\n if (primeraUltima) {\r\n evento.preventDefault();\r\n abrir(primeraUltima[1]);\r\n }\r\n break;\r\n case \"Enter\":\r\n evento.preventDefault();\r\n onEnter();\r\n break;\r\n case \" \":\r\n if (espacioConfirma) {\r\n evento.preventDefault();\r\n onEnter();\r\n }\r\n break;\r\n }\r\n },\r\n [abierto, abrir, cerrar, moverIndice],\r\n );\r\n\r\n return {\r\n abierto,\r\n caja,\r\n indiceActivo: acotar(indiceActivo),\r\n abrir,\r\n cerrar,\r\n ocultar,\r\n moverIndice,\r\n setIndiceActivo,\r\n manejarTeclado,\r\n };\r\n}\r\n","import { createPortal } from \"react-dom\";\r\nimport { cn } from \"@/shared/lib/cn\";\r\nimport type { CajaPanel } from \"../hooks/useListbox\";\r\nimport type { OpcionSelector } from \"./SelectorDesplegable\";\r\nimport { CLASE_RAIZ_MAPA } from \"../styles/raiz.estilos\";\r\n\r\n/** Props de `ListadoOpciones`: el panel en portal que comparten los selectores. */\r\ninterface ListadoOpcionesProps {\r\n idListado: string;\r\n /** Nombre accesible del listado. */\r\n etiqueta: string;\r\n caja: CajaPanel | null;\r\n panelRef: React.RefObject<HTMLUListElement | null>;\r\n /** Opciones a pintar (ya filtradas, si el selector filtra). */\r\n opciones: readonly OpcionSelector[];\r\n /** Valor elegido, para marcarlo con `aria-selected`. */\r\n valor: string;\r\n indiceActivo: number;\r\n onElegir: (opcion: OpcionSelector) => void;\r\n onMarcarActiva: (indice: number) => void;\r\n /** Aviso (cargando o \"sin coincidencias\") que reemplaza a las opciones. */\r\n aviso?: string;\r\n}\r\n\r\n/**\r\n * Listado `role=\"listbox\"` en un portal con posición fija. Es la parte visual que\r\n * comparten `SelectorDesplegable` y `ComboBuscable`.\r\n */\r\nexport function ListadoOpciones({\r\n idListado,\r\n etiqueta,\r\n caja,\r\n panelRef,\r\n opciones,\r\n valor,\r\n indiceActivo,\r\n onElegir,\r\n onMarcarActiva,\r\n aviso,\r\n}: ListadoOpcionesProps) {\r\n if (!caja) return null;\r\n\r\n return createPortal(\r\n <ul\r\n ref={panelRef}\r\n id={idListado}\r\n role=\"listbox\"\r\n aria-label={etiqueta}\r\n style={{\r\n top: caja.top ?? undefined,\r\n bottom: caja.bottom ?? undefined,\r\n left: caja.left,\r\n width: caja.width,\r\n maxHeight: 224,\r\n }}\r\n className={cn(\r\n CLASE_RAIZ_MAPA,\r\n \"scrollbar-fina fixed z-9999 overflow-y-auto overscroll-contain rounded-[10px]\",\r\n \"border border-slate-200 bg-white py-1 shadow-[0_8px_24px_rgba(0,0,0,0.18)]\",\r\n \"transition-opacity duration-100 ease-out starting:opacity-0\",\r\n )}\r\n >\r\n {aviso ? (\r\n <li className=\"px-3 py-2 text-xs text-slate-400\">{aviso}</li>\r\n ) : (\r\n opciones.map((opcion, indice) => {\r\n const activa = indice === indiceActivo;\r\n const elegida = opcion.valor === valor;\r\n // La opción de valor `\"\"` es el \"sin elegir\" de `permitirVacio`, no un\r\n // dato: se pinta en gris para que no compita con las de verdad.\r\n const esPlaceholder = opcion.valor === \"\";\r\n return (\r\n <li\r\n key={opcion.valor || \"__vacia__\"}\r\n id={`${idListado}-opt-${indice}`}\r\n role=\"option\"\r\n aria-selected={elegida}\r\n data-indice={indice}\r\n onMouseEnter={() => onMarcarActiva(indice)}\r\n onMouseDown={(evento) => evento.preventDefault()}\r\n onClick={() => onElegir(opcion)}\r\n className={cn(\r\n \"cursor-pointer px-3 py-2 text-xs text-slate-700 transition-colors\",\r\n activa && \"bg-[#E9F1FA]\",\r\n elegida && \"font-semibold text-slate-900\",\r\n esPlaceholder && \"text-slate-400\",\r\n )}\r\n >\r\n {opcion.etiqueta}\r\n </li>\r\n );\r\n })\r\n )}\r\n </ul>,\r\n document.body,\r\n );\r\n}\r\n","import { useCallback, useId, useRef, useState } from \"react\";\r\nimport { cn } from \"@/shared/lib/cn\";\r\nimport { useListbox } from \"../hooks/useListbox\";\r\nimport { IconoBuscar, IconoChevron } from \"./iconos\";\r\nimport { ListadoOpciones } from \"./ListadoOpciones\";\r\nimport type { OpcionSelector } from \"./SelectorDesplegable\";\r\n\r\n/** Props de `ComboBuscable`. */\r\ninterface ComboBuscableProps {\r\n valor: string;\r\n opciones: readonly OpcionSelector[];\r\n onCambiar: (valor: string) => void;\r\n /** Nombre accesible del control (y del listado). */\r\n etiqueta: string;\r\n id?: string;\r\n disabled?: boolean;\r\n placeholder?: string;\r\n /** Lista de opciones en vuelo: deshabilita el filtro y muestra un aviso. */\r\n cargando?: boolean;\r\n /** Acepta un texto que no calza ninguna opción (la lista puede venir truncada). */\r\n permitirValorLibre?: boolean;\r\n className?: string;\r\n}\r\n\r\n/** Mismo estilo del disparador que `SelectorDesplegable`, adaptado a `<input>`. */\r\nconst CLASES_DISPARADOR =\r\n \"flex h-9 w-full items-center gap-2 rounded-[10px] border border-slate-300 \" +\r\n \"bg-white px-3 text-xs text-slate-700 transition focus-within:border-sky-400 \" +\r\n \"hover:border-slate-400 disabled:cursor-not-allowed disabled:border-slate-300 \" +\r\n \"disabled:bg-slate-50 disabled:text-slate-400\";\r\n\r\n/**\r\n * Combo buscable: como `SelectorDesplegable`, pero el disparador es un campo que\r\n * filtra las opciones. Con `permitirValorLibre` acepta textos fuera de la lista.\r\n */\r\nexport function ComboBuscable({\r\n valor,\r\n opciones,\r\n onCambiar,\r\n etiqueta,\r\n id,\r\n disabled = false,\r\n placeholder = \"Buscar…\",\r\n cargando = false,\r\n permitirValorLibre = false,\r\n className,\r\n}: ComboBuscableProps) {\r\n const idBase = useId();\r\n const idListado = `${idBase}-listado`;\r\n const inputRef = useRef<HTMLInputElement>(null);\r\n const panelRef = useRef<HTMLUListElement>(null);\r\n const medir = useCallback(() => inputRef.current?.getBoundingClientRect(), []);\r\n\r\n const [texto, setTexto] = useState(\"\");\r\n\r\n const seleccionada = opciones.find((opcion) => opcion.valor === valor) ?? null;\r\n\r\n /** Al cerrar sin elegir de la lista: confirma el texto libre o lo descarta. */\r\n const alCerrar = () => {\r\n const escrito = texto.trim();\r\n if (permitirValorLibre && escrito !== \"\" && escrito !== seleccionada?.etiqueta) {\r\n onCambiar(escrito);\r\n }\r\n setTexto(\"\");\r\n };\r\n\r\n // `total` sin filtrar: basta como techo, y cada tecla vuelve el resaltado a 0.\r\n const listbox = useListbox(inputRef, panelRef, {\r\n medir,\r\n total: opciones.length,\r\n indiceInicial: 0,\r\n alCerrar,\r\n });\r\n const abierto = listbox.abierto;\r\n\r\n const filtradas = abierto\r\n ? opciones.filter((opcion) =>\r\n opcion.etiqueta.toLowerCase().includes(texto.trim().toLowerCase()),\r\n )\r\n : opciones;\r\n\r\n // Fuera de edición el campo muestra la etiqueta de la opción elegida (o el\r\n // valor libre tal cual, si no calza ninguna opción); abierto, lo escrito.\r\n const textoMostrado = abierto ? texto : (seleccionada?.etiqueta ?? valor);\r\n\r\n /** Al abrir se filtra desde cero. */\r\n const abrirFiltro = () => {\r\n setTexto(\"\");\r\n listbox.abrir(0);\r\n };\r\n\r\n const elegir = (opcion: OpcionSelector) => {\r\n onCambiar(opcion.valor);\r\n // `ocultar` y no `cerrar`: al elegir de la lista el valor ya es el de la\r\n // opción, y pasar por `alCerrar` haría que el texto usado para filtrar lo\r\n // sobrescribiera (\"Torre\" en vez de \"Torre 2\" al filtrar y elegir).\r\n listbox.ocultar();\r\n setTexto(\"\");\r\n inputRef.current?.focus();\r\n };\r\n\r\n const alTeclear = (evento: React.KeyboardEvent<HTMLInputElement>) => {\r\n if (disabled) return;\r\n listbox.manejarTeclado(evento, {\r\n alAbrir: abrirFiltro,\r\n onEnter: () => {\r\n const opcion = filtradas[listbox.indiceActivo];\r\n if (opcion) elegir(opcion);\r\n else listbox.cerrar();\r\n },\r\n // Escape descarta: no confirma el texto escrito (a diferencia de Tab o del\r\n // clic fuera, que sí lo hacen).\r\n onEscape: () => {\r\n listbox.ocultar();\r\n setTexto(\"\");\r\n },\r\n });\r\n };\r\n\r\n /** Mensaje que reemplaza la lista mientras carga o cuando no hay coincidencias. */\r\n const aviso = cargando\r\n ? \"Cargando valores…\"\r\n : filtradas.length > 0\r\n ? undefined\r\n : permitirValorLibre\r\n ? \"Sin coincidencias; presione Enter para usar el texto escrito.\"\r\n : \"Sin coincidencias.\";\r\n\r\n return (\r\n <>\r\n <div className={cn(CLASES_DISPARADOR, className, disabled && \"opacity-60\")}>\r\n <IconoBuscar className=\"size-3.5 shrink-0 text-slate-400\" />\r\n <input\r\n ref={inputRef}\r\n id={id}\r\n type=\"text\"\r\n role=\"combobox\"\r\n aria-label={etiqueta}\r\n aria-haspopup=\"listbox\"\r\n aria-expanded={abierto}\r\n aria-controls={abierto ? idListado : undefined}\r\n aria-activedescendant={\r\n abierto ? `${idListado}-opt-${listbox.indiceActivo}` : undefined\r\n }\r\n disabled={disabled}\r\n value={textoMostrado}\r\n placeholder={placeholder}\r\n onFocus={abrirFiltro}\r\n onClick={() => !abierto && abrirFiltro()}\r\n onChange={(evento) => {\r\n setTexto(evento.target.value);\r\n listbox.setIndiceActivo(0);\r\n }}\r\n onKeyDown={alTeclear}\r\n className=\"w-full min-w-0 bg-transparent text-xs text-slate-700 outline-none placeholder:text-slate-400 disabled:cursor-not-allowed\"\r\n />\r\n <IconoChevron\r\n className={cn(\r\n \"size-4 shrink-0 text-slate-400 transition-transform duration-200\",\r\n abierto && \"rotate-180\",\r\n )}\r\n />\r\n </div>\r\n\r\n {abierto && (\r\n <ListadoOpciones\r\n idListado={idListado}\r\n etiqueta={etiqueta}\r\n caja={listbox.caja}\r\n panelRef={panelRef}\r\n opciones={filtradas}\r\n valor={valor}\r\n indiceActivo={listbox.indiceActivo}\r\n onElegir={elegir}\r\n onMarcarActiva={listbox.setIndiceActivo}\r\n aviso={aviso}\r\n />\r\n )}\r\n </>\r\n );\r\n}\r\n","import { useCallback, useId, useRef } from \"react\";\r\nimport { cn } from \"@/shared/lib/cn\";\r\nimport { useListbox } from \"../hooks/useListbox\";\r\nimport { IconoChevron } from \"./iconos\";\r\nimport { ListadoOpciones } from \"./ListadoOpciones\";\r\n\r\n/** Una opción del selector. */\r\nexport interface OpcionSelector {\r\n /** Valor que se entrega en `onCambiar` (siempre string). */\r\n readonly valor: string;\r\n /** Texto visible de la opción. */\r\n readonly etiqueta: string;\r\n}\r\n\r\n/** Props de `SelectorDesplegable`. */\r\ninterface SelectorDesplegableProps {\r\n /** Valor seleccionado (string; convierte números en el llamador). */\r\n valor: string;\r\n opciones: readonly OpcionSelector[];\r\n onCambiar: (valor: string) => void;\r\n /** Nombre accesible del control (y del listado). */\r\n etiqueta: string;\r\n /** `id` del disparador, para asociarlo a un `<label htmlFor>`. */\r\n id?: string;\r\n disabled?: boolean;\r\n /** Texto cuando no hay ninguna opción seleccionada. */\r\n placeholder?: string;\r\n /** Añade el `placeholder` como opción `\"\"` para volver a \"sin elegir\". */\r\n permitirVacio?: boolean;\r\n /** Clases extra para el botón disparador. */\r\n className?: string;\r\n /** No trunca la opción elegida, para que un contenedor sin ancho fijo la muestre completa. */\r\n sinTruncar?: boolean;\r\n}\r\n\r\n/** Estilo base del disparador (coincide con los `<input>` de las modales). */\r\nconst CLASES_DISPARADOR =\r\n \"flex h-9 w-full items-center justify-between gap-2 rounded-[10px] border \" +\r\n \"border-slate-300 bg-white px-3 text-xs text-slate-700 transition \" +\r\n \"hover:border-slate-400 focus:border-sky-400 focus:outline-none \" +\r\n \"disabled:cursor-not-allowed disabled:border-slate-300 disabled:bg-slate-50 \" +\r\n \"disabled:text-slate-400\";\r\n\r\n/**\r\n * Selector desplegable propio (reemplaza al `<select>` nativo), con listado en\r\n * portal, teclado y cierre al clic fuera. Comparte mecánica con `ComboBuscable`.\r\n */\r\nexport function SelectorDesplegable({\r\n valor,\r\n opciones,\r\n onCambiar,\r\n etiqueta,\r\n id,\r\n disabled = false,\r\n placeholder = \"Seleccionar\",\r\n permitirVacio = false,\r\n className,\r\n sinTruncar = false,\r\n}: SelectorDesplegableProps) {\r\n const idBase = useId();\r\n const idListado = `${idBase}-listado`;\r\n\r\n // Lista efectiva: con `permitirVacio`, el placeholder es la 1ª opción (valor \"\").\r\n const opcionesLista: readonly OpcionSelector[] = permitirVacio\r\n ? [{ valor: \"\", etiqueta: placeholder }, ...opciones]\r\n : opciones;\r\n\r\n const indiceSeleccionado = opcionesLista.findIndex((o) => o.valor === valor);\r\n const seleccionada =\r\n indiceSeleccionado >= 0 ? opcionesLista[indiceSeleccionado] : null;\r\n // Se pinta como \"sin elegir\" cuando el valor está vacío.\r\n const vacio = valor === \"\";\r\n\r\n const disparadorRef = useRef<HTMLButtonElement>(null);\r\n const panelRef = useRef<HTMLUListElement>(null);\r\n const medir = useCallback(\r\n () => disparadorRef.current?.getBoundingClientRect(),\r\n [],\r\n );\r\n\r\n const listbox = useListbox(disparadorRef, panelRef, {\r\n medir,\r\n total: opcionesLista.length,\r\n indiceInicial: indiceSeleccionado >= 0 ? indiceSeleccionado : 0,\r\n });\r\n\r\n const elegir = (opcion: OpcionSelector) => {\r\n onCambiar(opcion.valor);\r\n listbox.cerrar();\r\n disparadorRef.current?.focus();\r\n };\r\n\r\n const alTeclaDisparador = (evento: React.KeyboardEvent<HTMLButtonElement>) => {\r\n if (disabled) return;\r\n listbox.manejarTeclado(evento, {\r\n teclasQueAbren: [\"Enter\", \" \"],\r\n espacioConfirma: true,\r\n primeraUltima: [0, opcionesLista.length - 1],\r\n // `indiceActivo` siempre está dentro de rango (se acota en cada cambio).\r\n onEnter: () => elegir(opcionesLista[listbox.indiceActivo]),\r\n });\r\n };\r\n\r\n return (\r\n <>\r\n <button\r\n ref={disparadorRef}\r\n id={id}\r\n type=\"button\"\r\n role=\"combobox\"\r\n aria-label={etiqueta}\r\n aria-haspopup=\"listbox\"\r\n aria-expanded={listbox.abierto}\r\n aria-controls={listbox.abierto ? idListado : undefined}\r\n aria-activedescendant={\r\n listbox.abierto ? `${idListado}-opt-${listbox.indiceActivo}` : undefined\r\n }\r\n disabled={disabled}\r\n onClick={() => (listbox.abierto ? listbox.cerrar() : listbox.abrir())}\r\n onKeyDown={alTeclaDisparador}\r\n className={cn(CLASES_DISPARADOR, className)}\r\n >\r\n <span\r\n className={cn(\r\n sinTruncar ? \"whitespace-nowrap\" : \"truncate\",\r\n (vacio || !seleccionada) && \"text-slate-400\",\r\n )}\r\n >\r\n {seleccionada?.etiqueta ?? placeholder}\r\n </span>\r\n <IconoChevron\r\n className={cn(\r\n \"size-4 shrink-0 text-slate-400 transition-transform duration-200\",\r\n listbox.abierto && \"rotate-180\",\r\n )}\r\n />\r\n </button>\r\n\r\n {listbox.abierto && (\r\n <ListadoOpciones\r\n idListado={idListado}\r\n etiqueta={etiqueta}\r\n caja={listbox.caja}\r\n panelRef={panelRef}\r\n opciones={opcionesLista}\r\n valor={valor}\r\n indiceActivo={listbox.indiceActivo}\r\n onElegir={elegir}\r\n onMarcarActiva={listbox.setIndiceActivo}\r\n />\r\n )}\r\n </>\r\n );\r\n}\r\n","import type Graphic from \"@arcgis/core/Graphic\";\r\nimport type { ReactNode } from \"react\";\r\nimport { useEffect, useId, useMemo, useRef, useState } from \"react\";\r\nimport { cn } from \"@/shared/lib/cn\";\r\nimport type { ResultadoConsultaCapa } from \"../types\";\r\nimport { CLASES_BOTON_CERRAR, CLASES_REALCE_BOTON } from \"../styles/controles.estilos\";\r\nimport { IconoCerrar, IconoRegresar, IconoZoomALaCapa } from \"./iconos\";\r\nimport { SelectorDesplegable, type OpcionSelector } from \"./SelectorDesplegable\";\r\nimport { Tooltip } from \"./Tooltip\";\r\n\r\n/** Opciones del selector \"Filas\" (tamaño de página). */\r\nconst OPCIONES_FILAS_POR_PAGINA: readonly OpcionSelector[] = [\r\n { valor: \"10\", etiqueta: \"10\" },\r\n { valor: \"25\", etiqueta: \"25\" },\r\n { valor: \"50\", etiqueta: \"50\" },\r\n { valor: \"100\", etiqueta: \"100\" },\r\n];\r\n\r\n// Clave sintética estable por gráfico: los atributos no tienen un id conocido.\r\nconst clavesGraficos = new WeakMap<Graphic, number>();\r\nlet siguienteClaveGrafico = 0;\r\nfunction claveDeGrafico(grafico: Graphic): number {\r\n let clave = clavesGraficos.get(grafico);\r\n if (clave === undefined) {\r\n clave = siguienteClaveGrafico++;\r\n clavesGraficos.set(grafico, clave);\r\n }\r\n return clave;\r\n}\r\n\r\n/** Props de `TablaResultadosConsulta`. */\r\ninterface TablaResultadosConsultaProps {\r\n resultado: ResultadoConsultaCapa;\r\n /** Título de la capa consultada, para la cabecera. */\r\n tituloCapa: string;\r\n /** Filas marcadas (checkbox): se resaltan juntas en el mapa. */\r\n seleccionados: ReadonlySet<Graphic>;\r\n /** Marca/desmarca una fila. */\r\n onAlternarFila: (grafico: Graphic) => void;\r\n /** Marca todas las filas si no lo están todas, o las desmarca si ya lo están. */\r\n onAlternarTodos: () => void;\r\n /** Acerca la vista a una fila ya marcada, sin desmarcarla (lupa por fila; solo aparece en filas marcadas). */\r\n onZoomFila: (grafico: Graphic) => void;\r\n /** Vuelve al formulario de la consulta (la modal se queda abierta). */\r\n onRegresar: () => void;\r\n /** Cierra la modal por completo. */\r\n onCerrar: () => void;\r\n /** Fila de pestañas (una por capa consultada, ver `ModalConsulta`), debajo de la cabecera. */\r\n pestanas?: ReactNode;\r\n}\r\n\r\n/**\r\n * Resultados de \"Consultar\" dentro de la misma modal: tabla con columnas por campo,\r\n * selección por checkbox (resalta en el mapa) y paginación.\r\n */\r\nexport function TablaResultadosConsulta({\r\n resultado,\r\n tituloCapa,\r\n seleccionados,\r\n onAlternarFila,\r\n onAlternarTodos,\r\n onZoomFila,\r\n onRegresar,\r\n onCerrar,\r\n pestanas,\r\n}: TablaResultadosConsultaProps) {\r\n const idFilasPorPagina = useId();\r\n const { campos, graficos, filasDevueltas, incompleto } = resultado;\r\n const [filasPorPagina, setFilasPorPagina] = useState<number>(10);\r\n const [pagina, setPagina] = useState(1);\r\n\r\n // Una consulta nueva reinicia la paginación: ajuste de estado durante el\r\n // render (no en un efecto), comparando contra el último resultado visto.\r\n const [resultadoPrevio, setResultadoPrevio] = useState(resultado);\r\n if (resultadoPrevio !== resultado) {\r\n setResultadoPrevio(resultado);\r\n setPagina(1);\r\n }\r\n\r\n const totalPaginas = Math.max(1, Math.ceil(graficos.length / filasPorPagina));\r\n const desde = (pagina - 1) * filasPorPagina;\r\n const filas = graficos.slice(desde, desde + filasPorPagina);\r\n\r\n // Cuenta solo las marcas de esta pestaña; memoizado porque se re-renderiza a menudo.\r\n const marcadosDeEstaCapa = useMemo(\r\n () =>\r\n graficos.reduce(\r\n (total, grafico) => (seleccionados.has(grafico) ? total + 1 : total),\r\n 0,\r\n ),\r\n [graficos, seleccionados],\r\n );\r\n const todosMarcados = graficos.length > 0 && marcadosDeEstaCapa === graficos.length;\r\n const algunoMarcado = marcadosDeEstaCapa > 0 && !todosMarcados;\r\n const checkboxTodosRef = useRef<HTMLInputElement>(null);\r\n useEffect(() => {\r\n if (checkboxTodosRef.current) checkboxTodosRef.current.indeterminate = algunoMarcado;\r\n }, [algunoMarcado]);\r\n\r\n return (\r\n <>\r\n <header className=\"flex shrink-0 items-center gap-2 border-b border-slate-100 px-5 pb-2\">\r\n <button\r\n type=\"button\"\r\n onClick={onRegresar}\r\n className={cn(\r\n \"flex shrink-0 items-center gap-1 rounded-md p-0.5 text-xs font-medium text-slate-500 hover:bg-[#F3F3F3] hover:text-slate-700\",\r\n CLASES_REALCE_BOTON,\r\n )}\r\n >\r\n <IconoRegresar className=\"size-5\" />\r\n Regresar\r\n </button>\r\n <span className=\"flex-1 truncate text-center text-sm font-bold text-slate-800\">\r\n Tabla de resultados\r\n </span>\r\n <button\r\n type=\"button\"\r\n aria-label=\"Cerrar consulta\"\r\n onClick={onCerrar}\r\n className={CLASES_BOTON_CERRAR}\r\n >\r\n <IconoCerrar className=\"size-4\" />\r\n </button>\r\n </header>\r\n\r\n {pestanas}\r\n\r\n <div className=\"flex min-h-0 flex-1 flex-col gap-2 px-5 pb-4 pt-3\">\r\n <p className=\"shrink-0 truncate text-xs text-slate-500\" title={tituloCapa}>\r\n {tituloCapa}\r\n {incompleto && \" · se muestran las primeras coincidencias; afine la consulta para ver el resto\"}\r\n </p>\r\n\r\n {graficos.length === 0 ? (\r\n <p className=\"py-6 text-center text-xs text-slate-400\">\r\n La consulta no encontró resultados.\r\n </p>\r\n ) : (\r\n <>\r\n {/*\r\n Grilla CSS con 'subgrid': el encabezado es fijo y solo el cuerpo desplaza.\r\n Los roles ARIA van a mano porque 'display: grid' quita los de tabla.\r\n */}\r\n <div\r\n role=\"table\"\r\n className=\"scrollbar-fina-visible grid min-h-0 flex-1 overflow-x-auto overflow-y-hidden rounded-[10px] text-xs\"\r\n style={{\r\n gridTemplateColumns: `56px repeat(${campos.length}, max-content)`,\r\n gridTemplateRows: \"auto minmax(0, 1fr)\",\r\n }}\r\n >\r\n <div\r\n role=\"row\"\r\n className=\"col-span-full grid grid-cols-subgrid bg-[#005899] text-white\"\r\n >\r\n <div role=\"columnheader\" className=\"flex items-center rounded-tl-[15px] px-3 py-2.5\">\r\n <input\r\n ref={checkboxTodosRef}\r\n type=\"checkbox\"\r\n checked={todosMarcados}\r\n onChange={onAlternarTodos}\r\n aria-label=\"Marcar todas las filas\"\r\n className=\"size-3.5 cursor-pointer accent-emerald-500\"\r\n />\r\n </div>\r\n {campos.map((campo, indice) => (\r\n <div\r\n key={campo.nombre}\r\n role=\"columnheader\"\r\n className={cn(\r\n \"flex items-center whitespace-nowrap px-3 py-2.5 font-semibold\",\r\n indice === campos.length - 1 && \"rounded-tr-[15px]\",\r\n )}\r\n >\r\n {campo.alias}\r\n </div>\r\n ))}\r\n </div>\r\n\r\n <div\r\n role=\"rowgroup\"\r\n className=\"scrollbar-fina-visible col-span-full grid grid-cols-subgrid content-start gap-y-1.5 overflow-x-hidden overflow-y-auto py-1\"\r\n >\r\n {filas.map((grafico, indice) => {\r\n const marcada = seleccionados.has(grafico);\r\n const numeroFila = desde + indice + 1;\r\n const clasesCelda = cn(\r\n \"flex h-10 cursor-pointer items-center text-slate-700\",\r\n marcada ? \"bg-emerald-50\" : \"bg-[#F9F9F9] hover:bg-slate-100\",\r\n );\r\n return (\r\n <div\r\n key={claveDeGrafico(grafico)}\r\n role=\"row\"\r\n className=\"contents\"\r\n onClick={() => {\r\n // No alternar si el clic fue para seleccionar texto\r\n // de una celda (arrastrar el mouse sobre el texto),\r\n // no para marcar la fila.\r\n if ((window.getSelection()?.toString() ?? \"\") !== \"\") return;\r\n onAlternarFila(grafico);\r\n }}\r\n >\r\n <div\r\n role=\"cell\"\r\n className={cn(clasesCelda, \"rounded-l-[10px] gap-1.5 px-3\")}\r\n onClick={(evento) => evento.stopPropagation()}\r\n >\r\n <input\r\n type=\"checkbox\"\r\n checked={marcada}\r\n onChange={() => onAlternarFila(grafico)}\r\n aria-label={`Marcar fila ${numeroFila}`}\r\n className=\"size-3.5 cursor-pointer accent-emerald-500\"\r\n />\r\n {marcada && (\r\n <Tooltip titulo=\"Zoom a esta entidad\" alineacion=\"inicio\">\r\n <button\r\n type=\"button\"\r\n onClick={() => onZoomFila(grafico)}\r\n aria-label=\"Zoom a esta entidad\"\r\n className={cn(\r\n \"grid size-5 shrink-0 place-items-center rounded text-slate-400 hover:bg-slate-100 hover:text-slate-600\",\r\n CLASES_REALCE_BOTON,\r\n )}\r\n >\r\n <IconoZoomALaCapa className=\"size-4.5\" />\r\n </button>\r\n </Tooltip>\r\n )}\r\n </div>\r\n {campos.map((campo) => (\r\n <div\r\n key={campo.nombre}\r\n role=\"cell\"\r\n className={cn(clasesCelda, \"whitespace-nowrap px-3\")}\r\n >\r\n {String(grafico.attributes?.[campo.nombre] ?? \"\")}\r\n </div>\r\n ))}\r\n </div>\r\n );\r\n })}\r\n </div>\r\n </div>\r\n\r\n <div className=\"flex shrink-0 flex-wrap items-center justify-between gap-2 rounded-b-[15px] bg-[#D8D8D9] px-3 py-1.5 text-xs text-slate-500\">\r\n <div className=\"flex items-center gap-1.5 text-xs font-semibold leading-none text-slate-600\">\r\n <label htmlFor={idFilasPorPagina}>Filas</label>\r\n <SelectorDesplegable\r\n id={idFilasPorPagina}\r\n etiqueta=\"Filas por página\"\r\n valor={String(filasPorPagina)}\r\n opciones={OPCIONES_FILAS_POR_PAGINA}\r\n onCambiar={(valor) => {\r\n setFilasPorPagina(Number(valor));\r\n setPagina(1);\r\n }}\r\n className={cn(\r\n \"h-6.25 min-w-12.5 justify-center gap-1 rounded-[10px] border-[rgba(41,45,50,1)] px-1.5 text-xs font-semibold text-slate-600\",\r\n CLASES_REALCE_BOTON,\r\n )}\r\n />\r\n </div>\r\n\r\n <span className=\"text-[10px] italic leading-[20.02px] tracking-[0.15px] text-slate-500\">\r\n Página {pagina} de {totalPaginas}\r\n </span>\r\n <span className=\"text-[10px] italic leading-[20.02px] tracking-[0.15px] text-slate-500\">\r\n {filasDevueltas.toLocaleString(\"es\")} registros totales\r\n </span>\r\n\r\n <nav aria-label=\"Paginación de resultados\" className=\"flex items-center gap-1.5\">\r\n {pagina > 1 && (\r\n <button\r\n type=\"button\"\r\n onClick={() => setPagina((p) => p - 1)}\r\n className={cn(\r\n \"h-6 rounded-[10px] border border-[rgba(41,45,50,0.15)] px-2.5 text-[11px] font-semibold text-slate-600 hover:bg-slate-100\",\r\n CLASES_REALCE_BOTON,\r\n )}\r\n >\r\n ← Anterior\r\n </button>\r\n )}\r\n <span\r\n aria-current=\"page\"\r\n className=\"grid h-6 w-6 shrink-0 place-items-center rounded-[10px] bg-[#005899] text-[11px] font-semibold text-white\"\r\n >\r\n {pagina}\r\n </span>\r\n {pagina < totalPaginas && (\r\n <button\r\n type=\"button\"\r\n onClick={() => setPagina((p) => p + 1)}\r\n className={cn(\r\n \"h-6 rounded-[10px] border border-[rgba(41,45,50,0.15)] px-2.5 text-[11px] font-semibold text-slate-600 hover:bg-slate-100\",\r\n CLASES_REALCE_BOTON,\r\n )}\r\n >\r\n Siguiente →\r\n </button>\r\n )}\r\n </nav>\r\n </div>\r\n </>\r\n )}\r\n </div>\r\n </>\r\n );\r\n}\r\n","import type Graphic from \"@arcgis/core/Graphic\";\r\nimport { useCallback, useId, useMemo, useState } from \"react\";\r\nimport { useModalArrastrable } from \"../hooks/useModalArrastrable\";\r\nimport { claveCapaConsultable } from \"../utils/mapa-helpers\";\r\nimport { CLASES_BOTON_CERRAR, CLASES_REALCE_BOTON } from \"../styles/controles.estilos\";\r\nimport {\r\n ALTO_MODAL_RESULTADOS_CONSULTA,\r\n ANCHO_MODAL_HERRAMIENTA,\r\n ANCHO_MODAL_RESULTADOS_CONSULTA,\r\n CLASES_MODAL_HERRAMIENTA,\r\n MARGEN_BARRA_HERRAMIENTAS,\r\n} from \"../styles/modales.estilos\";\r\nimport type {\r\n CampoConsulta,\r\n CapaConsultable,\r\n FiltroConsulta,\r\n OperadorBasico,\r\n ResultadoConsultaCapa,\r\n ResultadosConsultaCapas,\r\n ValoresDistintosCampo,\r\n} from \"../types\";\r\nimport { ComboBuscable } from \"./ComboBuscable\";\r\nimport { IconoArrastrar, IconoCerrar, IconoRegresar, IconoVerTabla } from \"./iconos\";\r\nimport { SelectorDesplegable, type OpcionSelector } from \"./SelectorDesplegable\";\r\nimport { TablaResultadosConsulta } from \"./TablaResultadosConsulta\";\r\nimport { Tooltip } from \"./Tooltip\";\r\n\r\n/** Props de `ModalConsulta`. */\r\ninterface ModalConsultaProps {\r\n /** Factor de escala de esta modal en pantallas grandes; `1` es el tamaño de diseño. */\r\n escalaInterfaz: number;\r\n /** Capas activas (visibles) sobre las que se puede consultar. */\r\n capasConsultables: readonly CapaConsultable[];\r\n onCamposDeCapa: (\r\n nombreServicio: string,\r\n identificador: string,\r\n ) => Promise<CampoConsulta[]>;\r\n onValoresDistintos: (\r\n nombreServicio: string,\r\n identificador: string,\r\n campo: string,\r\n ) => Promise<ValoresDistintosCampo>;\r\n onEjecutarConsulta: (\r\n nombreServicio: string,\r\n identificador: string,\r\n filtro: FiltroConsulta,\r\n ) => Promise<ResultadoConsultaCapa>;\r\n /** Cierra la modal (no limpia los resultados ya mostrados). */\r\n onCerrar: () => void;\r\n /** Se llama cuando una consulta termina con éxito. */\r\n onResultado: (resultado: ResultadoConsultaCapa, capa: CapaConsultable) => void;\r\n\r\n /** Resultados por capa consultada (una pestaña por capa, ej. Línea y Torre a la vez). */\r\n resultadosConsulta: ResultadosConsultaCapas;\r\n /** Filas marcadas (checkbox) de la tabla de resultados. */\r\n seleccionadosResultado: ReadonlySet<Graphic>;\r\n onAlternarFilaResultado: (grafico: Graphic) => void;\r\n onAlternarTodosResultado: () => void;\r\n /** Acerca la vista a una fila ya marcada, sin desmarcarla (lupa por fila). */\r\n onZoomFilaResultado: (grafico: Graphic) => void;\r\n /** Cierra una pestaña de resultados sin afectar las demás. */\r\n onQuitarPestanaResultado: (clave: string) => void;\r\n /** Cambia cuál pestaña de resultados se ve. */\r\n onCambiarPestanaResultado: (clave: string) => void;\r\n}\r\n\r\n/** Operadores del filtro: solo igualdad exacta y búsqueda parcial. */\r\nconst OPCIONES_OPERADOR: readonly OpcionSelector[] = [\r\n { valor: \"=\", etiqueta: \"Igual a (=)\" },\r\n { valor: \"LIKE\", etiqueta: \"Contiene (LIKE)\" },\r\n];\r\n\r\nconst CLASES_ETIQUETA = \"mb-1 block text-xs font-semibold text-slate-600\";\r\n\r\n/**\r\n * Modal arrastrable de \"Consultar\": arma un filtro por atributos sobre una capa\r\n * activa y emite `onResultado`; no dibuja resultados.\r\n */\r\nexport function ModalConsulta({\r\n escalaInterfaz,\r\n capasConsultables,\r\n onCamposDeCapa,\r\n onValoresDistintos,\r\n onEjecutarConsulta,\r\n onCerrar,\r\n onResultado,\r\n resultadosConsulta,\r\n seleccionadosResultado,\r\n onAlternarFilaResultado,\r\n onAlternarTodosResultado,\r\n onZoomFilaResultado,\r\n onQuitarPestanaResultado,\r\n onCambiarPestanaResultado,\r\n}: ModalConsultaProps) {\r\n const { posicion, alArrastrar, ref } = useModalArrastrable({\r\n ancho: ANCHO_MODAL_HERRAMIENTA * escalaInterfaz,\r\n alto: 320 * escalaInterfaz,\r\n margenInferior: 8,\r\n margenInferiorInicial: MARGEN_BARRA_HERRAMIENTAS,\r\n });\r\n\r\n const idBase = useId();\r\n const idCapa = `${idBase}-capa`;\r\n const idCampo = `${idBase}-campo`;\r\n const idOperador = `${idBase}-operador`;\r\n const idValor = `${idBase}-valor`;\r\n\r\n // Formulario o tabla; local para que \"Regresar\"/\"+\" no toquen las pestañas ya conseguidas.\r\n const [vista, setVista] = useState<\"formulario\" | \"resultado\">(() =>\r\n resultadosConsulta.entradas.length > 0 ? \"resultado\" : \"formulario\",\r\n );\r\n // Por qué se abrió el formulario con resultados ya existentes: decide el botón de\r\n // \"volver\" a mostrar. `null` = primera apertura, sin nada a lo que volver.\r\n const [origenFormulario, setOrigenFormulario] = useState<\"agregar\" | \"regresar\" | null>(\r\n null,\r\n );\r\n const [claveCapaElegida, setClaveCapaElegida] = useState(\"\");\r\n const [campoElegido, setCampoElegido] = useState(\"\");\r\n const [operador, setOperador] = useState<OperadorBasico>(\"=\");\r\n const [valor, setValor] = useState(\"\");\r\n const [cargando, setCargando] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n // Respuestas indexadas por la clave pedida: una respuesta tardía no pisa la de otra capa.\r\n const [camposPorClave, setCamposPorClave] = useState<Record<string, CampoConsulta[]>>(\r\n {},\r\n );\r\n const [valoresPorClave, setValoresPorClave] = useState<\r\n Record<string, ValoresDistintosCampo>\r\n >({});\r\n // Clave de lo que se está cargando ahora, o `null` si no hay nada en vuelo.\r\n const [cargaCampos, setCargaCampos] = useState<string | null>(null);\r\n const [cargaValores, setCargaValores] = useState<string | null>(null);\r\n\r\n const capaElegida = useMemo(\r\n () =>\r\n capasConsultables.find((item) => claveCapaConsultable(item) === claveCapaElegida) ?? null,\r\n [capasConsultables, claveCapaElegida],\r\n );\r\n\r\n const campos = useMemo(\r\n () => camposPorClave[claveCapaElegida] ?? [],\r\n [camposPorClave, claveCapaElegida],\r\n );\r\n const cargandoCampos = cargaCampos !== null && cargaCampos === claveCapaElegida;\r\n\r\n const claveValor = `${claveCapaElegida}::${campoElegido}`;\r\n const valoresDistintos = useMemo(\r\n () => valoresPorClave[claveValor] ?? null,\r\n [valoresPorClave, claveValor],\r\n );\r\n const cargandoValores = cargaValores !== null && cargaValores === claveValor;\r\n\r\n const opcionesCapa: OpcionSelector[] = useMemo(\r\n () =>\r\n capasConsultables.map((item) => ({\r\n valor: claveCapaConsultable(item),\r\n etiqueta: `${item.capa.titulo} (${item.servicio.nombre})`,\r\n })),\r\n [capasConsultables],\r\n );\r\n\r\n const opcionesCampo: OpcionSelector[] = useMemo(\r\n () => campos.map((campo) => ({ valor: campo.nombre, etiqueta: campo.alias })),\r\n [campos],\r\n );\r\n\r\n const opcionesValor: OpcionSelector[] = useMemo(\r\n () =>\r\n (valoresDistintos?.valores ?? []).map((item) => ({\r\n valor: item,\r\n etiqueta: item,\r\n })),\r\n [valoresDistintos],\r\n );\r\n\r\n /** Invalida lo que dependía de la capa/campo anterior (lo comparten las tres rutas). */\r\n const invalidarSeleccion = useCallback(() => {\r\n setCamposPorClave({});\r\n setValoresPorClave({});\r\n setCampoElegido(\"\");\r\n setValor(\"\");\r\n }, []);\r\n\r\n /** Cambiar de capa invalida todo lo que dependía de ella (campo, valor). */\r\n const cambiarCapa = (clave: string) => {\r\n setClaveCapaElegida(clave);\r\n setError(null);\r\n invalidarSeleccion();\r\n\r\n const item = capasConsultables.find((candidato) => claveCapaConsultable(candidato) === clave);\r\n if (!item) return;\r\n setCargaCampos(clave);\r\n void onCamposDeCapa(item.servicio.nombre, item.capa.identificador)\r\n .then((recibidos) =>\r\n setCamposPorClave((mapa) => ({ ...mapa, [clave]: recibidos })),\r\n )\r\n .finally(() =>\r\n // Solo apaga la carga si sigue siendo la de esta capa: si el usuario ya\r\n // pidió otra, esta respuesta tardía no debe apagarla.\r\n setCargaCampos((actual) => (actual === clave ? null : actual)),\r\n );\r\n };\r\n\r\n /** Cambiar de campo invalida el valor y precarga sus valores distintos. */\r\n const cambiarCampo = (nombre: string) => {\r\n setCampoElegido(nombre);\r\n setValor(\"\");\r\n if (!nombre || !capaElegida) return;\r\n const clave = `${claveCapaElegida}::${nombre}`;\r\n setCargaValores(clave);\r\n void onValoresDistintos(\r\n capaElegida.servicio.nombre,\r\n capaElegida.capa.identificador,\r\n nombre,\r\n )\r\n .then((recibidos) =>\r\n setValoresPorClave((mapa) => ({ ...mapa, [clave]: recibidos })),\r\n )\r\n .finally(() => setCargaValores((actual) => (actual === clave ? null : actual)));\r\n };\r\n\r\n const consultar = async () => {\r\n if (!capaElegida) {\r\n setError(\"Seleccione una capa.\");\r\n return;\r\n }\r\n\r\n if (!campoElegido) {\r\n setError(\"Seleccione un campo.\");\r\n return;\r\n }\r\n const valorFiltro = valor.trim();\r\n if (!valorFiltro) {\r\n setError(\"Escriba o seleccione un valor.\");\r\n return;\r\n }\r\n // El backend solo omite las comillas de los campos numéricos, así que\r\n // un texto en un campo numérico travela al servidor y vuelve como error\r\n // crudo. Se valida aquí para poder decirlo en el idioma del formulario.\r\n const tipo = campos.find((item) => item.nombre === campoElegido)?.tipo;\r\n if (tipo === \"numero\" && Number.isNaN(Number(valorFiltro))) {\r\n setError(\"El campo seleccionado es numérico: escriba un número.\");\r\n return;\r\n }\r\n if (tipo === \"fecha\" && Number.isNaN(Date.parse(valorFiltro))) {\r\n setError(\"El campo seleccionado es de fecha: escriba una fecha válida.\");\r\n return;\r\n }\r\n const filtro: FiltroConsulta = {\r\n modo: \"basica\",\r\n campo: campoElegido,\r\n operador,\r\n valor: valorFiltro,\r\n };\r\n\r\n setCargando(true);\r\n setError(null);\r\n try {\r\n const resultado = await onEjecutarConsulta(\r\n capaElegida.servicio.nombre,\r\n capaElegida.capa.identificador,\r\n filtro,\r\n );\r\n onResultado(resultado, capaElegida);\r\n setVista(\"resultado\");\r\n // Sin resultados no se marca `error`: la vista de resultados ya muestra su aviso.\r\n } catch (fallo: unknown) {\r\n setError(\r\n fallo instanceof Error ? fallo.message : \"No se pudo ejecutar la consulta.\",\r\n );\r\n } finally {\r\n setCargando(false);\r\n }\r\n };\r\n\r\n // Si la capa elegida deja de estar activa, se limpia la selección (ajuste en render,\r\n // comparando contra la lista previa guardada en estado).\r\n const [capasConsultablesPrevias, setCapasConsultablesPrevias] =\r\n useState(capasConsultables);\r\n if (capasConsultablesPrevias !== capasConsultables) {\r\n setCapasConsultablesPrevias(capasConsultables);\r\n if (claveCapaElegida && !capaElegida) {\r\n setClaveCapaElegida(\"\");\r\n invalidarSeleccion();\r\n }\r\n }\r\n\r\n // Sin pestañas (se cerró la última, o un \"clear\" global) no hay tabla que mostrar.\r\n const [entradasPrevias, setEntradasPrevias] = useState(resultadosConsulta.entradas);\r\n if (entradasPrevias !== resultadosConsulta.entradas) {\r\n setEntradasPrevias(resultadosConsulta.entradas);\r\n if (resultadosConsulta.entradas.length === 0) {\r\n if (vista === \"resultado\") setVista(\"formulario\");\r\n setOrigenFormulario(null);\r\n }\r\n }\r\n\r\n const entradaActiva =\r\n resultadosConsulta.entradas.find(\r\n (entrada) => entrada.clave === resultadosConsulta.activa,\r\n ) ?? null;\r\n const mostrandoResultado = vista === \"resultado\" && entradaActiva !== null;\r\n // \"Regresar\" (cabecera) cancela el intento de agregar capa; \"Ver tabla\"\r\n // (pie) vuelve a la tabla ya obtenida sin repetir la búsqueda.\r\n const hayADondeVolver = resultadosConsulta.entradas.length > 0 && origenFormulario !== null;\r\n const mostrarRegresarEnCabecera = hayADondeVolver && origenFormulario === \"agregar\";\r\n const mostrarVerTablaEnPie = hayADondeVolver && origenFormulario === \"regresar\";\r\n\r\n return (\r\n <div\r\n ref={ref}\r\n role=\"dialog\"\r\n aria-label=\"Consultar\"\r\n className={CLASES_MODAL_HERRAMIENTA}\r\n style={{\r\n left: posicion.x,\r\n top: posicion.y,\r\n ...(mostrandoResultado\r\n ? {\r\n width: ANCHO_MODAL_RESULTADOS_CONSULTA * escalaInterfaz,\r\n maxHeight: ALTO_MODAL_RESULTADOS_CONSULTA * escalaInterfaz,\r\n }\r\n : { minWidth: ANCHO_MODAL_HERRAMIENTA * escalaInterfaz }),\r\n }}\r\n >\r\n {/* Asa de arrastre. */}\r\n <div\r\n aria-hidden=\"true\"\r\n onPointerDown={alArrastrar}\r\n className=\"flex h-3.5 shrink-0 cursor-move touch-none select-none items-center justify-center\"\r\n >\r\n <IconoArrastrar className=\"h-1 w-7\" />\r\n </div>\r\n\r\n {mostrandoResultado && entradaActiva ? (\r\n <TablaResultadosConsulta\r\n resultado={entradaActiva.resultado}\r\n tituloCapa={entradaActiva.capa.capa.titulo}\r\n seleccionados={seleccionadosResultado}\r\n onAlternarFila={onAlternarFilaResultado}\r\n onAlternarTodos={onAlternarTodosResultado}\r\n onZoomFila={onZoomFilaResultado}\r\n onRegresar={() => {\r\n setOrigenFormulario(\"regresar\");\r\n setVista(\"formulario\");\r\n }}\r\n onCerrar={onCerrar}\r\n pestanas={\r\n // Aparecen desde la primera consulta exitosa, para poder agregar\r\n // otra capa desde ahí sin tener que \"Regresar\" primero.\r\n /* istanbul ignore next -- esta tabla solo se pinta con una entrada activa, así que nunca hay cero */\r\n resultadosConsulta.entradas.length > 0 ? (\r\n <div\r\n role=\"tablist\"\r\n aria-label=\"Capas consultadas\"\r\n className=\"flex shrink-0 flex-wrap items-center gap-1 border-b border-slate-100 px-5 py-2\"\r\n >\r\n {resultadosConsulta.entradas.map((entrada) => {\r\n const activa = entrada.clave === resultadosConsulta.activa;\r\n return (\r\n <div\r\n key={entrada.clave}\r\n role=\"tab\"\r\n aria-selected={activa}\r\n className={`flex items-center gap-1 rounded-lg py-1 pl-2.5 pr-1 text-xs font-semibold ${\r\n activa\r\n ? \"bg-white text-slate-800 shadow\"\r\n : \"bg-slate-100 text-slate-500 hover:text-slate-700\"\r\n }`}\r\n >\r\n <button\r\n type=\"button\"\r\n onClick={() => onCambiarPestanaResultado(entrada.clave)}\r\n className={`max-w-36 truncate ${CLASES_REALCE_BOTON}`}\r\n >\r\n {entrada.capa.capa.titulo}\r\n </button>\r\n <button\r\n type=\"button\"\r\n aria-label={`Quitar ${entrada.capa.capa.titulo} de los resultados`}\r\n onClick={() => onQuitarPestanaResultado(entrada.clave)}\r\n className={`grid size-3.5 shrink-0 place-items-center rounded-full text-slate-400 hover:bg-slate-200 hover:text-slate-600 ${CLASES_REALCE_BOTON}`}\r\n >\r\n <IconoCerrar className=\"size-2.5\" />\r\n </button>\r\n </div>\r\n );\r\n })}\r\n <Tooltip titulo=\"Agregar capa\" descripcion=\"Consulta otra capa y suma sus resultados a esta tabla.\" alineacion=\"fin\">\r\n <button\r\n type=\"button\"\r\n aria-label=\"Agregar otra capa a la consulta\"\r\n onClick={() => {\r\n setOrigenFormulario(\"agregar\");\r\n setVista(\"formulario\");\r\n }}\r\n className={`ml-1 grid size-6 shrink-0 place-items-center rounded-lg bg-slate-100 text-sm font-bold text-slate-500 hover:bg-slate-200 hover:text-slate-700 ${CLASES_REALCE_BOTON}`}\r\n >\r\n +\r\n </button>\r\n </Tooltip>\r\n </div>\r\n ) : null\r\n }\r\n />\r\n ) : (\r\n <>\r\n <header className=\"flex shrink-0 items-center gap-2 border-b border-slate-100 px-5 pb-2\">\r\n {mostrarRegresarEnCabecera ? (\r\n <button\r\n type=\"button\"\r\n onClick={() => setVista(\"resultado\")}\r\n className={`flex shrink-0 items-center gap-1 rounded-md p-0.5 text-xs font-medium text-slate-500 hover:bg-[#F3F3F3] hover:text-slate-700 ${CLASES_REALCE_BOTON}`}\r\n >\r\n <IconoRegresar className=\"size-5\" />\r\n Regresar\r\n </button>\r\n ) : (\r\n <span aria-hidden=\"true\" className=\"size-6 shrink-0\" />\r\n )}\r\n <span className=\"flex-1 text-center text-sm font-bold text-slate-800\">\r\n Consultar\r\n </span>\r\n <button\r\n type=\"button\"\r\n aria-label=\"Cerrar consulta\"\r\n onClick={onCerrar}\r\n className={CLASES_BOTON_CERRAR}\r\n >\r\n <IconoCerrar className=\"size-4\" />\r\n </button>\r\n </header>\r\n\r\n <form\r\n className=\"flex flex-col gap-3.5 px-5 pb-4 pt-4\"\r\n onSubmit={(evento) => {\r\n evento.preventDefault();\r\n void consultar();\r\n }}\r\n >\r\n {/* Capa. */}\r\n <div>\r\n <label htmlFor={idCapa} className={CLASES_ETIQUETA}>\r\n Capa\r\n </label>\r\n <SelectorDesplegable\r\n id={idCapa}\r\n etiqueta=\"Capa\"\r\n valor={claveCapaElegida}\r\n opciones={opcionesCapa}\r\n onCambiar={cambiarCapa}\r\n placeholder={\r\n opcionesCapa.length === 0\r\n ? \"Sin capas activas\"\r\n : \"Seleccione una capa\"\r\n }\r\n permitirVacio\r\n disabled={opcionesCapa.length === 0}\r\n />\r\n </div>\r\n\r\n <div>\r\n <label htmlFor={idCampo} className={CLASES_ETIQUETA}>\r\n Campo\r\n </label>\r\n <SelectorDesplegable\r\n id={idCampo}\r\n etiqueta=\"Campo\"\r\n valor={campoElegido}\r\n opciones={opcionesCampo}\r\n onCambiar={cambiarCampo}\r\n placeholder={cargandoCampos ? \"Cargando campos…\" : \"Seleccione un campo\"}\r\n permitirVacio\r\n disabled={!capaElegida || cargandoCampos || opcionesCampo.length === 0}\r\n />\r\n </div>\r\n\r\n <div className=\"flex gap-2\">\r\n <div className=\"w-32 shrink-0\">\r\n <label htmlFor={idOperador} className={CLASES_ETIQUETA}>\r\n Operador\r\n </label>\r\n <SelectorDesplegable\r\n id={idOperador}\r\n etiqueta=\"Operador\"\r\n valor={operador}\r\n opciones={OPCIONES_OPERADOR}\r\n onCambiar={(valorOperador) =>\r\n setOperador(valorOperador as OperadorBasico)\r\n }\r\n disabled={!campoElegido}\r\n sinTruncar\r\n />\r\n </div>\r\n <div className=\"flex-1\">\r\n <label htmlFor={idValor} className={CLASES_ETIQUETA}>\r\n Valor\r\n </label>\r\n <ComboBuscable\r\n id={idValor}\r\n etiqueta=\"Valor\"\r\n valor={valor}\r\n opciones={opcionesValor}\r\n onCambiar={setValor}\r\n cargando={cargandoValores}\r\n permitirValorLibre\r\n disabled={!campoElegido}\r\n placeholder={cargandoValores ? \"Cargando…\" : \"Buscar valor…\"}\r\n />\r\n </div>\r\n </div>\r\n {valoresDistintos?.truncado && (\r\n <p className=\"text-xs text-amber-600\">\r\n Se muestran los primeros {opcionesValor.length} valores; Escribe para encontrar el que buscas.\r\n </p>\r\n )}\r\n\r\n <div className=\"mt-1 flex shrink-0 items-center justify-end gap-3.5\">\r\n {mostrarVerTablaEnPie && (\r\n <button\r\n type=\"button\"\r\n onClick={() => setVista(\"resultado\")}\r\n className={`flex h-5 shrink-0 items-center gap-1 text-xs font-semibold text-slate-600 hover:text-slate-800 ${CLASES_REALCE_BOTON}`}\r\n >\r\n <IconoVerTabla className=\"size-4\" />\r\n Ver tabla\r\n </button>\r\n )}\r\n <button\r\n type=\"submit\"\r\n disabled={cargando}\r\n className={`h-[calc(1.9375rem*var(--factor-escala-interfaz,1))] min-w-[calc(5.9375rem*var(--factor-escala-interfaz,1))] shrink-0 rounded-[10px] bg-[linear-gradient(265.86deg,#0092FF_0%,#005899_98.31%)] px-4 text-xs font-bold text-white shadow-[1.03px_1.03px_4.12px_0px_rgba(0,0,0,0.3)] ${CLASES_REALCE_BOTON} hover:brightness-110 hover:shadow-md hover:shadow-[#005899]/60 focus-visible:-translate-y-0.5 focus-visible:shadow-md focus-visible:shadow-[#005899]/60 focus-visible:outline-none active:brightness-95 disabled:pointer-events-none disabled:opacity-60`}\r\n >\r\n {cargando ? \"Consultando…\" : \"Consultar\"}\r\n </button>\r\n </div>\r\n\r\n {error && (\r\n <p role=\"alert\" className=\"text-xs font-medium text-red-600\">\r\n {error}\r\n </p>\r\n )}\r\n </form>\r\n </>\r\n )}\r\n </div>\r\n );\r\n}\r\n","import { useEffect, useRef, useState } from \"react\";\r\nimport { cn } from \"@/shared/lib/cn\";\r\nimport type { CoordenadasPuntero } from \"../hooks/useCoordenadasPuntero\";\r\nimport { formatearGradosDecimales } from \"../services/formato-coordenadas\";\r\nimport { CLASES_REALCE_BOTON } from \"../styles/controles.estilos\";\r\nimport { IconoCerrar, IconoCopiado, IconoCopiar } from \"./iconos\";\r\nimport { Tooltip } from \"./Tooltip\";\r\n\r\n/** Milisegundos que el botón muestra la palomita antes de volver al ícono de copiar. */\r\nconst DURACION_AVISO_COPIADO_MS = 1500;\r\n\r\n/** Un eje (latitud o longitud) con su valor y botón de copiar. */\r\nfunction ValorCoordenada({ etiqueta, valor }: { etiqueta: string; valor: number }) {\r\n const [copiado, setCopiado] = useState(false);\r\n const temporizador = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\r\n\r\n useEffect(() => () => clearTimeout(temporizador.current), []);\r\n\r\n const copiar = async () => {\r\n try {\r\n await navigator.clipboard.writeText(valor.toFixed(6));\r\n } catch {\r\n // Sin permiso o contexto no seguro: no hay nada que copiar, se ignora.\r\n return;\r\n }\r\n setCopiado(true);\r\n clearTimeout(temporizador.current);\r\n temporizador.current = setTimeout(() => setCopiado(false), DURACION_AVISO_COPIADO_MS);\r\n };\r\n\r\n return (\r\n <span className=\"flex shrink-0 items-center gap-1 whitespace-nowrap rounded-[15px] border border-slate-200 bg-[#F3F3F3] py-1 pl-1.5 pr-1 text-xs font-semibold leading-none tracking-normal text-slate-900\">\r\n <span className=\"text-[10px] font-semibold uppercase tracking-wide text-slate-400\">\r\n {etiqueta}\r\n </span>\r\n <span aria-live=\"polite\" className=\"tabular-nums\">\r\n {formatearGradosDecimales(valor)}\r\n </span>\r\n <Tooltip titulo={copiado ? `${etiqueta} copiada` : `Copiar ${etiqueta.toLowerCase()}`}>\r\n <button\r\n type=\"button\"\r\n aria-label={copiado ? `${etiqueta} copiada` : `Copiar ${etiqueta.toLowerCase()}`}\r\n onClick={copiar}\r\n className={cn(\r\n \"grid size-5 shrink-0 place-items-center rounded-md text-slate-500 hover:bg-slate-200 hover:text-slate-700\",\r\n CLASES_REALCE_BOTON,\r\n )}\r\n >\r\n {copiado ? (\r\n <IconoCopiado className=\"size-3.5 text-emerald-600\" />\r\n ) : (\r\n <IconoCopiar className=\"size-3.5\" />\r\n )}\r\n </button>\r\n </Tooltip>\r\n </span>\r\n );\r\n}\r\n\r\n/** Props de `ModalCoordenadas`. */\r\ninterface ModalCoordenadasProps {\r\n coordenadas: CoordenadasPuntero;\r\n onCerrar: () => void;\r\n className?: string;\r\n}\r\n\r\n/** Panel flotante con las coordenadas WGS84 del punto marcado; al cerrarlo desactiva la herramienta. */\r\nexport function ModalCoordenadas({\r\n coordenadas,\r\n onCerrar,\r\n className,\r\n}: ModalCoordenadasProps) {\r\n return (\r\n <div\r\n className={cn(\r\n \"flex h-11.75 w-max max-w-[92vw] items-center gap-1.5 rounded-[15px] border border-slate-200\",\r\n \"bg-white/95 py-[7.5px] pl-[11.25px] pr-[11.25px] shadow-lg backdrop-blur\",\r\n className,\r\n )}\r\n >\r\n {/* Etiqueta del sistema de referencia. */}\r\n <span className=\"shrink-0 text-[10px] font-semibold uppercase tracking-wide text-slate-400\">\r\n WGS84\r\n </span>\r\n <ValorCoordenada etiqueta=\"Latitud\" valor={coordenadas.latitud} />\r\n <ValorCoordenada etiqueta=\"Longitud\" valor={coordenadas.longitud} />\r\n {/* Botón de cierre (desactiva la herramienta). */}\r\n <button\r\n type=\"button\"\r\n aria-label=\"Cerrar coordenadas\"\r\n onClick={onCerrar}\r\n className={cn(\r\n \"grid size-6 shrink-0 place-items-center rounded-md bg-slate-100 text-slate-500 hover:bg-slate-200 hover:text-slate-700\",\r\n CLASES_REALCE_BOTON,\r\n )}\r\n >\r\n <IconoCerrar className=\"size-3.5\" />\r\n </button>\r\n </div>\r\n );\r\n}\r\n","import { forwardRef, useEffect, useImperativeHandle, useRef, useState } from \"react\";\r\nimport { cn } from \"@/shared/lib/cn\";\r\nimport { useModalArrastrable } from \"../hooks/useModalArrastrable\";\r\nimport {\r\n MeasurementTools,\r\n type LecturaMedicion,\r\n} from \"../services/tools/medicion.tool\";\r\nimport type { HerramientaMapa, VistaMapa } from \"../types\";\r\nimport {\r\n CLASES_BOTON_BARRA_SELECCIONADO,\r\n CLASES_BOTON_CERRAR,\r\n CLASES_REALCE_BOTON,\r\n} from \"../styles/controles.estilos\";\r\nimport {\r\n IconoArrastrar,\r\n IconoCerrar,\r\n IconoHerramienta,\r\n IconoRestablecerMedida,\r\n} from \"./iconos\";\r\nimport {\r\n ANCHO_MODAL_HERRAMIENTA,\r\n CLASES_MODAL_HERRAMIENTA,\r\n MARGEN_BARRA_HERRAMIENTAS,\r\n} from \"../styles/modales.estilos\";\r\nimport { SelectorDesplegable, type OpcionSelector } from \"./SelectorDesplegable\";\r\nimport { Tooltip } from \"./Tooltip\";\r\n\r\n/** Sub-herramientas de medición que expone la modal. */\r\ntype SubMedicion = \"measure-distance\" | \"measure-area\";\r\n\r\n/** Props de `ModalMedicion`. */\r\ninterface ModalMedicionProps {\r\n /** Vista 2D sobre la que se montan los widgets de medición. */\r\n vista: VistaMapa;\r\n /** Definición de la sub-herramienta de distancia (nombre e ícono). */\r\n distancia: HerramientaMapa;\r\n /** Definición de la sub-herramienta de área (nombre e ícono). */\r\n area: HerramientaMapa;\r\n /** Cierra la modal (único modo de cierre). */\r\n onCerrar: () => void;\r\n /** Factor de escala de esta modal en pantallas grandes; `1` es el tamaño de diseño. */\r\n escalaInterfaz: number;\r\n}\r\n\r\n/** Métodos que `MapaView` invoca sobre la modal desde fuera (acción \"clear\"). */\r\nexport interface ModalMedicionHandle {\r\n /** Deselecciona la sub-herramienta activa y destruye ambos widgets. */\r\n limpiar: () => void;\r\n}\r\n\r\n/** Alto fijo del diseño (el ancho es común a las modales de herramienta). */\r\nconst ALTO = 203.1455078125;\r\n\r\n/** Nombre en español de cada unidad de ArcGIS. */\r\nconst ETIQUETA_UNIDAD: Record<string, string> = {\r\n metric: \"Metric\",\r\n millimeters: \"Milímetros\",\r\n centimeters: \"Centímetros\",\r\n decimeters: \"Decímetros\",\r\n meters: \"Metros\",\r\n kilometers: \"Kilómetros\",\r\n inches: \"Pulgadas\",\r\n feet: \"Pies\",\r\n \"us-feet\": \"Pies (EE. UU.)\",\r\n yards: \"Yardas\",\r\n miles: \"Millas\",\r\n \"nautical-miles\": \"Millas náuticas\",\r\n \"square-millimeters\": \"Milímetros cuadrados\",\r\n \"square-centimeters\": \"Centímetros cuadrados\",\r\n \"square-meters\": \"Metros cuadrados\",\r\n \"square-kilometers\": \"Kilómetros cuadrados\",\r\n \"square-inches\": \"Pulgadas cuadradas\",\r\n \"square-feet\": \"Pies cuadrados\",\r\n \"square-us-feet\": \"Pies cuadrados (EE. UU.)\",\r\n \"square-yards\": \"Yardas cuadradas\",\r\n \"square-miles\": \"Millas cuadradas\",\r\n acres: \"Acres\",\r\n ares: \"Áreas\",\r\n hectares: \"Hectáreas\",\r\n};\r\n\r\n/** Unidades que puede seleccionar el usuario en la modal. */\r\nconst UNIDADES_PERMITIDAS = new Set([\r\n \"metric\",\r\n \"centimeters\",\r\n \"kilometers\",\r\n \"meters\",\r\n \"square-kilometers\",\r\n \"square-meters\",\r\n \"hectares\",\r\n]);\r\n\r\n/** Abreviatura de cada unidad. */\r\nconst ABREV_UNIDAD: Record<string, string> = {\r\n millimeters: \"mm\",\r\n centimeters: \"cm\",\r\n decimeters: \"dm\",\r\n meters: \"m\",\r\n kilometers: \"km\",\r\n inches: \"in\",\r\n feet: \"ft\",\r\n \"us-feet\": \"ft\",\r\n yards: \"yd\",\r\n miles: \"mi\",\r\n \"nautical-miles\": \"M\",\r\n \"square-millimeters\": \"mm²\",\r\n \"square-centimeters\": \"cm²\",\r\n \"square-meters\": \"m²\",\r\n \"square-kilometers\": \"km²\",\r\n \"square-inches\": \"in²\",\r\n \"square-feet\": \"ft²\",\r\n \"square-us-feet\": \"ft²\",\r\n \"square-yards\": \"yd²\",\r\n \"square-miles\": \"mi²\",\r\n acres: \"ac\",\r\n ares: \"a\",\r\n hectares: \"ha\",\r\n};\r\n\r\nconst NUMERO = new Intl.NumberFormat(\"es-CO\", { maximumFractionDigits: 2 });\r\n\r\nconst MENSAJE_INICIO_MEDICION =\r\n \"Empiece a medir haciendo clic en el mapa para colocar su primer punto\";\r\n\r\n/** Abreviatura lineal equivalente a una unidad de área (para el perímetro). */\r\nfunction abrevLineal(codigoArea: string): string {\r\n const lineal = codigoArea.replace(/^square-/, \"\");\r\n return ABREV_UNIDAD[lineal] ?? \"m\";\r\n}\r\n\r\n/** Formatea un valor con su abreviatura, o `—` si aún no hay medición. */\r\nfunction formatear(valor: number | undefined, abreviatura: string): string {\r\n return valor == null || Number.isNaN(valor)\r\n ? \"—\"\r\n : `${NUMERO.format(valor)} ${abreviatura}`;\r\n}\r\n\r\n/** Filas de la tarjeta de información según la sub-herramienta. */\r\nfunction filasInfo(\r\n sub: SubMedicion | null,\r\n unidad: string,\r\n lectura: LecturaMedicion | null,\r\n): { etiqueta: string; valor: string }[] {\r\n if (sub === \"measure-area\") {\r\n return [\r\n { etiqueta: \"Área\", valor: formatear(lectura?.area, ABREV_UNIDAD[unidad] ?? \"\") },\r\n {\r\n etiqueta: \"Perímetro\",\r\n valor: formatear(lectura?.perimetro, abrevLineal(unidad)),\r\n },\r\n ];\r\n }\r\n return [\r\n {\r\n etiqueta: \"Distancia\",\r\n valor: formatear(lectura?.distancia, ABREV_UNIDAD[unidad] ?? \"\"),\r\n },\r\n ];\r\n}\r\n\r\n/**\r\n * Modal arrastrable de medición, sin sub-herramienta activa al abrir. Unidad y\r\n * resultado se alimentan del `viewModel` de ArcGIS. Solo se cierra con la «X».\r\n */\r\nexport const ModalMedicion = forwardRef<ModalMedicionHandle, ModalMedicionProps>(\r\n function ModalMedicion({ vista, distancia, area, onCerrar, escalaInterfaz }, ref) {\r\n const [sub, setSub] = useState<SubMedicion | null>(null);\r\n // Instantánea de unidad/lectura del `viewModel`; la refresca la observación.\r\n const [snap, setSnap] = useState<{\r\n unidades: string[];\r\n unidad: string;\r\n lectura: LecturaMedicion | null;\r\n }>({ unidades: [], unidad: \"\", lectura: null });\r\n\r\n const {\r\n posicion,\r\n alArrastrar,\r\n ref: refModal,\r\n } = useModalArrastrable({\r\n ancho: ANCHO_MODAL_HERRAMIENTA * escalaInterfaz,\r\n alto: ALTO * escalaInterfaz,\r\n margenInferior: 8,\r\n margenInferiorInicial: MARGEN_BARRA_HERRAMIENTAS,\r\n });\r\n\r\n const contenedorRef = useRef<HTMLDivElement>(null);\r\n const controladorRef = useRef<MeasurementTools | null>(null);\r\n const activadoRef = useRef(false);\r\n\r\n // Expone `limpiar` para que `MapaView` la invoque desde la acción \"clear\"\r\n // de la barra: la modal maneja su propio controlador, fuera de `codigoActivo`.\r\n useImperativeHandle(ref, () => ({\r\n limpiar: () => setSub(null),\r\n }));\r\n\r\n // ─── Ciclo de vida del widget de medición de ArcGIS ──────────────────\r\n useEffect(() => {\r\n const contenedor = contenedorRef.current;\r\n /* istanbul ignore next -- el contenedor oculto se monta con la modal */\r\n if (!contenedor) return;\r\n\r\n if (!controladorRef.current) controladorRef.current = new MeasurementTools();\r\n const controlador = controladorRef.current;\r\n\r\n if (!sub) {\r\n if (activadoRef.current) {\r\n controlador.desactivar();\r\n activadoRef.current = false;\r\n }\r\n return;\r\n }\r\n\r\n if (!activadoRef.current) {\r\n controlador.activar({ vista, contenedorUI: contenedor }, sub);\r\n activadoRef.current = true;\r\n } else {\r\n controlador.alternarSubHerramienta?.(sub);\r\n }\r\n\r\n // `observar` con `initial: true` produce la primera instantánea.\r\n return controlador.observar(() =>\r\n setSnap({\r\n unidades: [...controlador.unidades()],\r\n unidad: controlador.unidadActual() ?? \"\",\r\n lectura: controlador.lectura(),\r\n }),\r\n );\r\n }, [sub, vista]);\r\n\r\n // Destruye los widgets al cerrar la modal.\r\n useEffect(\r\n () => () => {\r\n controladorRef.current?.desactivar();\r\n controladorRef.current = null;\r\n activadoRef.current = false;\r\n },\r\n [],\r\n );\r\n\r\n // Cambia la unidad y refleja el cambio de inmediato (sin esperar al watch).\r\n const cambiarUnidad = (codigo: string) => {\r\n const controlador = controladorRef.current;\r\n controlador?.establecerUnidad(codigo);\r\n setSnap((previa) => ({\r\n ...previa,\r\n unidad: codigo,\r\n lectura: controlador?.lectura() ?? previa.lectura,\r\n }));\r\n };\r\n\r\n const opciones: { def: HerramientaMapa; codigo: SubMedicion }[] = [\r\n { def: distancia, codigo: \"measure-distance\" },\r\n { def: area, codigo: \"measure-area\" },\r\n ];\r\n\r\n const unidades = sub\r\n ? snap.unidades.filter((codigo) => UNIDADES_PERMITIDAS.has(codigo))\r\n : [];\r\n const unidadActual = sub ? snap.unidad : \"\";\r\n const filas = filasInfo(sub, unidadActual, sub ? snap.lectura : null);\r\n const opcionesUnidad: OpcionSelector[] = unidades.map((codigo) => ({\r\n valor: codigo,\r\n etiqueta: ETIQUETA_UNIDAD[codigo],\r\n }));\r\n\r\n return (\r\n <>\r\n {sub && (\r\n <div\r\n role=\"status\"\r\n className=\"pointer-events-none fixed left-1/2 top-3 z-10002 -translate-x-1/2 rounded-[15px] border border-slate-200 bg-white/95 px-3 py-2 text-center text-xs font-medium text-slate-700 shadow-lg backdrop-blur\"\r\n >\r\n {MENSAJE_INICIO_MEDICION}\r\n </div>\r\n )}\r\n\r\n <div\r\n ref={refModal}\r\n role=\"dialog\"\r\n aria-label=\"Herramientas de medición\"\r\n className={CLASES_MODAL_HERRAMIENTA}\r\n style={{\r\n left: posicion.x,\r\n top: posicion.y,\r\n width: ANCHO_MODAL_HERRAMIENTA * escalaInterfaz,\r\n height: ALTO * escalaInterfaz,\r\n }}\r\n >\r\n {/* Asa de arrastre: barra superior a todo el ancho de la modal. */}\r\n <div\r\n aria-hidden=\"true\"\r\n onPointerDown={alArrastrar}\r\n className=\"flex h-3.5 shrink-0 cursor-move touch-none select-none items-center justify-center\"\r\n >\r\n <IconoArrastrar className=\"h-1 w-7\" />\r\n </div>\r\n\r\n {/* Encabezado: título + botón de cierre (mismo margen lateral que el contenido). */}\r\n <header className=\"flex shrink-0 items-center gap-2 border-b border-slate-100 px-6 pb-2\">\r\n <span aria-hidden=\"true\" className=\"size-6 shrink-0\" />\r\n <span className=\"flex-1 text-center text-sm font-bold leading-3.75 tracking-normal text-[#292D32]\">\r\n Medición\r\n </span>\r\n <button\r\n type=\"button\"\r\n aria-label=\"Cerrar medición\"\r\n onClick={onCerrar}\r\n className={CLASES_BOTON_CERRAR}\r\n >\r\n <IconoCerrar className=\"size-4\" />\r\n </button>\r\n </header>\r\n\r\n <div className=\"flex flex-1 flex-col items-center gap-2 p-3.5\">\r\n {/* Sub-herramientas a la izquierda; «restablecer medida» a la derecha (alineadas al combo). */}\r\n <div className=\"flex w-[288.22px] items-center justify-between gap-2\">\r\n <div className=\"flex items-center gap-1\">\r\n {opciones.map(({ def, codigo }) => {\r\n const activa = sub === codigo;\r\n return (\r\n <Tooltip\r\n key={codigo}\r\n titulo={def.nombre}\r\n descripcion={def.descripcion}\r\n alineacion=\"inicio\"\r\n >\r\n <button\r\n type=\"button\"\r\n aria-label={def.nombre}\r\n aria-pressed={activa}\r\n onClick={() =>\r\n setSub((actual) => (actual === codigo ? null : codigo))\r\n }\r\n className={cn(\r\n \"flex items-center gap-1.5 rounded-[13.38px] px-2 py-1.5 text-[11px] font-bold text-[#292D32] hover:bg-black/5\",\r\n CLASES_REALCE_BOTON,\r\n activa && CLASES_BOTON_BARRA_SELECCIONADO,\r\n )}\r\n >\r\n <IconoHerramienta\r\n codigo={codigo}\r\n rutaIcono={def.rutaIcono}\r\n className=\"size-4.5 shrink-0\"\r\n />\r\n <span className=\"whitespace-nowrap\">{def.nombre}</span>\r\n </button>\r\n </Tooltip>\r\n );\r\n })}\r\n </div>\r\n\r\n <Tooltip titulo=\"Restablecer medida\" alineacion=\"fin\">\r\n <button\r\n type=\"button\"\r\n aria-label=\"Restablecer medida\"\r\n onClick={() => controladorRef.current?.restablecerMedida()}\r\n className={cn(\r\n \"grid size-7.5 shrink-0 place-items-center rounded-[13.38px] text-[#9EA0A2] hover:bg-black/5 hover:text-slate-600\",\r\n CLASES_REALCE_BOTON,\r\n )}\r\n >\r\n <IconoRestablecerMedida className=\"size-5\" />\r\n </button>\r\n </Tooltip>\r\n </div>\r\n\r\n {/* Selector de unidad: la etiqueta va sobre la raya del combo. */}\r\n <div className=\"relative mt-2 w-[288.22px]\">\r\n <span\r\n className={cn(\r\n \"absolute -top-2.25 left-2.5 z-10 bg-white px-1 text-xs font-semibold\",\r\n sub ? \"text-slate-700\" : \"text-slate-400\",\r\n )}\r\n >\r\n Unidad\r\n </span>\r\n <SelectorDesplegable\r\n etiqueta=\"Unidad\"\r\n valor={unidadActual}\r\n opciones={opcionesUnidad}\r\n onCambiar={cambiarUnidad}\r\n disabled={!sub}\r\n placeholder=\"—\"\r\n className=\"h-7.5\"\r\n />\r\n </div>\r\n\r\n {/* Tarjeta de resultado (siempre visible). */}\r\n <div className=\"flex h-[44.95px] w-[288.22px] flex-col justify-center gap-0.5 rounded-[10px] bg-[#EBF3F9] px-3 py-1.5\">\r\n {filas.map((fila) => (\r\n <div key={fila.etiqueta} className=\"flex items-baseline gap-1 text-xs\">\r\n <span className=\"text-slate-500\">{fila.etiqueta}</span>\r\n <span className=\"font-bold text-slate-800\">{fila.valor}</span>\r\n </div>\r\n ))}\r\n </div>\r\n\r\n {/* Contenedor fuera de vista donde ArcGIS monta sus widgets: solo se usa\r\n su `viewModel`, la UI propia va arriba. */}\r\n <div\r\n ref={contenedorRef}\r\n aria-hidden=\"true\"\r\n className=\"pointer-events-none absolute size-0 overflow-hidden opacity-0\"\r\n />\r\n </div>\r\n </div>\r\n </>\r\n );\r\n },\r\n);\r\n","import Point from \"@arcgis/core/geometry/Point\";\r\nimport SpatialReference from \"@arcgis/core/geometry/SpatialReference\";\r\nimport * as projectOperator from \"@arcgis/core/geometry/operators/projectOperator\";\r\nimport type {\r\n GeometryUnion,\r\n GeometryWithoutMeshUnion,\r\n} from \"@arcgis/core/geometry/types\";\r\n\r\n/** Rango válido de X/Y (o longitud/latitud) de un sistema de referencia. */\r\nexport interface RangoCoordenadas {\r\n readonly xMin: number;\r\n readonly xMax: number;\r\n readonly yMin: number;\r\n readonly yMax: number;\r\n}\r\n\r\n/** Sistema de referencia con nombre legible, para los selectores de la herramienta. */\r\nexport interface SistemaReferencia {\r\n /** Well-Known ID (código EPSG). */\r\n readonly wkid: number;\r\n /** Nombre para mostrar en español. */\r\n readonly nombre: string;\r\n /** `\"geografica\"`: lat/lon en grados. `\"proyectada\"`: este/norte en metros. */\r\n readonly tipo: \"geografica\" | \"proyectada\";\r\n /** Área de uso del EPSG (epsg.io) para validar coordenadas. Sin ella, no se valida rango. */\r\n readonly rango?: RangoCoordenadas;\r\n}\r\n\r\n/**\r\n * Sistemas de referencia de Colombia, en el orden de los selectores de `ModalProyeccion`.\r\n * `rango` sale de epsg.io; en 3115/3116/3117 y 21897 cubre todo el país, así que\r\n * detecta menos errores que en 9377.\r\n */\r\nexport const SRIDS_COLOMBIA: readonly SistemaReferencia[] = [\r\n {\r\n wkid: 4326,\r\n nombre: \"WGS 84 (4326)\",\r\n tipo: \"geografica\",\r\n rango: { xMin: -180, xMax: 180, yMin: -90, yMax: 90 },\r\n },\r\n {\r\n wkid: 4686,\r\n nombre: \"MAGNA-SIRGAS geográficas (4686)\",\r\n tipo: \"geografica\",\r\n // Área de uso (Colombia, continental e insular): epsg.io/4686.\r\n rango: { xMin: -84.77, xMax: -66.87, yMin: -4.23, yMax: 15.51 },\r\n },\r\n {\r\n wkid: 9377,\r\n nombre: \"MAGNA-SIRGAS / Origen Nacional (9377)\",\r\n tipo: \"proyectada\",\r\n // Límites proyectados: epsg.io/9377.\r\n rango: { xMin: 3681461, xMax: 5683150, yMin: 1080616, yMax: 3307328 },\r\n },\r\n {\r\n wkid: 3116,\r\n nombre: \"MAGNA-SIRGAS / Bogotá (3116)\",\r\n tipo: \"proyectada\",\r\n // Límites proyectados: epsg.io/3116.\r\n rango: { xMin: -197289, xMax: 1804467, yMin: 15738, yMax: 2236203 },\r\n },\r\n {\r\n wkid: 3115,\r\n nombre: \"MAGNA-SIRGAS / Oeste central (3115)\",\r\n tipo: \"proyectada\",\r\n // Límites proyectados: epsg.io/3115.\r\n rango: { xMin: 141082, xMax: 2142384, yMin: 16483, yMax: 2233599 },\r\n },\r\n {\r\n wkid: 3117,\r\n nombre: \"MAGNA-SIRGAS / Este central (3117)\",\r\n tipo: \"proyectada\",\r\n // Límites proyectados: epsg.io/3117.\r\n rango: { xMin: -539047, xMax: 1468798, yMin: 10303, yMax: 2255185 },\r\n },\r\n {\r\n wkid: 21897,\r\n nombre: \"Bogotá 1975 / zona Bogotá (21897)\",\r\n tipo: \"proyectada\",\r\n // Límites proyectados: epsg.io/21897.\r\n rango: { xMin: 440177, xMax: 1804482, yMin: 20285, yMax: 2016393 },\r\n },\r\n {\r\n wkid: 3857,\r\n nombre: \"Web Mercator (3857)\",\r\n tipo: \"proyectada\",\r\n // Límites estándar de la proyección (±180° de longitud).\r\n rango: { xMin: -20037508, xMax: 20037508, yMin: -20037508, yMax: 20037508 },\r\n },\r\n];\r\n\r\n/** Eje (`\"x\"`/`\"y\"`) fuera del rango de `sistema`, o `null`. Sin `rango`, se asume válido. */\r\nexport function ejeFueraDeRango(\r\n x: number,\r\n y: number,\r\n sistema: SistemaReferencia,\r\n): \"x\" | \"y\" | null {\r\n if (!sistema.rango) return null;\r\n const { xMin, xMax, yMin, yMax } = sistema.rango;\r\n if (x < xMin || x > xMax) return \"x\";\r\n if (y < yMin || y > yMax) return \"y\";\r\n return null;\r\n}\r\n\r\n/** Crea un punto de ArcGIS en el sistema de referencia indicado. */\r\nexport function crearPunto(x: number, y: number, wkid: number): Point {\r\n return new Point({ x, y, spatialReference: new SpatialReference({ wkid }) });\r\n}\r\n\r\n/** Proyecta una geometría a `wkidDestino` en el cliente (sin Geometry Service). */\r\nexport async function proyectar(\r\n geometria: GeometryUnion,\r\n wkidDestino: number,\r\n): Promise<GeometryWithoutMeshUnion> {\r\n if (!projectOperator.isLoaded()) {\r\n await projectOperator.load();\r\n }\r\n const proyectada = projectOperator.execute(\r\n geometria,\r\n new SpatialReference({ wkid: wkidDestino }),\r\n );\r\n if (!proyectada) {\r\n throw new Error(`No se pudo proyectar la geometría al sistema ${wkidDestino}.`);\r\n }\r\n return proyectada;\r\n}\r\n\r\n/** Proyecta un par de coordenadas de `wkidOrigen` a `wkidDestino` (modal «Proyectar»). */\r\nexport async function proyectarCoordenadas(\r\n x: number,\r\n y: number,\r\n wkidOrigen: number,\r\n wkidDestino: number,\r\n): Promise<{ x: number; y: number }> {\r\n const proyectada = await proyectar(crearPunto(x, y, wkidOrigen), wkidDestino);\r\n if (proyectada.type !== \"point\") {\r\n throw new Error(\"La proyección no devolvió un punto.\");\r\n }\r\n return { x: proyectada.x, y: proyectada.y };\r\n}\r\n","import { useId, useState } from \"react\";\r\nimport { useMarcadorPunto } from \"../hooks/useMarcadorPunto\";\r\nimport { useModalArrastrable } from \"../hooks/useModalArrastrable\";\r\nimport {\r\n SRIDS_COLOMBIA,\r\n crearPunto,\r\n ejeFueraDeRango,\r\n proyectar as proyectarGeometria,\r\n proyectarCoordenadas,\r\n} from \"../services/proyeccion\";\r\nimport {\r\n obtenerParametrosProyeccion,\r\n ParametrosGeneralesError,\r\n} from \"../services/parametros-generales\";\r\nimport { CLASES_BOTON_CERRAR, CLASES_REALCE_BOTON } from \"../styles/controles.estilos\";\r\nimport type { VistaMapa } from \"../types\";\r\nimport {\r\n IconoArrastrar,\r\n IconoCerrar,\r\n IconoIntercambiar,\r\n IconoMarcarPunto,\r\n} from \"./iconos\";\r\nimport {\r\n ANCHO_MODAL_HERRAMIENTA,\r\n CLASES_MODAL_HERRAMIENTA,\r\n MARGEN_BARRA_HERRAMIENTAS,\r\n} from \"../styles/modales.estilos\";\r\nimport { SelectorDesplegable, type OpcionSelector } from \"./SelectorDesplegable\";\r\nimport { Tooltip } from \"./Tooltip\";\r\n\r\n/** Props de `ModalProyeccion`. */\r\ninterface ModalProyeccionProps {\r\n /** Vista sobre la que se marca el punto de coordenadas escrito. */\r\n vista: VistaMapa;\r\n /** Cierra la modal (y con ella desactiva la herramienta). */\r\n onCerrar: () => void;\r\n /** Factor de escala de esta modal en pantallas grandes; `1` es el tamaño de diseño. */\r\n escalaInterfaz: number;\r\n}\r\n\r\n/** Formatea una coordenada resultante con hasta 8 decimales y sin separador de miles. */\r\nconst NUMERO = new Intl.NumberFormat(\"es-CO\", {\r\n maximumFractionDigits: 8,\r\n useGrouping: false,\r\n});\r\n\r\n/** Estilo compartido de los `<input>` del formulario. */\r\nconst CLASES_CAMPO =\r\n \"h-9 w-full rounded-[10px] border border-slate-300 bg-white px-3 text-xs \" +\r\n \"text-slate-700 focus:border-sky-400 focus:outline-none\";\r\n\r\n/** Etiqueta flotante sobre el borde del campo (mismo patrón que `ModalMedicion`). */\r\nconst CLASES_ETIQUETA =\r\n \"absolute -top-2.25 left-2.5 z-10 bg-white px-1 text-xs font-semibold text-slate-600\";\r\n\r\n/** Opciones de sistema de referencia para los selectores. */\r\nconst OPCIONES_SR: readonly OpcionSelector[] = SRIDS_COLOMBIA.map((sr) => ({\r\n valor: String(sr.wkid),\r\n etiqueta: sr.nombre,\r\n}));\r\n\r\n/** Etiquetas y ejemplos de X/Y según el tipo de sistema de origen o destino. */\r\nconst CAMPOS_POR_TIPO = {\r\n geografica: {\r\n etiquetaX: \"X (Longitud)\",\r\n etiquetaY: \"Y (Latitud)\",\r\n etiquetaXDestino: \"Longitud destino\",\r\n etiquetaYDestino: \"Latitud destino\",\r\n placeholderX: \"-74.0817\",\r\n placeholderY: \"4.6486\",\r\n },\r\n proyectada: {\r\n etiquetaX: \"X (Este)\",\r\n etiquetaY: \"Y (Norte)\",\r\n etiquetaXDestino: \"Este destino\",\r\n etiquetaYDestino: \"Norte destino\",\r\n placeholderX: \"1105000\",\r\n placeholderY: \"802000\",\r\n },\r\n} as const;\r\n\r\n/**\r\n * Número con signo, miles (`.`) y decimales (`,`), incluidos estados intermedios\r\n * de tecleo. Un solo `.` sin `,` se toma como decimal (ver `aNumero`).\r\n */\r\nconst PATRON_NUMERICO = /^-?[\\d.]*(?:,\\d*)?$/;\r\n\r\n/**\r\n * Convierte a número: con `,` esa es la decimal y los `.` son de miles; sin `,`,\r\n * un solo `.` es decimal y varios son de miles. `NaN` si no es válido.\r\n */\r\nconst aNumero = (texto: string): number => {\r\n const tieneComa = texto.includes(\",\");\r\n const tieneVariosPuntos = (texto.match(/\\./g)?.length ?? 0) > 1;\r\n const normalizado = tieneComa\r\n ? texto.replaceAll(\".\", \"\").replace(\",\", \".\")\r\n : tieneVariosPuntos\r\n ? texto.replaceAll(\".\", \"\")\r\n : texto;\r\n return Number.parseFloat(normalizado);\r\n};\r\n\r\n/**\r\n * Normaliza un texto pegado con miles y decimales mezclados (`1,105,000.55`,\r\n * `4.863.546,32`): el separador más a la derecha es el decimal; el resto se descarta.\r\n */\r\nconst normalizarPegado = (texto: string): string => {\r\n const comas = (texto.match(/,/g) ?? []).length;\r\n const puntos = (texto.match(/\\./g) ?? []).length;\r\n\r\n if (comas >= 2 && puntos === 0) return texto.replaceAll(\",\", \"\");\r\n\r\n if (comas >= 1 && puntos >= 1) {\r\n const posDecimal = Math.max(texto.lastIndexOf(\",\"), texto.lastIndexOf(\".\"));\r\n const entero = texto.slice(0, posDecimal).replaceAll(\",\", \"\").replaceAll(\".\", \"\");\r\n const decimales = texto.slice(posDecimal + 1).replace(/[.,]/g, \"\");\r\n return decimales ? `${entero},${decimales}` : entero;\r\n }\r\n\r\n return texto;\r\n};\r\n\r\n/** Descarta de un texto pegado todo lo que no pueda formar parte de un\r\n * número (letras, espacios, símbolos de grados, unidades, etc.), quedándose\r\n * solo con dígitos, un signo `-` inicial, puntos y como mucho una coma. */\r\nconst limpiarTextoNumerico = (texto: string): string => {\r\n let limpio = \"\";\r\n let comaUsada = false;\r\n for (const caracter of texto) {\r\n if (caracter >= \"0\" && caracter <= \"9\") limpio += caracter;\r\n else if (caracter === \"-\" && limpio === \"\") limpio += caracter;\r\n else if (caracter === \".\") limpio += caracter;\r\n else if (caracter === \",\" && !comaUsada) {\r\n limpio += caracter;\r\n comaUsada = true;\r\n }\r\n }\r\n return limpio;\r\n};\r\n\r\n/**\r\n * Modal arrastrable para convertir coordenadas entre sistemas de referencia en\r\n * el cliente (`projectOperator`). Solo se cierra con la «X».\r\n */\r\nexport function ModalProyeccion({ vista, onCerrar, escalaInterfaz }: ModalProyeccionProps) {\r\n const { posicion, alArrastrar, ref } = useModalArrastrable({\r\n ancho: ANCHO_MODAL_HERRAMIENTA * escalaInterfaz,\r\n // Alto aprox. de la modal contraída, solo para ubicarla al aparecer.\r\n alto: 275 * escalaInterfaz,\r\n margenInferior: 8,\r\n margenInferiorInicial: MARGEN_BARRA_HERRAMIENTAS,\r\n });\r\n\r\n const idBase = useId();\r\n const idOrigen = `${idBase}-origen`;\r\n const idX = `${idBase}-x`;\r\n const idY = `${idBase}-y`;\r\n const idDestino = `${idBase}-destino`;\r\n\r\n // Sin sistema elegido de entrada: los selectores muestran \"Seleccione\".\r\n const [origen, setOrigen] = useState<number | null>(null);\r\n const [destino, setDestino] = useState<number | null>(null);\r\n const [x, setX] = useState(\"\");\r\n const [y, setY] = useState(\"\");\r\n const [resultado, setResultado] = useState<{\r\n x: number;\r\n y: number;\r\n wkid: number;\r\n } | null>(null);\r\n const [error, setError] = useState<string | null>(null);\r\n const [cargando, setCargando] = useState(false);\r\n const [marcando, setMarcando] = useState(false);\r\n\r\n const { marcar } = useMarcadorPunto(vista);\r\n\r\n // El sistema de origen decide si X/Y son grados (geográfica) o metros\r\n // (proyectada); sin selección, se muestran los textos de geográfica.\r\n const sistemaOrigen = SRIDS_COLOMBIA.find((sr) => sr.wkid === origen) ?? null;\r\n const camposXY = CAMPOS_POR_TIPO[sistemaOrigen?.tipo ?? \"geografica\"];\r\n\r\n // Sistema de origen elegido, X/Y numéricos y dentro de su rango: condición para poder marcar.\r\n const puedeMarcar =\r\n sistemaOrigen != null &&\r\n Number.isFinite(aNumero(x)) &&\r\n Number.isFinite(aNumero(y)) &&\r\n ejeFueraDeRango(aNumero(x), aNumero(y), sistemaOrigen) === null;\r\n\r\n /** Cambia el sistema de origen y limpia X/Y, que dejan de tener sentido. */\r\n const cambiarOrigen = (valor: string) => {\r\n setOrigen(valor === \"\" ? null : Number(valor));\r\n setX(\"\");\r\n setY(\"\");\r\n setResultado(null);\r\n setError(null);\r\n };\r\n\r\n /** Actualiza `setter` solo si el texto sigue siendo un número decimal en construcción. */\r\n const alTeclearNumero =\r\n (setter: (valor: string) => void) =>\r\n (evento: React.ChangeEvent<HTMLInputElement>) => {\r\n const valor = evento.target.value;\r\n if (PATRON_NUMERICO.test(valor)) setter(valor);\r\n };\r\n\r\n /**\r\n * Normaliza lo pegado en un campo de coordenada y, si sigue sin ser válido,\r\n * explica el porqué en vez de rechazarlo en silencio.\r\n */\r\n const alPegarNumero =\r\n (valorActual: string, setter: (valor: string) => void) =>\r\n (evento: React.ClipboardEvent<HTMLInputElement>) => {\r\n evento.preventDefault();\r\n const texto = evento.clipboardData.getData(\"text\");\r\n const limpio = limpiarTextoNumerico(normalizarPegado(texto));\r\n const entrada = evento.currentTarget;\r\n const inicio = entrada.selectionStart ?? valorActual.length;\r\n const fin = entrada.selectionEnd ?? valorActual.length;\r\n const nuevoValor = valorActual.slice(0, inicio) + limpio + valorActual.slice(fin);\r\n\r\n if (limpio === \"\" || !PATRON_NUMERICO.test(nuevoValor)) {\r\n setError(\r\n \"No se pudo pegar: el texto copiado no contiene una coordenada válida \" +\r\n \"(solo se admiten números, un signo negativo al inicio y puntos o una coma como separadores).\",\r\n );\r\n return;\r\n }\r\n\r\n setter(nuevoValor);\r\n setError(\r\n /[^\\d.,\\-\\s]/.test(texto)\r\n ? \"Se pegó solo la parte numérica del texto copiado; se omitieron letras u otros símbolos.\"\r\n : null,\r\n );\r\n };\r\n\r\n /** Intercambia origen y destino; si había resultado, lo pasa a la entrada. */\r\n const intercambiar = () => {\r\n setOrigen(destino);\r\n setDestino(origen);\r\n if (resultado) {\r\n setX(NUMERO.format(resultado.x));\r\n setY(NUMERO.format(resultado.y));\r\n } else {\r\n setX(\"\");\r\n setY(\"\");\r\n }\r\n setResultado(null);\r\n setError(null);\r\n };\r\n\r\n /**\r\n * Proyecta el punto de origen a la vista, lo marca y lleva la vista hasta él.\r\n * La escala de acercamiento (`escalaZoomMarcador`) se pide a BD en cada marcado.\r\n */\r\n const marcarEnMapa = async () => {\r\n /* istanbul ignore next -- el botón ya está `disabled` cuando `!puedeMarcar`; guarda de más por si se llama de otro modo */\r\n if (!puedeMarcar || origen == null) return;\r\n\r\n setMarcando(true);\r\n setError(null);\r\n try {\r\n const { escalaZoomMarcador } = await obtenerParametrosProyeccion();\r\n const wkidVista = vista.spatialReference.wkid;\r\n if (wkidVista == null) {\r\n throw new Error(\"El mapa no tiene un sistema de referencia con WKID conocido.\");\r\n }\r\n const punto = crearPunto(aNumero(x), aNumero(y), origen);\r\n const enVista = await proyectarGeometria(punto, wkidVista);\r\n if (enVista.type !== \"point\") {\r\n throw new Error(\"La proyección no devolvió un punto.\");\r\n }\r\n marcar(enVista);\r\n // Si ya estaba más cerca que la escala configurada, solo recentra.\r\n await vista.goTo(\r\n vista.scale > escalaZoomMarcador\r\n ? { target: enVista, scale: escalaZoomMarcador }\r\n : enVista,\r\n );\r\n } catch (fallo: unknown) {\r\n if (fallo instanceof ParametrosGeneralesError) {\r\n // Sin parámetros de BD no se marca: no hay valores por defecto en el front.\r\n console.error(\"No se pudieron obtener los parámetros de Proyección.\", fallo);\r\n setError(\"No se pudieron obtener los parámetros de Proyección. Inténtalo más tarde.\");\r\n return;\r\n }\r\n setError(\r\n fallo instanceof Error\r\n ? fallo.message\r\n : \"No se pudo marcar el punto en el mapa.\",\r\n );\r\n } finally {\r\n setMarcando(false);\r\n }\r\n };\r\n\r\n /** Valida los sistemas y las coordenadas, y lanza la proyección. */\r\n const proyectar = async () => {\r\n if (origen == null || destino == null) {\r\n setResultado(null);\r\n setError(\"Seleccione los sistemas de coordenadas de origen y destino.\");\r\n return;\r\n }\r\n\r\n // Formato: obligatorias y numéricas (sin NaN ni Infinity). No se llama a\r\n // la proyección si el origen no pasa esta validación.\r\n if (x.trim() === \"\") {\r\n setResultado(null);\r\n setError(`${camposXY.etiquetaX} es obligatorio.`);\r\n return;\r\n }\r\n if (y.trim() === \"\") {\r\n setResultado(null);\r\n setError(`${camposXY.etiquetaY} es obligatorio.`);\r\n return;\r\n }\r\n const valorX = aNumero(x);\r\n const valorY = aNumero(y);\r\n if (!Number.isFinite(valorX)) {\r\n setResultado(null);\r\n setError(`${camposXY.etiquetaX} debe ser un valor numérico.`);\r\n return;\r\n }\r\n if (!Number.isFinite(valorY)) {\r\n setResultado(null);\r\n setError(`${camposXY.etiquetaY} debe ser un valor numérico.`);\r\n return;\r\n }\r\n\r\n // Rango: la coordenada debe tener sentido para el sistema de origen\r\n // elegido (p. ej. un Este/Norte de 9377 fuera de su área de uso), no solo\r\n // ser un número cualquiera.\r\n /* istanbul ignore else -- `origen` ya no es null aquí y siempre corresponde a una entrada de SRIDS_COLOMBIA (viene del selector) */\r\n if (sistemaOrigen) {\r\n const eje = ejeFueraDeRango(valorX, valorY, sistemaOrigen);\r\n if (eje) {\r\n setResultado(null);\r\n const etiqueta = eje === \"x\" ? camposXY.etiquetaX : camposXY.etiquetaY;\r\n setError(\r\n `${etiqueta} está fuera del rango válido para ${sistemaOrigen.nombre}.`,\r\n );\r\n return;\r\n }\r\n }\r\n\r\n setCargando(true);\r\n setError(null);\r\n try {\r\n const proyectada = await proyectarCoordenadas(valorX, valorY, origen, destino);\r\n\r\n // Valida el resultado contra el destino; `.find()` nunca falla porque viene del selector.\r\n /* istanbul ignore next */\r\n const sistemaDestino = SRIDS_COLOMBIA.find((sr) => sr.wkid === destino) ?? null;\r\n if (\r\n sistemaDestino &&\r\n ejeFueraDeRango(proyectada.x, proyectada.y, sistemaDestino)\r\n ) {\r\n setResultado(null);\r\n setError(\r\n `El resultado quedó fuera del rango válido para ${sistemaDestino.nombre}.`,\r\n );\r\n return;\r\n }\r\n\r\n setResultado({ x: proyectada.x, y: proyectada.y, wkid: destino });\r\n } catch (fallo: unknown) {\r\n setResultado(null);\r\n setError(\r\n fallo instanceof Error ? fallo.message : \"No se pudo proyectar la coordenada.\",\r\n );\r\n } finally {\r\n setCargando(false);\r\n }\r\n };\r\n\r\n return (\r\n <div\r\n ref={ref}\r\n role=\"dialog\"\r\n aria-label=\"Proyección de coordenadas\"\r\n className={CLASES_MODAL_HERRAMIENTA}\r\n style={{\r\n left: posicion.x,\r\n top: posicion.y,\r\n minWidth: ANCHO_MODAL_HERRAMIENTA * escalaInterfaz,\r\n }}\r\n >\r\n {/* Asa de arrastre. */}\r\n <div\r\n aria-hidden=\"true\"\r\n onPointerDown={alArrastrar}\r\n className=\"flex h-3.5 shrink-0 cursor-move touch-none select-none items-center justify-center\"\r\n >\r\n <IconoArrastrar className=\"h-1 w-7\" />\r\n </div>\r\n\r\n {/* Encabezado: título centrado, cierre a la derecha (con espaciador simétrico). */}\r\n <header className=\"flex shrink-0 items-center gap-2 border-b border-slate-100 px-5 pb-2\">\r\n <span aria-hidden=\"true\" className=\"size-6 shrink-0\" />\r\n <span className=\"flex-1 text-center text-sm font-bold text-slate-800\">\r\n Proyectar\r\n </span>\r\n <button\r\n type=\"button\"\r\n aria-label=\"Cerrar proyección\"\r\n onClick={onCerrar}\r\n className={CLASES_BOTON_CERRAR}\r\n >\r\n <IconoCerrar className=\"size-4\" />\r\n </button>\r\n </header>\r\n\r\n <form\r\n className=\"flex flex-col gap-3.5 px-5 pb-4 pt-5\"\r\n onSubmit={(evento) => {\r\n evento.preventDefault();\r\n void proyectar();\r\n }}\r\n >\r\n {/* Sistema de origen. */}\r\n <div className=\"relative\">\r\n <label htmlFor={idOrigen} className={CLASES_ETIQUETA}>\r\n Sistema de coordenadas origen\r\n </label>\r\n <SelectorDesplegable\r\n id={idOrigen}\r\n etiqueta=\"Sistema de coordenadas origen\"\r\n valor={origen == null ? \"\" : String(origen)}\r\n opciones={OPCIONES_SR}\r\n onCambiar={cambiarOrigen}\r\n placeholder=\"Seleccione\"\r\n permitirVacio\r\n sinTruncar\r\n />\r\n </div>\r\n\r\n {/* Coordenadas de entrada. */}\r\n <div className=\"flex gap-2\">\r\n <div className=\"relative flex-1\">\r\n <label htmlFor={idX} className={CLASES_ETIQUETA}>\r\n {camposXY.etiquetaX}\r\n </label>\r\n <input\r\n id={idX}\r\n inputMode=\"decimal\"\r\n value={x}\r\n onChange={alTeclearNumero(setX)}\r\n onPaste={alPegarNumero(x, setX)}\r\n placeholder={camposXY.placeholderX}\r\n className={CLASES_CAMPO}\r\n />\r\n </div>\r\n <div className=\"relative flex-1\">\r\n <label htmlFor={idY} className={CLASES_ETIQUETA}>\r\n {camposXY.etiquetaY}\r\n </label>\r\n <input\r\n id={idY}\r\n inputMode=\"decimal\"\r\n value={y}\r\n onChange={alTeclearNumero(setY)}\r\n onPaste={alPegarNumero(y, setY)}\r\n placeholder={camposXY.placeholderY}\r\n className={CLASES_CAMPO}\r\n />\r\n </div>\r\n <Tooltip titulo=\"Zoom a la coordenada\" alineacion=\"fin\">\r\n <button\r\n type=\"button\"\r\n aria-label=\"Zoom a la coordenada\"\r\n onClick={() => void marcarEnMapa()}\r\n disabled={!puedeMarcar || marcando}\r\n className={`grid size-8 shrink-0 place-items-center self-center rounded-[10px] border border-slate-300 text-slate-500 hover:bg-slate-100 hover:text-slate-700 ${CLASES_REALCE_BOTON} disabled:pointer-events-none disabled:opacity-40`}\r\n >\r\n <IconoMarcarPunto className=\"size-4\" />\r\n </button>\r\n </Tooltip>\r\n </div>\r\n\r\n {/* Sistema de destino + intercambio. */}\r\n <div className=\"flex items-center gap-2\">\r\n <div className=\"relative flex-1\">\r\n <label htmlFor={idDestino} className={CLASES_ETIQUETA}>\r\n Sistema de coordenadas destino\r\n </label>\r\n <SelectorDesplegable\r\n id={idDestino}\r\n etiqueta=\"Sistema de coordenadas destino\"\r\n valor={destino == null ? \"\" : String(destino)}\r\n opciones={OPCIONES_SR}\r\n onCambiar={(valor) => setDestino(valor === \"\" ? null : Number(valor))}\r\n placeholder=\"Seleccione\"\r\n permitirVacio\r\n sinTruncar\r\n />\r\n </div>\r\n <Tooltip titulo=\"Invertir sistemas\" alineacion=\"fin\">\r\n <button\r\n type=\"button\"\r\n aria-label=\"Intercambiar origen y destino\"\r\n onClick={intercambiar}\r\n className={`grid size-9 shrink-0 place-items-center rounded-[10px] border border-slate-300 text-slate-500 hover:bg-slate-100 hover:text-slate-700 ${CLASES_REALCE_BOTON}`}\r\n >\r\n <IconoIntercambiar className=\"size-5\" />\r\n </button>\r\n </Tooltip>\r\n </div>\r\n\r\n <button\r\n type=\"submit\"\r\n disabled={cargando}\r\n className={`mt-1 h-9 w-40 shrink-0 self-end rounded-[10px] bg-[linear-gradient(265.86deg,#0092FF_0%,#005899_98.31%)] text-xs font-bold text-white shadow-[1.03px_1.03px_4.12px_0px_rgba(0,0,0,0.3)] ${CLASES_REALCE_BOTON} hover:brightness-110 hover:shadow-md hover:shadow-[#005899]/60 focus-visible:-translate-y-0.5 focus-visible:shadow-md focus-visible:shadow-[#005899]/60 focus-visible:outline-none active:brightness-95 disabled:pointer-events-none disabled:opacity-60`}\r\n >\r\n {cargando ? \"Proyectando…\" : \"Proyectar\"}\r\n </button>\r\n\r\n {/* Error de validación o de la proyección. */}\r\n {error && (\r\n <p role=\"alert\" className=\"text-xs font-medium text-red-600\">\r\n {error}\r\n </p>\r\n )}\r\n\r\n {/* Resultado. */}\r\n {resultado &&\r\n (() => {\r\n // Etiquetas según el sistema del resultado, no del destino actual.\r\n /* istanbul ignore next */\r\n const sistemaResultado =\r\n SRIDS_COLOMBIA.find((sr) => sr.wkid === resultado.wkid) ?? null;\r\n /* istanbul ignore next -- ver nota de arriba: `sistemaResultado` nunca es null en la práctica */\r\n const camposResultado =\r\n CAMPOS_POR_TIPO[sistemaResultado?.tipo ?? \"geografica\"];\r\n return (\r\n <dl className=\"mt-1 flex flex-col gap-1 rounded-[10px] bg-[#EBF3F9] px-3 py-2.5 text-xs\">\r\n {sistemaResultado && (\r\n <div className=\"flex items-baseline gap-1\">\r\n <dt className=\"text-slate-500\">Sistema destino</dt>\r\n <dd className=\"font-bold text-slate-800\">\r\n {sistemaResultado.nombre}\r\n </dd>\r\n </div>\r\n )}\r\n <div className=\"flex items-baseline gap-1\">\r\n <dt className=\"text-slate-500\">{camposResultado.etiquetaXDestino}</dt>\r\n <dd className=\"font-bold text-slate-800 tabular-nums\">\r\n {NUMERO.format(resultado.x)}\r\n </dd>\r\n </div>\r\n <div className=\"flex items-baseline gap-1\">\r\n <dt className=\"text-slate-500\">{camposResultado.etiquetaYDestino}</dt>\r\n <dd className=\"font-bold text-slate-800 tabular-nums\">\r\n {NUMERO.format(resultado.y)}\r\n </dd>\r\n </div>\r\n <div className=\"flex items-baseline gap-1\">\r\n <dt className=\"text-slate-500\">SRID destino</dt>\r\n <dd className=\"font-bold text-slate-800 tabular-nums\">\r\n {resultado.wkid}\r\n </dd>\r\n </div>\r\n </dl>\r\n );\r\n })()}\r\n </form>\r\n </div>\r\n );\r\n}\r\n","import { useState } from \"react\";\nimport { useObservadorTamano } from \"./useObservadorTamano\";\n\n/** Indica si el contenido de un elemento está recortado (para mostrar un tooltip). */\nexport function useDesbordado<T extends HTMLElement>() {\n const [desbordado, setDesbordado] = useState(false);\n\n const ref = useObservadorTamano<T>(\n (el) => setDesbordado(el.scrollWidth > el.clientWidth + 1),\n { escucharResizeVentana: true },\n );\n\n return [ref, desbordado] as const;\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport { cn } from \"@/shared/lib/cn\";\nimport type { ItemLeyenda } from \"../types\";\nimport { CLASES_REALCE_BOTON } from \"../styles/controles.estilos\";\n\n/** Inserta en el DOM el elemento que ya generó `symbolUtils.renderPreviewHTML`. */\nfunction VistaSimbolo({ elemento }: { elemento: HTMLElement }) {\n const contenedorRef = useRef<HTMLSpanElement>(null);\n\n useEffect(() => {\n contenedorRef.current?.appendChild(elemento);\n return () => {\n elemento.remove();\n };\n }, [elemento]);\n\n return (\n <span ref={contenedorRef} className=\"inline-grid size-4 shrink-0 place-items-center\" />\n );\n}\n\n/** Swatch de un ítem de leyenda: imagen (ArcGIS REST / WMS) o símbolo (FeatureLayer). */\nfunction SwatchLeyenda({ item }: { item: ItemLeyenda }) {\n if (item.tipo === \"simbolo\") return <VistaSimbolo elemento={item.elemento} />;\n return <img src={item.src} alt=\"\" className=\"size-4 shrink-0 object-contain\" />;\n}\n\n/** Leyenda de una capa: un ítem va inline; varios, en lista colapsable. Nada mientras carga. */\nexport function LeyendaCapa({ cargar }: { cargar: () => Promise<ItemLeyenda[]> }) {\n const [items, setItems] = useState<ItemLeyenda[] | null>(null);\n const [abierta, setAbierta] = useState(false);\n\n useEffect(() => {\n let activo = true;\n void cargar().then((resultado) => {\n if (activo) setItems(resultado);\n });\n return () => {\n activo = false;\n };\n // Cada fila llama a `cargar` una sola vez, al activarse la capa.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n if (!items || items.length === 0) return null;\n\n if (items.length === 1) {\n const [item] = items;\n return (\n <div className=\"flex items-center gap-1.5 pl-6.5\">\n <SwatchLeyenda item={item} />\n <span className=\"truncate text-[10px] text-slate-500\">{item.etiqueta}</span>\n </div>\n );\n }\n\n return (\n <div className=\"pl-6.5\">\n <button\n type=\"button\"\n aria-expanded={abierta}\n onClick={() => setAbierta((previo) => !previo)}\n className={cn(\"text-[10px] font-semibold text-[#2563EB]\", CLASES_REALCE_BOTON)}\n >\n Leyenda ({items.length})\n </button>\n {abierta && (\n <ul className=\"mt-1 space-y-1\">\n {items.map((item, indice) => (\n <li key={indice} className=\"flex items-center gap-1.5\">\n <SwatchLeyenda item={item} />\n <span className=\"truncate text-[10px] text-slate-500\">{item.etiqueta}</span>\n </li>\n ))}\n </ul>\n )}\n </div>\n );\n}\n","import { useEffect, useRef, useState } from \"react\";\r\nimport { createPortal } from \"react-dom\";\r\nimport { cn } from \"@/shared/lib/cn\";\r\nimport {\r\n CLASES_BOTON_BARRA_SELECCIONADO,\r\n CLASES_REALCE_BOTON,\r\n} from \"../styles/controles.estilos\";\r\nimport {\r\n IconoFuenteInformacion,\r\n IconoOpcionesCapa,\r\n IconoRegresar,\r\n} from \"./iconos\";\r\nimport { Tooltip } from \"./Tooltip\";\r\nimport { CLASE_RAIZ_MAPA } from \"../styles/raiz.estilos\";\r\n\r\n/** Props de `MenuOpcionesServicio`. */\r\ninterface MenuOpcionesServicioProps {\r\n /** Nombre del servicio; se usa en las etiquetas accesibles. */\r\n nombre: string;\r\n /** Metadato del servicio; se traduce a texto plano en \"Fuente de información\". */\r\n metadatos: Record<string, unknown>;\r\n}\r\n\r\n/** Vista del menú flotante; hoy solo ofrece \"Fuente de información\". */\r\ntype Vista = \"menu\" | \"fuente\";\r\n\r\n/** URL http(s) dentro de un texto, para convertirla en enlace. */\r\nconst PATRON_URL = /(https?:\\/\\/\\S+)/g;\r\n\r\n/** Una entrada del metadato ya aplanada: `clave` en negrilla, `valor` como texto. */\r\ninterface LineaMetadato {\r\n clave: string;\r\n valor: string;\r\n}\r\n\r\n/**\r\n * Aplana el metadato a líneas `clave / valor` a cualquier profundidad, sin nulos\r\n * ni cadenas vacías. Las claves anidadas se unen con un punto.\r\n */\r\nfunction lineasDeMetadatos(metadatos: Record<string, unknown>): LineaMetadato[] {\r\n const lineas: LineaMetadato[] = [];\r\n\r\n const recorrer = (valor: unknown, ruta: string) => {\r\n // `ruta` siempre tiene valor al llegar a un valor simple: el nivel raíz es un objeto.\r\n if (typeof valor === \"string\") {\r\n const limpio = valor.trim();\r\n if (limpio) lineas.push({ clave: ruta, valor: limpio });\r\n } else if (typeof valor === \"number\" || typeof valor === \"boolean\") {\r\n lineas.push({ clave: ruta, valor: String(valor) });\r\n } else if (Array.isArray(valor)) {\r\n const esPrimitivo = (elemento: unknown) =>\r\n elemento == null || [\"string\", \"number\", \"boolean\"].includes(typeof elemento);\r\n if (valor.every(esPrimitivo)) {\r\n // Lista de valores simples (p. ej. roles): una sola línea, como en aplicación.\r\n const texto = valor\r\n .map((elemento) => (typeof elemento === \"string\" ? elemento.trim() : elemento))\r\n .filter((elemento) => elemento != null && elemento !== \"\")\r\n .map(String)\r\n .join(\", \");\r\n if (texto) lineas.push({ clave: ruta, valor: texto });\r\n } else {\r\n valor.forEach((elemento) => recorrer(elemento, ruta));\r\n }\r\n } else if (valor && typeof valor === \"object\") {\r\n Object.entries(valor).forEach(([clave, subvalor]) =>\r\n recorrer(subvalor, ruta ? `${ruta}.${clave}` : clave),\r\n );\r\n }\r\n };\r\n\r\n recorrer(metadatos, \"\");\r\n return lineas;\r\n}\r\n\r\n/** Convierte las URLs de un párrafo en enlaces; el resto queda como texto plano. */\r\nfunction enlazar(parrafo: string) {\r\n return parrafo.split(PATRON_URL).map((parte, indice) =>\r\n /^https?:\\/\\//.test(parte) ? (\r\n <a\r\n key={indice}\r\n href={parte}\r\n target=\"_blank\"\r\n rel=\"noreferrer\"\r\n className=\"break-all text-[#2563EB] underline\"\r\n >\r\n {parte}\r\n </a>\r\n ) : (\r\n parte\r\n ),\r\n );\r\n}\r\n\r\n/** Vista de detalle: metadato del servicio como texto, con enlace de regreso. */\r\nfunction VistaFuente({\r\n nombre,\r\n metadatos,\r\n onVolver,\r\n}: {\r\n nombre: string;\r\n metadatos: Record<string, unknown>;\r\n onVolver: () => void;\r\n}) {\r\n const lineas = lineasDeMetadatos(metadatos);\r\n\r\n return (\r\n <>\r\n <div className=\"-mx-1 flex shrink-0 items-center gap-1 text-xs font-medium italic text-slate-500\">\r\n <button\r\n type=\"button\"\r\n aria-label=\"Regresar\"\r\n onClick={onVolver}\r\n className={cn(\r\n \"-my-0.5 grid shrink-0 place-items-center rounded-md p-0.5 hover:bg-[#F3F3F3] hover:text-slate-700\",\r\n CLASES_REALCE_BOTON,\r\n )}\r\n >\r\n <IconoRegresar className=\"size-5\" />\r\n </button>\r\n Regresar\r\n </div>\r\n\r\n <div className=\"flex shrink-0 items-center justify-center gap-1.5\">\r\n <IconoFuenteInformacion className=\"size-4.5 shrink-0\" />\r\n <span className=\"text-xs font-bold leading-4.5 tracking-normal text-[#292D32]\">\r\n Fuente de información\r\n </span>\r\n </div>\r\n\r\n <div\r\n className={cn(\r\n \"min-h-0 flex-1 text-xs font-medium leading-4.5 tracking-normal text-[#292D32]\",\r\n // Sin metadato no hay scroll. Con metadato, `overflow-y-auto` solo\r\n // saca la barra si el contenido no cabe en el panel; si cabe, no se\r\n // ve nada (sin `pr-1` no queda hueco reservado permanente).\r\n lineas.length > 0\r\n ? \"scrollbar-fina overflow-y-auto\"\r\n : \"overflow-hidden\",\r\n )}\r\n >\r\n {lineas.length === 0 ? (\r\n <p className=\"text-slate-400\">\r\n {nombre} no tiene información de fuente.\r\n </p>\r\n ) : (\r\n lineas.map(({ clave, valor }, indice) => (\r\n <p key={indice} className={indice > 0 ? \"mt-2\" : undefined}>\r\n <span className=\"font-bold text-[#292D32]\">{clave}:</span>{\" \"}\r\n {enlazar(valor)}\r\n </p>\r\n ))\r\n )}\r\n </div>\r\n </>\r\n );\r\n}\r\n\r\n/**\r\n * Botón de opciones de un servicio: despliega un menú flotante con sus acciones.\r\n * Se cierra al elegir, con `Escape` o al clic fuera.\r\n */\r\nexport function MenuOpcionesServicio({\r\n nombre,\r\n metadatos,\r\n}: MenuOpcionesServicioProps) {\r\n const [posicion, setPosicion] = useState<{ top: number; left: number } | null>(\r\n null,\r\n );\r\n const [vista, setVista] = useState<Vista>(\"menu\");\r\n const abierto = posicion !== null;\r\n const botonRef = useRef<HTMLButtonElement>(null);\r\n const menuRef = useRef<HTMLDivElement>(null);\r\n\r\n const cerrar = () => {\r\n setPosicion(null);\r\n setVista(\"menu\");\r\n };\r\n\r\n // Coloca el panel debajo del botón, alineado a su borde derecho; si no cabe\r\n // abajo, lo pone a un lado (izquierda del botón, o derecha si tampoco cabe).\r\n const posicionar = (ancho: number, alto: number) => {\r\n const rect = botonRef.current?.getBoundingClientRect();\r\n /* istanbul ignore next -- el botón está montado siempre que se abre el menú */\r\n if (!rect) return;\r\n const acotarX = (x: number) =>\r\n Math.max(8, Math.min(x, window.innerWidth - ancho - 8));\r\n\r\n if (rect.bottom + 6 + alto <= window.innerHeight - 8) {\r\n setPosicion({ top: rect.bottom + 6, left: acotarX(rect.right - ancho) });\r\n return;\r\n }\r\n const izquierda = rect.left - ancho - 6;\r\n setPosicion({\r\n top: Math.max(8, Math.min(rect.top, window.innerHeight - alto - 8)),\r\n left: izquierda >= 8 ? izquierda : acotarX(rect.right + 6),\r\n });\r\n };\r\n\r\n const abrir = () => posicionar(190, 100);\r\n const mostrarFuente = () => {\r\n posicionar(285, 235);\r\n setVista(\"fuente\");\r\n };\r\n const volverAlMenu = () => {\r\n posicionar(190, 100);\r\n setVista(\"menu\");\r\n };\r\n\r\n useEffect(() => {\r\n // La vista de fuente queda fija: solo \"Regresar\" la saca de ahí.\r\n if (!abierto || vista === \"fuente\") return;\r\n\r\n const alClicFuera = (evento: MouseEvent) => {\r\n const destino = evento.target as Node;\r\n if (\r\n !botonRef.current?.contains(destino) &&\r\n !menuRef.current?.contains(destino)\r\n ) {\r\n cerrar();\r\n }\r\n };\r\n const alTecla = (evento: KeyboardEvent) => {\r\n if (evento.key === \"Escape\") cerrar();\r\n };\r\n // El efecto corre tras el clic que abrió el menú, así que ese clic ya no lo cierra.\r\n document.addEventListener(\"mousedown\", alClicFuera);\r\n document.addEventListener(\"keydown\", alTecla);\r\n window.addEventListener(\"scroll\", cerrar, true);\r\n window.addEventListener(\"resize\", cerrar);\r\n return () => {\r\n document.removeEventListener(\"mousedown\", alClicFuera);\r\n document.removeEventListener(\"keydown\", alTecla);\r\n window.removeEventListener(\"scroll\", cerrar, true);\r\n window.removeEventListener(\"resize\", cerrar);\r\n };\r\n }, [abierto, vista]);\r\n\r\n return (\r\n <>\r\n <Tooltip titulo=\"Opciones\" alineacion=\"fin\" deshabilitado={abierto}>\r\n <button\r\n ref={botonRef}\r\n type=\"button\"\r\n aria-label={`${nombre}: opciones`}\r\n aria-haspopup=\"menu\"\r\n aria-expanded={abierto}\r\n onClick={() => (abierto ? cerrar() : abrir())}\r\n className={cn(\r\n \"grid size-5 shrink-0 place-items-center rounded-lg text-[#2563EB]\",\r\n CLASES_REALCE_BOTON,\r\n abierto && CLASES_BOTON_BARRA_SELECCIONADO,\r\n )}\r\n >\r\n <IconoOpcionesCapa className=\"size-3.75\" />\r\n </button>\r\n </Tooltip>\r\n\r\n {posicion &&\r\n createPortal(\r\n <div\r\n ref={menuRef}\r\n role={vista === \"menu\" ? \"menu\" : \"dialog\"}\r\n aria-label={\r\n vista === \"menu\"\r\n ? `Opciones de ${nombre}`\r\n : `Fuente de información de ${nombre}`\r\n }\r\n style={{ top: posicion.top, left: posicion.left }}\r\n className={cn(\r\n CLASE_RAIZ_MAPA,\r\n \"fixed z-10000 flex flex-col overflow-hidden rounded-[15px] bg-white p-2.5 shadow-[0px_4px_4px_0px_rgba(0,0,0,0.25)]\",\r\n // La vista de fuente crece con el contenido hasta 235 px; luego, scroll.\r\n vista === \"menu\" ? \"w-fit gap-2.5\" : \"max-h-58.75 w-71.25 gap-2\",\r\n )}\r\n >\r\n {vista === \"menu\" ? (\r\n <button\r\n type=\"button\"\r\n role=\"menuitem\"\r\n onClick={mostrarFuente}\r\n className=\"-m-2.5 flex items-center gap-2 whitespace-nowrap p-2.5 text-left text-xs font-bold leading-4.5 tracking-normal text-[#292D32] transition-colors hover:bg-[#F3F3F3]\"\r\n >\r\n <IconoFuenteInformacion className=\"size-5 shrink-0\" />\r\n Fuente de información\r\n </button>\r\n ) : (\r\n <VistaFuente\r\n nombre={nombre}\r\n metadatos={metadatos}\r\n onVolver={volverAlMenu}\r\n />\r\n )}\r\n </div>,\r\n document.body,\r\n )}\r\n </>\r\n );\r\n}\r\n","import { useState } from \"react\";\r\nimport { cn } from \"@/shared/lib/cn\";\r\nimport { useDesbordado } from \"@/shared/hooks/useDesbordado\";\r\nimport type { EstadosCapas, GrupoServicios, ItemLeyenda, ServicioGis } from \"../types\";\r\nimport { CLASES_REALCE_BOTON } from \"../styles/controles.estilos\";\r\nimport {\r\n IconoChevron,\r\n IconoDescargar,\r\n IconoOjo,\r\n IconoOjoTachado,\r\n IconoOpacidad,\r\n IconoZoomALaCapa,\r\n} from \"./iconos\";\r\nimport { LeyendaCapa } from \"./LeyendaCapa\";\r\nimport { MenuOpcionesServicio } from \"./MenuOpcionesServicio\";\r\nimport { Tooltip } from \"./Tooltip\";\r\n\r\n/** Props de `ArbolCapas`. */\r\ninterface ArbolCapasProps {\r\n grupos: readonly GrupoServicios[];\r\n estados: EstadosCapas;\r\n escala?: number;\r\n onCambioServicio: (nombre: string, visible: boolean) => void;\r\n onCambioOpacidad: (nombre: string, opacidad: number) => void;\r\n onCambioOpacidadCapa?: (\r\n nombre: string,\r\n identificador: string,\r\n opacidad: number,\r\n ) => void;\r\n onCambioCapa: (nombre: string, identificador: string, visible: boolean) => void;\r\n /** Zoom a la extensión de una subcapa, acercando hasta su rango de escala. */\r\n onZoomCapa?: (\r\n nombre: string,\r\n identificador: string,\r\n minScale?: number,\r\n maxScale?: number,\r\n ) => void;\r\n /** Descarga en GeoJSON la subcapa en la extensión visible (solo dentro de escala). */\r\n onDescargarCapa?: (\r\n nombre: string,\r\n identificador: string,\r\n etiqueta: string,\r\n ) => Promise<void>;\r\n /** Leyenda de una subcapa activa; `etiqueta` es el texto de respaldo de cada ítem. */\r\n onObtenerLeyenda?: (\r\n nombre: string,\r\n identificador: string,\r\n etiqueta: string,\r\n ) => Promise<ItemLeyenda[]>;\r\n}\r\n\r\n/** Estilo de la píldora de cada fila de capa (algo más baja que la de servicio). */\r\nconst CLASES_FILA_CAPA =\r\n \"min-h-8 rounded-[13.38px] bg-[#E9F1FA] px-[11.25px] py-1.5\";\r\n\r\n/** Estilo de la fila de un servicio: fondo blanco con borde tenue en el tono de las capas. */\r\nconst CLASES_FILA_SERVICIO =\r\n \"flex min-h-10 items-center gap-2.5 rounded-[13.38px] border border-[#E9F1FA] bg-white px-[11.25px] py-[9.38px]\";\r\n\r\n/** Capa lista para pintar en la lista. */\r\ninterface FilaCapa {\r\n clave: string;\r\n etiqueta: string;\r\n visible: boolean;\r\n opacidad: number;\r\n fueraDeEscala: boolean;\r\n /** El servicio dueño de la capa está activo: solo entonces se puede alternar su ojo. */\r\n servicioActivo: boolean;\r\n onToggle: (visible: boolean) => void;\r\n onCambioOpacidad: (opacidad: number) => void;\r\n onZoom: () => void;\r\n onDescargar: () => Promise<void>;\r\n onObtenerLeyenda: () => Promise<ItemLeyenda[]>;\r\n}\r\n\r\n/** Control deslizante de opacidad (0–1) reutilizable por servicio y subcapa. */\r\nfunction SliderOpacidad({\r\n etiqueta,\r\n opacidad,\r\n onCambioOpacidad,\r\n}: {\r\n etiqueta: string;\r\n opacidad: number;\r\n onCambioOpacidad: (opacidad: number) => void;\r\n}) {\r\n const porcentaje = Math.round(opacidad * 100);\r\n\r\n return (\r\n <div className=\"flex items-center gap-2.5\">\r\n <IconoOpacidad className=\"size-4.5\" />\r\n <div className=\"relative h-3 flex-1\">\r\n <div className=\"h-full overflow-hidden rounded-full border-2 border-[#C0C0C0] bg-[#C0C0C0]\">\r\n <div className=\"h-full bg-white\" style={{ width: `${porcentaje}%` }} />\r\n </div>\r\n <span className=\"pointer-events-none absolute inset-0 flex items-center justify-center text-[10px] font-bold leading-none text-[#292D32]\">\r\n {porcentaje}%\r\n </span>\r\n <input\r\n type=\"range\"\r\n min={0}\r\n max={1}\r\n step={0.05}\r\n value={opacidad}\r\n onChange={(evento) => onCambioOpacidad(Number(evento.target.value))}\r\n aria-label={`Opacidad de ${etiqueta}`}\r\n className=\"absolute inset-0 size-full cursor-pointer opacity-0\"\r\n />\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\n/** Fila con controles independientes de visibilidad y opacidad de una subcapa. */\r\nfunction ControlCapa({ fila }: { fila: FilaCapa }) {\r\n const {\r\n etiqueta,\r\n visible,\r\n opacidad,\r\n fueraDeEscala,\r\n servicioActivo,\r\n onToggle,\r\n onCambioOpacidad,\r\n onZoom,\r\n onDescargar,\r\n onObtenerLeyenda,\r\n } = fila;\r\n // Ícono de ojo según visibilidad; bloqueada por escala: ojo gris sin tachar.\r\n const bloqueadaPorEscala = visible && fueraDeEscala;\r\n // Con el servicio inactivo no tiene sentido alternar capas sueltas: se\r\n // deshabilita el ojo y se explica el motivo con un tooltip.\r\n const bloqueadaPorServicio = !servicioActivo;\r\n const Ojo = visible ? IconoOjo : IconoOjoTachado;\r\n // El tooltip del nombre solo aparece si el texto queda recortado.\r\n const [refEtiqueta, etiquetaRecortada] = useDesbordado<HTMLSpanElement>();\r\n\r\n // Estado local de la descarga: no forma parte de `EstadosCapas` porque es\r\n // solo feedback visual de esta fila mientras la petición está en curso.\r\n const [descargando, setDescargando] = useState(false);\r\n const descargaDeshabilitada = fueraDeEscala || descargando;\r\n const manejarDescargar = async () => {\r\n setDescargando(true);\r\n try {\r\n await onDescargar();\r\n } finally {\r\n setDescargando(false);\r\n }\r\n };\r\n\r\n return (\r\n <div\r\n className={cn(\r\n CLASES_FILA_CAPA,\r\n visible && \"space-y-2\",\r\n // Fuera de escala: se atenúa el fondo y el ojito pasa a gris.\r\n bloqueadaPorEscala && \"bg-slate-200\",\r\n )}\r\n >\r\n <div className=\"flex items-center gap-1.5\">\r\n <Tooltip\r\n titulo={bloqueadaPorServicio ? \"Activa primero el servicio\" : etiqueta}\r\n className=\"min-w-0 flex-1\"\r\n deshabilitado={!bloqueadaPorServicio && !etiquetaRecortada}\r\n >\r\n <button\r\n type=\"button\"\r\n aria-pressed={visible}\r\n aria-label={`${etiqueta}: ${visible ? \"ocultar\" : \"mostrar\"} capa`}\r\n onClick={() => onToggle(!visible)}\r\n disabled={bloqueadaPorServicio}\r\n className={cn(\r\n \"flex w-full items-center gap-[11.25px] text-left\",\r\n bloqueadaPorServicio ? \"cursor-not-allowed\" : CLASES_REALCE_BOTON,\r\n )}\r\n >\r\n <Ojo\r\n className={cn(\r\n \"size-5.5\",\r\n (bloqueadaPorEscala || bloqueadaPorServicio) && \"grayscale opacity-60\",\r\n )}\r\n />\r\n <span\r\n ref={refEtiqueta}\r\n className={cn(\r\n \"truncate text-xs font-semibold\",\r\n visible && !fueraDeEscala && !bloqueadaPorServicio\r\n ? \"text-slate-800\"\r\n : \"text-slate-400\",\r\n )}\r\n >\r\n {etiqueta}\r\n </span>\r\n </button>\r\n </Tooltip>\r\n\r\n {/* La descarga solo tiene sentido con la capa realmente pintada: se\r\n deshabilita (no se oculta) fuera de su rango de escala. */}\r\n {visible && (\r\n <Tooltip\r\n titulo={\r\n fueraDeEscala\r\n ? \"Acerca el zoom para descargar\"\r\n : \"Descargar capa visible\"\r\n }\r\n alineacion=\"fin\"\r\n >\r\n <button\r\n type=\"button\"\r\n aria-label={`Descargar ${etiqueta}`}\r\n onClick={manejarDescargar}\r\n disabled={descargaDeshabilitada}\r\n className={cn(\r\n \"-mr-1.5 grid size-5.5 shrink-0 place-items-center\",\r\n descargaDeshabilitada\r\n ? \"cursor-not-allowed text-slate-300\"\r\n : cn(\"text-slate-500 hover:text-slate-700\", CLASES_REALCE_BOTON),\r\n )}\r\n >\r\n {descargando ? (\r\n <span\r\n aria-hidden=\"true\"\r\n className=\"size-3.5 animate-spin rounded-full border-2 border-slate-300 border-t-slate-600\"\r\n />\r\n ) : (\r\n <IconoDescargar className=\"size-3.5\" />\r\n )}\r\n </button>\r\n </Tooltip>\r\n )}\r\n\r\n {/* El zoom a la capa solo se ofrece cuando la capa está visible (ojo activo). */}\r\n {visible && (\r\n <Tooltip titulo=\"Zoom a la capa\" alineacion=\"fin\">\r\n <button\r\n type=\"button\"\r\n aria-label={`Zoom a ${etiqueta}`}\r\n onClick={onZoom}\r\n className={cn(\r\n \"grid size-5.5 shrink-0 place-items-center text-slate-500 hover:text-slate-700\",\r\n CLASES_REALCE_BOTON,\r\n )}\r\n >\r\n <IconoZoomALaCapa className=\"size-5.5\" />\r\n </button>\r\n </Tooltip>\r\n )}\r\n </div>\r\n\r\n {/* La opacidad y su leyenda solo se ofrecen con la capa visible (ojo activo). */}\r\n {visible && (\r\n <>\r\n <SliderOpacidad\r\n etiqueta={etiqueta}\r\n opacidad={opacidad}\r\n onCambioOpacidad={onCambioOpacidad}\r\n />\r\n <LeyendaCapa cargar={onObtenerLeyenda} />\r\n </>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n/** Manejadores de opacidad/visibilidad de capas que comparte `ItemServicio`. */\r\ninterface ManejadoresCapas {\r\n onCambioOpacidad: (nombre: string, opacidad: number) => void;\r\n onCambioOpacidadCapa?: (\r\n nombre: string,\r\n identificador: string,\r\n opacidad: number,\r\n ) => void;\r\n onCambioCapa: (nombre: string, identificador: string, visible: boolean) => void;\r\n onZoomCapa?: (\r\n nombre: string,\r\n identificador: string,\r\n minScale?: number,\r\n maxScale?: number,\r\n ) => void;\r\n onDescargarCapa?: (\r\n nombre: string,\r\n identificador: string,\r\n etiqueta: string,\r\n ) => Promise<void>;\r\n onObtenerLeyenda?: (\r\n nombre: string,\r\n identificador: string,\r\n etiqueta: string,\r\n ) => Promise<ItemLeyenda[]>;\r\n}\r\n\r\n/** Deriva las filas de subcapa de un servicio a partir del estado actual. */\r\nfunction filasDeServicio(\r\n servicio: ServicioGis,\r\n estados: EstadosCapas,\r\n escala: number | undefined,\r\n manejadores: ManejadoresCapas,\r\n servicioActivo: boolean,\r\n): FilaCapa[] {\r\n const { nombre } = servicio;\r\n const subcapas = servicio.configuracionCapas.capas ?? [];\r\n\r\n return subcapas.map((capa) => ({\r\n clave: `${nombre}::${capa.identificador}`,\r\n etiqueta: capa.titulo,\r\n visible: estados.capas[nombre]?.[capa.identificador] ?? false,\r\n servicioActivo,\r\n opacidad:\r\n estados.opacidadesCapas?.[nombre]?.[capa.identificador] ??\r\n capa.opacidad ??\r\n servicio.opacidad,\r\n fueraDeEscala:\r\n escala !== undefined &&\r\n ((typeof capa.minScale === \"number\" &&\r\n capa.minScale > 0 &&\r\n escala > capa.minScale) ||\r\n (typeof capa.maxScale === \"number\" &&\r\n capa.maxScale > 0 &&\r\n escala < capa.maxScale)),\r\n onToggle: (valor: boolean) =>\r\n manejadores.onCambioCapa(nombre, capa.identificador, valor),\r\n onCambioOpacidad: (valor: number) =>\r\n manejadores.onCambioOpacidadCapa?.(nombre, capa.identificador, valor),\r\n onZoom: () =>\r\n manejadores.onZoomCapa?.(\r\n nombre,\r\n capa.identificador,\r\n capa.minScale,\r\n capa.maxScale,\r\n ),\r\n onDescargar: () =>\r\n manejadores.onDescargarCapa?.(nombre, capa.identificador, capa.titulo) ??\r\n Promise.resolve(),\r\n onObtenerLeyenda: () =>\r\n manejadores.onObtenerLeyenda?.(nombre, capa.identificador, capa.titulo) ??\r\n Promise.resolve([]),\r\n }));\r\n}\r\n\r\n/** Servicio de un grupo: el check lo activa y la flecha despliega capas u opacidad. */\r\nfunction ItemServicio({\r\n servicio,\r\n estados,\r\n escala,\r\n manejadores,\r\n onToggle,\r\n}: {\r\n servicio: ServicioGis;\r\n estados: EstadosCapas;\r\n escala?: number;\r\n manejadores: ManejadoresCapas;\r\n /** Activa o desactiva el servicio (independiente de los demás del grupo). */\r\n onToggle: (nombre: string, activo: boolean) => void;\r\n}) {\r\n const { nombre } = servicio;\r\n const subcapas = servicio.configuracionCapas.capas ?? [];\r\n const activo = estados.servicios[nombre] ?? true;\r\n const filas = filasDeServicio(servicio, estados, escala, manejadores, activo);\r\n\r\n // Despliegue de las capas. Arranca según el servicio y lo alternan tanto la\r\n // flecha como el propio check.\r\n const [abierto, setAbierto] = useState(activo);\r\n\r\n // `activo` puede cambiar desde fuera (selección exclusiva del grupo): se ajusta\r\n // en render para no dejar abiertos ítems inactivos.\r\n const [activoPrevio, setActivoPrevio] = useState(activo);\r\n if (activo !== activoPrevio) {\r\n setActivoPrevio(activo);\r\n setAbierto(activo);\r\n }\r\n\r\n return (\r\n <div className=\"space-y-2\">\r\n <div className={CLASES_FILA_SERVICIO}>\r\n <label className=\"flex flex-1 cursor-pointer items-center gap-2.5\">\r\n <input\r\n type=\"checkbox\"\r\n checked={activo}\r\n onChange={(evento) => {\r\n const marcado = evento.target.checked;\r\n setAbierto(marcado);\r\n onToggle(nombre, marcado);\r\n }}\r\n aria-label={`${nombre}: ${activo ? \"ocultar\" : \"mostrar\"} servicio`}\r\n className=\"size-4 shrink-0 cursor-pointer accent-[#2563EB]\"\r\n />\r\n <span\r\n className={cn(\r\n \"truncate text-xs font-semibold\",\r\n activo ? \"text-slate-800\" : \"text-slate-400\",\r\n )}\r\n >\r\n {nombre}\r\n </span>\r\n </label>\r\n\r\n <MenuOpcionesServicio nombre={nombre} metadatos={servicio.metadatos} />\r\n\r\n <button\r\n type=\"button\"\r\n aria-expanded={abierto}\r\n aria-label={`${nombre}: ${abierto ? \"contraer\" : \"expandir\"} capas`}\r\n onClick={() => setAbierto((previo) => !previo)}\r\n className={cn(\r\n \"grid size-5 shrink-0 place-items-center text-[#2563EB]\",\r\n CLASES_REALCE_BOTON,\r\n )}\r\n >\r\n <IconoChevron\r\n className={cn(\r\n \"size-4.5 transition-transform duration-200\",\r\n abierto && \"rotate-180\",\r\n )}\r\n />\r\n </button>\r\n </div>\r\n\r\n {abierto && filas.length > 0 && (\r\n <ul className=\"space-y-2 pl-3\">\r\n {filas.map((fila) => (\r\n <li key={fila.clave}>\r\n <ControlCapa fila={fila} />\r\n </li>\r\n ))}\r\n </ul>\r\n )}\r\n\r\n {abierto && subcapas.length === 0 && (\r\n <div className={cn(CLASES_FILA_CAPA, \"ml-3\")}>\r\n <SliderOpacidad\r\n etiqueta={nombre}\r\n opacidad={estados.opacidades[nombre] ?? servicio.opacidad}\r\n onCambioOpacidad={(valor) => manejadores.onCambioOpacidad(nombre, valor)}\r\n />\r\n <LeyendaCapa\r\n cargar={() =>\r\n manejadores.onObtenerLeyenda?.(nombre, \"\", nombre) ?? Promise.resolve([])\r\n }\r\n />\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n/** Árbol de grupos → servicios (check) → capas (ojitos) y opacidad. */\r\nexport function ArbolCapas({\r\n grupos,\r\n estados,\r\n escala,\r\n onCambioServicio,\r\n onCambioOpacidad,\r\n onCambioOpacidadCapa,\r\n onCambioCapa,\r\n onZoomCapa,\r\n onDescargarCapa,\r\n onObtenerLeyenda,\r\n}: ArbolCapasProps) {\r\n // Grupos colapsados por defecto: se despliegan con la flecha que gira 180°.\r\n const [gruposAbiertos, setGruposAbiertos] = useState<Record<string, boolean>>({});\r\n const alternarGrupo = (nombre: string) =>\r\n setGruposAbiertos((previo) => ({ ...previo, [nombre]: !previo[nombre] }));\r\n\r\n const manejadores: ManejadoresCapas = {\r\n onCambioOpacidad,\r\n onCambioOpacidadCapa,\r\n onCambioCapa,\r\n onZoomCapa,\r\n onDescargarCapa,\r\n onObtenerLeyenda,\r\n };\r\n\r\n const sinServicios = grupos.every((grupo) => grupo.servicios.length === 0);\r\n\r\n if (sinServicios) {\r\n return <p className=\"text-xs text-slate-500\">Sin servicios configurados.</p>;\r\n }\r\n\r\n return (\r\n <ul className=\"scrollbar-fina min-h-0 space-y-2.75 overflow-y-auto pr-1\">\r\n {grupos.map((grupo) => {\r\n const abierto = gruposAbiertos[grupo.nombre] ?? false;\r\n\r\n return (\r\n <li key={grupo.nombre}>\r\n <button\r\n type=\"button\"\r\n aria-expanded={abierto}\r\n onClick={() => alternarGrupo(grupo.nombre)}\r\n className={cn(\r\n \"flex w-full items-center gap-2.5 rounded-[13.38px] bg-[#DCE7F6] px-[11.25px] py-2.5 text-left hover:bg-[#d0e0f3] hover:shadow-sm\",\r\n CLASES_REALCE_BOTON,\r\n )}\r\n >\r\n <IconoChevron\r\n className={cn(\r\n \"size-4.5 shrink-0 text-slate-600 transition-transform duration-200\",\r\n abierto && \"rotate-180\",\r\n )}\r\n />\r\n <span className=\"truncate text-sm font-bold uppercase text-slate-800\">\r\n {grupo.nombre}\r\n </span>\r\n </button>\r\n\r\n {abierto && (\r\n <ul className=\"mt-2 space-y-2 pl-3\">\r\n {grupo.servicios.length === 0 ? (\r\n <li className=\"text-xs text-slate-400\">\r\n Sin servicios en el grupo.\r\n </li>\r\n ) : (\r\n grupo.servicios.map((servicio) => (\r\n <li key={servicio.nombre}>\r\n <ItemServicio\r\n servicio={servicio}\r\n estados={estados}\r\n escala={escala}\r\n manejadores={manejadores}\r\n onToggle={onCambioServicio}\r\n />\r\n </li>\r\n ))\r\n )}\r\n </ul>\r\n )}\r\n </li>\r\n );\r\n })}\r\n </ul>\r\n );\r\n}\r\n","import { cn } from \"@/shared/lib/cn\";\nimport type { EstadosCapas, GrupoServicios, ItemLeyenda } from \"../types\";\nimport { CLASES_BOTON_CERRAR } from \"../styles/controles.estilos\";\nimport { ArbolCapas } from \"./ArbolCapas\";\nimport { IconoCerrar } from \"./iconos\";\n\n/** Props de `PanelCapas`. */\ninterface PanelCapasProps {\n grupos: readonly GrupoServicios[];\n estados: EstadosCapas;\n escala?: number;\n onCambioServicio: (nombre: string, visible: boolean) => void;\n onCambioOpacidad: (nombre: string, opacidad: number) => void;\n onCambioOpacidadCapa?: (\n nombre: string,\n identificador: string,\n opacidad: number,\n ) => void;\n onCambioCapa: (nombre: string, identificador: string, visible: boolean) => void;\n onZoomCapa?: (\n nombre: string,\n identificador: string,\n minScale?: number,\n maxScale?: number,\n ) => void;\n onDescargarCapa?: (\n nombre: string,\n identificador: string,\n etiqueta: string,\n ) => Promise<void>;\n onObtenerLeyenda?: (\n nombre: string,\n identificador: string,\n etiqueta: string,\n ) => Promise<ItemLeyenda[]>;\n onCerrar: () => void;\n}\n\n/** Contenedor del panel: crece con el contenido hasta `26.375rem` y luego hace scroll. */\nconst CLASES_PANEL =\n \"flex max-h-[min(26.375rem,80vh)] w-77 flex-col gap-2.75 rounded-[15px] border border-slate-200 bg-white px-5 py-3.75 shadow-2xl\";\n\n/** Panel de capas de escritorio (cabecera + `ArbolCapas`); solo se cierra con la «X». */\nexport function PanelCapas({ onCerrar, ...propsArbol }: PanelCapasProps) {\n return (\n <div className={CLASES_PANEL}>\n <div className=\"relative flex shrink-0 items-center justify-center\">\n <h2 className=\"text-sm font-bold text-slate-900\">Capas y Servicios</h2>\n <button\n type=\"button\"\n aria-label=\"Cerrar panel de capas\"\n onClick={onCerrar}\n className={cn(\"absolute right-0\", CLASES_BOTON_CERRAR)}\n >\n <IconoCerrar className=\"size-4\" />\n </button>\n </div>\n\n <ArbolCapas {...propsArbol} />\n </div>\n );\n}\n","import { useDesbordado } from \"@/shared/hooks/useDesbordado\";\r\nimport type { AplicacionInfo } from \"../types\";\r\nimport { CLASES_BOTON_CERRAR } from \"../styles/controles.estilos\";\r\nimport { IconoCerrar, IconoFuenteInformacion } from \"./iconos\";\r\nimport { Tooltip } from \"./Tooltip\";\r\n\r\n/** Props de `PanelMetadata`. */\r\ninterface PanelMetadataProps {\r\n /** Información de la aplicación tal como llega en `configuracion.aplicacion`. */\r\n aplicacion: AplicacionInfo;\r\n onCerrar: () => void;\r\n}\r\n\r\n/** Convierte el mapa de metadatos en pares legibles, descartando vacíos. */\r\nfunction paresMetadatos(\r\n metadatos: Record<string, unknown> | undefined,\r\n): { clave: string; valor: string }[] {\r\n return Object.entries(metadatos ?? {})\r\n .filter(([, valor]) => valor != null && valor !== \"\")\r\n .map(([clave, valor]) => ({ clave, valor: String(valor) }));\r\n}\r\n\r\n/** Fila `dt`/`dd` de metadato; el tooltip solo aparece si el valor se recorta. */\r\nfunction FilaMetadato({ clave, valor }: { clave: string; valor: string }) {\r\n const [refValor, valorRecortado] = useDesbordado<HTMLElement>();\r\n\r\n return (\r\n <div className=\"contents\">\r\n <dt className=\"font-bold capitalize\">{clave}:</dt>\r\n <Tooltip titulo={valor} deshabilitado={!valorRecortado}>\r\n <dd ref={refValor} className=\"truncate\">\r\n {valor}\r\n </dd>\r\n </Tooltip>\r\n </div>\r\n );\r\n}\r\n\r\n/** Panel con los pares de `aplicacion.metadatos` del contrato (herramienta `metadata`). */\r\nexport function PanelMetadata({ aplicacion, onCerrar }: PanelMetadataProps) {\r\n const pares = paresMetadatos(aplicacion.metadatos);\r\n\r\n return (\r\n <div\r\n role=\"dialog\"\r\n aria-labelledby=\"titulo-metadatos\"\r\n className=\"absolute bottom-0 left-full z-20 ml-2 flex max-h-80 w-64 flex-col gap-2 rounded-[15px] border border-slate-200 bg-white p-2.5 shadow-2xl\"\r\n >\r\n {/* Botón de cierre, solo en su línea. */}\r\n <div className=\"flex justify-end\">\r\n <button\r\n type=\"button\"\r\n aria-label=\"Cerrar\"\r\n onClick={onCerrar}\r\n className={CLASES_BOTON_CERRAR}\r\n >\r\n <IconoCerrar className=\"size-4\" />\r\n </button>\r\n </div>\r\n\r\n {/* Ícono y título, debajo del botón de cierre. */}\r\n <div className=\"-mt-2 flex shrink-0 items-center justify-center gap-1.5\">\r\n <IconoFuenteInformacion className=\"size-4.5 shrink-0\" />\r\n <h2\r\n id=\"titulo-metadatos\"\r\n className=\"text-xs font-bold leading-4.5 tracking-normal text-[#292D32]\"\r\n >\r\n Fuente de información\r\n </h2>\r\n </div>\r\n\r\n <div className=\"scrollbar-fina flex flex-1 flex-col gap-2 overflow-y-auto pr-1 text-sm\">\r\n {pares.length > 0 && (\r\n <dl className=\"mt-1 grid grid-cols-[auto_1fr] gap-x-2 gap-y-1 text-xs font-medium leading-4.5 tracking-normal text-[#292D32]\">\r\n {pares.map(({ clave, valor }) => (\r\n <FilaMetadato key={clave} clave={clave} valor={valor} />\r\n ))}\r\n </dl>\r\n )}\r\n </div>\r\n </div>\r\n );\r\n}\r\n","export default \"data:image/png;base64,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\"","export default \"data:image/png;base64,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\"","export default \"data:image/png;base64,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\"","export default \"data:image/png;base64,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\"","export default \"data:image/png;base64,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\"","export default \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAABwCAYAAADWrHjSAAAQAElEQVR4AWT8adBt2Xnfh/2fNey9z/TOd749dwNogAAIAiAJAgTFASRBkQQpiSDFQbZVlocoVhKXXbZSlbLjT/7ixJWKky+JYyexHStyRZE1y5JYkghRBAESaDQaPd/uO9/7jmc+e1r5rXMbilM5913v3mfttZ71DP9nWGu/3W73p7+atu1nvpp2fvrX0t6Xfj3tf+k3nrSf/XW+fzUd/NyfTYc//5vbdvTl30q5HfzCb6WDL9P/C7+ZLn2Z9vN/lnG/nvZ/5te27YC5Bz/3G2k/t5/9jXRAO/zF305HP0/fL/zZlGkc/dxvPblC8/Kf/J105Rd/J11mzOVf+u10+Svcf+W305Vf/ZfTja/+G+nZ3/5L6dnf+ovppb/w76SP/MX/Zfr4v/MfpR/4t/5y+uy/9C+nP/nnvpK+8ts/kX7+Nz+TvvhLH0u/9ue/mH71z30u/epvfDb9a//Gb6df/rWfTL/8O59JX/6zn0xf/jOfSL/w1R9Iv/RnP5Z+6Tc/nn76qx9JX/hTT6dP/tRBeu6zg/TcJwfpB390lC495WgxfeGnn01/+d/7SvpX//UfS3/mX/tU+vW/8Kn0K3/mp9Knf/wj6ZlPVem5HxqmFz49SV/6Uy+nf+Vf/3z6t//tL6X/9b/7C+k/+vd/If2nf/lX03/y7/9y+o//3Z9N/+5f/On06T/5A+mXv/qZ9Bf//OfSn/9XPpN+7c99PP3ir7+QfuZXbqSf+sq19KU/82z6+V95Kf38r76UvvLrH05/+qsvpj/9p59Lv/KnXki//MvPp9/5sx9P/9JvfjL9ua9+Mv1b/9KPpX8TGl/8uSvph3/hUvqxrzyffvJP/WD6ym/9SPr53/jh9Omfeil98Zc/mf7kb/5I+tGffTl97PNPpR//lZfTj3/1o+lLv/mp9KXf+sH087/z+eSUPynJOaeiKOS9l4wfZzIzOc8Qb0p890VUb1Lg6kNQiGE73gUnY36em69mtp3LRY5fZiY6lJpOXdsp+KDUNUp9q8Tafd9vr/le+ZPEd8lcUDEcqRwWEuOD93KsE8pSLo+pa+0m02df/LievvmsQpQu7Y6VUqedUdDh5ZGWek9+NNXQJ42QY1BkXpLarpOJPmQYOK9RHOnmtcu6+fSeJgdjHV3Z1YdfuqQXr+2pZKzMNJ9NVbmhgiv04O57mp1u1Da9qiJqNKq2+mubpE3vtBvHCGHq4e94Y3r1fKV15zQYjTQYlqokDTvTCp3cna70xoNTrXppnZZSkNpVI9d5dRuv2Ef5TqqXtbp1K8TQsql1Ol/pR597ST/y3At66cqOSrdCTY265UaDaBqWXtOTM80enetwNNG4GGnX76idd1qebTSfnqNHl+RhxsxQXC/1nRwr+OiVDe5jVAheZRkxZi9ulfpaTqYnxhXjvXwMKgYDlcOBMkAsOvmykGOCQ9FQh3bP9yAhtFhPGF98zHiaQUDr+ySGyztoFtX22natDDo948071oXEfK5+MdNm+Uivv/s1Pbj3plhZCcFr+Ku7Xuu61cV8qbErt8BrkSvT6RwAUKemrVWw2O5goslkrADPs2mrk9NGSxRd7e0rDSrdn1/ool1iuF4lYB+UQWNkKwDC7KzV3miiq6MdXa7G2vcRsZKO4e3hfKHH617fOJnr1sO51AU9WDR6uFqrtY6VkbUNaluhjl41coZggOtEj8/navG2YTXQs1eu6LMf/Yg+9vwzOtqbaDIqNRp4fej6Na6l9sJEz+9d19gHRajuwF8ZnY4fnWh2vtaNm1e1f7gn0Kj1coYMpkOAqNkq69KUGOyKKMOIAUNnAwYUHmKUh2hucCiHixUwFMcoCyYiygkFRo5hCwKXx5aFQlWqGAzl83fvZc4JrUjqhY31BEV8dQZZ0/ZZAnx0eQxvzMuthJc+NfI+ysNLnAzlqgIvWGv97ltqbr+lvp6qs1YOwzeW1KIA47pGyQX096solxcNTj7TpzUoerlptAGIF3UjxVLD0VCbZdIehrx2eKiPf/xFjfbGWgCkc7xttV7g8TMtz6WinOCBrXzpdO36nnZ3KyUizLRea4Ecex56tAXr3tvUgLDeiuhC0pw1z7tCsZpoUJSaEM0m6PHS7o7G6K1tncbjgS4f7LCO18H+UEeHYxWVZ26tWp1acGN9ANQtUaXT0aUjvffwoQaxgF5QQ2S9uFhpYKWef+qaJnsjrdYb1YuVIg42P5mp26y0M8R2RVUplKV8CApFkGF4572wjAyP8aDJZwM7J0//1phwgCzK9wGDO+Y6xiQMnMeEIso7J0MZZpKHppy2hvb5glL7rpU54xvd+bdxbw7zSQ4v32qM+eVgpMFkpJKWAWdtD90kA4B+d6JFcjpd11o0DaG3U8eclihW832x2ogOzfuGFFAowkR+NvJR41Co8kFZmx1gSNAdxkqH4x1dvnKEUUklpBggpwbl+Q+8PSDnclkTXTqVAPTS4UT7OERWeo8cCySYW5/J6jHp7v3pRg1pwaPbMAwyPPzxOun+2pCz0pXxRDd393SwS7QhXTTw4Qdhy/OcSLbqah1Pp7p9ckpUWegCudaSPMBOoUTjTrPpWpf2L+vq4TVoFgqu1NWDAx1d3ldD1Fwsl0rtRqVD14SbahwBUqsVEdDFDICCSbk5L+89RLyMqyVW6vgFEeRidlIPgWy8lmuH9/QwZCDdnIGZ3JjD+IQRQojytDgo5R00GZMglGk4jCBzDJac48pzBslQsANUFaHOwxtEt1hgmhwKyhOsiKpuPis7uK5GXi31waZp1YHuDeiv8dgNfE3Xa7XQHRdBPcBI8NnmK0Ri9HhgoTLAl0mDstLe7q6qnZE89Bvk88zNctTIMlsvNSBNnM96vfHW91B8r8Gg0v7ORAEHyHJtMh9toxOixf3VSu/NN1osGyVqCJbWktSyYX7qnKaN24LXsf6oLBVclDenHbw15fTgemUAnyPDeycnevcYAJD25hjteLnQBXI69LOzuyeLplhWWlL71Oh+MCg02Sl1AR8Pzs602iwB7FKns5mOSUuZ7mrTKusf5/UKCGzO5DyGkNC5e9ICTBWlXFHIYLSX46GT92F7lfdikoRhEsoXH6PPMyfiuQEFRZrju3emrUJhkAkylCaZth9nmYRkJnNOWxo+8NXk+B7gI0CjQ4uJENghRL9Yygi5Y7xlODD5QrIgtX0nx78NSt8gZMH8AkMuUeQmRx1QnVCUU2JUr8ILcCQZKWa8O1YRSzy2Q2ENz8J2VDZuMIexL0mp1J0HtzUclzo62pHzTjnqwDl0ROtJLa2OARCYVENBllpTfd6pm/aqKb7aaa0NUeC4MV3gYH2MMrghsGKsWh0Rckn0aohMc1LZxXKlonIAzgFYMXelDSE85OhcFlr2G33rne/plffe0Ft37+rx9FxngKRLrQSYVps1YFqTthr4Ne0QuS5PJkpEKmdK8kksn2R8C2WlALLicKByPFIxHioUBc+8LKcEnvk8hnzjaeaDDAWLT/aWrt4oZXQS6lz2ZgxgZhI5OGXjQCPhhQxCaMnjS8ZclobXVsbcANgcdMV4c5KhZMFnXqefzbW6d0+b999VevxQVWYeYNQofIXXt4TrYKaevqxIx7wNSqZDmUZ+NghB4xhUsGhJy9caz0US2EraEPq9nKJ5BVKMS0LxhUahUsRYEdDt7o8BxFgRXtsMKtNWnhJdLCU9Jvd3dUKEpFT30JEqdDDwUK47dYtay03SnJ1Aj5BjHIaMofWmV01La8azVos+RDQYVvl7qzYDed6oRabp6kLvndzV927f0tt3H+psOtdysUbURhk4Gwj26Lphp9LDXTFAZhBvpdem26D5JJeNkZsnCrii1IAwOMDwo92JKoxfEL4jraD48gibQ00GR8gAYYsWylJCiYahHUZjPXWkhgbUZmb77G0899A3lG7cR5Rg9A+6pUb1TGF+Kjc9UTF7rLi8kF9M5fm+u+EZBoR3ZUEciu0WC7WguyECON9rEJO8i8re0wEYzxjHhDLiVU5aoLB59gRAFDFmZUERIxl88FUxBA0BsmcODqFAf0P0qPE+rwyfpMJH1eTx6TxpCcBLcuh4ZyAhc9YJF20A4BIQyRzF2kaZhoOmYy3PQgOcaFBGDaoIPVbrJFK8wAGFq0hV0gArB/h20NgjFQV03mCm3mrAcq77D0905/YZRnOqKNxPLs707e++q7fffag1aY/AoZ3doeRNLbog9+RbZf7KIlL0DWhD9WbbHcewrHiG0eNorGpvjzAzVAhebnUqnd1RWpzjlRv54JS3dwMq5YL8EhCi5AqvKhCqqCCE8c0hGMoS9zgNe+R2C4YEM54wHgFNQknOo1iQPezXqtheFSB5CBAm1qoqCw1RyXh1rgEayvxYTht4NL6khJQdW7tm2mhxvtH5rFXIRmReQPAEAmtib8f4DJqA4gP8tABpHEvAYjQnJBfOJ+e9DA3xWxeE1QU5dlwNiRCVWjyo8RimqHSwc4Ssh3r3/i2NdgfcAzpSSgfdZEax1RGKG02ZX9Mf2L1UVVBEP9WgUmAd54Kc83Lw67Py+N7LwY9XIor4GJTripRMezjf3s5Ql9gB7FRes7OlHj4gtmCL0Y7XxexMb717T2sK4KyXnvlV9Hrq8h7bxIF2JwMdTIba45rbETuafbZ+BWtEQD7gWtFcNRmr3N9TKEtaVGzOtNO8oZ36NY2mf6jB8e8rPvi60r0/UHv7D1XffkOrN99WCwMtCMwtIEw5HikUQVkIXxRynvsQ5cypwyDZcMF5RcY0eJEHfed9oQv2sJvdK9qMjzQfHqkZ7Wkz3NUShV8M99X7qI76Is9pjh+rvpiqH5fqotMK91nXDuU6qWvl2WIZypuR87yk3VAopbRNcUfFUDvlUM45BQwGjgCTqcY7N3zJIF1TU+RiL0eSIUZfbzbyGO7y5cs6Gr+oNVFhujrbGqtXknmHfNBQp9p6fie2jR1RZ6UaGauQVA6iAs3hND362Cioj4G+Uq4MKjBu700iWhS96YBdSK7gR0TXgrQQ4a8yr2bRqV4Dsk2texzu3D05l4JpBc+pEJFM2sXAlyZ72iVi744HAKHS7s5QIw6eSoDY4hRZBmOtMbzghvAwRCmSOqpWmz9ScfGmutmJVhcXSsup0vxE3cX7ai/eVj+7o+bhW6qP35Z79I7S3Te0vvVtLd/5ltxmAT+mSGQoWCwGjI/y0LjMeWElJb5HokgoglwsNPA9+1aemW2/Z2O1Z8fwQpjHKD3Gy4ZpHh9r9fabWj68rx3qsKs3vQ6fG2hypVAVFth+rSJJWYEjX+gAxe1zXrFLxMmGqEk3NfXBRbMETFI2OClULWBZUogtyZENkWNNdJo2G60pqhqtlQovCnZtGFMDtFff+GP5gOlJEQGAG/NzhS/mZq8XnxWg2bam1nI9V8H48V6lcrdUD5Nt2SmVpjCMgKBQgXFq9crRqCxLuVCoBvDzFoEwvKdtNk4PTpIenrfEuJPgnwAAEABJREFURoMnnmXQOO45dVwtW43jSNc5O2iUk0bCxDBjXB0NoOQI4zyALJ1aom8NGDr0Sw2QlE7uaPLoj3R5/m259T2JAWURCYGtGhQiQmGQUyxa7e2vde3mRqPhQ+3sPdblq+c6mNxXevA11W/+oTZvvaH+4lzGor7ygpiEgQ1BnI/0R8XBWAV94yB012lneaJrodGknWvSzHU1rXS1m+uI7x7Pro8fqSLsXX+q11OsO168paeL+/rYlamOJg3HpKahLzXmqLNkjRLjjONAO8VQl+JEZ1Ti90g3J2sAgNGUPCIloQOZoRBJ+Ryhk2Ewp4NypPO+lpzJEwmef+qH9bf+/l9T75cqhk6bdgWQamKAtse3i17Kaed8PnvikSaVVO2dq5mz0NWDoJdfONTkqJQfmlakuoWxWvAaxCGOEyT008YA/R0NyqGscKpJSQzTO++dQL/RwWHU/k6lQh4n6ZTYSQRvusxh0dVLO9ChH9vtjibaKQfyZjLA6TLAOAtpsyPwPXnTErCb93Ld+X2Vx99UP72v08fnVL5BwQvPrPT5D/+QPnT0vEZWarcYaOJovpItWsU1g1bGPAM0vV462NeXf+g5vTycaf/B99S8Ck1OpwJKDKQIh1HMOZkFlaOxLDg1Wfm0ZnKoKUjesEY93tdJijqmQn68kVqOc+uzhwr9hcYXryutptrDe3Zcj9GTvDM8tMuYVTAvl9dIosjplAvAHsGvcthi8pqhiMdEqjP2xQ1e5mOhIV43hLch845iqUjIPcVzl+TyMBT10JH+9t/7uxrhwV/+8d/Qz3/+T2PcSgkjOi8N4LlsgwKhosgy4PmGbEX0Kgu/BfgjgPHO+UxdYdowr/W9eowROeTxXAtfwFlQCx/z03N1gC+mubxmOjuearKD3vdGSl1QS2RIgDy3AEiuXtnX0c5EYz+SevjnWUQPT+9f0bXRoYbYLPXGuUOtGTJluXIESPA+b9Zy45N/phhXVK6NBGoXCJ/D2mRQaY+dwKW9Q/2JT/+YfvUnf0G//rO/pN/+k7+iP/NTX9aPf/RT+uLHPqsvf/aL+sUv/KSigr7x7Vf19M3L+pFPPKdf+pFndb07U/3ogUSoaUFz4qDEwxzmkqH49f41LcsdNbuXtTq4IV1/Xv7G87Lrz8k/9xH5q89ofXxPbbrQvr+vDoU5kNuSHo45U7933KgnPG/Ii0vyfke0cDIlWtd1mvP9BGN3jN/g7l00tTGpwRCd9apQVgDtFU1d0mrWKG2ELE439o7w5oV+4We/ops3ntZPfO7n9fVv/b6++8prOqxuaBQvqQVErTVal0knBOdj3yhWpiHrlADJEgaHh4YdArZT6zsVw0LlwMnZUt7m6ruFcuHpeHEz8bXuvP2GAroaQfPi3lLv3TmFsnR8uib9DRUHpXJxeXA00pWjXR0OBjrcO9DlS5/WcPADeu9tp/fek77z1lIPTkZEkafVz6+zq7oMgEopwBNA2AA8YQsXrVboKh2MCwg7VUUh7516kPbKK6/o7oP39ODxA/3hH/2x/vk3vqE3OYN/7a239Pt/9C19l7z88OyxvvXqq7qop/roR5/nxcw7unXnrh6ePlZv50SIu9L8XInjSDMnRS+LUc5HZQZCLBSLQqGI8jHI8dwVQfmzunio5eNb2rlayeEVHr6YLfSnQRlVEMKsSdoJpUof1Cc8C6MkANdxbxj1ou11//GJCoxR8laucl4U5yLVakaqWXFEmtcalQNC6UQ3eBO4i0e9//AeRkr6t/+Df0V/85/+t/obv/dfa9E/0tHlPX35J35ZP/TST6L0F7R2rZykfcL22BealCMNfKmdYqJd7nfLSp4oNgCkQ/MaAczhaq5hv5Bys067O4VGNlPz6F0tHs919VKp+f1TIvIFupJu3Z1rMCkkkxqAPKawm4yJQsgniuHjxYVmvOR57e1/qsOjG3rm2Zflw0jD0Z5C8Nrnpdalg2sqrZBHD94FBXldqUp4d17jUmK3wdVUSLq6e0Mff+nzuvrsR1SjjLts1e6uz3XcnuqN+9/V+fq+4uXEs7neX76rs/SYEHOhVx+8pfVgozvLe/r2ndd1tn6kyfhc6dGbKopSxWgkA3lESATzKvk+2NvdoroYDiiKSgXA4c3U4bmb4/fkB72u79Ww26jHtxNaaAi1iXFu5NS6HqW06vC0FuW2eJtjTC/poq8151CFdyBaXrRasGtYLjuc3cmjuNHAq0TgsgzwELVMtWq8I+84xpOR1vOO9b2qsddw6LXAcG88+Kb+yj/4P+ju9I0tN7PZWhte3RrA2ykG8ixsPFmnpYZF0mW2YlcuTTS2tXJ9sxc2OqCeGY8KORZv3UbL87sqF+da3jV99tNPa8Z+/9HdlaZEuZMHtUajUvucUo6HYw14WdUj/0G5r5LtdzKnUbHDzuA7OrgknS2+rdfe/Cfq2vcU+1sq3R2l/h0t2NW5sJJ3DoB6HbHNjBblQhEUKymBjB1faXcwUcE2bB7Guls8ozvjz+je6NM6nXxSp8OPahFf0IqJ0+lcxw/P9Rhm275XRPKdkTQeOO3uljBaKIQg7ztVg6nS9H1hVb7btt9hQD8oVKDoYjRQxKMj4y31DNto9eg9HR62unlNMsBgGJWCFuPxnATmzSs6L+ccA3IzKY8BPPnKIpoDiPNTtmScerVsEROGKQsP/ZbaIhEeOzUAZMqh1flqQWFUKznTjDphw/e77z5WNek1GheKzPNGlEFWIKR7D+/qEa9bOeJQ9KYCPgbIFGJQrrh7HtSkJSNt5dTVwl4KSZQ36nySR9YNZ/uLB3c0IO1eiWOlda3vvfqO/vCNC333zlLnjbR7vdLeXqn9g6F2tiBw6NProl1QgHYYzunS4bO6efWmapxgQ1TbxHNdaKplv5Qre60BmYpOSZ2iCwqxUEtanBP9XIdAM87M87agN6e5Jvr2Sa+//85dvLuWFVFhMFRx+aa6Sy/o4fAFXdgVORtrSNisikInJ2ccVCzkk5M3UwxOwSUxFQ8Lcm4lLd7mFe5r28VDVlTw23uH4kx8MHzPVq1H8bq4S0h8qN10onJ9Kg+t4LxKkG8eerQeAVoE7uE/n7q1ba+EF6JirTiJfDybsw1rJetUTLz8kNtSUm/iG82pg8Z8tcTgG+bUQiids1O4oK8GPIbSIulxWJo6Ku4yivfpG+W1jkl9M5wAaKgnxDtJLf8StUWJZxdFod47AEXLtJDPAFfBs0FZanV2ynb6geJ8rfFmV/Wy3Kaw9dppylGvDb0Or4w04cx+/3BXPgTYSxpXrBi9WmgqJTloPnj8us7n99ATY5yTk/FPejw9093zE50uZpxhtFvjU/4I8yiDeGNdHmtasXedc8R6sV7phMOGttiVm+xLLJopJVNeS4nDDfNRzfC6tPO8ah2yJQoQjgrRsUiNCnp1lpQ9ZjDgGasl9QrVQlq+yYHSLV3HE4xQ3WNAYPmE+GapNH9MsfKOhu072vWP1S/OxVD1eFMLSH2I6p1XBAAOwweYa6GxaVgXBa8Yl4HccN/zLMirJNzm8RYk700dxlqvmy3NxPi8U8iHKWtC/xT5E0odkRv71Ono2liFL1Xi1R2RIvMRoleAj+R5fnioyWBXGYAbvKnNR86sjU3kMD4bA22QvelbJUs4RFSEbi6M3cMzuQunR3db3X10rscZUGxXHx1vNGVfeXi4o6OjfR2SPqrSq4KHqgyybGBz8ujBzJT4l9fK3wNrjoiqQ4qcsnCynB6Rq297wN7BZ6uGLT3DhP8p03Ori4WW06kajLvmxK7BMAmiiQVkJm6fGF/ccvJnKKitDnQxvKnNzgtq/ZGGFYqqKnV4YL9tHQvYVsk1L1YyA5a8fFhoPH9Pn0eo9uEdGcwkxuNW8mfvajB7TTu6rSo9UrOeKa9vWZt4asoo5N7LqeV831B0yrzCszMH6LQFX672N3iHD6aq8hoMvMDmNipVSN0zqgYwNYCazkgPACIXVit2Fz3zGgxUocCAq5Rcy1I6P1nLRU8qGGzpZYUk65XBMCh2+BrUpiS6MIxTApy5Fsnqywc8Cf4swSORaXF8opO7j3XnwVIPzjr5iZG7C917cK7X7y+1gseDK0MdXZmoGkbFImh/OKY+G0i9trQTOkt5PRZoAfF2LQmwBgUcLmLhAn4rwFAWUQNaEbx65rTMRUzoOAVDmy3hLpKTXLmvlb8qjW8oDPcEYGmJFbW9GpPzHrw9f4gX1SikUn4fvxk/rcbGLBzhL6ihMgVwct7L+Nfl1ZS4k3qKsqeuXdUj3mCNe7Z3j25LZ/dVze5qsn6oXbdQpDJO5E0TBsXwLVcHoyHGrYAeoQMtAYAMVnHvs3CskeCRVC9ewuFtnpmtHM9dTiEoBr3Iomm4E+DP5BzXENUxVwCs70xJfPiF/ZXgvSfCTCjkLrETKfDEHuF6gLshar7HaeiK17Y7ASdwpSroMRuW4N4jryUlZ3x34hd667S5oL+utHuwqyvXo/aGQW++fqq37szVedPupR1dvrmrooo4TFARCrnMO8wnuMN+QkzupCfyQ4+dUO7IwG7gT3LKxu7YyRn3BTIWvlBFy/cmT0QQDf3sUVj0gxta7f+A1kcfkw6fkR/tQgMJZMqfxDWRm/us6JPvaXPnD5VavCIEEHykhcaSrxQGFDIskthLYDv5GFSAYLAAmV4JcNw7u6cV6SamC40378kevqFifl8DwhUiyxk0UWSLIC0eLnMKRUS+RIQxyTm5/A0tOJTigkchcJgkM1PDM2FkbhmLyrgxs61CsufUvIptiBo9AGoxcE5XhpEiIOsy05LqHkhg5PWy12hQao8ibEW1nwvJhsjRwVcHMNbdXOf1Az339Ie0X95Q3ztaJw89D19lVWqnGmkQKzlL8qy3j8Gfu7mnF5/a0TNXdlW6ke4/XmkKcgcc+BxenmhnlzmDSoVDVpPWROf894uIiNE7DIdc6NLJMGWQ84Y3O23gu8sIod+SKfWmFhBksaL3Kn1QGTz8OQmdRMfc+ehjaq7+sPr9ZxU5hbNY8pAfBohP9iplpeLfVo5k3bm687fUUrnSJcfWx42vq7FdEDxSZ6UcCsgK7pnnMnpZNKVe3js94MTRmUcqybuzLb35dM0SToUPCqCVkTLnVBaBPkNgQ7FEF+bDknKIb83EQoTeftuETImHhUu6zEljNnYAgNv+zE8Oy3jKZt1CS+wAGsGeOkL/er2R8S9Cv3JeCfA5RU1Jj/sAIP818+xxm0lpQ5HY8a7AEzUT6WLTLfRwdks3b3xILgwUnJOHtyHh94ATSC1XEimrIPqNvLQ7NnYgS71z64HeuXOu44u1mkIKk0hkGmjvYKAha1ZFlDMHV1LWXQPgEqDv0GOPLAnmvXMU3hLLqaf+4LE6gNHTGMZE9IZS2r6XoBWRLbigCBgG6DoaANgcflg2OZR4CE0Z/yCp73+MG+NBzytiA8FdvCobPa9i94AnkiM0a7gPgse6uB25kTIAABAASURBVFiqb1Yw05CzKg1YIDqnGALGRiAfNZ6M9fr739GPffKL0kba2TcNxp0GpYHiHrTX2mCAEuONo5c68WHMoBSBha9IFKQSusaTrBCZqUMpHVAfIKBR+Di+u6wRUJrB4LJ85nV4sKdBUajdrFWT/joKwggdD40RdUxZlopy6ogA5aSSK4KWFwvt7Qet2VlkllpyeehNDmBtAM8DUkFRBrV5/XJMf9Ru3NXm/gM9euNdPbz1vt599V3de++O3rtzojdunW9PXk/mK53WK3XOacThzlNPHWjCWzxD3zmcd1w7ZKiRpdWTj5kp9+VvPTw2vKtpts87nMVnaeGjoyVt0w88Gm1LC3r5J2TjYwvnnZxxQGMy5QeZaG55K9Y9uK00Oyf/92pPHqs7OZfj5Ur51CdVXHtZxulgD3NmBkNOGxKvC4Wqsth61znKmlNVm0Gb6sgHpyJO5FJA+Avdeu8tfeKFT6sj3w8nnZpuybxaifAcoJsjWf6L3SmVcUto26jlwEd4Q+LOlF/bPkG2qYV+/ovgnrOIWTvXnAMbUXl3nL6VH4TlXknnF1M9uvdYi+lSEUuulkt1bD0TxsRtFSj6elTYONQVpWStTi/OdUiRe5VnL1w5Us3hULtKgDXoymRHl4g2jtphwyFTfzZUsbyp03sbfe8P32JfX+nq9c/pHpV+h2IXHPGeYfTB3kCr1qsLEd6DXBkB5kQHu2O8s5C5gE6TsqczDR3BSy+M5fB44wtOgJcbl0R/g8665NSgt6IqtpHTe8E/qzqh97CV13unyJq2TQ88x9F4rA8+UBOLUiG7+bnK6bF0+23ZO9/V8OSeDrJ34FkH9FcP3lc9m27nsaZC32ivnGmnbCjoz2G4U011vdp0mrPP9a5EvygHcDjnNZ3NNJ2f60c/+2Oq87YTJC8wxBrPGuGdVem0QajpvFXNAjPC6IY8iKwicJPrEmHfiBSNcsgNABiQC9Iyb2qC5DCwRwuYUqWPKLThuVMsaMFricEYJe+cejw3QGPDkSGRHU+KGlVDlFVow/uLvb2x9gZjDeRUcpITfcXhy67qaa0mnyzWTq9/723NTzfqMexv/NK/Qf8eufxj+tyPfUlf/OIv6akbH9Eup57HZ42WyBvw+BamUyHtHFS6Sj0Q0U/2zhbZeyybLZJBYPDWMifhCE7CKaX8vCZ9bWgmqVBURYuAuSFSb9i2ip1XBEyiL8prVFQaot8sb0sdE61AIibnH2MR7C+hEBeCKgyec1Go10rknwUEWjjqQfESA8annmeokzOnAII7mKvXDzEAZoL5FoY73rMDVArBgfo+0gJoLBWoMx6cnWh6Mtef+OTPsO2LSi2GgOFWPcaSyhgJ1czDOAsUvKD4mp7O9M67DwDPUp6UYaUTwJfzYp/sKbaihqOBBoNSNUBu4OmpvT0izloOuRLRYDQcwCNqxNI+CEBElSjFJLnoNQdsLeHHXNR4PJYNgl67xdaU4s1Ci4qCylGlE9LC7UfHKgem566+rDW7Aem+Hj/+uv5f/9V/rAf3XtPv/dO/o//sP/sP9c+/+Tf0ytuv6Xu3HqvnYONkXmtJdBrtjeQKr+vX9jTkPD5vLVeEdHNZ0Ya+emU9NjiT2n5r+PzIw2vL95wKUJlK7BVNOGBBBE0axREAruSRQ3WviJJ6it/Vcq0awwfk9Oivc50ctIRU29Ca7xPoWblSZ1ee0+Lpl1V/5NNqXv6M9PRLsqOrmj31EVWf/QmFwQjIGFOT+jhQGj2jtqnE7ggDJgwDR9GpoJpNQnEd59CE1ISBn9p/Vv+rv/Qf6u/+w7+jf/q139UoFBqi4I3baIqngx0MFlQvazWcs4+iZKSYR3fO1NfGF6nAMDiySiRnGbY4fitMwKs6lDhk3RiDmn6tnu8BJSSizAiAVFTnRSw1HI3gt1U0aCJ3j6JnRIYG0K3x/AVKOzvZaLg/1K2zpRzAGmOoAuWf3j3XgHDaLwr9+d/5n+infuYFjQ+XKvd7Da9UWtlaO081un9yrNpWmuwU1Dv7SqFAAwX6C0rdWtcPhro8KalJauWUtKkXyk7l5fhnuJ0J8ZWN1PW9cj2T8KrtFe0HrDCpBiqCabOuGSew0qn2nWIVNRzgEFWpYlAoFazpnTbIhUqUkMM1yzlEe+VPNr6dHWvv7K7Gd9+Se/tVxXdelbi6t78je+sVDd59Vd2br2hym+3g8YM8TeaCNLmiNl5TYVGO5p1T4Qs5RAgqFFF4y1anBoWf//QX9R/+J/+Bbp2+qdFO0GoVeZuVOJHsMVbSBsMLjw8ApyQs9hgnWadyWOrGM5e0Myqga9ohB7sQ1ZoAXQtopBqhOgX1rt8q5XQ60+5wRGhOKlDAGiXVpJ1m3RMlOnh36vpWLnBFoZFr/oPWhGQ5Ckbea5xwYJT/APNk+ljnF3M9ZNcyPBrxsuxQw0tJ/+1/91/ozq1bgK3Qh24+qz9+7T1Nrg6JEo0GB04tnpbKIBubwu5QR1dHOppUepkXHVf3drYpLefvGsPExquAt8K8vAU4MlFiKIf8XHz2gCB6T4SOGodSO8WQZwkZvAqAMERfJdopyS0V6WpQBI0GpUaAoIxRWZchmIY4h1ELuP2zVyhWViyUKNB6lGhaBDx6ONHe7oR83qLVtargFdj2mHfaAU0DwmNH/lGeSZ5mdfWj63wrBQRlMFpTBOa8enX4tHb8Hqd7a2XvL5kfx06DyUhLPO1ieaEKuvt45CAWeBbCwDhyaLlcbAVsWausTNmryQjqQ9CMU8aL1Ur5FK5R5sTgt1NDmNvgJfkdQvSFrnGkmgUvi0I1obeB1my2oQ7o5Fi3KMPWCYzokdMZQjCO5+dT7Q6GGh3uqWN3cO/YAcIhyis0LNERyEu0l1/+mI7rpR5w9v4KQCj3ClWjAEemS9f2VXIiGeNKouC9drnStcOhDtBfu+m03jRshZNK8itBGx1LK3VasnXMz9Y4worIhDgK2MDDYwT0E+qQ6ML2hdeGMN/hXM16o5botcBZOtLfFjTYoYe2ow5w9BW0oTkF8mYGk7vmHije/TbhoFXiQb97qP7ommajfT0cHGhFKlhffkaPil0dhx09spEehYneJ6cnFznZOidMrwU21NN/vgpazKdSXhjPXVH1/uDHfkif+8Ev6MM3P6rPfvyz+q/++n+hOAgqS68Cg8eRKfmO9ZNkST18nJ1vCFWGIZKyZ4QiqpqAYOiOi5FcKtmeNeTsDQZPSoT4JUVka0ZEaZjT0t+rAEjH8xlGKFU3a7U59uHxWZnOO7V94kVQoxxSHUB21svHQAwx7YyGMnjJPO0e7emp5480KLw25PvJsCKuBY0GBa+JL6DdqxpXmvLqvBh4YSddeWokc62qodeYPHZ5L+hw6FRhSIRVTjWwotg5tdRNm9RoxhlDg95yfjf4QTOKTrSeZiqc3wJmk0FBjTWE0wxuFoJGUu+cvJyKEJScSYzP28Q54MjH3y0FZosOl2w/a2o7d75aaORrJZJ3i+dsG3m4p3V48Jq3VvNHD5Xb9NEDnd16Vw9f+bYefvc7evidb+n87Tc0u39Hq/mZ8p80xf0XUcRlkFirgeaNKzd07959ffftV/TM9ef1t//RX1eooox/DmZ7tez9F1rnlyloI6lHFpolLQGPy+MQKOECAcMkvMMkXRzzBvJiJkdhJyohQ+wMJkgIPcpbUJ/o9VFLDFYCBMMqPcpdchLpoNOhROtNARqZF1kvkKCsGG9OCY+NeFmDh61R4IJDGyuSRuOgmshTFU6OMaePH2v2aK561qAH471Kq2tHEw1joT0q/L39gWIICp55RK3s2bnOwb6a97VOiR4bIqFyR58kS7Is5PaamGdyFtS0ljMjKaOTHGMKrzaPSbAdpTqindQiu0GCTiX1eHybDQ3diL4dOlyjgxX9K3Zv7tRd1hxPl3fqqZx7PKThPfXq5ETn771Le1sXd95HwAcIvVaDUsuDK1K5o7h3RX2xI+cKNeTa9fm5Nm6kevis/OBQRSz1Ay/8kHxpOtk80O9+/e9p2pzIhWxWKRujA/lC2oYw1dIQVSEEFYTN4BweXKgqkA7U9mxtMo8Np3EbdiNV6bQzqtjXz/Xg/gnCJtUYymQURI1qDLdYAURyavBQhq5zAT075XVZVrlgNBTl+NI0HdFrhQF7FCg1jW1DdFWUirFSFa/qysHzeh4gX93n5DSNNZ9GnZ4stTu6qUuDF/T0wUeounc1HFzXTnldsd/TpLhBijtC4EK9eTzVVBMyFxi/x+gNaOjhIXHvzckwVgsgEsaVk7IHb0hbKfQKhdG8Ev2ypIjdqkGlJusx25y5BfJ7rkKeFkdO2HWA4SdErWEVFQunUVHocDCUu9CLmrlDrdjarS/O1RAuV6cnWtLWeEoqRioOr2tw+WlVXMPBkdxwqDgcyZWlDGMKz2lZbMNBy/z0VBvtqA7XKFQOdOvOO/pnr/6u5ptzuQoByogiOjV4QgcSAaKkICGMkbu8edh3GD5onP8DjOjkeqZkJRHyEu8gEpFKhPsqevXQWV7M1VP8gRcZiu1BdgZC9vw1wieiR8OcxGIbANJRVaVkWlCQLjhoqrtOHc8SIKgBWg1oNqtW08VaARCPR+MtuAbhqm5c+ZReeuEL+sSHf1KX9z+pl577E/A70rUrz+snPvfL+tSHv6Cndj+hT3/oF3V97zM6LH9AL1z+gl648kUN3DV5RcYb9Hr1rOsxWoknm0mGDlI2HPcud0jAAp0Fr2GIbJedmEgvl5RpcIXfzHsAEd26IcU1gHalDY4sokTpnYrgiMiN8sFcjR4DiioAWuGD3IJXwcvjxzq/9Y4WhPglrytbQr+VAw2oBYZHlxXHY4WqlOFFJECt2cNvOAjqCS1KSRv2zmvyfkcBIl9gm6RZM9LGLuku6WO1mcN0Kx+SWFtrFN8QfrNRNhiwAd0bctJ8sdL5dKU5obRl21dUhQaDKEPI8XCkgvULZ5qdzdQjyIIU8OjBicpBocleJQZqzE7BQExGPtpDIa1KosmSNfPa2eN6lLyh4nbew5NXQvFZ+QUDslICwFpy/tECquFgwFaTMWvTYn2qRfOegnuk6fnbKPohNchD3br9Hb353jf1DtfX3/6WXnz+Bd19/Lrm9T14WmKMhdbdseQa9YAv082pVoku1gzwYZIQDRAYVu2294irMniih1dkTJJpC1C8PTE+y8FFBf0O4A/KuNWRj4ADZHkMH1xALW7behyoxlHVixlp+5+5uXaxVP7v7JrVmgo6qUFoFQOFwUie0OfhwnUbdVTq3exUPYbvVktlRQrU9XiXLMgDGIsRkHiJ3Jc49p35A134fbUtTDC27Vo1mQGWD9EDBlMGlXdS6jutCVcz8v4CY01nS7UAKjlTh7HmJyuiVK1+kXR+PNUs52OE2yPXjnaiCEqMW5O3G1qnku1QEbw65BkBitQDQHP0lxJ+2AGCTLsiLMYYlI0fzcSPPL8c6w6GAx0Kh0oJAAAQAElEQVQ/PFZDRf700Yf13HPPAdDXdPHom3r37X+i+w//SF//xt/Tor6t++ev6R/9/t/UH7/5Nd15eEvfeOX39c69P9DDi9f19nvf0nfe+j2dLh5ohfwtni+skJC7Re4egKe6JDYc6eaVj2pYHMlrBC8mD88JT66Jjm12oMLJOwxMDYPaFbgvkfMAXncHpYI3iZ8iBHn+4Z/q+JVbDIXGccCJYVC0ILUiSMBMh6LDaCLjoRiUeNgRMhty7friXBvSQ52BAvOprOQHYzkM3rb19gCja6AkB6ANhXcCHVKmEfDKoxdlhx/l667MwVIRFKrIypJnP+pAqnOOJJCbySOAeSmHtRr6DZ6edwihBP2E/7PThZwPGo8G2j/Y0QDvxvLqCH8N5wcp8811PB5IcFQRRURKGJYRcLdqoZf5CEWhEVV7WQXF4AmTJSCICuaU5+VWEM0EyDrODkA+PM30+Hyl2w/P5R3bN3J4iIZXd9qseuqOVuXY69756/rEhz6nT3/s5/Sxl76g3fEVffyln9APfuSn9fKzP6pPfuiL7IZ+Tj/M8+vUDEeTF/Ty859T4Xegs5J3Ax3tP6/D3eeJpkHsXNVsIutEzM46qrXBei0g6okGK8C9omaY05f/psAjg1Hc8jiLAT2vAqeMAN2cKYPugiK2RhculSO54Y4sDBjvEFLq8Y6c0xNEzBVyjPHjXfkRbbAjYfysxCSpBUAtCM5zDOgZnU0mzv59Q1RpU1A3uimLO3h5oRgdhk8KRa+esEVsor8FiYa5mEz4dtkG0BbIrQaVdg4H2rCF80WSq5xiWeqFl29ozLaw9J7otCE6LIVkWi5aTXYmKr3k8BqWU8LLwDigKQGhyXmnnfFAO8OCbV0kvEbl/65gAeBb9uUZeCEG3b97rKvXJ4T7uabz2zo+vaXkTCsftCKF1Qt2IbbRnGPh5UWj4aRSGHidr071xp0/1u17r+ts+o5mzbs6Pntbjx6/rcfHt3T3wZu69f5rvBJ+FX5XbFs3unf2mhb9Xc0Wt6X+ROv1XXDb6Okrn9AzVz+lIhxod/Q0INlXTp+eGiDLm8zUEFkX7HTSJmmoQp73EY6tpSE0/gQA0AV6TVg4O3bwXg4lF0WU406Sl5lx6+RClIF6l9HvoxQKGS3ESh4UmfNigEIIUjIaP02DEzbK3tUDiI7v7WbNcqY+0+uFdzCOa4AmdmUtDIe3ChK9tepdrZyHcUZ1bK2Auyz18j4p/4HpiDBfjqOKgSOMB4xfajE705RiteEdf0vF3+W1+04NkWOxmEuqUe4ML0oYuIVuUo4cu+NSl/ZHVOqlyoiMfSK/r7aVdP4DEedZoyp1/ald9SsOg6qJ9nYPdDBiJ6CBDCPPULovgq4cRkUEcoRnqdHseIkcUcfz+3rzLgY/va11M9X57B5gwMDrY50v7+vR2bt6TDtbsMOq72i6vIc9V1qkWuv8rznXxfK2Ls7f0Cknpt6dq12faZj2tev2VSlq4KI8KXjogkblUAOLCubRl1cIJnxPW3NZwrET9ZBEsNCGA6iSsfl/beN6GYbqJeewq/+gOQklmH/yXVxT/o51zIyvgVn56mTM22DIBqOb+Bh9GF0Y2tMcXUKBuv5D6osrms2XKquAUdZqUWJ+7BEg0FwyedYpUKyHs2ZbiC0pCjdyBL8JhWBdL/EGr8cPZ7qgLjA4CYWDXsebxxpvF/JIMhNHC1vBc5WfAEg+CJnymroldC8odJdEqI76IqeNEp4T2nG4TBlRJG0waPS9bz7WMS+trhwe6d7tUxRdasCzDgPUrLG3U+hoN+iFZ3d1UAYVfVTH+4ujySU8GDkBpQNgPQVYjqoGQB0tODhHnz1h25CtMKchBh35ICXHWURS3M5ZquZwyeEISjPlg6dB3JfrvCK6j6HYyjrMKQ3QTmj5pHYYi21UBR/olDHQdPCbbYqqVfB8g82cxVKGoaCi/DEzpXxDM+M+W9CZ5J34qqzhhGf2oJ4hSpbkeNYiaAZBS1XfUxMknq9JBbl+2FDcJRirSQXr9pLWKy+6AEIJiYT4qAGD90WnBuO07Ao6wlcPIAZVhQJaQmXzBNl9UEthFxxc8nw630jsjX2ZVECuJhR64n+L5FuFG0vwU5NCcj0xJu9Xg0LOeQUMsCHa1Bi+Zs0eWQw+ztkZ5W2xgN2K171HN3e1sTPtXC5Vc1K3W43hZ6UL3ik8mjbK3n9t0Klg6+hJITd3x7r3+l2dEw2WFK3eojzuGGhCLz4EuRiUD3FqnKBBGUYaDX3S2JcaM74CCL33Mv6VHFRF0rEYc3r8tg52L2vgd9BhrR69Rwtq2PZ10MpRkynK/+lXg4oazk68ixpSJVclQDAxr0WHzIWe885hW6esEJlT/piZPJ4gCPabjRLKYQYnbAgLGBytJ38nro45xootY9fZo4gGucjoKUoEUOrlSg3nCZ28qks35F/4Mc2aiSqU2CGwUEiB9w0GQxXkpBCdzMNPCPIoKee2DgM9fH+pJSH/ASdua6qi6WKDATbaAJT5zGkUr2gzL9luJdZrtDzvoRM19Bxr33ec0kXWdMrrZfDWqd0CLxAqc19DhNjQDGV6jBBi0uk9zu+9ND4o9f57j3V2fqLp+pyItNCNg2t6npc5kajUEpC72uvS4Y4+8tIVDdtaJTR293fI+VPVnFmYkhJenI2Sj6ynm5Wy8X3w6qNXovUuqYEvQ69V8ioAYOYV9JAeSJPoyoVOd+69ppKXb47I2sD/Wq0a9DAjYp5hr/w/kcoHYC45VYNSa/pbwmEPeB110ZBdUaQ4rq1nBW11wu/v/yRueuXKPi/uIeCKoIw+OacEcwyQmSkrLh9cwLdKQlCPkA1MCs/E9nkYRowwl5QwWhcKFYNKxY2XmO/kLIonhOweWuKkrVAkGuVqVa4nQgQNGD+ZTPTss4Tgd2aqeG1cg/pyhzx+Y48t00A/+skf1//0L/zP9Zf+zf+FfuqHv6zPffxL+vAzn9aXfvRX9e/9pX9PP/jyj+iHXv4x/cSnf0UboodjjQqglTTvvWr61oC8AbQXF0sFjHL37qluv36i7N0tAGwpPKe8mKkx0CKtFYYmD4Sai6TxntfSan30E59QqDHsWjo/nerd1+6qXSXNV53mRMUlzpGjTDKnRJEW0FPhnMah1EBRJY6wjWyo1rypR8f57x/XAJPprGYyxvtiQ2pbMv4QbARNeVu5RAYOUlVVUbuToSZEukFlShg+p7YaYOTDMQMAm5Yqo1nKsJUzM4kfeHlyxf6JL0YIciFI2UshnppOico3G70ndBiTDEECucTFUtvxMJeHE30lOfVsM+rZhZrZFK+Eab5nwbrju0o51JN/JVPPpByCHXOeAKBQ5qEoPI8bbUgrqV9pft4oek8wahV8r8P9UkcHA7ZIK73z7tsUOWtNRmMtl0uKxCF5LurR8SPlHcRwVOrO7bv0IRPo7J2pS4nQ2aoid49QWAnQu76TxU43Cfs1Gq0mFVw1On7M1o83fINxgTfWenh2gohRN5/eVcH8wSQC1lKvvnGu126dYPBG2VtvXhppDz2OLGgnFsLplNBfJMoNyihQpAVr9r1xayqCV8SrPc9jSBryPZjJsAnesgVr1zui0W3t7hyq68otYC1H5F4Us60MfUZay2FaTa1gFhWck3OeYjhpRVpY0k6mG2STMIEklLFt3D75wTcJKwlr9n0HGhniHVeYwQhmTmb5nuYkc1xNykZP0DIWFJ+m7dUAnJYcZTJtzh5zIIYyUQqPRebYLtsCjobWIwTT1eHlUJN3lcwkV/S68eKIs/q1fDR0UatdSLvVCzIq53/ye/8P/d//n/+p/uHv/RX9wSv/QF/71t/Tf/u3/kv97/7P/4lev/MN/fNXflffev1ralEUAVdYnzValO1oQWVZ6fx8ow3husNL1tQW5STq6ef2tFjMlD9tloO8L4qzvulISRt471So1/ThUn/rb/9T3T2+0ClVdoLHK1d3tc9Wc4P7Dn1UheHGLmrEfekNvqUSs+8IUGKwBVGotqTewx4AN2obKyTsJ0+h2wPcjobHyFsP6L+p/f2nFMNAzpyqDBaeLylC560j8rIGyuuQeY1ua+yY06eJTy8VPoObe2170vayvaUvG6GnJxuzo7DJXiqIGYxajg7eM0ooIMk5w1BORQEavVNiIYZJMnnGdoS+Ta4D8OTm/ndVRBSdcyCVeI+hG5TeM6HN1kfwhHlLikaKVIqtNgdH1Sgeu8hH04jtWINSq2JXP/6FL+npZ57F+zeajIJ28FjSm4a8sUuE60y/Kg0vSdrfG6uKEX47wqeJx8wDoAibj35dkTRguzmmSJzPaj334T1kSeTQpBwJDo92dOVwoiPGhCR1GLq0UqGnRnh/o++xS5jjNC3pYHxpoJtX9tR5UywKLcnTnaToPM0pb9kqisJBiqrMw5NDasPDOyJcJ3N8zw2jijk9cxv006PTvFX11AzDkaMeua/d3WcU44g2ARtRVlxF3qty4VDmD+T9nmJ1pFgeqSoPVA4OZGFHo8llOXNOMqNJ4oJJlT+GUgSyMwDMmRxNfDIAHP1mJu+cfPByGNnMyckUMg2MmueJ5+a8HGMaaoDNYilf7spZq4Lwl6OamakjSihJ3GoQSg1iob29HegHCa8pqqEqrGoQrwbGuE6Cv+n8WP/wH//X+v1//g9Uslsoi0g6aDW/2Gi9aKhjEgrtt3OHRZArpJxjnXPKS/bySr7YFo4dx91HpJTL+5UWZwttAFwGzooXQy2poCQdecbXi071tFPoTAVGyJ5cQltEtEDEKDgJ3MP4k92RJuOxiqLS3mAk702N67S2RpBR8J6Lo9QxWS85Im2kOe6VnQGAN0SZjr5cBzQ4laBBpsjBS3W2AXqt21OhYjm3r8neh1QOr2lntC/HiL3dXR0eXtVofFm7ezdUTS7R9jQaHcDbjharx3LZCD1hIxssh13DEtkQiatAXGLhHoaS+KD03J8wcMdBj9GFNSRuDKWa4ybPI+T0xPaUCdEXQpQvCnXQ8Zee1zrBoDmJdfklYU8lAzxh24pQKNKKUKnCsOOdoWpy1mPCbAuNFUe9eXzekt0/uadHp8fqrdMZL5JOzjbqvdOGlBNiUJYtR5hqEFG6FKNXD8NdH9TigTVluVPSpPSqz9fakAYSa928uYPRvAqih0O2DW8NNe/ULJOWa6eSl0S7gGVGjfPm2w/UQrXD+6tR0HBnoJJItebNYw3wl/1Kgr9Anw9Sg34QF368Inow+EnMF53tOin/PUND/m4AYb1u1QEEYYusryyPgpOhV5kpArzz83fl3YJ55ypC1PnJO+o3j3Vx/JZOH3xHFyff0/3739aDh9/VbPquFvl0cvo+qXkKAAjPIj8I4+aWjZ0Xy55uUl5DPnOtpPx9O6yXMlj6lM1HLwryIShWAwVyaeA+UTlnEDgPszDqYyHng1KspN0XOQtoELlTx9oOYXoEzPR6PJ5iHKGTwD1mPQAAEABJREFUzJwyrYZt1WzWaokBejwvI76G7/WqAcWNQhlUA7gpAGgBZzl0GgyDhiP4gbaxkgWTzxMRwOTUJacNVf2aNDQoiRKWOFVc6+R0qeGg3BpwibcPyMOe8db2WpwstGT7WQCmA4pPUU2/9/4px7hrdRjFs1YRhUwtQG6VeAdRQatGFy3ybbg28JfzeC/GuaTOI6dDj+iokWlGYbxY9RiHZ6yZje9wEGO8Rx/Re5WBJq+BM+4dRuwYf86R9duanr2jRDRrmet4brSu79TSZ3haz/oNumvhp0dml42NLuQwmof7HAl6wk/HwCTJzEkQydf8PSOwg2DyuV8sBnd8h385+oqqlCfPBh+UP5leYr5jG7UFQQYC1WutkRyFjbYTDTq9Gt7d59OpGuaXHOhkQGw2jeYovRxVGu8FDccjXeJ8vmOsI0pUk5KwFrVmHLaVy2whWI/XNG1SjE5GXO3xuhbBxaCshJb5+c+kiyqgSnFk3GiXdw5HVO0+J3iX+9aql6Ya8DliL9FYe9QYB5OBJsx78OBC796bKxuu5mE5irp0sLtNYUGGN0reDDUYKjQFOVUuUNkXMm9iJ6g14MTZeeLQQVKDQ6wRvMVAHRHFOyf3AXidOUXvoWNSAkJJIpsqOCfBXwsPCVC1yJowdotdNsjcQKel4cOiflWNfnNhmCORg0+Z8zLDCCBWoLSjOurWC/W89mUpBUKpZ+FMQBkYEO0h2BJmG87cO4q7/Aeg9Yo5KBZ7C3GU2BN3FHgOMDhA4csIx/wQJTQ4UBmdvPPKtEx5fVOLAjqq4RwRuiwA8xOCX7l5RaNhpQBoCkKpYeANEWC4U6lGqjneurs/UJmjwbrXfNrKzMB3J8GQc1LH1tPM5JGlJoX50BNpGp1TMzh4GwyjLu9V2izWani7uINBL07WTJTG+dmVXV27vK9rl/bUA64z6ow6OXgK0O7lZAo+alxVGqOzgqjQoNPA4qWLKq1Q4YotAHLFHr2JSSLyY/he4FaBL8bNllamzQDjmnqTd0HBnMhd2N+0wlHXH9hCfGqiYMoAF+bn2mYQocM8xczUpZ5UBcgAWM19BU/OF5W8L2gYgpzVXJypPjkmPG5UY+SGHFYv52y5ppxxz5QBICgaQkFfInJATx2Ga5i/otBbsQ+vOX3K/XIe1gzGTZFwqM1cdn4bL7mQU6m+SajNZGZyFlTEASRJE/LqMtgSS4LYtom8lk5azzZa0BK8LeZrcrHX7tFIl6/ty7ugrjUhu/YuTTQsA17Vq0MJCWbMbKuAFaDqGbRHrs6Ddw4qHUJDfOZU/6EpdXlnT57TvT0M/9yNA13hVG9cFYohsXNY82bvnPca9TaKxdJRVJUKGNTHXqNYshsZSiaVPsgMniR5jKhsYBmRwGtCBNtB/wFdOuZmnnZGJfVIqWhOVRHxeGRi7gqvXvcNQGmVHSZHpNzynCUOs+ra7VhjrJnJmI+NJfSX74N5NOrhxwNCU56biBiuq9mgrC5Uc7DRcNS6OjtT46LCaAeDDYRVlDLj9FmsZLFQoDkM7xHOhShzEAf5uV98XO5nrEcR5p0cAvYwr+lUg+M/lDv7Q1FxYfxeCYUwRWZepqCe72ZR3pVyfA/BI3TS8dmpJleGWs8bhOoVWL9e1Lo4Xm1fkFSx1cU5L07Yml2+OhYRkO1box4qOcR6b8qFaBEG2lBYhWjUIRuJEcNSAAs9ECHyu4Wnr1NRh6EORhM9fXhZ+0WpMW1+PKUGaPXa6w8QZaUQI6+eB0SdShVgm2C8QQwaD+gfjHVOZEwpKSK/vCnn3Ji8Ant0o5axXsgsifvQSRUyObNtFBiUhVovLa3bXr2TrE8AvEMfnXoitVLP9xYRklocQsjKAyX6GwDTsECb7wHH9ooj5ChRc3WMTejarR490uZiqsUUwxNW3eEllXv7iiWGNRaFeYeghgLMeznvZWagPXDvVBRRImX0vGzpKKi2AmD4AAgM4xWEw4jneO675TlefCbPUapSIue3ABQtyKABbRfoTvRpS58hnOqtlIgEO4cjnRLWM62T+xvdf38qZFPLMemc4u/xw4UWs0ZHVyoq9VqbZYNSWuQIGgwwUDWSc5Gica0Zqaphe5dQ2nAYGNepAyWRPXlA7jVV6Ju37mqOPAuOUlco+86tx3DpRE2Isb3IOpoCwMWyVUKRIkzn84PhYKLDyUhDeV0Z7snM8TzJZ+NZ0iYbJV/hewNYW3YciVBaE0F7Il3HYVOtTnPGuaLUsIoaBPQNfQd4JBNBTsmZnIePlGTBKUhyztTAS29eHf3OnLKjgC1eDrX09VIybQDACpvNOGhxPd7b+0p+guGPrlFo7W8V5uVkSSxnUv6N0c0FGYZ00UGoVywKdRgHSEqgt5jsqhjvyGH8ADCKopDxvCdXZWXbcFepuiIP4x76NYWbfJI5BGS+Z50SI7nkVK9rNRglNzOvmvP0Ea9eHSH5Eh7aIGBk61YNgkZ43qXLI127VGp5ttSDO0tF38nkJX631AQG3cePp/LOqaF22GDYUEoTAHA4GqtCic16LbBKlFnq3v2ZzjgNNLz53fsXumDbeE6F/tatUz08a/WAs4AWObaGI0LujofanYzleYm0RuYVW7icFmvCcw8P2fAOdrzLfHXyljmTYEdK2gK+Ua1EZFIQKcIY0xLFauW6qAUkHYbrMWAwJx+icuifA5zsCMRFjp9r1XzJug6Ma6gP8guiFkAF1si2yM4yJ4ralq9eLo5H8luDFfIIZN5xwrVWR4EHDQlOXTZOfoahTPCLQXOoyYWa43usABBj8veW4qrdLJnfKAPIERI9SvRsERNhsXj6BzQux6o3G+ROzJYMgfjN+rYVtv4gdGZ+YiwUaDGaBlVJrh7o5PhMO7sTxcFAA3YHWSnj3bE6F/ToUSvPWKNYFB7uXdIOQDw+fqwGxJ+eTBVDoQrP2pkEwrXp7P6xLh6ecR/EiYM2FK/PfWhPRHUtp0s9fjTTCp6WndcDXvmuSG8tNCI0Jhz4jMZR+/u7siIoSBhtjXE2yjsaA6hlL5XJKSJnPsXbCMPaRmu8PAPc88ybqURHCwAycE7CQ1v4JZKjR6dgUodxs44d9Gr0l6+78GGAIzC/ZbtcU4RviGBTAJ493eNo6pNqoliHxgMOHH0hmVfhjacoqQC5IXrWrCn0lspIE6BwuYmVYSbnFTMmYGiVUYn7jPCG/NIDmsTCLce7HQsl55VThouRtZMMwX0RFaNTH0rmIgzjPAWTkhgjISU3kgc1zvXw0KgovGoKS4+iyt6rwRgXxzPSghQAVTUs5GPQhjdu9+8syMudckE33itkyumkh3bPFrHX7mQPYaHBegHLOotKTdJ6ttY57+1P2f93Kw5sKIyODoa6ONmoSwUhNalHR3JeDpn7ZNuwfPloR/m/57/E8fLV/T15vLNAD2JMy7uJrPBRCKjKq8zXLsivpUj+FwZvaGt1amKn3vd0mWYYcBewbvBq47k1pp6zig3pqoevITxUGC5uASJ1eS1JNTwt0H+NnYxnG2wyDlE7PioDwzopsOcskLkovaoiqemd4AixxhMorNn2LNB+lAPdxkQzwyC98pasJRx3hMd+vVRfb+RgJhFCfB4DSnMNUfMc3UoymTklwmDex8ZqKAOlzjk5SQ0507moHi9Alq2Bcg7MYGpRdJKpQeia3HiOsfMaJ3jn/Gylu2+dYeRaFcbf2d3hiHOgTMvMaUDfkFQwmBSKRSnnCnUoYs2p4XSxYr2k6zcPNRyMmF8w3uvgaAzIAsowUt9IRVlKMHX7uJYGe7p951wHh0d4NApDPuyiazeuUf1vtIHuLrXFblmhSGOtbquXhh1GfvnVo5dcmQs+YqiUJGQ1CYyVG6exoqrkZWYyzhS6otcuu6SIDrw5xhsGTvIY3TGOQoL5PQ5iXCFmwmd4jmQdukZdmmD0rK8hjouvKTipIzoAL0ZJOXqwogYO01svIC6XMGhyTqEcSoQr8YEnfms7ocfQWZiWkNOzkMwzrFfHNq+l9TAbc+6fUPDArPlCBuJ7PMJ5Lx8DiyTGb1QvF3h0rVnjEFxylpS93bu8XFIDgts+yfjnYBIcUGhtKDG8ajnCaq8iDjTkffcKrwjQVu+owgcaD0fsBkoNK6+eYrZmckqma4RmR57fmDDcTBtSlAtJu7sDdez179+54Ax9rAHn5ioHaixqZ/8QEJmee/Gymu06UWcXQhYKzGzY+ZK1IqowNRgswXOQR9lJLc7BSPXBNCcH52dtNgK6qJG3DtKaUL6hnkBg+UZawQePtpGmpZ7IhupadAxd70wD0tnIBw1JheJ7nxKrmSL3LSDHUhSKXnlsgHaO1vnvDy7gtctQMqc8r0XNQBvD96qI+FdGI7kQM+pNPTnOTDIzCHk5TyNfOBYOZSG5vIzUQTQhkAcwYTBEZwMZ+MrRIYPCzLbINHMyMzmA0OXUAH1lgZiTFOQcz6GfGJNR6rgGZ8rKct6rKqO2eXp3iMGDkvV4aaXBuNIIYwdAFlwhZ1EFwhzt7ejqzoQtlEORAY5QUFEQHnsNRkMM1SkfyhxcmWjM6SGjOJJYaVAVOuBFyZVLLyPLJXYSIz1+2Cj1US89/5KuX/uIjg5v6PrVa7qYX0C71sFuqaJyCsHJ0VoMUiPnBmdxyBC828qRDbEhrC9peUyD3loM1MDdGsPl3UWuA/L2EMyqZWvhAIBJMsaWzpE+kA/PplsrAFWzTp1psOZWb+jKs2ZkLNOVjYwq0YtBxD0BJXPyWHNSwdgB9hwCplwTOcfobNBsCJNJEE40cyZzDtRHOR+VQ7lzXkkMkZcHOD0GfRIhNsrRwRjHDSR6+SJK0OhgOtPLE3NV6nxQTR40xS1zmUZKxsoGYaeWEzYzU80pZEf+N5ivAIpjxGg82hp7MCg0Ar3RRQVzyvmtOV1p+mhK0bbahmdBo8K4HkHHAKBmx7Emx/fs9QOa6tkmxhi27wt2do70oZc+oQ+/9HldvvIRvfTsx7VbPqWd4VP6uZ/9Of3MT/yUPvrhD6kYGCBx2t0fKlDtG8nVhI9hkJ6aJoNKfDw89VwFaLPia5wm5+gNRs39XUp4IYCkwnPwOXQmoctqC2rJo4/gTQX6TyjOzOQYk2WN5hRNMtY1+hJrZ+N3ROcpqTqvgXhKzIEz5fkMU+mdvPi4pCXgO2aLe0x0c3E4xJhO5nkMA3mC8jQUnwu7BGOG0XxR0p2fJm0XZkxmmvW3/b1zKKUQnMlR/OWWI4cjTwpFtxkIzivy3ZU7in5IG8i5IAdzZoG5Uc45dSTbNXvsBkksOeX8nxVSFh5vrmQmPq3MdVqv1tvXt4/vPuCQ5gKdd3hfox4aJSA0JVKE1/Rsiod1WkzXADRh3KEmRJKjvetqqPrfvvVt3br1HZ2ePoBuUmsrvXv3Xf3Vv/43dDy7p4vlsVCPTI0K+IjI5A3q6ElbJfQK6IrFtcKdHc9K9Nbi7SsMXWN86jD1zuSDU4icn2IAABAASURBVBGQBYdxzDHl704hy844x5gOvmuebR2LNfJa4pOjBVNVOifP9wT9NcZPpJ4ePrqu3zpWy9xgTtl5gndEwrRNPTXga5pWG+yRC3jIdMJlWLyHDfDZ1Uo87GkZXea9LHrxUD3IEYIZswShXOglrj1Mm6EMGMjPfVEoZAUBBB+inPPbVrDf3vaPDmS+AhdDxTiU8VzOwFNC7LQ923eZRhkkYt8+4X1Abs/hOpaFeoTr4KVjq+p9Uv7PnB9xhHvGFm3J61QeqUUpFTyUwbQBTINYasGLnZKtY+eNdXqNiyN98uNf0t7+Jb17+5u6e/cbev/2q3o85a3a+q6+9o2v62//o7+rb3z3a3rtnVcArFeFURGZdAJrciKFw0+vHNq7ZNtC0MmUjdKZkwM1ayY0/yOPNfRU8WyAbhEbwCc5MyJjq62i0Udgnehs25+NLoqElBu0OuTPI7uuF4KoAewNIOlMWqvVAgWsaYl1BN0cFfKWMEce1KJ8ALSmxsg8u5q8BmSUa4BtoQexPNFckIVSmUA2dH7/nxkwmBOfBCOJ1bcNAHgYpnsrsPOeaU7OudylTN9cUIiFMk+eq2DWDO+3yDjSATiEjDJd807DYSWnnmFJ41FUjghj6oGAQPldg/VOo2qkXXYxm7pX/p9cTzde82WP8U1VETQZBDVsj9bUIEcHO9qj0BuNS1X099bjhcY78tt65917sGgacC6QGX74+JZycXjBtvPGjX1NJgN4ZLxDwSh6jkevuHZcu+21BwSCV+NqGqILj2wLnCgbKnrT1ph4p0dIRIfHTtkgwQUmOs0Ix02XMB9Pk7YeHo0F+So+Dm0U6HVAi+jVAwbjmeV7QoI5U4L2Bguf8v5mRsprUfaavo7W0z8npT6cLTTnecN3g2OXikK9HMVdLxGSVOCRBQLjuea8HAvkaNCiSMvMZsPTcrjZNoizMlCASzjyMOMD7MKQgVRjETN+e8ddr/xf2sRmLkGDXpnxOzfW4g4iUkHuzootypLw7QjtS9Ucm4bCCw1vPSbhbaGs1GH8fLiTyMlh6Kngx7p8eUdHhxOBEbXwURPinTmNdyqZa3TGYVDXbzRd3tEffPPv6N33X2X3UODFUWt2KCfHvR48muvGjT3t8YrYFLVLzeG84fGmLDci4uW1ts6BoQU/GyU1eYyZRPQJGCsbrXJeZQaFkximJ55rAg9KcgroLMYgQ9cdhunRW48HG08zcAxyHX3GZJPJI1NCHlgVRyDqoF/TF9GHI8+Q5pXXS0masXu7YAt7RqqcAoAWe8EGzz0myKvTIVbwhFbvgkIO2zAuPnQTeXqJAsdyHx0JphLMKV8FiwjfklMyQDJTjqjhvJfBUG7K8CIMOu+Upo911R5p0D6WGU9AaA+XZk/GJ2Mt6DoelmXE88caDceqOVZ17JXlWI95PiKCl5JrtZhzfkF43d+r5KNXAQgmePKw8jrmHQfktV+OJEzHubQuTufk/wFpptbjE/hwc5WjFsNvdHJeqxwPUGjUHtHm2vWx1pzN4+SK8FNTjwieRy5oFAo98VjJcd8jXwdPnbXyGNQXTiOcqzAnM/iGg55rkw2JvMF75RydCMVM0/BfACQBxE45pPes5dCHHJOt4wy/0X2Kt9u8yzjBi08p+h5yxnH3Yq7j5Vod40MwDYuIRhJRkcIYw2cQ5B2EY/0CPiNre/iK8OF6CHQcHSYM1ZJTzUzOOTmuQntbtIawFSIzJD49oOlJFUBZXS54YiG5IAbJHNwilBiT7xMwf1ITRFn9SP3F25qfP1bLUWWf3xCC0jwvh+QMgB6w5bOBS5f2oV3r7Phca4rBwaRSA9gCnlJWFfv5lYzt1friQu3aeDm00IJTvdaarfLApAoEHRHJClprphJwDih6dy8FjUaJnUan47sbTU87PXhQa7GWzqkletfrmRePVJToATkbdg6dOYXoVdCcd9ogY+Gi8BAl3yFCp4FJ+e8APEAOnVSEoJ6+rOggRxxxGF0YuNWG9JFDdIPRNsiVDS4AFuyJHgsflVhzzjo1OlxwPWM3McWjzxYbPeQs4mS5ouCstek2XOm7mOkUIFxsGl2Q9vLxdZvtAJ0SgJXwk+2a6MtFeY0ju/n0dFsdW4EHMcDjXQZ+OsDQMyDn5B5tWm/yLmR55TOTMN0DEPNejv5M2MxJeQ5vBlPbKM83mUR/CF4jqzWfH1OR1sImCsyNweUREr/77GoAIJppdj7Tw7uPMcpaFad7OacPOCnLdKYIOiTcXbDtu39vro41i4HXDufyEZpESpmXHONrk6bIYiggVj3e7jQ7PdHZ7XN2EEhaBh0eVRpzvpBUaO/SUM/dvK5iaBjLSEFemUfvvcwkjyzOeo1iIq83rL1RTeHcc4iV8zsRXBvkyHl2sQ25rZJ6ZUNkAGf/qGLY0sl8Oi+edqSTfjuvtaQ1uluj2zkGdyzaYPyHGPYEb17WNbQ69QBIgMfJ5OAJImoACkPVocOEkcUzzwIR2TOdlBek5fG5LzDPjXb2FAcjZa/eDgLxPQt35I2WMNMTssRAQwE+BAlxGry3zVEjJTkHC2ZK3HsES9QKa6JKsiiLpYwXOKEAzS6qt5FijITtC87zEQSGG4yXAJxQYPCGwisV0FnP5ox1CoVx5FttC7cGvkIwDYpGtgAgtx5t0U/prQ1Ky+E1ctBUTUYaETHMRTUoasiLonV+BV0kraD7+O5MHkCXRJ9dDLDkmPne7QvNCa981S4pBD9Akb3MTEFODoViGwWQZRQX6F4Fyt0rhhqmoNhraxg5UwMvFrxQlWrONdboEPVIjG+Y22MEbT9OxniPbssQ5Z2T8077yLDnPSArtzRa9FTjcA22geUtT2a2veYU4aHnjLnMNzNYeNI8tCr48AYZGOhhOkf0rPMN9uth0LlqR+VkjIAMCoHQ3GuDIlpQVIzHGCDKec9QBISJjrPuLboIV3Agi0HJBYVqoILQLCqQOCxVjErmGUPSk0hAWF2MntKj+kihHKqs9lT4IOuzSFKETuR0rRg4QvlCd99/iCBSxRu3MIhadUsUvOHN3SNFjnlbwl8oCl2+uatL1/Yo/Ia8fdsoooAh/O6GiQIKuHx4qHffvSvP8W/DsXfLq+D10stj4YZQ2ax6nZ0l1Z0RQcZ67pl9rfjXozAPgItQqifEN5w5IBqO0irh5qUViq6S94XKAtm5TxbUAJQAyMfmlEN8dqCe8bCizFuuCZIwkDN52hqXXdLAoyJF7tB5MZOtXKcc7vP/MPt+PkInqqBNntm/aHgdP72cEbuwcgG9MjgV3HuawQO4VG5JUq4RehzCe6ceYYhfcuV4KOYreKlZXKirl+TWXp4tVmaeeTIzGRBwkApFxZ1kLOYy4rxXHFYqaZ77oiwVaXnuE6AkmTkJhhwA8UeflFVPEzpbrYgyCVRGmqjKB5VXBQCabq3JwUBFBkSsNCy8fOdw9E6LizOE3ujug5XunS/0zlsXOjlbazbrVQCIo52xLk/2lRHeES6PSSXXn7mmHsS37D48ID4cdppzNsA0PZ73WocOeaUDHCFZrxJweK6zzVy3z895m9hJrWmDZzeZV+9Uo8g2G9a8HED2MSoWBfd+q09DS5G+UUQfzss7h2GcBtE0xEgDnjl0MokFzwyD1zqeb3Sb3D5rkh6TPu4uZzrjRDSD0eEo2U7eOXnv5M0UnVegeefkaMofgJsvJqf8yfpN9GWAyaQQPPM9UarFYVo5Y6JhWAsBggWvSDv1hJRYVgyERF4VYROC93h9S+GV87sQ0LF4KBCwLBQJYRHDB9KJc4FA0CuPYxp0gjxjjVAW2Ivb5AV1cVcjjGVF0qpdyBdOgXZK0Yfr6MrlPR3s7WuU/+8logBcStN7tfaGrDxrFL1TwRHvcLcipdQYOGkyqjQqB8iQAElSAV8njy+gnXQxPdfFgzVEFgocFq3mQdM6aBU9dLyEDpLWMgwfLcqEonppjF4qE4qWSh/kJJlzyl57CsAeE1WmpL0F4FgArhZNG7ON+QX3UdIIYAzRT54v+hv0W+PRjrWcx0Fwpvmyw9hrnKJVLu7W0ArI2MMXBpEzk6c5k7Y8mDD6k2bYIrBm4T18OgXG5bHeJG6Vn1tKjHfbKJDriAbeNtjD9eTgQAhz3isXDx2MGce1gmhqe4nDCW6VC8GeYqpDYOjKFSWtkMFRIpRiYTmzJ+jH2B3EcxRwEdaiU09oTOLDL394VdXudXL5QJv5avsMnSqH5D2M+txTl3X18JJ+8gs/rS986vN65uBF7Zc3dfPay1qd9XqPlzUPphs9pgjsWefytYmOrk9UDIMeLU4171dKeHUopJ39StEapU1Sv3ZazaV7J04PLpI4WtjyTJGvAe8XxoMK5XmY7JSBUPmoDQjOf9uXldWjCMN4ec3SGzk6COah0zEuaU56lJxSZ7lb4AU6ElNEl1ooJ4/5nKEuT7owzXmPezqvtx7plRQweKaP5hWSV64zIiB06NaZFMzRTAXXSBsArCEAq9DxsIyqiggIvEzaNjEvr4+91WKD/Io6y4Sbs1KCWwyfWLgn7yeMLz4eQgAGzvnhhh88qpc5CGMpi6UCKSIQxgwyripUDAaSlwzFePo9oTuOxlLmGvoGETOT9UlucSZrFpovF/CHMIxPCSVulgrMb13SGSdWt96/rXsP72myM9D+0QiP7nQyX5MbpZzDBuy7OrENatcSa0wGcQvUOZ7ZQydh2UuTodppp51ypF0AcnZhOl05aEUltAJ+lO1WocAWZ4A7ZV6ptzBQLY/BdgYDOfhOtAJ9RfpYEHGdSue31/w9hEI5tGcjgXt8p8fovdbodQ7BGdveFn2JNuO19CnF8mNCfgtdM1OQyUE7mZNZUIfzOfTtLMmbAITk5QBF0KCMXE0lCxXBK3oPiBoZeojBiWnqE+tj9Bbdt9w3pCwu2zFl8AoQdeYdQpqa2VTdGgNkYRnC6kpM7JnUEY7gUWZOLhYKValYBoUiqqRiHfAa1jAahJTR5mAqToYouZCh1Bw9kFmSSasLFbNbCvVjrddzhRBUsF3zwRjvoRfVsHf76Ec+w0HOsd54/xX9/rf/ib575+u6+/AVdVTVea0B277xTtBg6BScU/bWAJMNoTRa0KCo5CWF3mt2stAekeD43kZd8OooSDeNyUenA1LISy/s6GmKyQEpw7s8y2tJfbLhjCNXPAV8D3xQNm50Tg5jEcjUKUFLGLhW3mo6kxw6i8i/VYd5xnoAJbXooUaPG9pi02gK/SXRNGERRmB8CbLbXz4bk2hrGD5X/j1AgOwHKgQM3uSRw9E6gLVht5bfduYBeZ01DpB5z8DazgMEHXZM8CvTlp+eB9zCX+a6btTCDPqTx8BiQmasB7mJe5AgQxhlAGCwEKOcBDmY4T57jHNeqamVx2eAFIBEzM9X571kJoOJuKGKT6daLc7VkzchKeSAqRaDJS045Dh5NNNTN17Q/uGeilHUeL+gKKw0HJg6isF10gGKAAAQAElEQVQu0woO4JjGbPcO9sYqCYVLTgzNFyqKoPUMMPeE+3tnunrzQOtlq9OFaXg0wXCmBguWhPyDo4GODocaEMV8potiknfw5DB4odzXoIMI/eACYng5dBF8YIxXRACTlMd45btEqG23YxKGy8ZrCTObttNiU+uc3Us2fjaOmck5ZnE1jN2ir1ypG31Z/x3rdsyFJeU+H4M8coMyLTgTyP8XkDU0E3IaSzsGMgX5pOyI2cgdOk/0m5n4kUCJ56ZnYKckzO80v/u+mulUxe4+g4wxaIdJjN7+8O1Jf0Z/WShxZS5SN2AlYchOHe/aE8jzAEQycu5G2hrYwXRQD5e2PFFo7rPNvAAojVhIWfCeqr8hJK44ybv37onu3Xug3/3a39RseaoQvYzFdnKFjlf0BtMxae+g0MHhmC1YlEPRDVV9XXe6evWSjnb2OGfY4MVPvjvvlLqB3MCpnBQqhl7j3aDLVwte9AS1eGXTdKzTw1fL2A7jlwrIYs5vjbvEgGuUmUd1FMMda2YvW9U9NUAi1JsW8LfsNoRivlM/5ZB7zq7qMZH1jDansp9jsCXHy3m+E/+wAPbQVt0meXjtSYeJzh65s+5zSgjeK+IpuW+Fw24jwwdG7BjXQCA32JKga+Zk2Gnb8r2ZzEyOvsSajntLrN9dnGt2/w6hkQKoGmwHCcLZk3PrIUyn5BlcFIpFibdidJh0Bd8p2jzesB0XCjnqA3NeeY6vKuZxD40ejx+0d9Uvj9XycqZjW5bHMFCreaP5bKP8J8sztm0VYX3enKD4DUMMjy7kvWl1vtKKYs5Bv8FoRFWKnlLWO0DYEwVK5Zc2e8OJ9vYmGu/s6GB/pGN2ArdvP5KPSUUZde3avp56aqLLl0ow2Ov0Yq0Zr5I7QmCiTYqn9fTlT2lK7fCRZ35cLz/1OV2ctTrPu49yX8/e/LTGg6fw/kv6yIs/psPhDT27/xFN4k1OET+jxbLRh176MY5nO8DRKYfkHk9GGCkZl9yckgzDJ9EpM8M4RoRr1XEoJhPPJToBolfwTi0ArJsOgPXMk8yYL6k3qUXHuXXM6rBf9nAeMd3JnG3Hmhl6xB7S9ruTqMduva5utCe3f6BECKJPCW/tOQjqucIvo5wMI/sA05wxq2kUeUlTsqUrh0MFQlOooraA4Hs+CAqkABejhHw9qcEwfFo9UI+XdHhTguGM6KIMzC/Z/2c6UaOdQof5jzW9l5PwcK+AndpmpSJIk9I0iKJeSVoCnByKM9vJvAr46DiW3eCFo0mpDk+bzc90+niu1RqemV/jgXsHY1VsGTd46YOTGUevrVZEj7w1Smb61Mf+hO7fv9DDO3NNOSRSu6N6aloDiIuTteplVGoHunHpRb104+MapIn23IFu7r2g5298UptFCS+XqXGinhRwSAJdfss5pxDC9mpm6Drhbz1Gp2G4XCe0uLHJmGsaFF7DIvA8AYBePQA1M/FYiQvq3dIQn575Wa/fbzxA/3mEZGY0J0z6xGE62z5zi/OpNDnUYDxWyk+V+3sl0JYwkpQHCu+JCjDfo+3IO/iKkBwwsElyKN4xLgwKuWAs0PEt02FxjN9dPJZb3SEPn6mm1shIzszm1hIW83uHy9fhAfBUo0LVMCpAZ4Dw/PDW7ljHtx6o9BJ2RmHScDzQ/sGOMsuLdSsXvSpAaNZrnpbbHUZP1X3r1n2UjedXjreKrbo2oThTwxarpRlRqwWQs9kKIPRbb/ra1//+do2jGyN2Ie/rzVuvKjL/yv5TWnNY8/6dt3Vyek/vvf+W/vE/+Yd67/5tnfJO5e7dt/WNb/6+yrijb37777MeDGOly+ORJkRD56K8D/LOyQzj68kHLeHBPUbulfiXdZzlH1WFKiJq20vZ81uiSLbJtjE1z+Oy/cl92xuZzJ607/d550QPsnfqMg3SaKeetNXL9ZPLKvGG6LwM5bTk4pS1mifBrOV+ri5EOZjzGDtMJjLGEJXV4nEZ1R43LWC4uThWPbtQztU9+S+dvq9xfVuTfsZbu41ajOIClJjfNi1e0sBUp5M7Z7wlXFHUDVRxIjgYRBUDbf+bwCK22t0Zyw2GatghlESNGa91H9490Z33TrRatApFVDWs1Huxt55qw1uzmtelO/TNLxYUc4Uc7xU6eTXmtGpqkQIVqWl8rLY1w2KxpL/V8eo9TdMt+QJa/i7v3O9q93KvanSm4d5SKdwFgDOl6lSnzVsK45kebt7UuW5rOntd451zSWf41YaxpuCdvAUV6DKYSYnHmEQ4WIej9TSDJ4lnEr+TooIcfXloTS3V5oisnn/aFnk9z3podYzu8iB9/5Po0dY+jueeb9Zr+wnRy3vWyD/uCRsuVUPOwHfIoRtarS30mSQmG4sYQMjhvMDw+RAon/QNiQBxPMRwrWKMEsQCivbmFTCSC07N2bE2995VO7+H5y5geq0WQXLebgjN3nvlNiSV7OxcIdRNtJjOCNVrTu2mHO1e6Aww9Wokzihuv3Wqtx6u1ATJ0KD1JZX7WJPdoapJVDkKnChiVDy19KUSSHj48ExvvUXhWZSc9y81Gu2qT41mvEhaNb1aGK8JqR3hsAQIzkGcqCAv+G3UYaDW1fKjXmtqllm/kAqp9Z3q0MlRU0i1KuQdOhTP9wveI8ytVo98Lad8PlSq0WMGaAmoyzJoOCxUwudoXGpMJCsIbc71chgnhKDcVqy3SZ0aIm7X99p+jN+5oQHu1MN7viZ+fb9xu/1xzknORHmkznhqkpnJ6JN9cM/VFRjAFqQBKvieUJgSveDPXCHlkeKDtzacSzuMXe1RL5RSgGiiEPOBcTCa/9hj/c4fafn217V+5/dV3/4Dbc7fJV/jMc3sCVjw0lgExTJqiEfH/D2UKGTMy5heBwd7KstKEdfrEbrwTjuF0/231zom9I4uj5SGniIoKaN/TehfzloKspEuKB4NBVah1/JizjuCu3p0PNOzH36Kd/1z3XzuSGfn5/KM6XKkQ9ZcF6w5DlzzcsmcFyrQdLnRgqPi89lGM4o5QwfLVacaQ8wA7owi7JwoOSV1zVZzrXiHYS6qDV75r23zO4iQkgy+F6s1NBvl8J29eEVUWua22mjDlnVFXbLc8Bz9VehidzTSiNrpgPRqAKrGWxb1equb7OWoRCnTRvfKTmC2/Z77kiSPk0b6onfoJ6mnmOzgm6GiezuWYXJ8cc4phig3Hge2S8vtgUbGWeJh740JhrKcTFKHoQ3jjy5d1Wh3R3mRzMMIg/FQq/u3VN/9Y4X0UDuTWrujVvsj6WhPcu186801hWM2qpmpKkuNyqidwQ5MSee8n89byAXHwrF0al2rgmIvwPnBZFeTwUBP3TgQEVyHB0M8F6ZCp73859mFV/YUi4V2Dnf18NFc52dzwa4uX76k8+lCk/0BlfmpLl3a1RqFh2gYoFb+n0ImvKggejnqlxpD8M5HzZbXhOIbnZ6vNWWLmSNG/j+VrAFMNoQ3p6IoVCDLSbvS8fRCI19oH4/fKQfq2K0sAdoUEMwA1RpjtyTzrIOeNXPobwFhD7GOQ4k5fM1JWQuuj4iEDX1tnZSjU8LoSPz/92NmctiqrIIqZBCfLEOd0wVzUs5xyejt1WcgoE++bH9nmnltJ6xucaA+SRYLCIIKCBsWNvK1575AoHJnTy46KtypGt6p9yySYLKbPlS6uKVJudSem6lsZ7JmLuPq67kS1XvKiu06mXOKZSA/Se0Cr37wSJ78Xo1Y1wlgeOWokiPRelVjoIVW9UJFJb37zpnu3J4RzlromC4RDRpc9vrT+7p8sKtnrl6Dr07jakdt50knkXTS6fj4XHuAxrpKD+9O2fePNQZ8BXwkvKzFAOpN+7tjZYUs4CvXLx08m6LMTC3KnAGCOTuF7MmGUhtcMll+7gSedIW0WJrTBr08Xi70eDlFlk7kEXU4UEt/D53E3Lxmm6MqRqnx8s6krP8NwMu7gFyo5fSTx2eexKdnQG7ZekxTHpONWBalenhZ8dYwz2+5T8KsPTSRLQkeoO/QvRw3XvLoGsGUzNPFNw/jzvGFQY5mZuqZjLXkUFQ1KlUQujty8ez2HdDd4LlJmfjq+LEmsVbpajmYzAdCfbdGp42atCH81Rikk/deRVkQISa6fDTUyd0z7ePBp/dniiB1fjZTQY40ePEOxTrTmFO+0+OpDGB6jHbpxp4mhMid/VLD4UB7+2NFV2o8HkvbfNvr/v17uvP+CbuAWmvy/KWr15XfOm4oVj/y8RusX6ihEjZJFdGjhK/86neFp2ZFxhhRSkA+NMUYhz4K58nzEUM7gRnlvuBMAeNFrDH0JqTURbPWjL78Hr/Gu1PWITQkk5kpf7LRcsv6za3rOozZqQcQ3+/P121Dw9s5/EqW0GlSjlCJ9RyMlMF4pbtGz9CAD4bJeQ/vadv0wfzc/y8ajs7P9nkHj64lJ/VMMhfkERTpZQhnPshRkJTDkRJM9mzfEjNHV67KylIZxfX8Qr55gGFXyoiGPZhsWbYHlb1yaGsxQgLiAfo74x0N3FIP3rqtDfQcfcboGUau8Wa0JDlpjwOc0XioK4eHKH7AW7+5Av09DKTedHiwowJAuuDlQ1QYFHKF6fHjU92/d6ENxeZoJ2rAtnAwjvBk1BcTzXn30PU1ekkY0ikoKvO3Jrc3nA8EGWnGqcy51HNP8yg6Aq7otd2Pj6pKZV7bTD28Qyj/Rp6eVNprsWq0ITKmXH1BLxuSy1bhWa9Ct6hR24/ByvcbHRkQZiaCxJNGX77P87llcOa7l2Nl552yprMRQY9QhHLkSgmu0NN2PBN7CPREhb4Xkde2LRN3EvaWnDkn7734JcEc/fyYfAgKMarCEOV4JEPZbiu4kxnPI6Fn+kjjYq4O9LW0depgKjOA8fGEfstMvicMEYoMPzm+daw7r1+wVFABkNbTlRZsvw6v7WvvaKJyUCr/HzuLInHgstHjBzOdTZf0RdUod73qNRgMdXHS6PThgnxda4SR8596v/7aXZ3PlxrtjRWJJvvk/NV6pjGHQnsc/uzsjBQ864aoAdEoIreZybzxnqGij2eFUwZbwLs8NyPGOeaIT1l6lSVjXFD0UZ55kiE/jXzfoWjJ4dFSdB6JE7bp5RxGxSjZwImr+JhzW1DkvictQYex3suZ/f8079yWhvdOMbA+/Cc5gNarl9SSYrZASHyh5TXMTKKZTM6cvIOuY00JnhjE1cx4ZkHGAIdQYoDyhwehiPJ4QubXF4Ui1XnPQolnhkIcBY1b3mV0re9vM3oGGz2ZfK/Ev47WyxyLZoDMF7p7byaXlRy8jh8+ElrQ0ZWxDnghU1ZeFd5chkLNotebbz3Ug+Ol8pq75PExhj7glPC9d/LWzunSzR2Vk6ApkegRW74FdYOcVzmutIbXdY4qzrTBu3uRhswpmtcwFioKLx+cRsNSe6OBxmWhfcA+Qea8rfNmpIqWKr9VjazrpsVAQumNnJIK71RBJ7ogD83Ad+eeSG9cfrlTXAAAEABJREFUCVQyM5k3bcO3EPWDJp4ne/KdLrzSKf8L5ok+cTvPOfhz9H7QvHPKa2TaeYtYI1/Wsz74+Dye+U++mgyKggl8UIlvSXyMfppz0PWejiTnvJcZD3JnbnwvyK8FZ/wBwzvv5TCWocCeQiNRzLjoJY50gy0l64Q825bzWQZBbhmFfZ9kzimiVAdzi8VK5ShozBn8irP388dLtoOlRgeVdtgT77JuGaTTR8d6P/8PGI8X26LKcvGZt2pobcFxbGDBPQAz2R0RMQa6/f6xHj48VQ7HxlobtmrTi9W2iIw+yvvAI09B2iugDoYoIlOJbIMQCO2l8uveXVLGBNkMsFb0b1DynKjTMac30xIQNLyIccTTRFqkWx4a3jslngdoBudl8LfhOf6Q8U2U6tQzJxd2LdccLbOuJMOo8IaOQqZTeNVEzoYxef+f18+GXnNotb2ndtnAQ8f1Ce2kJLGeg5Ipf7LeRa/Zk++5rwcFuTEoP6FJZiYH3y7BMHcyvpj3KoZDPGikoioV2X450kAPU/UyG1v0D6TgtuM71Ck5KRvauIiP2XYB1lS+CdANwdSy9w0Y4tL1oWQOr2w1mgx0dH1XA7Yxg+hFdbn9q90HnPA9enihBXt/Q5kD0kKEzvY1BPn66rUd9XhljIUe3T/V+7ceUoPAzTBk0Ov8bKkK/sc7FcViIW8YqIfB/CqZUN1j4ETr0SK9gj0ixkbLttYFRj/HyFMqcobKOVOPQRiqNbuANW//pmzpzok2CyJLQyG1AXDtNvxLaFbZ6tE5GZOyQRLKSNz3GRTQyvQyCFrmpgT9lIg2pE9kqpGv3xo4PaFlBkloGTLQhaqhn/ueNB4KEiwJGKAjPjzZfueWx5YvfBcRrCc9taSMjqv0/NWPZOtlegxiIQcY4mioHAF88DL1Snh8B+p6BIrjXflYCkhr8fgBSo9yvoKAlJmGTeYIoibHeO+f9LQIVaO0HiCtFmJx03BS6MpT+5rsDDQoyi0gjk+mmnKIk7EQglM5jMpbuB2AEqOpKD2gKSR4rVH6lP3y++8+4LtTAUg2657NQOTYeKQrV/c0Hhas1atlbDZGjRw1htpgyJ49dmVBVSjYvzs1FI53SVF3ZgvNGDddr+VYJzfJSUkySWvmnxC9FtlYGGrrqRS6LfctfS110HYgutO2MZF5+SeDIF+FoRKWTBDNIBRXunhkTHVy9qSZ8Z3GA6YwmkGZhhn9dBqNqQJfyv25mW17t98xgZwzmRnfe3UALkePHhBe23tKagNrZf5M4kdGBAhlJKxlgXv46kFxL24UinIbEXqq6M3dt1TM3lfB8eVOOVR0UdnBcvgrQxSzlfAwg2iCw8SCw51CBUYMhceIY126cqAdirPgkzxMzlcrGUbPQmw4bOlQZixMg53I2sKjw7ZOMDjt8eRyUHHa90BTDmpkTt4HlfC4TwG43R6yjjNjG9piXFCfDQSYa5RQ49rZa8xMlbxGFtnKltstpvPGCk9anv/kztCBybFO4uka3laAZEm0mHF4s243yqA165U/iV8d8jOUu//vj5kpy2c8yLriop7Umq9m9EKfizzANLPtxB7d5Tnfb9tOfm2N3qIXm2ivvEJ6c/LYzzknc8xl25iy7lmhZ3AHnR7QmblsTr341Muc0o7Et06eiytLZQGysZrZVMQ9OaKAnJf5IM9zBwLbB2+q2LyBso419jO2eri0I6SwYMfBUY+Se4Tv8PbEwtn7huNSu3ulHICZ7HRacTI2ORgDCEfx5fHQpUJMcsw/P19SeHkVE0yDVtd46mxZywBPjSczShsiyqvfvq3HD2caUPDJGehuSSVR1cBLmYfUqTdjTYcaTLCkChniFmRs2QBCK1PrOp2QW/J9iSaulWMdMC44x1OjafsxfuemTA3aHeF8QVRbcHLXotytspE35YVyY23R8pzcHPMjegzmZHIYywm21WdatKRemXZCx9lgKdOkgRh+MqQkM9u2F29+VD/xqV+gfVmHk8vaHx7qEy/+iH7s41/S537gS9vr5z/xs/o833P7Avc//omf04/n6ye/pC9+8md1uHtJP/MTPw8PeE3c31UsvRI5MBd33Cg5U/pgQR+CHMy75ZlG/V0VYa1Q9DSM2bIVw3CC2T4zn4VXUowBxvutoCW0fb+SMFxVjDC2qRybPLuBNecQK9qCI9s77x1rtuwp/Hq5ooCHQvOLDes4/CRpuew415/qFgc9s/malFBqSM0yGAwUi4FyrVAQNYro5OE94fWwBA9eAswbvvfm1fGsT6YlZxENYBkVhYKk6abWMYddK8ARvKEcFC7JOydH45Y+YQRhqx7wdwArIafUAIi8luVH3GRDZpBsH/Kdbjl+FR5dQiuDps+A2bakfL9tWY/osCfVmEx53dzM+PZBO5gc6b177+jb73xdx8t7ujt9R+8+flWvvP3P9Sp9333nG3rlza/rW7Q/fvMP9e23cvu6XsnXN3n2zh/pH37jv9d//bf/T3JxNEZ5UYmXDoGw6lxUGOzwoIDdzLJtr2ZeKoZargFGjfyG8CC3g9kueyYMIwvyJlmeRuszEAqvhpcmNWflj9+faXFa68WP3GCbN6cY2WhG3l0tF9z3vLxpNFt0hO1OgcqsxziJk4Uiluz5Nzo52UCxUMDIe0cjHVwa6PDyUMOxl8FPxVplESQnRTzdBQ+j2ub5JnsY33so9EnakLdz1zAEIk6jB4Aw/1c4G+TgRwYRZyZjrDHHOZP3ThFgi366JZOEsI6xOfpvx1nulJyj1/OYJvry+AZdbWhd1huNacqfPhsd5WXQ5O/fb4k+FAoPSUZnHpcAU27TxZnOFyfUYc22LTh2n67ONdtcaLq+0Iz7OW22PtPF8pR2pvPliWbrU+U/tctjH5zelfOZETy/nOzBj5MvCwUqaOc8S0pmJkMYTzh2O/tqikP1fSXeqkooxjvH+XulwImZYYSMYh4oevp5QTEqDW/slMyJ2ktXbuzw0ihp6Pb1qef+jD5042e1nh7o5FGpF5/5jD72/A/r5o2reFSjhsgy3Ct0fr5SwQlcg2euAepwXGg0CNqjgEzWKmRA7Jcq2QUI68IKntmrRq6at3UbXtaETlTBSTVRoGFMT9FXUn+cs8W6j/GnnBl0KNfMpPzD1fKN+NCf8HCBGCNlZDnFMzPTk48BjiDvHPbCWPS31AcRnSG2kvjQl6+Jb1tDQssRZQJAz/257/u6M4MuP8z6Fz/5q1n+LSjQzW0PX9sow9fU0yGfxVeLjC2g6hiZwWJmci43JzOu2EayJ31iYDOfCtY5aVvI8kZckqEkT5h0ziuUUYYrdOT1yaDXoDIV/ViffeanVPooJm+5cubkWMCz8IAwXEqK5P3ojLyfdOPZQj3Iuf/gNuMbcnJFWJ/ryz/5O/rpL/yavvKLX9UPfPiT8t2unK9Y0wjzQy2oAdouacW2cG9S6oj64erlfWUFsxRK7xWLuL2u2L5loPSs3QGYncFAHSDvhDowopNRL3TaAeQxBLZ+nZbk8axMB+/GPGMMksjz3Xsv5wJNyjryLDiMJn7EEzljgnoA20qMLwqvitQWfVDJvZmjf2t2iXFbGs6pdJEW1Gc9018ChD71MnRuevIvcZ9bn6+5zyBhiV+55cuTazZyBlyu8BP2TMhrXmIZmRlN6IaxgMSSYw2xbqvUJ8bgPZNrT+HReFlR8fqWIMkihmSWhUex3piE5/mztzRs7su0VFeudM4J3KdfAATdmAgQIWhSSirQTsdbvJqaYcWYmr1fz7vplsp5NDDt7QXNmnP9nd/9P+rWg3+k/+av/e/13/+9/6v+y//mP9PX/vjva7o5kZVJY14WnXMSOBnuaknOPzwc6/KViSYUftkT0bE8Hlk6yaG8gBLlDXUirOAjBK1IT5a88qO8Hc3v+eccJy84WAoQiBi3ARhZGYZkT5pkZsofVIFIie98SyLv9+jI5OW2fWbG9UlL4jk7jIZ3ASIydaSZbBgpP3nSCnQ6ChF+TGI3YXjrk5PURF8PWFuMgw3Qo8t6l6FbISfEMx36811uxnPJJBpsKK+TASW+J8b1tCf99IAGqKpHoA5dmZnokhsdXlfJHrrY3ZPH01sM3eM5mV3vJce2r18vlCgyjtavw/RCfaqZnPT6wz/Suw/e1c9//k/rK5//Hf3cD/8p7Q0Ptgw7E/z06KFVaU5XLhfUlr2OT8/Ur4J+9kd/RyfHM7335mM9Pn2ocmejfrQAGGcajIMO8fLUONXLXtPZuYYjr8MrQwVyew/KvTd5hEEOlCZEZkEWzceuoWQtvkbvt88qgFCzm/DCf5NUI9+6a3XB1vOU+oPJcvBoNGdeTiYHYTOISHK58SzR3/O8i4UMms475fF5hCXDs0zZRgxHB4FnUvBeDk3nJubn7VhmCrtrrZ4KxxjntCIFgQfhoGIYoHPq8dB876JXwKk8/BgduQ1w1kEYcnQ8gD6A8qUG5YT1DRYSfU7eOzlvcuiMaTInnqftc7DBGowzv8WFfByg+JEGi/saT2/Jz9+Vn/2x7PHvqbn/j2XNbcLlFDodTcqCJN/pztkb+qv/6P+mb37vn+nO/Xf1oZsf04Kt3GI6V1V2mgydeK+jet4o+qTNdENYT/prf/d/q+PzC9Gp/cMgY9CCFzk1J2yrxULnj5Y6e7BQPs3bvzzW7lGFIPZEKciRfzzKLTGGQ7IGUGSFGdy1fauM8uQcB0Om/EcSWezGtQLRWwW0FGNz6oCaq2eOM5PjapLyvXE1M/Ej4z5HCPGllwlbazAoULDBDzTRplkeJWWvY3h2btWE3J6W5/Z9v6Wb+Zplp2K4A5AG70yXc9ACDqKOEhWlUch4DGhmnLt12uQCCsJmpk2z1kef+5Q+9dLn9eHrn9Rzhx/Wx258Rl/8wZ/T1b1nFEgvkFffJXUddDOLgCnryeSkpO0nRwnHCAk49iBQq1NdKi703O5cB+G+drtHGvWn2vVnqtIcRhqE8pIr2C12ysexPkiNLdiKfE8nszsSAj9z5cMalRMVXaCJ07OGBXvl1FCEQnujSs0MrmCwKE2LeaeTx4165jrQ6kG7weXh9R1VExawJLKHmr5XQgHoh0KHpdCcBwRVrvxNvAbuESXJzLiKbV6LeIm1EZq+FjnzX+cwSvkQZ8q21DCCc0HevJwkZ2K+o9m2aftJSoKjJBku2uKqNSkky5q/w54kHqr/4Mo3eNvWIoTbHuXnRz38dzTHKMdCZsZ6TsHnHhOzxHDAg5zULCxGH/fQSsnU0QQfb9/+nr727X/INvAP9Na91zSvp9rZHevNW6/phz/2eR0Or0h5rEEXtvq8Pt9NTsF5ZHU8F9+cnEtJ/QxPPL+rcnNHSWwT5g+1mT3SejlX33XqCJkNuXRDbmsxUt8afUnOUJxzKgmHmd/8p9KPTt7TpYOn9czVl3VQ3ZDvr+j6tR9QVV1lvFeMXq9/+6Een0mhjBi90mImteTOmlM1V0px4KTQKUgB3SQAAAo3SURBVFHMwK88Rm7hwWMoc14tPDdU2R2CZVBsuO/FP7TXY+Sm7lWTf/OfYdVtrzXo8d4U4dOcoNvzS/IYM8jkaY4HZsadaGiNNVCGtP2WZGZy/BOKlIw7U8HMCD98VZJkZvkX9NEpvGQPEx8DIWY8y4Og2+dn8C7Rl/sl5Yv3XN12kHrGZSbzN+UP379Pb1XPtGguMPy5ls1UD87f1++98j/ovcdv6LW3XtEnPvxZppq2/0xy2Cg3OqGU5FnMmxNsyPmL+6ouvqtJ9452qzMtV2fsFWc87JSZ6FB8zYnXBsSb/BaU8KJMMMagHG7IIhQwiTkbvXvnVb3+1j/VsJD2Jle0u39TN658XC8++0XtjCaanvZ6xBu9Ymegde01X0mhigp4cTnmWsImBVTCzRsq+g2gaDBgRvGGan3J95wvO4rKhjzO6K3yt/rUk0+D0WF76zHgAJk2Subg1UhLEUA55frAO3ty5ZlDXc5sK5+y1v/HTXz4nhiTZWeUsjECig3M5akyfwYsxJiOQT3aTXh75k/Q3V63hKX8LPOeq/YOGbq+hV4GcOJZw30HmV4JoXpo6YOP42q07Q/9mYdMY1LtSYCZ2Vqspzo6vLz9blvensxw8Jq/95kvukwm52h+dVuVv6fCTtiqXWjNnrhBew5kO3OCN4YGeVzTWanc54Fq8EENIXSz2qjmxUmMGw5kTPu7A42HDQc339H05G0tzt7Vm2/8vkajPV27+lntHXxE1c5Q+e8JM41kSWEcVHDmX06iisJjKKcQnFhe+ZNQZAZiSxRasd4ig2DTaQ0wGiKUc07em4J3tKQYPXwaSugp+BrVjMmgMDWAvNTBaKS8DfTOsQZNTz6wAgAMecU1CR1zD90Q6BCfJKaIpegXAMuQEPeG4RJRp1VHTZGVzOLM72kp3yr/4u4DCBj9Up/HfiBbjrQ5ehkG6iiyE9Gvo4kZzmwrjxm8Oi8zkzqvZy6/pI8//2l95Kkf1A++8CO6tve0yjBSQZqNoWScQy9e3jkxQz30ukyfNXuuCQHdCi80RZn3MJ8ET0pdkrFYDFFVWdEGeEpBi3LOFLKCuW6ooi1tNBh0ROy1sKOuT/b03MF1TYoJ+/epTuePtGjv6u03v6bTi04/8eO/iHJNm2WrWBYaTQaa0CoMXwQv7K4CQw5Zw38QDtGBjH/wu+WxJV2s1xiXyn4JEJZEhpwiskJlpqw0IyXAIvwKBXitOfbFoTSKpS5zNrBfFCjLZ9KS8cO8xI0ZX6Rtf5+v+WsST3JLGK6Xl6DplDsjPBsL5bH5pK8hHXUArodZM7hA2Qll5+c5eyR9/wM44DExTjxwBj0IGp5sXDMH2Tkgsf0mfh9MLuszH/mCPveJn9ZPfuYXdG33aV2aXNXp9J46IsmHbn5cL7/4cb196w34TMyQMlUHkQzu1LEm0THXbjliiY/rwhGDKlpUYCtRxEoRJXkXEDLIgbjcPN9NiVDfq4pS36450Ws5BezkMMABcy8zN817jdyurh7cJBRd0d7BiFe9nd546zt659Y7euXVVzRfNORxmCtMRelVOkcE4mpR0ZVyFlUVlUpA4c3JySSaWb6KT1an1KLcFoFqcv4GMBCQ1FP1BsZlMFHgIIOUc3BLVFtvpBXXJdV/YkxANkTCM5AHQ2SjdfnKiugqm+fJGn23Bd5WaUkq0EXB3Gy8zJFjvJnJIQcQgV7CID2keZoMY3DVBx9u05ZyR0cPb+I5txjemeeLgxqOxr3LY+Gny4ACvXujI3Q10sX5VI/O7+uNe6/oW2//nt558B199/1v6u3739Wbd1/VN9/4AwrmBqL8sD6MsAaM87NdEF4F7Syv2710KBdMa/Jtj0ILjB9CASN4R+9QKIIQOsxJPfmgAPHr+YnWMFGEtY7vUZAsWi0XvVYniNY4Xbp0pKefelbPPfe0lAY6edRRsCQ8fQ/vD/q5n/pVfezDn9Jz1z+sSzvXFIOoDwYAK/KcNXOR2Zv2h9f0lT/x5/TVL/8F3Th8gfVRmKMhl4Mfgyn0wzek4b5HsK0BkWNQFfIOZfKIoUIDWlEQXJCuTpZLXdSNHEasImsqGwne8dSOuVvDMjfrI9+je3SYx7AUd1mnnojpnVfHdzODVl7ryVV8Ml89E/MaZiYzo1dbGfKz7ZftXPGs3wLGIGwObrG8GVcZ45nDhGys9WatN6mxXn3vG3qFlz7H8/s6Wz6GQFJyrW4fv6c3bn9XKw7hPLS84AkaCT6yHMo8ZDa49qwtPk5l0HiwK+OLD0EF++rUG8rz9JnM8r2T9zQsNZvNNTtd6eT+VI/vrtjz9zo4GqqFycU66dlnLmkwMkL/PbZaF5rPa80Bx85R1HsP3uGN1Lf0zjtv6eqVa7p++Rn94Ic/p2evfly+L6XWKaaRUhtJEdLVvRf12puv6Rvf+rpuHD2jP/mFX9dueUn5w3L5An8O2yZ2Eb06UsOGuiCf/iVl3v2TMVmpfO9QRIs3t1zXRIINnrUdwK+sYLrV53tAwIUZ/GahrQLpc5mOCe9qqSva7bp1ppeYlSR+mGMyMybyPc/lWf7aM79nrPL3PHK7GDO4mvhnUo5UeICchTxCCSOa+Me6mUaOBDVnAF3fyACJM2ORDxrjEvSdNznEdjmFBieIafuBRbHW9t5YlxtnkiPdyxF+hnGkYTUQ/Ckw0bsEE40SHQbFQD0A6OWIAC2RYXTI+PFAN5/d14icwOt8Xbm6ixc7vX/7Lb2Okf/4e+/o7qOZmq7XnBO9zi056ePkb/OOXn3vn+mVt7+mV9/+Iz1782X9zOd/U7/8M39Bv/hTv6Wf+ZFf00//8Ff1w5/6EyD8Edub1/Ttd76mf/yHf0+/+cv/qrTJEQoJ+EkJPmncbnltWSu3/IYy81UWhBciVx6XxxhKFY1NhlrAkgFhaGKrkqxQWr5vyeUOpUYflJtHB9v59CUU2WHQ/N0pj0KRfDGeifncPvmBr65r0XvWPrZintGXG8zSwUroNw8O6DVEeKXCMPM8s9wtcXGSHHSNL2a2vffmFFxQ8AWtJEVpu45zJgcIElE7y5A+oI+Jt0uKJcUvzxgmCtpJgVzsYcClIOjLlCDYbJv5RIgOcjwwAp6PnY44oNk7rLR7qVI18To5WWmzKjRvF1o0j7XhUGnBe/x7dxbKp2/5MGfEK9tQmqgpVY2d8v8faFlf6N7Zm/of/vCv6q//4/9Cf+0f/ef6f//u/0V/95/9lW37z/+7/40e5VeWIclYd1Y/1N/63b+q/9m/+pdVuT0EhqOsVDk5o8nBu0n8nm1WOl9sqMybrVcPeX+Q04P4mJmyApz30JD6D4wpPikl9Sgtcd+jh5YokT0/EB3FvHxvZjKei+c9XicAJXro5ne+05YT8cl0OniELGs6mlc2Uh7LY4ySZGbb/r5LSgpMNtH7Qcur8D3lq5RZbfHahgiW658e2pRBWzri01Lf1PUGuWvSeq1N03C+2KGDTjm6KH+gxaLKfxL3/wEAAP//o6oulwAAAAZJREFUAwB+1ueIRtqbegAAAABJRU5ErkJggg==\"","export default \"data:image/png;base64,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\"","export default \"data:image/png;base64,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\"","export default \"data:image/png;base64,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\"","export default \"data:image/png;base64,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\"","export default \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIIAAABwCAYAAADSWajvAAAQAElEQVR4Acz915dkSZLeCX6ilxhxcx4ePCJJZXE2Vd0Ahuyc2ZfFwz7tnzl79m0f9+wMBgfobqB7uqtRNDmJDE6cGyd3fp+aW4RHpEdkZpEGbl65ykSZiKioqKh5ZPrwuGk+OWmaL06b5k6/ab48gzukPyf/Y8qNcx4+uiDvfPn5+AdHTfP+YdP8FvjNQdP8837T/Id7k+b//euj5v/7/knzN8T//RejxvB398bNPz2aNP/HZ/3m989mjcdwl/HcGzTNy7Bono0WzWy+aBaLJUynk2Y47Dfj8bCZTEbNeDJu9k+Gzf//t0+b//DBfnM8mDSz2SzDfD5vljAjnAIOV3nLcLFYPG97Pps1Dx/eb/72P/7vza9/9Z+a0+PDxv25vWU7yzqreH8yb+4PFq+Mubkw/XC4aPrTBWNYtjEej5rjw/1m2D8hb9ocHx0C+82D+3eaP/zmn5q/+ff/v+bvgEG/3/RPjpunjx80v/qHv20+fv83zYO7XzSPH9xthoN+MxgMmuHQtJjkcEDeEPpMoM84wwhajaHVhLlMm1SFVEWjMjVqx0IF8QykK6AFtJ+D1EpSDbheQV1evekJEAzlGVIiPZst9ORwrDuPh0Bf+6djShvCqb58OtJmt1K7SgpyL35D44U0AVzeNI3gmyKSkxlCjeoytN4udHd/pKcnE3KkiK+22jRuqNGrT5PbXWg0Gupw/5mSQhsb2wr6ifhqO6v6dCnTbJV+U2g6GiJCvCqKQtPpVIsm5GHNZlNVVUftVkcP7t7R3t6e3vnuj7VYzHR0tK/hYKBLl/YUqaB+aG19U0VVUsdQKaVEvFJd1xlSUdGHoSQscnlEKEFvhEDqxFyd2am200RbaaaNNNdasVCvXMD8RkWSLCAlgmKhyRAStFbSm58AbwUWhEsbtf7nH+/qf/rRrn5wa0PvXO1pe72lt/Y6+sGNNQShZIDBxJRBr3lWrGMlyhDhkRhcdwl79FUw+EfHUw2QnAXMfdFcvIiei0XABBq3IJwcH+nTTz7SKeHu7iX11jeUaO8c+oVRLxJl0buw+Hmm6fGiuVBEgpkbqlstBGKsyXis2Xyq6WSi4aivVnuNugjnsK+6bqm71lN/cKp2u61UlioRggAj0XBEKGIFybnA8o2IHPEcDeA36njFC0L1T5RgdDRzVc1U1WyglmZIt9AWjUotVFJWANYidSzQDk0WFGsJC8Wy+dzHVz7FWc54utDT44n6o1kmVShg5EJoesJGXgkpl5xVyEGTNZfzDe7L2slFKSW1IJzDlAngXMk8b4F4daPSl2iFv/voUA8OIC4aaYnhbygiHHkFGs1YmYcHz7T/9DEr70R1q1ZRVbTbgHtRHbLPXrrVetEIkSKnAd7wMlAzwxiLxSL3O5/PMi063W6eyGg0UKfT1dMnj9Qlr93u6tGD+1pArF5vQ67X7a7JNIh489jcj8F9RkSuk0zMXtkgAELaN8k0uxrY0GgKISzZ7Zgxqbk2i5l6GqmL5tjQUGsNgtJMEJA5TFoAjbydZFUnngY4e+kv91GS7g9n+uDeqX5350SfPjjV/slYjw5G+vhBX7+7e6LDwQQsyXXEY8Z3EdbdlrRdN9qpF9qqFrk9isHzxJlDFgLHnStVRbA1lPrZrXX9/Pa6atTfb+/39Qf6OWYM0znzbIyb+LyoZwI1i0aTyViHhwdqFnNt71xSVbfpKylSQbjENy6Vv/Lm7aGQNqDtEvMrKGTQP1+GwVcwfqZj+hsNB5qMxprOJsJGUP/0SEeH+whAT9du3tbR0YFm8znjCJVlpQ4CcOnyNbXQChGMD5BCFz0RoYjIRSkZ9yw+hRAIpETlutXWeDzV06dPIcAhhJhoOBwCgwxj1NR0NmPlLjSbzTU4PdX0+Klmhw8VoxPFdKgKrZGikVeEXnmCPg1rrULvXO7onStdbXQqdepCW2uVbu609c5l8tql4Onz2j2kp8fqEgMtEdGSRgrACEtGMAknFMsvZREh3rztlYV0ZbPS9+jvFn3cP5jod/f6uvNsKAvDgnZzxbOP2xyPRzDhWAP24L0rELm7rtFkSpspE984+pqnCF1Ih2W1Rl4wXoieq22B0+NDPX18X8P+qeYIwQkM/+zjDzTGRhkhGK1OR2OEJMEr49+4dVs1e//65rbM1OFwpPF4gnZozmCRF/MYvs3g2wJt87pxJ/SO0NQYXoyaEe7vP9V//s//Sb/+9a/1/vsf6MMPPtTvfvc7/eY3v9Ef/vB74A+kf69nz/b16aef6vd/eF///Ktf6c5Hf9DhvU/Ung9kYShojgUoAlp98Zo5651Sb19e042djm5e6shCsLNe6xKw26vVRjAiIlcysby6AuE6P4mIZXlGyr0s0xGhiCVIgdhIFZReo83L2AvvXGrrh9e7WqPRJxiQn2Kwng7nOv+YyFjWCH8fQrfU7vbUYlsw0U9P++r3+yyEmegGiPNVvxK/qNSj8lZqTdxiezVzD5490eOH93VydAjzxjo4eIrqv4dATPWMhfmIsp1LV7XWW9fW9i5aoKvuGloOIzIiYScMM48+/vhj3b17V/fv39ODBw/0yScf68MPP9Bnn32mhw8fsLjHXxmjM1KLkc4VCho79QTnC91+5ztZBfVHE4RkgdU8zivDFSYYLUdHh7nBzY1N2YDa3d3NhGm1WrLd0EIYWhibZRIGpmu9DCYgvMmrtQDH8QIUh4Yg7tcE66AJHDrdsB9GLEubV1axy1+AcUIRQVbkVW/0gsatfa5vt/UeGun719awHcY6Gc/AU8Z3u56j9+gGy3zv0q4u7exojX25SImVNtfx8TE0GVlB6eseupTnkI1shLkGukx2jXkVi6m8DZygCU4xRh89uIfwDaDtRMNBX2NgCE+ePLqvX/6r/x4aT5TYlhgoAlrTdSjCcxRlU83h3Qjt8SsW5t///d+zYH+LEHyox48fnwnEhwjxgHosfxMkx5af5EF2PShU+l0k6AT1cvv7P9Xlt76rn/zr/1Hf/ckv9N/96/9B//p/+J/005/9XL/85S/113/1V7q8d0m3bt3Ue++9p1/84pd65513dZP9q81+heZXdzFS0cyyavSqLhkvr1ZgAhmgiUrGYg1icF5GIq+DXdBmbKa4GXQ2Z0pefRsyDAS58rKXRIUW0uhwgoFoY9QYzqvJb7Nn/Ot3N7TVreTtwX24PKXQmC1xOp3k1RcQf4hKrrDKL+9dRvh35ZPDnH3a+JCVYNU/0XMvTWFfKdsK62WjjapRj9NYzEY6OnymQ1b+nCNiZ20tj2FEvyX7/tMnT9RE0oSyjc1tNEBPDtc4HlZ1TQ/LORJBCGaygPzoRz/SD37wQ/3whz/IoeO/+MUv9L3vfV8/+clP9eMf/1i9Xs9VMizOtgrPO5WophkZNKVUd5XaG5pFqXmqlFprmhYtjYu25lVXTVGrYJA+qkSEBuxl4gRRFklXr15RhUUdEWphaxRQoOTU4farJNQzwNgtEGa4QwuIoUzKx1OqyOAyC6iBIuRgAZjQkSew+ngCy7jLVrDMWX0ZjloMwKUzDEAvBNcr6aiDft7oWBQFwY0hGT+llFfqDEEoilI+wnmFNiyWoJ4FYs6eO8WYFo/bc7tEL3zdpudpbZCg14Dj3j4nERuCg9NjnaANpmjaHY6nC8Z4/96XevLoAbQudWnvCnBVNUfFdfswcg/BOJfgpPsvEdL19fXM6O9+93sIwg90+/YtFutt4BaL9Kb2EOI6C5FyfZ170gIhGC5Cp4tCm1dvaRvDKCLOoUiNQiNw+oukWapUd3tqtTsYJiP2s2lWk1ZLuVIjRSS1Wi21ELJqNmTFzxRS3iZWQlDCYUNBCG2zALjbgt6soXpoAsephhAsFBEAyM44g4atwqM7S74xiIizcga4isE9M7SDoExmDe0bJ1SkkhMC42cOM4y26XSshHCYVgZrAykYaaPl47BhnA6XOf5GuD3HDA3CNcwMfoKqf/r4oQYnpxSEigJhpKqdRqlIGefqtRt6+533dOutd3Xl+g2lAhxJBQyPMB2SIiJDDXM7GJLFGU5EKDFeKXTR0zBvg3EiQhGhNMX6ny0Sk1pmRIRe90ArDeYYJvMCjVFjuGxkSV1wvJpz7l3Wa3LDiqS1tZ7aaS4NjpXYD+eoQ48vA93EeaByi63ABpQ1gQUmAgTyPeiIF3Gy8ut+XZYT+dPwNRC88jasNDcRsWzHxQvGPeGIaENUZ9kRIRN7m9W5sbWj8WikBVtAVdUIK/NGVbtP4yTm2CCM0FVaNaCXn4hlww0L7phTwOnJkbx6U1Fkg/DZ0ycac0LxOA4P9tU/PYEXjS5dvqIeK3zv6jW1OBa61YI6KRVKEDBi2a7zIyK3GfEiz/nfBmCTJfvNVTzRJYSmuD6tQYYIT9v7FasmFYUWELoxEtMgyuqQIhKC0pZmYy36Bzp58lBgKvTiKaJRl9VvAfAxsZ2kgLjiiQjaXRDze76W0yuGr0LnvR5o6nm/Ect2FwhCc9bXqmbDHMx4pxNEnyIoqSjQEGyPCIS3Q2sRb4feGiYcKY1riAgHr8DZ+CiqWbk9aDZjSxlyLHX9BQLiPr09fPbpR7KA3br9jrZ391TjNPIY3GCJPRNBI078iRARioiXWklj1Zrr5cyXMM4lPCUzeY4wjNkqGhg9a5KaogVUGpM/zxODeRDUrZYQcX1jA0/lQmkyUEszWmyA5Wsc750WBrZseXwmjpm0xBB5xlqGEcu4ibck0jKt/DhuyInnHxuCEaE4y2lgfoMQLOYLBLXOuQUCOCVtCbblfXpyTD4CwzxSUSixf83QBrYXpuznog0z55QVPJ16TqBf8FI9C7MNQgtCH9/LwbNnsj21ubkleytP6OvZs8cyra5dv6V33/u+1je2FBH0675L4gWgv9jDzcKra/TlvswyaKAatV2w2p02xpzIaI7BCIyi0rAp1GfbaBTQaA7mAtMKTCZTY+jUrUrdTq0520QnLYwlP95u+rQxXSzZFBGKoA1TEISGkJcY1gCRiMjxZeC4IWe99rNAeo0/ZXV7C7NzZYIh6PicVW6hq5GEMSeLJrfyYr9v49Y1860JEo3MEaAZ26DbbKMNGZVOMZrdTq569vG4+xiCg8EJqn8oO4UO8NEEdOytb2gdt/AaFnyNt3KOIHkWe1eusiVc1RrlJYZ3ShaClOkRYQzDWQd/5iB90/bKaGRY4ZtgY7YHawZvF3O0AbpBTRRZiqd4sxYgRwTpxPFnLfvKD54+UoFmaGNIyo0o8nZjgVigTQwRSQE4viTwCwKYwMpPKMKQE3ziDAheebnlNb9kws6xiSaTkeZZPfc18IpmhRdJQl5ymyUnoxbGcLvTkWGK0LjfAed6gwXHK9zDb7dbcs8WLuMsu27yXn+Ik+gBN4ZH3Ffc//KORmwHW5s70KIrC1RE0sGzp/Lpoddb186lyxwRt9jvK6UsBKGIJSzb/ct9mf6bGzeCJ2yGzxTs8eKr/Dht3uIf6AAAEABJREFUAShIeX9fY6UPWVVzUSsxAVYwL5ohUIW1Whwr7Qa1MNRcarXOWyhM2IRcMl6KeKEVUko5rXPPwlw7l74oOgdnOJkL+RKtQdzQApXuLcHHQTPT/S1AMG5JnxGRGVGxIgu2hKKsEYYueTVG40xFSjm0ME0RoKXQtJcynQcRefX3MQrdj93ENjgtUImjqJmejUOEy8KzjlOuhWbpYTvscWLrYGBHKnJLpl2O/At80qoPd2pi9PGyLSDggozxdCGrS+MQFTQVdBI8VpBpIMivbyM5hamcjylbqEmtM+I0WnXS7rTlG7LHjx9pNhliJEquZwFwIxEhx5cwJz5XUYTIptjiyKqFaS4n45U3XkobZ8Y8IkJtBlZk2i6yMIiRNbRj7dAgGBEpz7Mql20UIJvBpoHLe+zXbTyLZVWzqvt4/YZ4/6bqs7cn6pYIx727X+qQC6Mn3A6O0Bx0q6pVq8bgW7CdXLq8VPl24UcE8yo5dg91HSfczqU9FQjextY2C6ZUxHIc+hd80qovdkU9PBzr44dDffhwoE8fDfV7bgjti7/HFe7vvjzVI8qN72EWfEy3OubYDwsG7xKpZesWHVAWidWn7GfgGEBhkyEVBZdWVIYRGYEwwRgT3Y0kiNoghHMMN4cWygZmjbh/z8Yaq7ChnMbOvUELot0mu5MnaKURkjubNyqQ2nApdRJtG6SQw6DMq7IJRsDWVpIWT4BXcF6fcKwzU1tY+2t4/qq6pVOY7GPgk4cP9OD+lwjEWI8s2DiY7tz5Qp9/9qn+4R9/pd/94QP9+re/10effK7fv/8RQi1Nx0NU/7YeP3qIhqm0e+kKF1ljXb56Q1fwG1QIgxibeCJCEUHsX+Z9LgjuroAQU4hoQp+iGVpVoY1OKa+sAs7X1RJ9NT4Ps7L3cDqA1ws3AclDM4wf0LXAOLt/93ORSVmoKlvyXliWSUcnJ4L+mVGNgv8EhIw8xxhrWEUix+CVu8/FyxCPnMsjjKdzT2Qh6I/nGk3nyFejqkiy57BkIF6RE2yWBmZLCUu9pTnC1QBFUWSmwPtz7UnJg2uafBNo9zJR5jWh3QKmNuA2MHVLMwR2MBjqEcydIKTH3EPMzwzQIzTEFFvEW+Kgf6J72AtdBOrqtevUl1r4B3psBfYXrLM10Cv5AfzLv0vO0q+79695fnp7Xe9d6epHN3r67tWOrmzWurHd0veudrXbq3SeByYH+g9V2dcMD5zgeERAxJBXYUN6nwsPM0E8Iwh1hDrd2NyEWUlTLMROEVovJV/HIk2KiExw76MJZlSskimePcGpKYJVYciZ0BH0YO4oaJmXwZjpHYS3haAhB3kcCTwz2zDFSLRQuEaFmnfbBe0VRWjBNkIrz99IoZK+PQ7fCp6y51s7TPAbmMFdjLs1rPtHjx7pGcfBG9ev662bN/Szn/1UVy5t68rutt69fUO3rl/Wz8nzMN/9zveyhvSPSq7fuLVcFIyjywkiFYX8RIQiwtF/UUjurYGgJ6O5/vHTYx0NpuqPF8Bc48lCx4OZjofz/DOvEWmrXdfJY2W846bSIlV5go/wkZPFLdg0rxofma5cvZpdpmaeBeIqHrNrnJW7mztKcMtKxj6EMhq5bkqFpghM7gNmOEwIgT1tAsN1nFZ+mvz1x1uLoWBGHptBCOISQlbrFUQvMNhmaBwGyB3CVC0M2ATyK3KgiKQCXPfg8oKtYowgeovybev2zi7znNPGWFvs7VtbaAdOJEgUeQOtb25kgb791ndUpAAKrcHwzY1Nbe3sqEDIfNHUW19XYn6h5X/6r/RANkjFbA9PYR6D+HJ/rP/00aF+9fmJ/hH4u4+O9E+fHes3X57on++c6NHRBKwXb2Miclk1ZY/c5yLFzJ+MJ5qT7nM0Y9HLP/wccKv2JQZVVdcqOTvXrZYqCER1LSFoNNhzRzrmEsaW9gSBaFDfdd1RibB5W2Go4AcaaCqv1inWt41cb181mkDYJzRkPjt4Dg3CboLv4908PjjQnK2nqmu1GIfkvvXSY9zu2rpu3HpHO7uXc39wDD4vNB6N2e/HGnEjuQ3Db9y4lrXHJgJxyI3ie9//iU5P+nrrvR9obb0H3lAb25eU0FZdDM+q1VFRFDRnKBWRpEwE/Vd7GIHyGG7stvVXXMn+6GZP/7cf7ejffHdL/+o7m/pffryj//H72/pX724CG7q21cpENkO0esq2vBjWt3cJF/KPKKbTke4/fKwRQrF35Yr8W7vbN6+rqpg49QpWq/kWsWSCGUU2R7O52pzfZ+y9FiYz2gNMRdKE/dbnf9sdXpnWHHNWtwVhDqNLhGAKjtV8hNtdQkqJJkILhMp7uPfpKSpe5CdWekZ1569ARGQGFzCwheaoq5b8C6AxW9WYbcYnoBHhA/b+AVvHbD7VzdvvqsaovHnrti5fvZ6FZmdvLzO+wQtbFuVyy0rQgfZf6fK/WjJBP1gSGRZNqEhJ9rJVRYJOSwjyFgEjmMhoEWKn4LiFFTwXK0vLumvb2mHiNavMrtNjDKXbt9+SDaODo2Md4jgxMaUQiiDX8dF0JQDicTzcF8bW+vo6NsREUwzPhpPFAqiqSk8fcz1bFFlgTEdvN30MsXZJHpOxIMxwBbstmkRoX4gsxbrKTd4EbdUwgsSc3HbfhrGlkgquZyCqiFBKhVocAcuqpRbCcImr3II8/3B0iJbrdNaUsDMe3LunTz/8g45xHjXNTGtcGVuQvYW02mu5rQ4CrvxE/kqrUP/VnywIHBRYLcuxLKDbFMBkyAw300ccCM6nMc7xBiII5Fv1u/4UIZlGS8EKs5NkytHtmJNBCYM2uWv4znfeUwHBxOSLFMpne0ITfQXiKalfACZimQrN2JfnrDQze46AlLRRpJTVrU8nQ4RgzjFvwgpfUJ5g3gIt0XDv73YtpjQLQ5MqBGlOmbVKzkdD+PjIQSOPRxc8bmPCFjVlHJ21ripW+5gbSW9TJePMfTGnDqeB4+NDfYQw9Pt9toYjKVhIBXoKIZ4zNrcVEYpYgv4behL8ysPxajFDsRNlppv5FggzmiN5ZjzykXHhfxYch6sybw2n81IjVShoocbneuv2LfBDJQyo2BcTDDThyVTyhwYndDDJgwjnqCgqeRVZEBYM6t69Oxpwdu9zWdPAOJ/BbXNMYP7D+6zCjz/WhM6tlieo6QZJbqjHizZYaHGWduNztpseBpvj7XaHbWsk56UUz5kTES6mLjrDjZCyJjg4wG761a/VH00lxtjHTjg6OtIzjrW+TXx2eKxTCHc6nOrpk6f4GO7LjrMnT57o7t27esTx0uOiuf8m37RiNvzIzDZPoN3zwQYxM+18SJaM4zrGtwBNYKqF4mia0CRJBZogq16Yt42V7JUzPVtZXo1mvn88+pu7p/r1nVOdop7d7goqvHI+rnn1PuGIVjAAr6o2+Q1t9rnoacjz+Mu6VrsMmelTtoWZDUhW/gKDcAmL54xtFLLV3sDwza0t9vM6d9nA9BXkDD7ub4zAub0p2wlZOjw80r0Hj3V4dKLPPv8Cx9H7OkHzPWaMtj8KNNade/f1H//2b7lDONLf/M1/1L/7d/9OH3zwQR6D2/hvERInQpmBZqpXOPSRiZ4YrX9eVRExQGdBw7zaM/MbycLgOpgKcp6ZMsKGOElrKtY2JfZyryYTOBVJ/mWwbQjxJFpabxfqASMkaWT/Nfs2RYoIGNRSSkllwd6/mEmUHTxldd35TFHUst0xpa93v/MdrXGr6T4KcM24CYKwQB07z+FzYSDP7VgLFKlQAdO8XdA07a9eJkbUdRvUeVB46FMG8XfffUc/+fGP9NOf/FB7O1u6fGlXN69d1u72lt55+7a+9967un3rpi7v7erf/tt/q1u3b+udd97RD3/4Q/n3gxG68HFfHqe1pW0cC6DzDBdW+Atk5q3BQmBGmgQG9+NBO25mm8HGcdxlhlWZ81hMWShWAjFD8S86O1xLM/NUaobqLstadQ1zYZYnLQyqFhKGVpat/hlq2/kGG4hjPIELVn6311NZ1bTf4Jn7Qo+tiulwfWtXxXyiObbB8cE+ezKeSgY9RwhsO0zRPt5eyFKDAJioc2yNhgGHIt95tNsdRUqiOU8pg+MN+N56+ngyM2PQLLW3N7Tc5tam1rprWsMmqKtCdVXKF0uyTYLAdrlP2eb0tLXJQpCyMPzwRz+Sjd8JYx1hX/S5hRwSDgiddh+nbH39/kBOe+4OZ2ghj9tguhho8i/yJgvACqARBPeaUQ6dvxIAM/7VEWRtQIHxHGfxZBSnp2T0ZyHbHKZ0gWFVlBVCweo2tcGcQ/ASSdhoF2pBVPE0JijlJbg2yojmH10WGF0TiLcoOtrgRNFBRbW4Au5iwNl+GKPCR1jxJlYJc6YYdzNWsZkO3xnCnNaZF0w18ytOAVKSjdqIXJQ/EcHcFxriI+ifHmsIs7pcOF2+vKf13hou5342Okv6cH82jP03CceH+0qR6GehS1wiTTjGThDG4+MTbJyBTmB0Zj5jNNOHDm1UnvZz+RjBrxA2C5jDMXVH5BnPPhiXO+755YH+mT9p1R78hADKYEY6bViVvyk0noXIOI6vwHmGSAUEcm7Iq20BM0oEoypC/qOTW/gw2nWBkMy1oEKB1qg5qnnydvyUaAT/WVdD2c7l62q10C746Xf3roI/V03a7dkNXKF1amCOEFgjeFWpaeT0AsHzKCqELNAEFoIx25L79thXEBFKwAJN9gwH1HjEXQrpgNFFMskaedta39iQx7XO6i/ReD3uC/z7AmapHsLTwln1zttv6Sp+lGt4WLexSXa2t3Xl8mU5vLS7q3UcTj5W7uFr6HY7ud0KgbBGcb4FaoxhKh4Ltu0RawiSf9bXs/qzNWgBglemewY3PFkkzVIJwxZMEhLBjDGr12VmhO2Dx8cT+c/QRqhOM8wTnWPsWWWWaIJQgN5goB1oE8KVWO27u3tax13b6XRVQriGds30GuKnSGqTb4GyIFkA3J7bNQMDZk7ZiiZAty7UKpdkiHA/yk8qGDfbzPDsxOJwgIE6IH2KcTgajtRDEPwDXavxDj6C8WiYf+hih5odaPtcSbvP58TILb/4JMZhYTG8yH0RK4tCFoidnW25fR/DPZcBWuoF1p8ntqTAn6etvDNYEDLQ5qIJ+TQxWBQcSZtslJoxAaMo1qKRihTcbkpPTye5PII6qEQ7hfwDTjNtwrFwyOR9W1fXtaYwaMD+nYqkGs1QVS01aBmvpAWaIBWFSjSOBSHYW+bkiTDoSwqcYYvcZ82eHxJFDOQsNK7BzD06PpTVe5vVPWZM7neMEHtLoJZSKlWwRfgK2duHf6a+xvH0cP+p7uNtPNh/wlhntO9tyX0Y6OhPeLfQKtYSU7aeP6GZr1T9swrCqvUFEWuHpX0RmiMQAy6nhnMfK0uZoRGBBzOUCNsYjZai0XQB4X22n0G8hmvezbwfT814VmOv15OfE+4ivNIsLFVZw5CkQwzGBd1a3+UAABAASURBVCu8g6cvIhQR5Be5HQsHGZJSFgALYAstUBdBdpC/fN1mg4G6QKgG7N8nXClXda1NLsh66xvqofotiAtwysr9hqZosSt4VP1j0wZha2GAHnPE7HPLOsYOGPSPtTx6/ulC4FFGRDZUvUUs0ILO+3NA+nM0clEbc+bt04bDGYIwU6EZjEioeuN7EimU1XIFQ/z3h8NpyJZzoDIrCF2wsrtr6zLuKRdYE1alolCFDVBjQxj3408+yef4UxhHlzqGAcc4evb3D7Ij5+DwUDZK5+z3Lm8UaiMEhTv3QC6AqQ01NNCE1W/ByuPo9rS+tY0Qd4GOIhKGZB8P50DWIG0EsLexpTYnilO8nX3GO2AbGQ372R2+7CaWwZ/49dZkB5WNTgvfn9hcrv4XE4SG5rHDNCPC6wWviFBKRV6lqwm0sP7XOTVURdKz/lxPD04h3AJN4BW3xLWqHUPUYzTBxua2tnd3lCJx1Brqt/4r7fc/0Bd3H+jjTz/Ljpv//Pd/r3/61T/p97//vT4h7y4OnjGXX0HfhQXgFX44aafRkD6sfaz+HRfPlWvXsyB6vEGfLU4qdkiNOFUMsPg9DhOxjY1g4Tx49kwNKzUxV9dpc08REUJZAKYEjf4J7xFC/uWXX+YF4wUy9uL4lu15XAZXc2jwHJz+i4C1gcFESFA7/0URRLIKd4cegMFbQ6cudMIlRtYaRgbBK7LEELStsMbee4KqbrUqFezNpxDEfz18+QoW+M6u9rDEF3RkUpshLYzGLRw9vV5PifZSgVBFkeMMhdZfvGNWvn98YmMvIhDEOat8qqvXb2IQLv0BQpQbtgzbDhOI32erEg11e2u5oTnG7Ryv5p3PP0Zw5rnerbfeUQtBMF5G+hM/c2wdu609n5s3b+IL6bIYRpy2Zn9Uy6b9qmJaRf4SoZnCti3vyQlCJvbWKUaOVe8CorrPhjxkQG/t1PrB1a72tnqKCGyFMROccm4/yXu02/LN4QJim3Eff/YJx8aubt64gdfu+/rZT3+mH/7gB7qGYNjDZw/gd9/7juzpu8rRreSuo0xJhgiYjUDq3BNZWFLuu0BovNfffoeLslSwkrF6YLpPJdYUhgWMj0iWD/nM/+lHH2iBA6hk27HGuHrjpq7euC3RVwSVJaLLUH/E0yDkH3zwvqwNbuOx9HGzYpHUCLzthfNNLpjbxHTm5nYOA/ICob5x3I5Dg8v6nH4MzMRZfzmY07QFoYAG/sOWAkI10SDJY0r8NipSI//DFZfWa+3tbstC0ngyo5GkUMDAMc6k66zQgPhV1cJg6qqua9mTt9Zbx5Bb18bGujr4FCx0NURqQ6S6rqRUqapqVfQdAe/OEcWrLKWkEttljh1hJk9wRl3iurnCFlkgsPMzprtuh2Npt9uT26MlLRBka4gDrtm7az3ZcHzvez/UZrYn2jJOQduuS+KPfv0PXrSYzzvvvM08N1QgrBEhz9H5h1z1nw5GGk1mOu0PsZv6hH22zLv69PM7evj4qe49fKwv7z/Slw8e6c79h/l3oyXtVGWh9EeP7BtW9Eq2ncCBAGPRq6tRg2SYUUsCh2bsH/BdzAvmtmSC1ky6wiDsYHxNMd6KqpA9c4vZWGVZ6tatt7SGA8Y/9fJQBhhn9778InvpTKQpzAwYXMAEpUJFSkruwMjAHDVrnBHOoqc4jSbgDzmSPrp/V0UU2tq5rAIiRSTNWemnJ0cyw6mq6XSMwVqpzQnBc/EpZn1jA6N0pkt7V7ULTFiNC+blFRgRrvZHw4z+67qGNrVuoGk8phEEHXA/M8QinzSlUlFphhawC36B8NoL2sPremXvkq5evqTtrQ3t4B6/tLOlS9tb2sM3sZ7d5BVu8krpjx7dt6i4ANeuZv/h7FwFBE5AoQXMsBqzsFQYjVWRFBGqqpZSKnCirKmA6R/+4TeZ+cafNonLq4E6rL6IUFnVtN5w13Ak31ZushJtuUcqZCZYaEoY6j4MIGvOCvfRc8424zo+kQw4JZiQNQK4hqPKdScWQPq3zWH74SkOItsIFZrCRus6eAf4DBi01rBFrGgCgfP2N8HumHLsbdU1xX+8IJg+X3zxhexe3uEWt2K+h4OpSlRsCw3XrhIXdxWLoqX1XldXLu0QriE0FXR0flc9GG7N0cHQtQZdQV1X0Dny+JL+DA9jUorXN2QGzDlC+qZzlmq1O73MwBL1beZWNDCdN9nR41bMBMOcS6IvP/+MFXaZ9hP1OghQ0v2HT2SvnbA7rAlMrBlqvSwrBQOxkFQQjGJZoMhcTjYiC4ctfguCGPMcYbx58x3to9qfHh7r0dNDiFhrihOrzyllyiqrqtKoqhCoNbaFTmdNO3g2XeYtZYivoI9G2tjYgkHg0s8WAlkgRAbl2nSmb/eYBh9//FGes+2cDtuSWyihV8k8izNwukgJvEItBK9gnPqWTyqokIA/9XUbjC9P+XxbefpIgsMFpWOujuVeybOxYiYmCLdguzC4bmJSM5bXDJV44+YNedVNWcXf/eFPFdO+jp4+lOqeNrnla+FZNF5Bm2Os+QV7zIALHhOxgCBsRCrLQgV9uG0HDfu684yfipS3E/+u8vHjx+ytJ/kfpZqiDdzWeHgqq/6GsV+6epOj6546bFc+yx/uP0bW5rRfqWabGAxPVDGeCgGfMvaIRJeeOYFWoeNfDx6j//ErbwW9Xk9rZxrwaDhXty5faqCBVoaXMr9lwjxgMhfXQltDQH3tFFjMMjCel3ATczeU0KMgLh4zImEserU3MGS5YiSruMqI4Fg7UIStsK4aa3+d28a7aIbZbKIb2Aam73wy4Cw91J0vPtfp8SGOnI4qGP7w7l09fniPVhrlwdChu7ZANAzQV9SRCs3RIN4KTjCyFlyJb7LH//f/5t/o7bduyQJaw1jXt4dxc2tHOxxRy7LMxuEYtX/3y881o41jjrRtfAg9PI+tVleJCVdlLWsMC9vZIPRtH/s9Hj16pCdPHj83DjEJ1GErYErftrmvxU+va9TEc22Hr8Nx+QoguxYkDAT5zXWJFUDJycB/5+h/TWyBOp6w4lxeQlyKEbgQ8iI/o+kcFb7QnFX15NED/Pb3sIYnesKKNfHv37mT/4pqEYU2YMAEV+7Uxh4nC98Evv2d78pMbGB8iuQou8iCI+kIg3OgFsI1Y/8+PTnVx599kcsiVXnVeav42c9/ppJV7VXYW99SAWNHMH+IMZkKhAjttAD8u4kGDVS6HGdUC4HorOEJhRJVXSsinoO+xXPMlvT06RN5O7h+/Ybc/gSLe47WrFmd8UpbEZH7eSX7WyWTvX9m4qu1nOcyA/2/WvzmtCufYSRC/2us2+VCWxrkP5JdsPd75USyiBgjJN4xasV/aNOqCrWqUjX7/Car8We//GvdvnVbB6yOE1zIP/rJz+QVaUauIQjd3npW7zb+1tEeR7iVvfItBBjXmjGBlVAUKbH/jzVCeD78+BO9y3Hs0eNn6qLuJ2wtN65fk2BkUSSEsUHTdDWEyXNWv7cEhqkiFSoZn+2Kbndd43yKqOWxLji3V1VLYQEEaOxbvVNsEh8H93GR+27maNzIJ4QaTdCtkyLiG7Xn+X4jRJCMyzol9rrXfRpeV/6GfARXiboet30JA2yDwgQic3R2v16yulZNeFdYY6LruJvrYmnUzTkGdbo9QXn8/DtKSer1ehiKj2Xn0uY6qpg2/DcNFpCgbf81cp+jXtCw5TEiFOwzM5jloyIywaljqAka4fr1q/riizsq0UqHRwfqIFCRSh0fHWZB8RYwRROMxwPBAY04WRxxuWWP5gLB2OQ4RuPa6G3mY2NEZPshe1BDf9STmOT9Bw+yp/TW1UvaW2+p2yr0bZuL+OY1IkJJ3/JxhYI6Dgkufs+NwdGmCc0ajDKuoy3xE9R44nxvRlka3UiEMR1bwhzVm4oCho2Qg2LpqPnBT/Nq3r5yVQPOzz4OtTjKraO+L1+5poiC8mlmxoxtpWnEPr4Q8qGyrDSbN/r0009wtAwy4/xvRJ5yX9BCjfsvlYXA1LRn9/UJ6nnK9uV/9/geW5G3kocP7urh/S/Zoh7Ix7mqqjUBp8aat02xhiCZkR5H6I0U0kWPaXEyXujy9dvytnB+oVyE/+fMe/NoG7oyEKxe2wAG8y1XdrlhhXAWrrJWePAgG5QplarKWhG5dsaOeCEEJoZhzhl/gS3x7NFDvf/bX6vAENznHG9Cz2HyZSz4Vt1WgUCNR30MxiPUe1cleCUrvKpKjOBQUSSYNdKQ1fzhBx/o0qU9ff75Fzo5OUEzjPV//1/+Z7ahQutcNa/G1GO7WaCNur2e7D+Y48Q6wSC1EM8R0A38B++8913Z8XXt+i2tb2zko21iNevFVPRNH9PK+79/LVWjGn07+kc089ruTM8VvA7pBTdeh0G+kdDWz+eYB+7PG0brItfLwIdX5reZ1O6aYZVSKsgz5gqU0x60/QPem+2hG3LBYyHwvz0QUcg//tzdwYiD2eIZchPYPz3OjOn2NjRF7dv1WyAUbmOAkXd6fKD19R7+gmdq5yNeKWuMCapfqIw2p4Q5tssEbTVD7T/DHjk8eCbbEsPBUB73Jr6BNqu/Be6Cyst/4WRNNU6oAoGMSPJMGNK3ehfsV/YSupJPBQzH0X9RSG/szbMCzHPjEXXwHBi/8sxfKXDSTLfwPK/rTEmpSJmoyk+jiHgOOYtPg4q29T1lX3d8c3tbH73/O21sbuS6W1duZ+fOAot9Ae4cxjXEg7pCD0y4cp5Opjpl1X/++ac6PDjUGEPQ/2zwweGRLu/tcSKZAjP5NFCi4hOr2fcZJwjMI7YAr3y308LNvY4GOGWr6HAqKBDeE+JmfFlXWfgqazi59xXoGz8NAjXBIi+LpHZVvLae8QyvRXhDQUQoYglGu6idNwuCawENYNXuLYHo174Bhhumb9giYUhz/ibTrxuTMZyAbTByGVt+Pcg+DPSqDpaG23hw765u+F8gvXZdU4i2d+kyLTSs6CUkIwEHh/uZ4aPRUHO2Fd/UDXAuHeEr8FaQUtIvf/FzbjPX5XiD+m+zwjc2tlVgQ0QUOuLEURRJ2/gNbL3P2AosRDVHTrfp9KW9K7m8zRVzgSZYTunFnJYz+fqv69lnEhHZP+AaEaGIcDSD6ZEjf6bPRe3NYJD59WfqYtmMp7CCZQ6CQGSBSCD8YpaZCeJZZJVC5Nw7wbU7YCsI+T+pg0etx57dQ+WX7Q2MzpCPUQs0wIQtYMS2MIfp3kr6OHf8NwYppCIVunzZDPNpI7SxtaMC22EwOMkCZAHwKWGCz+LLu19iR4w16J8oopAvu4YcL+3ZG40m6vZ6WkcbmYhr6+vZ5V0iOCkViohzo//m0QXEmMGAGTRoXqnmflbgIscj4mv7Mp7BdS6C15V5DH92QXCDjBm2vzwU5i1rlTHHyFVJRMCUVcraoWFP7muxmGmBprBmKFKpS1wJ94djtTmm+WKlKNxLoyn7e//0SN5uEkylfdBRAAAQAElEQVSGpqj6af5byBqV7v+vwebmlt55+23518A+41ugumvr7OsdbIVOvt//7W9/q88/+0yfffapjtEgI4RjQH+Pn+7r8ZOn2UvYYvWvb25ra2tXjhdFBWM8jq9nkM6eTAMGOca5YeOQKFtcPNcGZ2gvBRGvb/88Y8/HX2rggkREvJTrlGei5xFJ5zGc7/SrEuu8N4Eb9ap8GSdYzdJ4LkUsW04pyaBzTyjk1W6YYLiVGHwmYNRdba615H+y16uxSAVHeEbGW9W1dncva8oKe3Z0KjNwMBwpwKmqlhq2AK/2KRpkyokjkV8iOD46rqNtrl29hru6z7Gyr/v3H+Q/Yo1I8li63Nx1cDa5TodtxPGIUCron1Df4PH4zfghAubQfo+IUIsTQlWkl1pYMTSC3oGXCs8lVnirrIglfkSssr4SRoQi4iv5B/0p8yF/xTSi8rCcznE+jn+l5hsy3I/rGFZoNAMD9bxt50eEPBmD04YIVger1T9Nc9pGnIlogfBd+oL9esGW4LKggxIBiJR0cnQkO4zWe2va7NnJVKqhrQIi53sNmF+jIdzeBKPR7YxwRx8cHKCBBmw/a/n/O3EVI3KLLeAt7huSZrp8aUvf++53M/ES/SjoOYM/UkRk0BueOePtT9BwLH/PpWDca60STWBKv6Hia4pW9Ir4+r5fbSIicpbbWIEzWngtE+PLKtuGIItLGfwBwwN3xrI6GV/zvg7PU2b+SgyEPnMrbtt958QrnzEq3yt4fXOLkkadjR2tdds4hFAnWgrQDOZOwGtoxIztcw0851Kq22nJP1G7evWKMdXudHATr6m3saUawWlz1GMYGnKruNbt6PDZIzQBnkMtVHDMubS7raf4Lg6ePtYm/oE17IOIUJ3rJaVUgFcwrq9/R2wB3n8jgnqhNTyERVqO34zQBU9EKCIuKFFeOOcL3IbhfN75+Ktlr6ZXuNtrtb7iYm4oXYGFw0DW179UYo4Z7/w0EjnQl8kJaGTXsweEva8F0rBqP2JZaw6DG1ZRgTVu8E/AWt0NlTAgFBA0ZYL47w1ddnp8qBI17xW/tX1JN7md3Nm9pAUCYq9fQT1fHhlnhhdQZ4/jpycHsgbosT1MKbt75wvsjrH8q+m6busKzqI8VuyV8rlxmBRhiLOWlsGE08wp+56dQkfDmY5Hsyz4RUpaqwtZAJaYX/+NeNG2+1/ViAhFxCqZ4xEXC9b5es8rnEUi4nndsyylVeR8GCQuLCD/da/rZOBDP8/RLBxOM1xxlcAWgcQ8Lw35v+dJBGPOfp4gXod9ecyJYMSt2+bGuhINeY8fjwYweS4z7tmzJ4oILpz6mnJZs40A7HK088qfYC8sFKqqUkHdyXiIRpmJBLgTlVWdme7+PLZTjMQ+F1pj8ILJ33rnO/IYPBb7EhICFUF1PibymP3+BGb3Yb6dQTMEr6AfXlXU995fI/WlM/TtHrd/vsaraZddlOf88xDBgM9luI7hXNbzKENexh3xynUKfqCHBBn1zZ+zPs+Cl+p5n+4WUodOFk3krcgI7i8x2IizWoT+6dg9VuYRlzv7z55qG59Bt1UbXRaGE46Iw2E/q+rNLdQ4KnyI+1iMtigKjoCn8umgRgBaqPOEZolw+4FQtCibYU9MszClImX8oyf39fDJfs6f45x6970fyr9CTkWBwFSq6mX/DX2MEACv+pSS6nIJFRMx09sw3gLQQQPYQ6g/4THDDBGhiHjeUsSL+CozIp7juI7BZefDVdz5FwGsUVYLKSRerZ4FkQb4pu/5uufruAODj45uz0JhQXM60SlzeI4+Y1Uv8Akc4hg6OTxQa20979MNqnmMkygVhez3f/rokU0XBIM0+Au2kjXUu5hBVdcK2i3LSiK9WDQwfSE7mThmKCJUsJVY0Po4rrponv7xvkb9I+3cfEe7l6/q5u23swCY2QYpRDXNacvxMiWV9NEqkywEZn5hBC2fiFhG/gLfxsSj3Yg/bx/mkZgTTQtzKQeS+zDomz+rcZnZq1q5CT4oAbGFkt1wfASQstwxOavXE+xzX2AjcY5AjFDRvgiycbfArzDE2XPK9XBR1nKe//WyCc4n1/M9Qatdq4Vh2OmsqYTRC3fqvpuZpuz/KRK2hdAkHdXcMK71NuS7gp3dPe3vP1OhuXavvgXcUI0mCYgQEXl4ZwEC1UCrUFmEnOe+DUaKcB6bzBmjnPenQMSyvVUb7sewSr8ujLN6ES/qR7yIv65elgGvTsPiPBdfV+OC/ESeAfoI7Uhq+cYygAEBmaXTeWgAuBtrhrPiHEx9xgeeoeqvXL+u3vomBlYhoQ0SEzm1kAz6Sim0IG/Q7+djo51Np5wYJtwv9HrYEmiN5SpWVvVCWxQIRlXXqgGXpaKQNUFRVfris0/kPxhx+p0bl7WB59C06E8WOuhj9A3nOKgafBRNFma6z+M9/zGDDM6LWM3aqW8Gq7rfDPtPw7JWO8GYPRnN8/xOsXOenp75EcwYw/kuvul0jGfiGCwITq9osWrTeY1C0FaJsJ0WGuJh9L+3FBGao94HMHoB07q9Lfbktqr1S2q1W5pNhnrG9XNVtTDeOrKN8NH7f+AW8YlsTBbYAEf4Efw/vShhrBk9o22azXu45+R/aaXBCJ3jh3DaN4tz0r/79T/qGXbIBqeNyxiZbWyRIkmeSxfLdrNb5j+8KchINNiukqwNdPZEhCLiLCWtGBrxIu954VnEOIazZA4iXo+fEfhExEt9kfWtXvd5MJhpjPHd4Rjr+a23C3lum52SOYdQiy+3mRkaL+ddlEpkGncVkmSw/i7hq02Exo10OC20aJL8D3GbOVb7/vWPmXXl2jUEAEHg+NYgGGO8i1O2iqquEIR1+WRwenLIwKUS4bCheIs9fWt7R+H/QrSNNsDoS8RTSirRBCVbig2L6Wyqk8FIH3/0IYhSd/e6DgcLrXMXQXWJT4LoGVKoOIsXxHkzs01UnXsiQhGRcyIi4zgRscxz/JvAq+2er/OmsvN4F8UXqHqfbGzAWpgLhpWYjOfkNKaOkisu/AEozxkITSYmWW98Pc8CDDdEADH8fQG5Qxo13iq3Ye9GFuQ6jEWz6YxV+URPnj5RbX/+xpZGqPl//j//ltV/qAXCcP/BI6z9hq0AAaBSiSFo5l67cVNvv/c9fed7P6D54OJocmbQSVVZPN9GCraCoF7DQD78w+/y/6G2z3Vza2NP/WcPpNGhnhwPGX+8DLT6bd6IeAndzDOcz4yI3IfzXi1z3kWwwluFF+FclOf/e83T04n2B1NWfpKZDhmWqE3DOAQsx5MdSo2Wj0MLRSyTr/+CaBwzukiisSXo3FOCwJxlQTmXLZHvOi0KzOREwgZb9uClpKePH+nDDz/SL3/xy+z3/1//1/+PPvQ/qolWuP/lF3r/v/wXFnbD1vBMNviKolRDm4tmzn3BiQ65cpYabBWMUtzIU+yOOU4q+wm++PgDzadj+edndkTF5ETjwSn2yIau7O1iA4QiQn4aCGWQQhGh1RMRL6VX+caNeKENVvkRsYp+JYx4uSzi5bTbNERE7jMiXmrDZb6WX2U6vWD1j/Fomvle0FudSrtrdRaCiHjeTkSsquUw4XfJkW/6cXWvZrZLWRBeac88yPC8XVc417i3g61KnOQaWfWfHB3q5ORIO9u76rY6eoZm+MEPf5Q1RIUv4Be//KV+/KMfsS10tHftqg4OnnHBdEm33noHB9Fcjx89UIpCY5h+iK0QxP1jVeiRTwsDnERzby84ovwD1Y2tLW3iuu6u9XR8fKT/x//z/6Uf/uTn2BNF/rVwRCgitHrORVdZF4YRL+qsECK+mrcq+7rQTDVOxIs2+pO5bNw9w7g7zAbfIv92057MxydTGZ5ygTSaLdSFQeustrII5uOW3gxZI7wZ5UVpEKXd3HAi7jTBS681AWNQVUgsqgxG8MQSK7XGUHScUokGUlHkv3H0L4VsvHU4AipKrf7H1j/8/neXq5WV/TFqfa3X1cH+gXZxNNV0YvcxIiVfIg0GQ7Wpz7rUcHCSL5Rm2ApffPG5Hj98gOCGIlLeQjrdrm6//a7WNjZVsNVUtNWuQsecEjxuKSkQqjxIfbNnOa8XuE4bVjnn485zegVOn4eIUERowWBs6c/ZIies9A7OKv/V+BYGnv+/1pudQv7nCfd6pa5s1Lq8XmuTsjbzeV3b5/tZxdMq8k3C+BokN8bYmcASkTGfxRuYIK2Vyt7FhEDYNrCTqEAQRv1TPXpwTw8f3tchN4JVd13+6bsnMp1M1eLmsFV3lGDiFJvi+q3baI7HaISFgrYm3CgWVVuXrt6ShXDKNuKfqY3J7+AwWuCHqBGQS1euM7BgS1lHo7ybwUfKhjYiQtZ0a5wWTscL+d7ATPAYqJTfV+NOG3Ihn9fFKcpvxMUUjAgJDNd/AdKAY9b9w7FGCDPyIJ9iSrZS44D+/I0IRUROu2wFOeOVz+vKkvGKZRuOvhYKShgDHUpGN+iVB9Phec7zcjId79JApzDJlygLfAH+2dcEtV1WtXzEKxGKy1eu5jN+0IvnVnEkrCg/PtrHHdzXlWvXtbWzKwtEu9PVFEEZIEhFStrZ2lBdV6rYUtbW1tBGc/kCqcWW00EQhB1Rt1ra4U7iyrWbaiMkc46uvryyRnG8YVzNpK85x9bT4UT+RzBm2BgLVqQF6xgXt0PnDfBreHuZoq1mnEaG3I2csBU1cM35nqnx9vf3iUIIfylzuYGkIsLBSzDFkTGG+RNgr1dlNV+kYCEg9tTX1zweq1EiIrfvvgzn8xw/D5BPColO+LzmDfJpk68yrgWnQIQYm1aPcbwtOM/lXl25LBohA/IPSmw3uCwiOC1wjMM+mENEsSLbMPXd735f69gKFZU9MDNmzmoOBGQ4HGrn0iVt4gl8gppfQ7UPuXMYsvcfYSA2qPGqLOkSYmEgmAHdtXW2jCHCMs7bzx4a4cq1G2wfa/gqKraOIfjShx99oidPnujp06fYKyf6Lxikd774TIPTI91/8JBLrUHeTu7du6vf/e634D7WIS5w/xtNf/M3fyP/y+0nuKv9f3n7h3/4B7nvv//7v89t+0/X/v2//z/Im+f0mz4RpqKp0cCPQOWX2C4QmkpnRcS++q6YvCpJEC9i2dYq702h6yczzkhfV20pz5IZ6ToeXo5T2fEylFVrziNONm+T8RFqYbfk8ggYhVTb928DL1LKVnyHFbx75YairNWpEB0EoI/HcIQAcHbU+jqrvd1hUU+VUiAUl+Wfuc8QpBJBaXfaiBNEpG3rnVa7nft3P9Y8Q04HPnZWaJcIDzBk7dDmyOq61iDLsqQtDMqN9Z6qIqmFdpnjiDKx2rS5s7OjFlqlROjqutbm5kbWQCkV5LeJV/Lj9hz6D1lv3LiRBczpiFDEC3DeChh6Pv4mhex5BQ2tZsqHRJ5e80S4fFkYEYqIZeLsGxFfyTsreh4kcDIB0UbPM89HEokVcx0Pp4FExFCQ8OJ7nQAAEABJREFUyQKGyY1gsdwexc9f7K8sDKAxqWV2RKiFv78sq/yTc+/x1hbDSSMzfTGbcBQ8heEFK7krIjrG81ikpP7JqS5dvpJXs3+TcILlv7t3mXuSlPtpUO1WjQ1UtaAVMEiKvKq9Up1PkfxUVYsgdO3KHu0N5P9p1zou5tu33yK+h0Bsa31jg2OlYHBJ3iX5L5A2MDAtmN///vf1y1/+tTbAMeM3N7f0V3/1VyoRkp/+9Ge0Lb377rvk/bUsNDnjNR+PawoRRj7zgZOgkfPmbF0kFREOMjg/R/g4biD6R78RoSQeNCnfr77uOvEBTwSZ0BaKnHYGVRy4EYPzyXrp9ZZgbeFMt7WAC4aClVazspy/1uspVR3V5NnYy/stV8t2IZdVlQ3DO598pKvXb+UVU+A7uPflZ7IQ+BhZtWqOo9KcvXyKzeHQQjBiz56yd5dloYI6Hl+K5C6zUKbkeKOiqFQVScEAE+Hm5iYaaF1FUcjGZre3wV1JoVTW+Bw2ZY3gshZGbAfbo6BtM9/awncWEYFB2st9WGCM22Er0wWPmWhw0ZTVWDKGqkxOygLtuhGmcs7Kn4iX0znzT/wk+JI1wuvacZcGM9NM8hgZaxYM53vITisPzjkvWrI2wJ2tONeDJXyCVT8HTMiiLHXM+X8KE8302sTFiFs1N4GxTx891N7Va6rqFsyeqIDwRVnQaqhqdTUcTSRuGY+PD9U/PcUmmOQVnlKhDVZporGySIrwSJocmsgrBth4nOWVx/gbmjJRzqZRplABjDm6jVmx/sHLmHP6/NzqMfoMJp5ykTOazrOwgpIvqozmshkRhxMKjOO0+6e7jO98t0lX8uOylJIMq7TDVyEi8nyc7zoGx78tJMb/2jpBCf3gpZOyEJBRAB6soUhioA0DacBsWAFLgJTUacRxlnpBGTlQq0Ft+49Nx9z9TxEEC0EnMz3kVVvXFW0t8ddYhR2cPkM0Q5ESDN2m/UX+v6s3tOVj5u133uMSZaGiqNTMYT6nB28z1gYz2g8G2MO2aHE1PcWWWDE/YtmH2/HgLHw1QtZwMnD6PESEWmXSertUj/NwycRHCIVXL8PQKbd3FgwzdgSTnb9iKNTITTl0j9aExlvhOD5mK3Da8bpMqgDxJOYc4VokeD1WA9ELX5et5ue4kRwaHH8TTBHw1zqUPATmLDPeY3O4aiwRcZnXl/FIyqGBY7i6IKyXjexFdF4uJ2KVfcqebovb+7XBxlzNiWHXRlhVKCIytDEMSxiccTAY5zDplKPZJke/I46SPgFYWPx7xk7LgjBXWdVKRcLL2JdPFIm27HCq0TLKhGVgHgy6JOX0si8Ty2n3FREZ4/wnIhiTgFCZDMqr/dgaAEY2kszEnbVKvVapIuOELECOV0WSoS6TOqyoNSznKhM0Mn1dZkdRC7UbWj4Rkftbpi76utcVLMs9D4NTq9DxV2GAh/IB/oknJxP1x3MNEez0KtIq7QKP1SF0E5rtOSxxmrzqE4VBRgEwR/XwFfTOhIB5sYo9WHFcnGnIudvMnE0mWXX7J2XBstrc2lYFs6aoJ5K5jieSigJj8pgedEaURteu36TuUO99/8fZJVzEgu3gWF4N4uljVE5Y/YltoaC+V2FZltriWNpiP4+I3D6otOkvwBBtl8yxJ0iR7xk59lWIiMz0EmbTEke8IvvxScpAcRaEV2t6Pgbnu/UEYpm0bAtCO+05GIyzwj0fj3BN51jDOmTgCkW8ABKascIXaN8GykFSnaC1Drl4MuM/ezrUx48GenQ00SHX0nMYa6FkKG7wZXBmwYfxSSEMJQl8mlUG8eT9Hxw7ito5bGQBsEZI1AHlOcE9uaODp/oCg8/7eETAvBOdsqcfHR2oZiXbULQQDCYznDhTmTEzGFpWldYx3qqq1BjNUKPC17HaE8wtsQ9iMUED+Jw/zm1ORmOV2BBttEyn29Ocvd/4G5vbKstKEWeDY4Duj4A8yRrI43T6PJghhvN5JRNsQ4B1DCAT8UWL57EujkcE/cWFhR7rRWP4KrIFwLBsZzW+iJCZ+9HjoT5/OtJnT0bcqk70xbORPoL5v7/X12++7OsUz+nVrTp7KrswrF0mwcKvdmMBKMimXb5SSDofL3ESdVn5HZAsCGtoAGiivBUYWcsnYpnwSjtlpc44Fob4D7V8dLifbxrNHJ/567JQbRWymLPiB3ry6L6ePnmYhanbW88GYEN7C8709gIenw7UW2vLbc+wBw65jJrSfhaauq1UFOpiY3QQCJ9OajROYemWn/DnDBoFjDVOhdCdZX6jICIUEX80bsSyrhlpKBhzxDIvYhm68Yhl3DirpRjhPIMxyEWqvfqtVWdE9vszPeEiysbtFozy3cS1rZa+d7Wjty+15a2oW8PAZfUXguAmoYdc5NDgPIMFw6H7dogQqQbB+QQy/xy6zYjIzItYhg2Zc1ZlREC0lD103oun45G2sQuu4uqtYdwcBjsvoX8qhKKPPXCMtqjQBD5dtLEZbPj5ttH/rF4bR1ALPNsYxm0QIB/rzPiK42RC2Og6a4ECDZFSkfuPCGdniHB8CQXaoqzqnH/+ExHUi5xFlLktMjieM/+IjxlqeLVqYsyGV/NfTi/HIi3DBQIwYo/3Pm+tbaP25k5bZvrVzVpe7WutUpc3W1kA3rvc0aVepRZMq5NbWcgPUQeSmYq2w6hZxp0GNzM5QFlNvEAbWCPY87WaTIQxQDr3uiwiNJ9PcfMO1O/3tcc9QVVXevzgvhRJV2/c4ry9LrHhzBEWX0JNcBm7NTPdzN/a2VPFSu2tb+oubl8LTd3bVadda4EGaNgPLTAFjG61OypgZvY4YodYOMuypPWUtzYTCrrRnxThXl6EFfXexIQICzYjXTWgrz6es+GrJS/nRCz7Nu4CIzgi8ngiluHL2Ms+vZc7390Pp418JT3A6Jux+j1Pb1GGDqt8s1PKN5EWhs1umQ3ULlx3eVkk1WwFraoQQd6CxfNcENyYmb+CVdoh4wNVS/URwou3JErO5OMJEeTJOB7h8iavnAFuYh8Ldy7tqYShcxjnI+ON22/nSx8f64bg2F6ghkyY05NDlajJLkfLMiU1cPDOnTtalF11tq/IEh64oH3ZNGVb6OCs6XJMNP4YJ5KPjz561u2OEtqALvNZHYnwMDN4nIac4JPoR2Jyuvg5j8v0QLoYN+Kr+efrUjG/EaEFWsx+EoPODw4M1zEMYbZXvP9wlihezkbmUVUk1UAJVGQ4nWgzhVTwKYEK7prpNSva6Yig5eXrWCoKBGGuBsMSVGUGB+XUzRqAduU4WS8Pz0hNiBOHEEpFOMNYS2gsrkTPhxGRmdDBcNvnUmeAZtjY2tGN2++IEWAPDNEYQ4Skxg3bzt7Cw5OBhuNpFhRvIzMl9TD23n3ntkanFpKQ7YEnjx9mbeE/gpmgAe59ibCwwqxp/NvGlArGKFUQwsKAPDG6170vz+VVrAZiGZgORUvciGVIRn4jXqQt0M0ZPVzouMHxCAuBt5hGZVkorYjtwlegVRUyVEWC8XEmBKGKOiWMImCOodWz6mOVdkmEv6ucF6Ev8vafPdOQxZOc7cagVRYCV1nVW7jwHLisIT1TaLJgMk6QPv9GhCIoY8VO8QrWdYvVXXJ8nGiBHVAihde4hEkpaTQey3tcC4PO6t9gAk6GpyrYs8ezkP9nHm3sAf9zNwXttutSc7yQzx49gihJHZxFrjPkaNriUmgbzbO+uQWBa4YVgJSoVxbiXn+hE87+E9SpKIkIvt/0Na7BJIs8x1drmgkG53t+Dg0R4QBYEuw8ToHGKoqKshUOUd6IyH2kEOM3BGmdwTKuNzwRxomMERHUixw//xlyCmtzWTfAaQc7BEGXAD4VlqjLIS/j/touqHE/+V9Prc70xKs4EWFU2nCYlIpCZlLBPt3DU7gBg1qo+5pjn1X4bDrWDNtgxJEvIsn/zP7+s6f48/HTY1sMj56K7Y4VkTg1DGXirvU29eTxAzTJidprXbXwDXQQpBG2ha+Yq6qGcEkRkWG1KKsiyftk10cbRun99ZCz9TFnbAsjWa99vQ/7OPbBw4HsCo6IC3EjXs6PeDmtFd0YlIVhztzdUMSreM69GCLibF6NrC0HMNPX56e41t1mRFxc8YLcg8NDee7b2ztKZVIWBDT+BajLLFC0VkhbZaPtutEmgA1CvcgIHoAjDlcwmYxgCCuazv7h7/6DhqxY+xBuv/VOZmjN6k0pqUDkCXTE8c+XRFdxGO1eupJ/PJIJh0ouPUiFzORPPvq9JqOhFAlDcyMTo4T5raqtFpqDAglcj0NnzyqeIvKY6yKynbGB27iDKhxMFrJgHA9n8m//9/tT+XeABu/PDu8djHWEA+YZx7Ihm/WqTY/xRVyKWNJEZ8+qLCIoWy4MF0U4nYgG8O1et+n/qdmAley4L8ncwiF3NmbuN4WN9XUVRaWUCiXooDyUV5e3Wz4DnxSKJIgoEbCFhAr5ebmSV79zHZZoAa/2sq60QJV//ulHWrBJl2WRHUkD7gVEzz7rN6wM7/dDVvUcLeFjpD2Em7uXVHH+P9o/0IO7n+v+3S+4FdxUb2MzbwltjEG3N8Ng7DGplJIiQn4iXg6dZ6JFLPOdTilUFggUFnWnStwnFPJvALeQ8nUcIz20h9FLBOftvY56nVJf4KixdrDguI0lmA6GZerVr/s1OD8ioMMC86iBAS/G67IVGNewSl8UXrlyBVqsq4tGrDDCuxjM/vcczsMWjjjD+bzzcV+772xvZ5olxiW9oI1efVy0AGEwl4aojRmwAMlETCkRe/HaBlhgrLlOVbVUFJUKQuc1rGz/y+pDDJM5al8IRURgO4y1+hdNx0i4UqEa5i8oL4pSY/wN+/tPdbC/r1arpZtolBYCYIOwgwFaoQksdNdvvS0/DWrX4UUQ4ZFJEctQPBEhzyMicr4JsoIiJbXQRj6O3dxu6Z2dUnu9QCASR7BA0fucE9QzHUIvHguFQZTFcxBPRKhgyzS43+V4jWtQfiKWdXLiNZ8gP8JfIVSLPAe3dxFERB7DRWXOoynq87VWYL7EvvoGWbQj21doTvjXoBUgAARfTgIEXsd9HJriFvZRcDg4ZYDzrMZPOClcv3krnwi8L1qFfXbnCz148EAff/SJHjx6orK1pstsC1JkI9KrvuF4tcHqN2O62AGbnBymrP4OdkZVdxTBimY1bO9eVoFxGRE5z2MxiGcVEv0T3ibX7bQqXe5K8/FQf/Phof633x3oKRc3C4T/5X6CuTd5LLkiH5cbiL70Om+B0EPOXMdpw0tIJJxnIPrK25Bucl0iF74RkfMvqj/htOX8ZAFIS7yMfP5jOS/4MC0ZpcSZdOrbQ/YiGypuwPgRLm1kJh3jOp43cx1zQzgeT+Sin/78F6weacnUgkEHlv88/z8a/+mf/4v2D491dNLX7//wvth+M1NTKjAKH2bh8TayubWlCmHoogJrTiJu130nVm1E5H6cfilg5fUAABAASURBVBN4vIY34by+rKGPkH8ruc6WcWur0Aau24dc3gx8lj6r6PYNERDuLM9BhMcYjj6HBQJkiHg5/znCWWSBoNioczICblhq5Doek3Nf7ss53xTqupZp+NoWXACNaa/J9sBSa4S2Njc0nUzzDz39P9sy88ccA5eStVDNCj14dqCIQgu2gNGwr/B/kXRwsK87X36pCfh7l3b09lu39dOf/Vxv3X5Lezub2tvd0px6ilLPuGdYQ/XbOXTtxm1t4mH06QCaIFTBuJavib6M+dv4o4hl+ctluejCz9fjnW+vUafd0s56Wzu9ihvQuR4fjxFgVuUrrb+uXecbIkJmgs4eM9vzM7jcYI/iKY4b2yTjWZM18hK9YUEtYxHxfM7LnK9+I96Mk+KVOk4vjcMmbwEtMtoFky8kXzDZuNrbu6Rer6fHj5/A2Lt69Phxvhk85IRQImFXr19XURY63H+GVT/n8uiBTrIWmWswGmmGdye03AI2Obp0OMv6H8rc4jp6jfij+3f05eefZvtgc3NLu5evaWvnEkRvdOfZJNc3gUyo1fDzIqFNp8/nO72CCHoFVunXha5veLl8WbfACG7VlSoMyCvrFT2G7jwd6wH3+9PZIleJiBx+3ScisiBELFf5gNOLmd6H8WPa8gWS/Sh2G3fx/3tMQ1RmRHBnM9WQY/eY29oJC9OLccQCs4FuPH3LJ28NVvmJdVbhJ2jBdF8rd4j7htFXyxaAFmmGm5uPCFlF37h+Tbdu3oAY0oS7/O7amsqylreNAefabq+noii1wd5u9b6Ls+fnP/sZGuCWelj5LYzCAZdLU04LLQSoRuVXENpn47ff+76ucBfR9b+ajtHZ0MunT0b6w/2+7u6P8t48w3DJq8hLKI9s+Yn4ZoxYYn+b77LdTGi0XTQz3d5toQVDv2dcXzwb5h95eEzGiVjiv9pDBJRsJAvzqsz4HdSuf7SyVqecbbfyeqtQyXKNCLWrJAvHmEumg6NjPXjCDe7+kZ4dHOrRkyd68PCx/LefU+yo3MC3+OQe6V9mtJnfS3NtlAug0VpacFRs0AwSC+B5sx70KjHFOFxfX8uXSgsYc3DwFJ/AU62t9cRBQTt7V/L5v80xZ46wnBwfys6flAo10xFHyX0VnP+3EJI2XsIE02995wfaunxdi6ggrLJH0KttvVPqxnZbRxxh7rMCj3EG7Z9OdWwr9mxAEZFjEcvw/FhzwTf4RIQi4jWYoQKrvyyTagi31yv105trusJN3wPsBR8vvWrF87q+kQFBKhZPIwvzFA05w14w41mPChjfrgq16YMoY5FMr4hQQYZ/O/nW7Vt668Y1Xd7b1e7Oti5x1N7b25PpZMF4Xd96zZNaGIAbxRymA8VCaT6B8U1GXzbW5IHkDD7OM0yRujFHuxmCgDGg5dn/RA3HSwXbAvZAib1gHFv5l/auYiDONDg9lpCQ+3c/0wHHwvVuB4kvtLV7TdHZ1F2K5yrVqkrVRcLxU6jXKtSuC13dqPXdqx19/1pXm5z1oZ8+fTrUE//pN46e2TnN4DEy3G/8fiv8RipSAV1CfLLH8rtXunrvclf+YcidZ2P2cr32oRZzlipWl7cAu737k0Z2fc+hjctfV9m02MARVpWFSupX0KiGVl221LVOS+1WqQm8MXhOhte1dT4/bVaNSoQhYelPZ/NctqzMbGUQk2pyLCK0sORyZzDlHmGMSp9y/Djl9rDbbePcaMvbgv9MbKHQ8cmJnjxBO/TWkeik/adPsqH4hHuCKSeKbfZ9/3ro+tWr2t27LP8fTU/ZJ/1/MbFAFUyyZAVERB5XC9VYl0kifZ37da9IX7cWpN9/MJB/iXOI21ivPMv5vJL5RyYbGLUAirJiTiWthBL9dxiXf/xxY7vGOzl9Ti+95okIlUVkIVpDyLuAQ/OhaaA3sKrq9Ovi5ocX5QjbyzitqkIYas1x0jn9OnCbhlV5SiHo6kElLfDqVVWtFQJjzXFQLA1ZCOwrmCFxCwSnQEVWdaU+guABeTBrrPAdjnpdtgLHxfPk8aN8yhjhGrYw+NLI24D//tA/U/evitbA3+xUuowBdsjq9p9+W8UuzhGEplQyYHsBWwiFV4YFYadXoTmS7jwbYT+MuVia5XHrz/A09G+iOjR4nguIbDqYPqsuzFSGpt1erR/f6NH/quTNYUTkLaZVJvggNSw0Q0Sm+msrexwnLLSDgwMdHx/n/5mJ06f9gUYssrnV5Wtrf7UgRQQDCEoCyRZxQ+j5pBmYeBasAv9jlEPuDLIgoD0cDnAWTdke/GMT1/FxL1jJEUk1QrW50dOD+/f0DM+gCeqfp9teuHT5itY3t7L9kIpClkirvcuo/y5bwZcYhL+925dtgH1U/+Kc2mc4iohcp10VuIVL+edXl9drBEV6dDzh7mAhPxGRcR1/E0TEa4s9rxVEJPCgD3RBRoj7XdZtY+R5Zdes9BEGnbeqVT1jvQqrsohQBG1aAbt94sZ1ucOIcJBXuS+Y9qHlEaewAZ7YCYuyKEuOtG1ZE0+mMxVoq4jIbUaEVo/bMzgdEbnccYNnRdiowYtX0uCCCUYsB2WpctqVF2wHE9SPHUanx4cy86komlMfy/8ER1Nd12Q1mnCc6fZ66nOfYAPx6NkTLWYTHeFs2uCI6F8Ud9bWEYJKBUIQQSuAhcGq38Lg1f7oaKxPnwz1JRc+3ns9Djp4/jptcMYawnNrp6X1TqmD05l+e68vG29mhssNxjU4fhG4zHC+LCKUUtIq3/EgLfJ5n+crP+FstdFWLHANOAbm7G/4cR8RbiO+UsNlU5huxntBOb3NPYENRN8fdNCoW5ubcnx9fUN27U84ghrvK41dkHEmCCGv+AUizjgymidcIlkpFUx2oZVAeBBHhwc6hfHOW6AphmiJnd09tblRdMfJhEK6H9y9kw3CGaeFqqpUVrVa3R6ngaQp6jUVhQqEL+PnXpUNKDrUWgx0e32iYjbQWtXoQ66AfVb3dnGG+jyICBUp1GFFbiIIW2sl+/RMH1HniBtDnT0RAaPiLPX1QcTLuBHLdPL8qO65EuQ3YlnmRERg7Cb6atTH5ol4UebyFUQEOHGWbLLAFdAkYpkXsQzdT0RkjeDfZVy6dEkWAt+9lGf4EZEXVpet2XyzEEw5mozQTHZGOS6FIkIXPQnew+S5phh/KRUgpjygiFAJkwweyBT1P2aPj4iMU1hIGMTJ0WFW8R18CMY75VRg7WFN4BPCDO1QIgQJ4nV7PXlLKKuWRsNR3i68n025neyzxdjGEJqpigWELHT7Uk9v73XV0Uiz0XFe4e/D3EOuiRcMPMJjiTyvRLwqUja+rm3V+v7VLkfNlqymM8IrH4/1lSzmFRlW+SuciGV+ROSixFwMC7ariHipTkbg4/F0Ki+iBkfYIhuPZL/xpSnKG9YBq+gNNSIu7pPKcr+ec6cuVJeR086zZvQJxQKxmpfOPUl0OIcRRSpV4PyJiFwc8SKMCHniqSjUxT9gZm7v7MpGjaVyD8+fOxtznOyi8heopC/vfKpUJLXQEleuXdMVTgZvv/Oe9jgdbGys004nE3AwGOoI58gYr5iF4QjDZzw80Uavqy3c2TtbG9pc7+r6utQrJqyKRv/n5yf6nC3jFD+Cty+98rTQy95efLavUdMXTfyVKm9MRkQe68tIL/Je136RQj4JBBVH03kWCJ/zLcRkvfIaC24g4G6PgHILhC7oW699GKoq5u8t1gujxfwNFXaLe7ATa4iWsBCfbyTN2fsXqPeqrs86NPp5FCmhKVrtjjqo9TZhF6/gHFvCPyRxukhJZVkqIUj+rWCQtnA9ffqM7aKjSzDf9be2LyF2Df0oGzdb7GnraIke2qTn0EB8g/YrtIjOnt4agnBlT/V8qJ16rM1uqQ8fDfWPX5zIGuIM7XlQwgDv04YZ4/QqWBU2zBVyM4ZYZX2j0AR2vRWy04l+VunXhcapWZkek+ugrbNA9HEVj1gwq3oNnPe/ArNgvMZzfkQwTse+Hlz/dVhBgfu3MBhQZPCBTN4GmDCOJIWKAhX2vEhfeVJK4JSytV8iMAv2d/sPTk5OdR+fgN2bBe7hQ24Rv/zii/z7ggp7wEfDp08eq2IrYP9hNc+UIikiMpQIT6vVUgdDp6Zdx9toEKc9JvFEhL9qc9Fz5fIl9erQZuprK461Xs60u1bp/BMRy7ZhUlWECtKeLHTWn+sx0WmWfpTBaYNe80SEVoyoi8h2UMX4XMcCMTNnqJvIM62l0PJxaFim/tQvw1BBH0WShtguth98r+GFkiJCEV+FVacRsYqCl1Sw6gsY2MaTNWM/77F67+PjfvToiT746CN99NEnerp/mI+MN27epk6TBWCKjTHEqCxZ6Skxkuetss7gkolyLitHI1Z9OwwEpq3trU3dvLyt79/a1XqB7TA+VX841oALmAePn3GlfYTMLbR6ihSaQ+gVSCFl0PMnwnnPkxdEGtpsxDDPlblOIh1y9QW0aLK2IeuCNyJYBEvclVC0iiQLxBhVPeZmMaVChojQm57m5YFk1IjX1zG+ISPycb+tKuXxtMqUTzmJfBVohIhgQl+FVQMODXO0gY+LH3/wvmZ4FYeDkXbxc1NZ17mE2uF6eZ3jy9Mnj9guajyNc7VY5XZ2zDg9ZII91z5eqx7BEtz+Mvbi6zyDcyJC3jI6aIdOq9Z8MtQEe8L/f8d79++rrgoYttBjtiSfqU2vEkEogAGq+ASbwrd5Xglu71VwP4av5jvn5bE6JyIQDudH7ld5Xk679GKIeEHjxLgqNESAumCwEQEZg9Ty9VhW4JyUEvScfQXHZd8GEv2aLu7bYUE6RbjjJbjTixo0A6d4HT1RNzJBAObcKRwen8r/76Qf/fAH8j8Rc+P6Fb1166Z6nVo7GJNjXNA/+e/+GkHoygbi6ckRLuYRzbg/y6BDvTQxfYMnIpSKQuvYFBXa6daNa7qJEG5jXBrabDd3HzzWx5/f1RHbVw2xe+1S/nOwXl1wdF3oeDSXV6J4XjdvivIbEReMMTLzX9QNcBPgkOAbvhHBCSlUMkYU12truZ82C+qY+UQs+3BegxYyfxw2CNNFDUREHn9EPC92dAXOfEkQnPFqYwuMF7dfcCvoMsfb7On+P6p95913YfAG+3ebiSTVZS17G/v9E12+ck2+di5S0oD0DE+kvYotbIlwRxnOxRhVxIt0LuYTEXkSRF96LQDbW1t5RZpAZn6iL8PGek+3rl1BGLd13B/p+LSP8C1UpFACbMl3uN+fMjdb0Dp7Ii7uy8URLnNsCRGxjPA1XVJKXxlnxAsc0F77JvC8Tx9wT2LHmX+T8DoPcQtN+OXdu5riXHKD7lsIg+MR36w/474KyVZqVtfcHeRGwXBoMFP9g5HD/Sfy6qZIPg34NwR1VXLVvOYsIPAunugZl0pe9fvP9lWxKhVJvpae4KN4+vghQrNJVvESwawSbbWO2SdtuAw5ZjmPRjWbN3LZDIat8pyBg+dJAAAAj0lEQVS/AgvA7s6O9vG3r/IiQmZKxfh2Nta0udah/FCHRyd5BYsnpZBVogUiSB+zZfgn64cwwlsIWRe8xlxmR4R8F+KTy128nt5y5oxxBvee2h3u1QKqaUjwtW9EqMuevc1paKNTyP4HnygsHGMs+lO2tYZWIkI+ae3gUXz85Ek+dkckpaJSxIvxgfqt3/8LAAD//7OUoUEAAAAGSURBVAMAlJNbkNJVDO8AAAAASUVORK5CYII=\"","export default \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIMAAABwCAYAAAA9m8PRAAAQAElEQVR4Aaz997NlSZLfiX094ogrn36ps6q6q8V0j+pR2MXMgFgAa1yQa0byj6PR+AvNyN9I2sJo+GG5i1nYCgBrA4xo3TXd1dWlslK/fPLqI2I/fu67mS+zMksAE+/4iTghPDzcPTw8Il6+DP/9g5S+DvzFw5Q28HXava7uv6Lv//FxSv/Tk8/D//I0pf/1WUp/Cfz1cUo/PU3p50ez9Jt7n6Z/82/+p/Tf/Df/7/QXf/H/Tx9++H76b//bf5n+xb/4/6T/2//9/5r+n/+v/0f61//6v09/8zf/Pv3Lf/kv0l/+5b9Nq9U8LZezNJtdpIvz4/Tw8Yfpw3s/Bn6S/t2///+l//nf/X/Thx//ND07fZAWi0k6PX2cfv2rn6Sf/PAv03vv/2X6+NGP02/u/2366MFP0nR20uFyfPP5JE0mZx1cXJylZ8AvTpv0wdF58jKvs4H58jzNFmfp04e/6HA8Pf8kTRen9DdN0+kptJ2np08+S6fHj9Ozo4fp9PRpmk5O09n0abr35L10/+kv07Pzz9LF7GmazI/T0/OP04cPfpjOJ0/So2cfpvuPfpmenHyUprMzcE3IP0u/fnKWfv5snn78bJl+elylnxD/+GiafvT4WfrJg0/TT+79Ov3k4/fSTz74m/STX/7bFPSGYCZFSjMgmuRxHqUN+Hcg/w3Nn2d7nddV87wMfN7P88okvK88qOvP63i6DFKzmmvy+L6ylPTHf/zH+uf//J/rH/35n+v27Tv6Z//sv9Q/+af/pf6r//1/pf/6//hf6x/9o/+dfvd3f486/wf90R/9sRJtQK26rjSbnatVrbwslaxRVuS6+9Y3dbB/S6P+DtVMbZNUL01NWmmxmmq5WKipqWu5gkU1Ta2qqtW2STFmyrJcvHTWUB6C6liqon6iXzNT4mfRTDStj5VCoyenH2m5nKqpKnABXrdtVJY91W0LDUlmgbJWy8VMW71DjQcH3TgmyxPNqhMtaG8KmszO9ODhhzo5O1FUn/y5JotjTRdH6umBtpt72q0/VT75pfrzX2s/faLe9H31V49UrI6U16caQP6gXypEOM4jaJanXcguAAdPdwqB0Dx2weoyeH0vLyi7WtdxXVbpIv/2ut3HlVciDa94v3gyKnsfm/oF39Apz89jVMxz5UUBrbaGEDsGIRNFGHn79m2Nx+MOoZl1sb/WQpHyvNBgsKVeHCnUmVLdasj3wfYdFXnfq6pBYapqBd4WwVSKWdR8NtXk/EyjwT4K0FVTnmfKKAsQXDGQR8tMC+t1hSlEzZSpaVrqJ7WpAZ+PWOr1RhqUOzo+OdLJ5DEKV1PWqkEJIkrV6/WpMwB6CiGgBHvKs54i+Mo4VD/bVhlGKvMhKiZNz6eUDHVt/y6KtlJlEy3qc62qqaaT8472FmXOUbhYNVrNK/XykYo4UBHoB15kVoK/VIgRJjkEibEpBgkaYLa6YLw74MW4RUTO+nHl8Tyv7+382xXkah2XicO6xctvF6LneH0XuNfrgExIkuNzvCm1WsLY/cN9bW9vycwUmZFm3lIwO3V1/cvMunIRzJiVCMrbJ+IAoa4QiY5DytQvtmHiWyqKQdemaRrNpjBzNsc60CdMrJm9q9VKhwd3VSAUEbxvou5pwXtemxrLOhyemZixbiVWxI4zIWiogsZcRURhWtPWaEe9YqgsFCh4qTwv4XtUZFwBaLBOBr1mwVHKFJTgQR564BjK2qB60Shjgrx151uyLGm+nCjVSc2yVWx72hlcU2YRxdnS3vatDg627mgf5d8e3dDezi1tjQ9VZH1F+gwmCZ51oFeCC8OF+7rY8yJ0dgASng6H4/I8/3Z08F3wwpNvBG+zAVcCV4w+uN3ieD/OcIPSHM0NXhFMAUYRMauSuh+E0tW7LPcyB1cCjzfgdfOiVK8/0PbWobZhRghZV5xQugQeCcarBW/D7G40HG5pe3TQ1cmydV3/aKg7QREmLA+tzLOeQ2NRJ3VUTb4pKlNPhQ3E9GXWVuqVYwXqNCwPIni/LYxqELjHCVrIhndgZkxez8sc6rpWxSwfY6mKog/KRslaFdlAmfW1NTzUaLirLJYsffsaDMbqD/rAQCUWdG3VMkX46ePpMRnKsi9Y7l1+MRi1jCrQJIfAh8MmHSnfKI2nN0ATuTIkT7wGOhzk01yedjZHcOcOZHqaYsUQmA0AeUaGmb9JbB6YWLW1XDgJATlsijw2e1HfzOSzqdfvK8Mse/kGYsxQkqGi5ay9M1lsEZ60s3WgGHMF6NCVsGykUwTugjd7uQ9n1FJRM2ZwCFFZKGVYI4cBS1NVL+WKOV2ewqN2rdQwqkU5nP6a5crjFgZW+Cc1Zt79kOVy0SnoeLDDrN6V8gqrtEIJCtXNSnVaKsSgiNIGaM57hXqAGZakXsnxv4CkGsXKWT5H/R0FH5v5C/DYwTM9xlIJRe0AHlNj/fi4HdZf67d/u0BdgM/BEa2LP/f2ug7ej7f1uPsm4crgeZtGZsasEgC3YOEm3wfiA6vapRrW5RgCRV6H6PKh6WXKIy8zRYRuFmVmHYhAkreLp1WDYiWcS4Og3e1rzLQDmSICE8FxJOokzRF0pUxmRv7Lj8mgNOqiidTjyygHqjTFWkwVC2m+OlejhS5w9parCUKuVK2Wqqqlzk6e0R/KSDPIQIiu7POuTQt9MUYpJBUliKjTrlrVq1rB4EGyTokjpjXH49/IrkWYdVOphVdVPe/6CSiOhQi1QaGb0bR3AdBWm2/qdOlAWQQ3/X3p4zxxcOIdvJ3Hrzb0Pjx/U9frOXi9jJeXEb309KLk9JmtiUmMsMUi+KhTwtF7nv+imdcRw3SgOswlRXMzk5npavByZ/J8dcYC0cgUNN7a1u7ONeWxlNmL+l533pjOETQF+qJQW6YZdVuZYghgNdVtpQTti8Uca8FSgoAqn9XNQmYJqzTRcj6T9+PdtqnWzHcRizNVzbxrX7ULLdoLgQCla5RipYLlL4uFAgoRYlQWM8raDkQwGFvh//jOqFouWa7mamwhi1JA4KE0acDHMJOGxJ4ughRNIF2DmSBSXyts2tCHaE7bpMCccIFGS+BvJTTUy5ObRpgDrfJyb0uD50+NY5d8NlwpcDO6+SyyUhmMbuGe2bq3FnyJb0dits7z9BcC9XzeTycTxTJpb++6ynIgke9WKNCHLoNZLWPrefn52sjM+0VpatO8EWiChuWegs9E/IzdwXWWv5EMfi+aC3F+oOPzR7r32fsajLdYxjJm70xPnn2q0/MnCA+XlKXGl7clM9uwTOJ0wFKUG4PS1/2Ui6HLup+A3SpJBRQryegoywrleU/j7V0NRgOZZQrkGxoRRrmUo3kZUGB2+ijERin6QdpASdoVxy0ISX1RMBMdvAz3HtzT0bMnbNGe4e1OVc0vVC/nbLGO9d7Hn+jp2RmES6bPhxgCa2+8ZKjJDICIqp1r2YKLWeKCZ3ntyjYYzGyTJF8d6JVgZuSvIcAQraLcVJfjTEVZUhZgblKMkbTR2oilItTq20RiiSLzjY+ZKVHqYOZtg3Z7N3R+dqzhcE+moDyUKMm2Wra6x6ePdHo216PHj/X+r9/Tw6OPtGpmKnolQszk/oYh/EIjhaavvEFp0lCFxgptiQKV1CtYclqZmVzxAvxzcN+g7PXIC4ohVy8fsVUds+TVcksTVquZDu1cO8BWmqqg47ydq2ymdDZXaa16KMkA6Mekktj3/5kk05sDdMhnutfJotRjbXOzdTqdM7hGp/OV2pBh9mrdPdjV/pjBeeVLlC7cDXhWojeG12n4ClNXY00UJLPAgLYkRTVYArcOfMgMIfDt6TWsvx2nlNZZV94tlufp00c6fnyskLcq2e9boIOubgLflcoyZVao7wqSFihL29F1tcYm7f0533yibfKkoIPdtxRgkDGzS2PsyvTs5AnWplCwTL47+Oz+Z7q+/w64oZixFPlARd5XCS/7/Z6eA7T2cYh7CNp3Chtw6+jO52qFL4ITulyuVLFVdppAh/PYqMKBrBm7K1wY2YlWi8eKzTON4lyH+VwH8QStP1FhcwY6k9qVUj1V64qCt9oPDYxInZK4YgRGacCrj5Hp4Pm3Dq+x/u7qzs1bKvsjjQdDFVmuw9097Y7HGhSZ4pX63sawVmIpMbUsYUm96LlSlmUqYsn3GBjJzGhLY6lTCB8syS7f4xdgr8mTvP5ittDZU0z18pmKscktQe3rOEtBCw0yvRQSXzFIuS3hyxwcb1YIUdmbJyTgAqoRQIYiLVm3/dst2tnZuY6Ppnr86FglVmDnYKRvfOcmM5YJiYXKrFSZDZXhB4QQ6P2LH+/L62XMxI1ylChRURQyc2pEHFTkhQoOn/rZjsJWVqlfDjXobTNj51pUEy3rmbIw1TgeaZDua1cn2tETxeWvFeuPldVPlNcXWJElCoNiYC1et3yYhJDWMOE07NHTJ3p2ivKxPWqZ2Wfnp3p0fKKz6QyGNrqkUQ1lPVW6nlfaC0vt2EI7WQ3R6uqYGfEG1IXMZxmppR+6JMktBBE5rz5GhgMRjzOtYWZcnF10R9UBXyEolynIQ7BMLjCT+edzMDPoybSTtdqOE7RwQdnre3Rh+87M+6pRhBXjn88XSizu7tB98MH7+vGPfiJ37G7fvaXbb19TieZXnITWLEP9cosJc1OD/lgZE8jsZVrouHvMTGbWpQMK42Bmz/O6Al5mphdlAmeUID2U2ta4v6e2Mn360X3dv/dQFyczXTyZC59G9dlSk+NjPX3yRKvJhRbnz7Q8+1gXn/1cJ5/8Qs8+/IXayZFiNWPt0yUL9TzQr2IQDG06LZxyumdKGpS5Mgp8djTsqT3PGznjB1rpGoowzEy7ZdAe0IvmxZeQ5Ixdf3i+g8SQ5ErhzGf5FbsteXpdT59jigg1nvzFxamOmJEFDlM/21U1wSHDd3DrAKkK5pipfOUxmTIrNMzH2i0G8slwpbhLOo2ZGqxaC22pM9FLdglPHz3olH82u9DTo0f66OMPZaHVaLtU0TfKWoFeu1jNEvzD3r6KoifnlQMGhvELSJpyYup51aX512tDgg8NQ0kvlZpJZtZBhrUNrrEtHFvMl7r30Wf67OOH+skPf6HfvP+J3vvZL/XzH/2dfvne+/rwV5/q/Z99qo9/dV9PHqAcjx/pyae/1v1f/lAf/O2/lc2fMeBWBYKP+nzY39nRzYMDvXPrhoaDgUpM3/72tt7l++beroos6xq1WIVrPcmF6szcgJl15ZLHDqTWkTbBh4qBUCQ/egKu+b2B+xKbOlfjBovge/rFfMrauWCGlEoIpWJZnB5Xmh5V3Vl+YJZdbbdJm1mnKKYIVXSqddjQHFjmtkKlEctqxYXTxfmJjtwvOTnWk6Mn+vWv39dkcqbDa1va2e+rPyzU65fwpqcs9jQe7amHMsSAb8Wa/+mnn+rnP/+5fvnLv+viH//4R/rRj36kn/3sZ13eRx991CncmooX7wY6apZ3VKLL0/c8iAAAEABJREFUNLNOkfzD7AXdIea5zi4mupjM9Pa3vqu7735bOwfXdeett7R/cKhr10jfuaNvvPUN3Ty8rWt7N3X75lu6efsmt3139PZbdzU7P9Ygu1CojrlVrDuF8I6ugs+ygIByhG4WFGTy7WCRZYqBL4hqMZu7WXM5yxLNHYh4EoIl6gaxSfu3wJPQ+SZVarVkja3l2yxXiJJXBG/FRFui8BVwiUZmhgIsteA2seLgZ3Q9U7FjgFSMpbLPnF4lzS+WSrTTa8ImK4+mvZI20GBtBQ9QAHyJA5bgHj5Hxa5p5cC5wsMHn6nPZHjw4H4nuIQ/Ehnzzt6W+sMh013y4+FBvq3Q9GT8+KxtuCktiqKzBL/4xS/0d3/3nj744AMdY7Ud12N2H5PJxSVOOMJAE+AIG2jydADXhuarsZc5BDUNTssTTaukePCWere+rVu/+5+rd/u7uvbub+u3fucH+va3v61vvvtNfbuDb+vmtZt6++439O63vqXf/p3f0Z//k3+o3dFAg/RUeTvplMG3p6UJob8AeCaHzNTVwfrLIUCZE1PiJ+wW64GQxZOEzAAa8LV+0jrq3va8rGJ72bALEoJd1CttrEGOArq1ykDUINQ5TN2UkQWWVucXz9Qf9TTcGirykxdRo2ulBvu55liNBYKk4hc+gyhdKxrdLGpdJ95nR1JgYXyinLClnmPOQ8w0YZkMdLzNOcJ8esGpYcVkyNTnNnNv+7pGvt0MjAuNzmIun0Q+SQQnb926rT/8wz/Sn/zJn+jP/uzP9F/8F/9Ef/7n/6iDP/7jP0FO31GJxdWV4PqQ4QzkAcWy8LzEzORlLTzZZIanKzK5katHB8oGW2z3ClneV5v1tchGOrKhGpAs00y9QR/mt1rheefKNShGGuLU3Di4pYI2vUL4Dk/wPy6E26USBpX0n5nka6ozzJXEoRckzw+UiUuZoa3kM8nzXJvX4IX6XGAc0LHOdiVqmV0S48A2JPyNDNNcY2VcbRIjdixNmqMg56o4l2joTx6C5A7cAhMeY5Dv8xfzueQd4BRnEM/QcaintK21ponoNU+gTYGm+9bboV4t2B08ki9DeZHLaTk5O1XZG+jDjz9WjjXskX/z5l3tjm/ocPuOxv0D9SIWoR0oywog63rqxgD+kksmv6K/e/ct3bp1Swcsu7u7u9rb29P29raKMlcIBvnWtdu8gkU5wIouy/G18MfM4FgttxxNqrDsrEm98a5GO3sgCh0iM+tiWVCyTPcWmc6bgTj8UoXZa0C05Ax9xX7fzBBqoRBoG6QsnymsfoPGP1NQkgvdlcDBFcKFHU3gFwErgI+wEysdFi3KQwG5a6Z7egNdptJGiOvPy3fieHaplnUxt1KDuAs9A1n3c1nFEjulGUKdMfiVagbuE6KIffWLLe3uHGjFeNyRLTDFRjO/ugaFsgK1dseKzPTa/iUz6yDB7QZL+5ADtkcPPtXp8ZEmbBlnWIMHjx7r4nyiO3fuam93C2v8mW7f+YZG8P7mrXdUlkM1eL0tfRV5Cb4AmDxkLKWj0VAxrvOC89rWaTPr+LLkXGjenMrjFjrNrGtvZo7iJYDM7jugOA3yrPAnanYtOJDpjY28hZkpMusXYUf35rlUFBpsjdRDw52o9hJzbn2N8r2O4F7WdNvPen6mGvNomGZBk11CJ2wIxoRoOyy0X7SKlDk+EWpu6MxMZsaXLmMUhzaJ/hzUhdS9Iwrbz7ZVZmPqBrmP4AP1QjNDUVr8g4USSpxDZ1RBPclQV6Pv3nAgnylNQz28cme+dV23yrEO7LRlrSlhuvWGsKFpzm4h4ZiOx9s6vHlbDXjuP3zATmCuFRdQ9z7+QE8f3mfSZLp2/br6+A9CsCsOhmKM6nOY1EKnd+M4zUxmL8DzPw8G/zKmXouir9Qg4BZrmdKaP7oSzOzyax0XYSD/ZZ8yjhRqNPmy9LWRI3ScrUWlfEvnLdtQmNkkUwvM8DWars8k4yeEoIgmF4FZ+ORXap89FPZXcLLDn/zN9e2OzfVWr9E+zG6xDt6PF72I/esFbPJf5KxTBiPz2FewuM7gbZdAxJMU+MmtR7qFURVMgwoG5f0uFwsV2UAhFZzI1er1B2pQigXOXs2ZQN6HyZWY4SwV0Nm2tAXT1cdp8zaVK1KMGgzH+BozPXn0UE+ePpUxA8uyUIZdujg70a3bb+u3vvd7KgdDLEJPeZ4DmbIsdmi9rvf9ur66CldeidH4ZxYKDbN9lp9SNf5Ti6X0/FchMW5zBl0WmL34CGWeX2a/GtENDf0EcEWMY60K4Vcw9mjZ6phzidMm6Omi0YqZ7DTloafMCkUY0i9GGuQjbeO99axGGVr0Yc3ILIhZHORrrNGtE9jCaCrJzDog+/nj5esPI7Ir5cb35x8zU2J2ebuENanqhWr3JViHS5jmLVyBvc7yYqXYFsz8qEFvzPIGrVQwmVqUorVK42sDnR6daMquy4WU4AdV5HFLP57XYg2QObO/ki85RyjBMw7UVijIzta2KpaKC+5fStb9a1iM3YNDhRDVolxuifK8kFmQmTlqDHCBUjZdH13GG14t46vdEqilbUAZeirCAEuR873G5XTqSlh/J0QGXI7Fi4O/XgUXmaNJmJoh68mKGbKps2iDJijBWRP1dBU0g3eNRTUMyh2wHIXwtbuPIoy3xqo4ReuvJtqyFQODYBDVoUSZ1ozgUwGmmBnlqAPErYn1khdg5hQ5vMh7XYrmcqE00NywPFXsLKbLM1Wcy8MzZcoV+PExwi0N3GlGoNvjfbm5XC6WoE2dlUgwukVJs15Sfzfq9Al4/E6FsVIJQbaaz2YoyRlXzlNN2dqdnz7THGvjyubWYmdri/nUMEbTkOXorXe+qW38s5xDpBhDZxEC1lSvCUWRQ0fT9fOa4susxPb4HF9hohZrYIwtmCvCa0UrD0ktE5tlq3OmV/JziATjXtsiwQTXdsrZ7JkKuJs5FiGMEGVZXzErVMSk7bJBiInvXAkm9cJQOcKOMVdvK5cF4wTzVGMudHooVgtzzUwhZGrooLlcpsyCWoTiEGMmM9PLYf39uewrlVrwrdqkCmeI6a7Ed8Va7NCsGqkOMLeWQOV4IhbMZ2pZ9NVneWihxWfpCsWpUeKak9EGhaqbleLANNgecDoL06Gzoe6KY+XZ9FxPHz/QKQdJ5xy1n51fyBDujF3J/v6udnd2NONK3HEPRmMdsC3P/fcOWEpDiPqyEOCfj8P78/jV+kEBfvcYUkAhpt0tboODnBi7LoMZA75Me36DDCqWkoqteN2iDJxDeHHw12sBBIaApm2O0CMdSr4TkEzJohJxLyyYTWfwfSGhCNnlkuPrd1RUkZXaO9zTYrrUxfmp9rJK29w1VMza1hWONj7IFubSnTxO5JvRB4NJV0CXgazLlF3G66gGV9VKZq0aBrlozl3/Zfz4LsGwZGKZo4Y8GC9jfAWCMdEfUJQD7QyvKbeeGpa+it2ST4plPWcsPY25UJuzrXa6GpSkYgdiZvJxuzL0hyMszVDHR890/fBQw/5QStLu/oFKbhR3dg80wlKU+A90/6VPghfJGoUQUGzJLU16wYCuvVlQ0S0LmQzFiOax6U3B27dYfJdRZiXkwTTeNWYzeKMaLT/H3LkwKmbDBeubm/1Exy0w43Yt0sC3hoUlGeYI26de9NaskelCibwahA659agtteRZbBWzqGpRqYDGrUxqcCCnq1rnSC8yOxN9NNAgWhl1HJzR/u1l3subgKb0k+RmOVHJsGUCGrR9yeniqlnIoDkoU4vCtDJ6EW91IWLBDIbOuEjL8wIBbqtfjuXWwc/8p5j+s2enKvG2W5R2yQXTkkMoV+4VyuDLRAveEYoy4ARxj31/FgNiEdamLx/7zu6e9g6uaWt7l2Wh6Po1Y6Bd6otejIYZvGrZrsd1/Za+Xm1h9JZhjcs4ZNLSZ8hltq6vV4KZUTui8H0V1HeFkLwf+hDhyem5HjLge0+PdO/pMz08PtMFdxW//OyRPjs6ZlZE+aTCYslpGuJU3Qgz7cDIQdxSRucrtk0X9TOl2nR+ekq9jPy+SmbbcDTUYrJCYYSP0SpBToAoQUR0xgVTjaNlZjIEU6OQZ6y9s/k5ilPp84H6rXSG6b9gb77gptLpitC1ZL/ttDgebIRSVslQBDRYgX5CiPQu8tQFM1OIUf4r8jPMeVbkyrgZFPkt5nRyca5IuaWgx/eeUJZphU+QYeY9v2Y5maEwg8FIkunoyUN8g6Hm86kqlqjxeIc2ufb2Dzur4P17PVfy2pczvTn4xJKSgkWZmZx+Ir0azOCbggzQVwgZcouWUTvKlcjxe1/B2+5vjbQ3Hsp/wWQXJ2ef9LBX6hbn5dGkjDVcdKXL0ChqiQlNmMo+p5R99vgxZGxplmoRzsnTY6m1bg17dvpE5+fnOj451ZLlYYR5cYvSj43GpHWJt+X2UAzc6K/FwuS9TIvVjJyEEiVmdaurAbmqnwWNWLv6QMCcVmmm1tdLWjXgi6FQFnrq4cw6fWZBIYaraLp0DEFmQWcnR3I/4OyMmBPEBnp9q1lwK7mcVyhso2tv7XFmsFBihp6d4CzOJvBiSd4SXC3LxEhiEN5uwCTIfRmCf+4vZCiZGQPkSWpw/C6gt+lArwmZFer5ZLNSxs9rqnRZCfPYYFkrJpRbsxq6Pa8rfOVlBiZA4HMrY2bIbcF0KRRECGQcbm9pxAHILmva4c62/Kh0F9P3jZs3ZGbUWj9mpgbBV9kAJqzk+2Y5MZj+nAMdg6kRhh8dP9KEQ6ejR0cKO0vt/VbOEXcuF9q18ki72UknTMe6xNlqweGzd1Ifa54mWoWZErbfj2WFcEMnMJOZeRMcpYRJFPjU5QVmT7ScmqYcc58w6RGlzaB1WU+olBSZzbTQq8HzY551Aq2xSlkoWNZWnbM5HI3kS13LnUcIURn1HPeUZWU6m0qMd8w9Q1Hm8OJUe/gKSFfX2T5u7+4rL4rOUjxXBDEafIFlw/hQiCnWdMly9jrhmVk3NjOjlbdLsNoXw+6zS9d1w1Z2JaetoK+YSysmxQpL3aAgLXxw3A6erlGUCqXxsku0IDMVLBlBEPbXH3ys3zx6ovc+va9f338MPNIHDx7pF598pqenZ138ggRBYNDcCk1YEqaY1iWnbshN0/mpZhdTZlCrGdu5i2dT1qZSfpQ6GuyrH41l4hRtH5MeSzI5kQu88hXET1bH8LGWE5r7LCoaJdZ7EVpMds020eMWxcHdoG0LUKg1dTk0uSBhm3Jm5MXsmZ6cfIqRgmGsvc4sL1vX9nZ8gcsZ6ev54bUbSsx4Z1jObil35aFyBW0XFyfKS8O6zRSwRBYCPsC29m/ua+/Orqo405DzBCnoxu07Go62ug4yxhGxDGbWfSdoNer04ljD7ACAL9m2zNbl+orBeeS/0pbhj5VcToWwbm/gDiFIsZZPLuev13XwdIxRWZbJYzOThx4nt9GYqDUHK9+5db2bTVlRKIHF4SgAABAASURBVHWIMilk6rFUtJJKGOvCdoBXgn+SZczevoz9sgjzBSYPXNOTpULTUzMPSlyC9fZoPyhVwJQlAoH9ykOpGHJaJbVo79yVCQ12zW1YenwwAQZ6P3PM8MX5mZacCLpT19DHEiJ8uVnUZxwzz3Eea5SovYxhgqzDPeUovOhorxTzTBZgEiVeauZvycw6KMu+8l5P3vegPxJkaDqdgb8ij7bK5beX08WZVNQqBrnKYU9FPujGUmQDHMahLEQV8MTpNAvKEJaZyYMLo8GxrdlmN8lpRtlRDi/7qpBgivOphQeO+9V2AbnkgXFYjt1ZMRFWilcUwOt7WzNo4kn07zifcHcSUsg0GI7lXvAtTsVuYuaucRt2wHboYO9Qg9G2dogvKmEJpDna4aeRKUSt8oFssKMMRhaxh2mtUaZWJd9aFLK8VTYMihBmSjpZzZ2WDpwAT1gwbbE0xUIsOwgWYSesVYty+Cy/ODuVz8wKR63hlG+BY9Zg6gymrFiazhfPNKtOtcTU1jhkPjjHKxnn/gjHDLwrBfqp8CewJQrkJdo76Eooy55yIMTIzB4pzwsOk+bUj+oxJmuCHj/5TEccsU+Xp4pZrsFgrH6xpZ3xdZkF+awDtVypHCQfeUJZm25t9sukeXOmeXMKnKlhn68vCU6nw6ZaiyI4bjPbZD2PzYy+aq3YgdTNUq50CYFvKqzxJFFNDYqZ4LWXvf+r9xVcsOAGgTiVQiANAq8Eg6V5LU08TewnjQvKlsAChVgCrWW6sAGnicb19lj5cgum9dQfFxruFepv58qzQqYgDxHaTRHSIM85JsG0qAIBCHxuMTreeBkHRJn1FC3KJFU4rO7FL1inF6RbBpEgvEXADY188Cssjw/OzMAbVGDpvF3G7JxzCrqsUcYkBdPzkLyvyy9P1iia/6LPfMqsrYIyaFBtupihlO5PpIGWF42mZ1NOGi86a5FQEpNpBV0V67HjvAoiNNBZYREYOV/rJ+uWtd764w3vBFFuZVrGamaKKKqPJ8YgM9PrQmTylWGoIg5UhhHjDV01x9UleDkdDTS1WChP//bvfp/7GZjDzoyZtRb+DOG7wH1NXiEgjzddUlW+VNTke9mCHcMM83ncFGi95Ld7WwdjDbZ7GnNN2+sN1YsjtS2MRQUiysOYtKhm0iVSI45ZpgIzG9tS0+OZmoWUtT0J/Ev8iQvO9Jds554+fqQzfBSWbFWcfcj3uyBqYVjqAMK0Ds68EDP57A4hyIyOGEAw0usq6zzS3rZhXQhoibf75ONP9N577+vZkws9uPdMTx+d6sc/+bE+uv+hHj841b2Pj/TwsxN9/NGn+g//4a/0wx/9UH/913+tn/3sp/rJT3+iTz/9GAsRwGw4oQ3jTzJFFQioRDglcQ+foQgD8o3ylqU3daArYcXWtMZB9CwzUwhBZoxDXxyCRblVzUL5Sv2kCmuxSlNV7Zz+GuIlsp+ov1UoVElkqBMy/Ox6gSfKg1REdXEMoiF14PVzZcBCuEKsENjKCj1YFVqGVlYkBJAj3J5KG8KMuiPAEUROBx+dLPQT9uuT1blmzalm9bmqNFdWZHRiapmZiRkptGaOFTg+eaLpcoKpX2iF8Mv+QD1mugsvRm/TqsXvoDFdpCsALRYw+0WXV+BkZVgpvRRSxywzUwMOx7PiIMkdsm12VDWDneE3PH7yRLPJHItX6nx6qrwf5L/HaW2Q327GsLYK7733np6gsP5vKJftVGK8AQFCgERdtVGhLYCexIlogncJppuZWpZFtwBuWTYQwOsWwC2Bp3UZGKUcLj+/ckRXHSkx5DKU05UlDz3SJgtBgXObThFEoG80SsqjFIOoxBiSulkPX7rYrQJZEKOunVuOJQM9V0/tjbc1x2TWtlKGoJxZTVup4XvZzJSFmvU1KoD5YjFDSRYykLX4Ce4XRCxEn1O8BaehC/yL89NjdXgKmG21xn7+gVD99wkLX1qgYoqD6QytUSI+YWrDgGEVzBUZzgC3DjmKEAPKY7oM1KFvb9tg2l0Y08lURxyyjblg+wd/8if67ne/re995zv6xttvaf/6UG+/e113v3mo27cPtX+wqxvcM/zRn/y+vv/b39fv/97v6x//43+sP/3TP9XNt64zQlOwIBdmgNEee9d11ahe1l25+dtMHryOmSmESJsXEGiry5BSC88rOU8Z5GXuV4/MDNkWiqlQjhJEJnEWCpXZUAVWKjABX8JG/a4fFzo0dwrgDN1UQm5cWWudTyb8VEvcKKjpjXWaxjpetqrTSsproYBKMvlMYApryKy64Gg6Q/MSiLv+6yh0htu/c7lgev2+aKQPfvV3Oj49VcmZf0YfPe4+Wpac2cUFqFoFy9hlLJnVtRrMaRZK5daT8ePCpQljSfgOpSKKRjbfoE5e4pDYBle6mJzJzGByI+f9Lmcu/i/Atrd3VPZ7tI86vHaAojzUcNhTjqIPOXHssQTm9UhnD6d68OFjNVNTPUmqzpPO7i90zJLylGVmdj7X5HSqX/74fd374DNNTmZ6SP2PfvUJyx3rstMDGCQF+BJCgI7Q0URW9yQUwXma4Fm0nDyvTfQ1HjN7jrdBkGZrHOSqxkp1lsGF7haiRqoorjZp6NPrgueDS1UtdcKkkvsdFQhrldwMjEBeMZhM3S0mxCdrkG9SZCnZG5cq81zDfFc9TjBDiGxjByryAi9+S93p3WCs4XgHRYsqqgwhFxqNtlCCRhccEc+xLI+f3NPO1mHHUHREkX7yUBBH+rZuiXLcWZ6jOAXQgwZRJoIRO8PxlaZTHT1+SF6ru3fvaGdnFzqjMujKaXt6dqwxitHgV5yjOP2dUm25UL5bK7Is7t/c1fd+8F2989272r22o53xobb2xxpsMaZ+oZNHp/Lr73e//019+3ff1eHdfd35zi1dv3mIEj3Sb372sT7+xaf69U8+1NGDZ3JBQcxLj1lQHnrQVMjMOtBrgiuLw2uKuiyzdVui7jvBkUV9oVX7TKHL4YXCdYJNpL/q43W93QZaEg0anMkQyEhRuQo82mHY5eh5TwGNbyXl0TRdrHAkp8zMlfI8kwtsOmXGY94Hg6GC+wVtgxD2mY1j7R/eoE6mGEN3ynd+/Ezbw0Pt9A+0VRxqu7+vxFrmF1OpMZafjL57GhQ7UJOpxt8w+u7RN5HM/EtYiqRer4+S1Xr04L7QPlXsCmp2Ds7UGYpy/fAO9O9juWYaQlvFNuvs4YVqZk2TLRTLJANvzIIKhN8f99Qbluqh9Fv7I93+zk3d/e5t9ThvMTPvvut/vDfW2791V+98/y299b27+s4fvCtfqianFx1dXcWv8HI6N9XMrMO9+f6i2K0ntdXLxuyayrUyfFGDLytzawJPOkVqBeoQVcWBTppcyTIZUGF6EkoiJTxX6iTpV4+mXZtaKyzRnMHXCH5XLpil3wxyyISh0TbnHSEaihRVln3M9kDBgiwYZwALzfEtCoQZUDzfqkXWwzotwddIJuXWp/6QrnPiSpuQUFyHBoVrUMCjo8cqsAJLdi/nZyeacNx8cXGmGQdXkSVmiKXqO9NioYvzU7aRC2b7iS5OqDOfdP2BEvQMjvfmadWgXw3lL+dvyn0cWR7limRmuvvuHZ09m3TWblPn7zs2gzEd0k2cmDgjhS7v7+HlSgFPVSPBGinMU9STpencD4tCpRC8K0MDk/Ii042tnrz+Cu/9fHqMUKcajsadaZ/jFNYcPff7uZZYixkevd8OuuXx3cSSK2THkfJKsQfxKFpAOeC43CrEVKqf7TDAXdWUebsC59WuDLdTBHYQNb7GjD5Ojo8w27eU+PFlyk211ylKp7NVzRLx7rvf01bvgC10y2HcsLMgfik3QWlqnFDRVgRv16ZGLXv4VTtTzTkI2V/piVnU/o1dPXt4jLVqv1Ibs41Qv7h6QlsdXtRKsKwFxK6uvsKdFzX+o1M1tK+ApSuE5ZraQGdtVB2lVZrTaVIekoa9oDNuAZ+cL/A7FnLB+4GMUVbiPK5cgdwBtUot++EszyWE7du4U24/7332mY7Pn6pXjLXiNOzk5ET+r5jvfXZfT4+eqFq0shTYspqM7UoB3miZslB0YzOzjhZequnr/OxU5VaO1elzGrrdWShXAhqrxxF1QmvnbHO3tnfV7420Nd5TybmIW7A8ZJj2C/n9iuOD34LF8t8kWnAqWrkyYKla1V3fX+U1GPelaHr64AiULyyKC9Lhq+D46nWsq1qjuD5du4+/jxdLNkzQGlijk0xmPWYoJqjNnnfRy1pkazqdLskzFXlPhsIkvuAkVsT0hGNfCzlO2Eh9zhbgCqZ7oh9zwPPDH/6UQ6Hf6Gc//jsOgO7rb//2h/oPf/VX+unPfqZf/OI9/fwXP9cU4eUGbnAUbJvy0NMmNHWNk+ZQydNnp8fdbyO1eMM1ZXlR4KyOtbW9o4YZ7gKoOADyM5ASSzEYry3YCt9iUc0Zo8lDcuJJJJaGhtM9kspZpjJDmbWu43lfBqcoZz5AmVlefSfyZfVfLU+ukZeZV9NmJjNjgrWwM3VpM75lTJRM4bLN31tUtVKd1ugCzGEnqUI4c6HfEeAMj8zy/a1CtTOfw5cYony9b9jKZAjCW/c4vawx43m5pSzL5bP3+NlTL9Kt27e0mK706NEjffzJx1qxpBxR1vOLNZYFn6WzVc0QratvZjKDGpjkS4yb9YrlqQH/gksyZY1uXX9HdlnHFWRZLVRjnSbTU5GtwXCoJaeeAVqn7GaePnmkuqkU8qADnNucnZB3ZkZfsDWzUr0wUhnHKsKQiZ558ZfCHHoePXqo3/zmAx3ePtDx01NVy6prZwZuoPv4mi/nu59xNCyLsIHWBoiJm9SSUTKuv3dlQL7MJqkh4cI0zE9iti1WMyXyhILQvYal6fpOqTyHKH9YThLm2M323v4NZlSPw5FMkZ8ZPsQ5V+Mi/bu/+7vdwc4/+2f/VP/gP/tjfQsv/A/+s9/Wn/7jP9T3f/CufvBHv6Pf/sEfaG9/Xzmm1kfcgtdjhxYFWK0W8hnjwp8vpnr7G9/F9B/I+29wKBM0rnBM54vzzoH0unmeK8CwTz58v3MgExvorcOxbt66q+FgW2bm6DswlCHHEsVAGwsvlekLgp88Ttm9TDhH+cY3vqmil+NAj/WIE9u24926cSLtE6dlXE6bw7qENxPRZPK8CmtWY10q4MGHD/T03pEefvxYDz96pJPHp1oy+XzituyccFCgmvZ/nw9KJvcdnKF7eSvuq1SUBeY4KYZs3RWzN2dGDQal8pIsBhBwOFeY3bPTU2VFrtlsrps332JQJhfEnFNJH+AYE723u6+trW3duHFDiZvM3gCm7Yw1Ho61vX2g/Z19DZip4VJAy3aiVTNVw0wPKN9wvNXNhrajo9T+HnggvMJ/8L4S+WXeR2F3VWYDaG/kM7ZBUY5OHurg5qGGBwONd8dYjC2ZRcXoYzMGI5lZB/oawfs8Zrt8dPRU/g+aD7hBNjOKYjCOAAAQAElEQVSNtobaYmznT89VY+0aZvZnHz/Qp7/+TO//+AP9/K/e06MPn3TCdUF/+qv7+uRX9/TRLz7W40+Our9G8/DjR9rZ29bhnX1df+uart85ZDxzHT86UsJCOg9ducPXoPcrV0VxUQjTBbd9M46nncmB2yXX6DUSw0CgAUQCQhHUxBUzodA+W0mv1++VatD8Au/aGX337l3dYXnIi0IJJtXtQqc4i/v711gypjKLymJPwQq50pmte/J3xdX2nDuQi9kxdwcP9fDeJ/J/Ge0HTYeH1xVCBgTlRakVS0HNzsB9hxrl9CXKwWfZxcWxSs4OZtWFXKEGo7GyPKIslTyYXenUM74iLLiE87/f9JOf/li+dI05XDMzFBY2EedMmul0oXvvP9Avf/SByqLUnW/d1rd/71391h98VwcIOShqm8vBWxyZ3373pt76rbfk6b3bO7r9rVsa7g6VFRljBMocJe6rLEvoN63CVBfLK4dO+nsOvmIvLNfjlWniZ81ZLb8x827MTDEmDbJGZqYsK1QwA7Osp8TP44efaTafqsCinJyeyYUzhPF5UShYUFMv9ZuPf6o6W3LgE2QxE2zDbVspZgmcfJoR0/fqGWcCM/msWnElG7BAvcFQq8VS460dhZhTOQFeP7EsXOiY2em3pCDQwbXrMG4E3gBlpv3da4ooQMbZg9HKlSeEwHigwzPI+zpPi8J7+9Vypd3dPd2585Z8PMtWjFWKweQW9PY3r+vt793Rd3//Wzq8ta+8yBSZKB7nZabt62MNtvvKugO8TBllAbocYnTa7AVZJHscs6/mS67mTxhXqxVWMbyo8fVSTHRx4Ob8em1DrC7OialCIWp6MQgrylJuJbxBy/ZzidWQTFE5srTO5F/gSY+2tmDAAAIn2tnZ0pK1z/+quztuPnNaxJ6xDCxY1xmJyqLH+YJUYBmM/gTOYCYPFetl66aKz35vqMLr8n395m2NWC682tHjB6pZN0OIGgzH6nGINRgMOrxef+W/9jY90cnFA80mF+qDJ4ZM1mbqsb3Ni0JmDFJ0oq8ekjOJ6r41nnPI9t3v/BbL35ZmnPWX0WRmlL54QgzKiigLL+frawTvcz5Z6IJTzmxoyvDdEjumHrJ5LVrvyuFNfXhZ4uWNXSGQs/h8Xt3TG2gQ9bwpMHmmhkE6MV4R0StwBpBYnxv24T43W2bDcDRi3z7RhIOgMUoRmpVOz0/YpQf1hyOEVmuBM1rhYQdlar0R7XqXXrsMIZn3LiWYHWOEgoh/hPajVF5UIDxK2R0soKlmXd7mqPmcddQtCMsV28ft3QP1BiPwNzp9diSfuVvDXcVBVGDA4/6e8qzXtTcFOV59jeC0Oe3nHFjleabf+u5vacTYfXs+hKk+Aq/zNVC+tqrjuAq+o5hzHT/cGmi43ZMF68ZAglG8goIyYWE6CK+UbT5dcMgVv0AwXB0Ss3Vp156GKDYmLsmF7gP09b/GFGVZTptEmeSHQaJhhUIs8fJDjBIzbtltrz7TkhnpgosoTYNS1Aj+9PSJYpvLhd/Mk6pprdhZAzfj4DWTQYozoAVnsla+NNCcpaKSmWFiC03YHk7w2kPMlGHy5+xYMmjrI5D+cNjVa3BOn/oFlgUtLuYa9ncUSCcsU+LCbdTf0hBLYj5oMWh5z3T+FR6n7wIafHt8fn6uCB0N7ZdYrS9q7u0cvqjOF5XV3C5W+ERxICbYElm0VF/THeifjxeP0wLP5fGL3NenvI7vHBw87bXgdYcys0a9NNOWnemgqMXdNDjbjvGihilqE2qWDIOeGCIzuFavP9CNa3cxZeyxkWII0rSasOw0ylkf/bTSbxLbKml/5xZKNQCj5DM2gTShXA3Hx4vlTJmV9J2hPEON2Ink+Cdlb6AYc5VlSZsos0DZtvr9If23cn/B6DTBCHfufGnY4iazRatz67HU9JksPcZSKMZMkunrhvv3P5PvngqcwcObd+Q+AujVQ7GivcCXsG5XcZuZzOxqVpf2eg7dx5WXmXX1zV7EXtxwKNayPCR4JZk8hFf68jw5UT7zXWe6jK/4YhxyoF9MRqPIcex2nGkAwxrOGjJmoOg4WqacQ6hgCB/p+XKR09BJKrmM2trZUU6ch7yb1dPJVHP23054mY+ZlzVme44DuCWfXe4celvrcKTOL2ncKiDMMvY0o+2UrenHH38irxNj1ADFcB/GcSaY0OMYvMFvqLBGwaxTiordhAurwmENpeRmfXtwoFFvT2XeVwiuSCYz09cNWY5z/fSJDg+vKYcvARQFrwh8GS6n1+HL6r1a7m1cwX25FsI1o1MZ42C24Xz5W18lOI2RtjxvrM5S91wZQmA9jyPuJCIzYEGX1nXaEYTZF6FHuQvc8T7Dg//1B79WzYw2C2wxD1UWIxV5oQEzeWe4Q9xXwXrfRyF2tw87IbuSzdl5tAi0QouJFBlkgOAGc7XCJD54+EiTyUQzjqgfP3nc0VPiFzgtM24lJ5hrdFJPHj2Q41ux9/at58P797TkFtN/F2NRTTUYDbBaQw1728pjKYNOhvG1nwYix3uHunnjpsYsS0U0uSJA8udwmX0Rx19UNzOZ2YuMV1LdWFnqHt8/UtEP8lPXTRUvgySFTcaXxU5opHYA3lTXGbopS6BurNcpQ6WljMZma2LNTPHSOuShlOP2I9gPP/oNjtyZjhDY7t4+M3+HWV4pQ3D9wZZ6RV8xZorsPm7feUePHz5AOXINWON91sINueabpMCsnXMV/pAj6ydHz1SUhe6+9bYGWABZUERZfQfRcJRdFLlqlOaMO4r5fK5nzNhnnGFUWAnfVfQHI+1v3VSvHMm3pRHfwszoziQZvX31x3nk/+B4gNN4wJnKV2/5oqaZycxeZHyF1GKy1NGjZxpfL5RvJ7kv5c0cTUCoMQZ9gWglF1J+WaNuxSkezRmN5xnJVx8mojzft50oO+0NppcSPWYM3gxktO9nWzifK3WBbw72dLB/qBvXr2MZGoh+QFx3h0kuEMc7Zs32ZaZljXt4/1N2HOe6ceuWfP13oWZZoYxBNfgYJyfP5Decj7k/8L+R+Ed/+AcyfoaDvvKceiwTLcfko9E2juQFu4g5y85CpyfHyigbb28rgGtnd197COxg/6aGKOOQrajTYGYd6V/3VTOQKZc320WEN1+39X9afUMg/X6pfCBZ1JXAWHh8MoUruS8lXRE6s0+NItNz4rHEOHISMnypvn909c1TkqdjkBYcfrcIImNdNAvi0RJfosgGSm6bqF5mfUzvUNtbWzIzvf3ut/Tv/sd/pSXm2onsYRnKPKcm/bKnnWPuW5waY1QTtmYRAWZ5xIqsurX+1x98oL/893+pGKIePnyoEkdxb2+XsqazEN5vi09xcvJUOXQ94Ep8ycnjFgr36NF9NeDeOtjWtDnGP2k05ERwMBp3+IwBmF0OsqPoq72WMA7SNcqDwldr8p9cq2lX8HqqFkcxIowlPpClXE6+L4XTyTm+2ETnTIKK+5o30oUSd5agabEItUD45bQ5i+izUxRvnxh9FlxtklrPAEXExA+zXbz8gnoNfkytZTXT/Uef4QxedDPUj4KH47FG45FGOwfKhlsKjCClJCf62o1bevTwvsY4mg1n9fPpHMxBn356r/t3C71eT9cOD3HODvV//j/9X9jI1Fpg/lecMwyGY2WY+fPJMdfcp4rso2/evkOccRo36/AMOHBaLuf0GVCEkbI8V4y5Oi7q64cWup0LkTF8UWsf3xeVe9kX1fGyFsvZYvVWrR/RG75IX6Ygi+JgLqHoFZOQNPUWbOEbzHJ/OJKFqKAvCb48fEmVrjiYniPzgXdbJUpmHD9Wl1vHBFNatNRr1mit/64AtOjxZ8/k/+T97lt3lbPVuv/Zp3rnG9+S/9qcC24L4SR2Bg3OZUKp5pwCxpjpg1+9JzOpZt23EFCesSr20Yl+bt++rV5RoARTcBZyJdjmuDdQL+HA1lxaLZqZKtpOZ+e6d++eTk5Otb2zoykHXpnlOtx+C8vRVwFNZnTEeL7O43xooaViQuUw6CqzncYNLk87mH15H2Yv6nibDQ6PzbwsyfvNrN/Fq3bGtnWqCXcPFfc5Fr1UWMseij7WnF2WW0nny1X6HN9/FDgSXxYY8/P23iV8gCBKLcrMFPjJQ09O4Kw50bw5w1ufsW5PtMRMufMW0NB9/AffTlpvJLEE5NGELsv/aZ3/NtQKZ89AWyLso6ePwc0HGQMcye9/73v6xjvfkPEj+uzhMI5Y63MEChJVLD0nZ490zqXTAWcUoTA9PX6iE5zHd955h93CQNv4Cn6TOWR5iCEDTQDMm38lcCH5jmHVYMlgCmQIXfhKba9Wcjyvfnuew9X8q+lgUc7nplP2cxRhAr8nwkgrMoH0fBgms6AeR+8NS+aKJSS8jkjPs6s9fEk6BMnreztdCS25DWuULJKKKrOhevkWy89cLlyxSIhZ2jDje5j2HMEn0hGznOPBbw36KsHtCmIQ3kB0IB6MRorULRFwxalmZN2XTDFElXmGwBcyM2Xk53kpb+/pQF7CPC65pMosY5k4k/9ltsW80RbXxLfv3JGfKJZlX0XZ69qHGPV1glsCP0VMzIaWhlkwTLXJSL/pMTOZ2ZuKr+SDVA7rLLN1m0RnLRa35na2ZYloOFDydEN6XdPfWAys65Xm3RjHW9uMeSS3fiEGwUQpC+sY2hVNMNARfHVwuhzXpgXo5LgCyEzrnxbhN9xgJtwy6O/Wrgvf/7MF3OMuIIZMJWcKvhMY7ux3NLkCOE4zU4gRQVdYkguN2Ak8OzpiCXBhB9EFywXrIetOZAbkeU7dFWtkLTP6BxbcDF7gXwzKbSkFlOFCF+fzzlReu3YNhhTUrxQgPPhgDLS0MyOhLw41y9eMNXUjqgwcgyx0vPzilm8uNTN4tMEouFZr0WJF8QcaZn5yJtK8auc4iheUAc1FZw2qtJlwVOBJWCm3DmIooCVHMrv8ICalgP8lxtEpjGd41w5dhr48eBtwyeOrtdEBnERyOm1MrgYYAdOCnQSSoIDB0XnDgnqLLWIGkgwBujmvOQkcDQeQkGSGoEk1TaWK5aGibMVBkJ88DqjjyrK1vSvvvygK+Yweb+8oxqiYxY6Zy8VMCxzIJ9wzPOVwKwaEFHIOnxJH3ucsCwPtcwgUjTYoUghRG4CsjtbNKyEAh+ffJObOaGIfQ6BBLwa+GCV1u8RrXmZO8WsKviArQB8DYjfHeOBjy8yv8b2WKEjFZV/3TdxgGV5FQzVFxgUrXy3qvlsm0drXTwgGm4Zie1/yHQTj6yp92SswJh5dHZuzIiPTY79kKiKzV5lyjqD72ViBHUVmRec0Hh+dqaXjIndBlnr6+L76u9dVwFBQKITQKYGfEk7OTnV+eqKEgvXxBW7cuqu33/mWetxlVCwXPtCAMAuWj5blRgQz09npqY6fPcY/mWNRxjo/O9ODzx7q9PhcK46a33n7myo50HKL5MrkfUomnP0IuAAAEABJREFUMx+BaRNctj5xpmyX/eDILYH7BZEqPt6cBMlN9TfGZl+lllQ1CybPBbN+2sUNVjULpaz7cdpE2QXDRni839ghBbFnWL1G9RJh870hITGoFn6Ksa4xUuiP8cKyib70VYLXR1Zd9eAfl42cMfBFLbd++4VxN5EgNXHZdIJWLxB0H3UYoARSYg2PCHA49p1A1TmS1zjoccKcyBZL4KeDPrsDneScGSQGYGj5wfWbzOo9rI4QaotAc7kiuLVwBzRjC7nEikT8CLcMiUFXnCr65ZP7DcvFQrdu3tL+7g01WKn+YChvo25E6oIL34+5ny0bnWHFZo3UZ4BDwC1AwUB9p2BmV1p1Td/4cvqvFvq3g+etmjl8OtbF6ilm/1wV5t5n/qqZal6fad6cq8E/aFCMGQ54o8qbwUfn5QvoMq+8DHoDsJyuruRiBJg0/ne5FmwzQx6FcCT4jMDWyGytPC81eu2Hac0AYl0J3nyBSc/ZyoyyBuKX4K6VrFbNWhcNK5D35KeOb79zVwWdL7gjeMrxcrnHlhDhOboWE3V+ftadJiYWPHf2Jlz3Hh8/08Hhdfn/6iLvjMpFr68UMsUYOFpeaXtvDwYlVatKvaIn/+WNplp09xnnXHz1epnu3rmpd975tgqcxbzI5YoQgmRm0CkE0qpGGyL07ZeZdoqgcW6KlDuQLR+6g/4TgpnJzOS/mrdoETYCbvEQUqfmCcyAEVliTG4FREmjlmWCXPL8vQbQgEtdXqLZOlcyGOXWt79V6mqIIeA873L0v63gA7pa6MvDururua9PO32vlnheJNOZ5syLKEAFVUxKco0BVGj+M90/+lA/+uGP5L+KFlnbL85Ptb2/p4PdLbVUXnD5VGMVVmw5G2LfbTixfmp2cHAgg/Bbt+6gaI0KlKeM1g244pzBt6hLThSdI2O8ZT++XuAztAxuOWF2caC0bKKuX38LRSg7XKK1mUnEyB/WmQZ5UAFeuhLsBf7+H8TLGCrN6tPOCqz7SepIeU13nn8VXlOly9rU6T4uX22gnxMmZrrMILIQ6YsZIOOGmIJWkjOA6Gs9zqSu0yutjLTntQpaMpsn1VxPZ8ba5h1SePkUOHtlr9T9z+4D93TOjG+LISY4h6zEjF4yiy9UMmvFUjL1m0WUasyZQcYsrtlGBZzA0pcNhU54Rr0ElGXBgKCAraV353+ddUC7AUfKZxcTZsGOvv2d72rId4JGH3uiV6/rkMDmY0MP/PM5pJSep78o8XXq1Xh2S5aAtnP6vhr+V/t2fm/ynEQfD3qvTdpjUam/VWg1b7vl2eu82lvwRiyXG1xfOQ7UdIZ5HP3F9+bxTpIFXTSZni5LDF6JWQuYwYjSRYltnf/jkIQjdvPGdS6D9jla3lUMCBVhzli/3GGEfrV4uTNm9RE3icvlFKeq0vn0mUbjbeWYbjNXP6nmDKJh/XMa3NwXZamA1rtg8qLUCgfz4ePH8vTO1li7O7tSlrMuJxRVzE7JGYQv26Udz+vA8Tl4mdm6b09/GbSs8y74LmapdIVb+elgM6G/Cv40X4biS8tdlusxmFYN0JoqoAaSolIsVAx6KIRxEBW68V5FGliWn393wv0K4/N6MUg+czz279fxxXAM2zBWieOyagtdVENlYahq1urJg2ca4rDlealr12+yRBxqxIxesQ08ffZUBet8iJEdwFInXCcnlg7/VbPJ/FRjtpJlOUDZA9ofYKZkzGaHhPKI4PcbiSkxw6L4dfSzZ88kiNzZ2dEOt5IFSwsugIZ4zAPoIwJD6hgUqOdj0xcEM3oD/+uqmNnnsn3rt2guul1BtyT42UB7gRJU9PufpghOxgqBLxv4Qc85e8Ty8tjZ74Z8PEGlIoPKy0YNh26l/zqgib5fACKVyFPgxdOl9QXB6zjjIhOciaxXx+0IN2AyZVSsje1c1ddWUauk0bz7N5atRqMRdwYjCSSPHz3houkTzbEK9+7d19NnHCjlhQL1O8H67xxiDa7fuK0b195W4EceTJ0yFDEw2CijvuOL9HuKIiyrpR48eCB3Gvv9XmcZLOa0pKEcJDOTSXK63UdAN7pvsl56zExma3ip4Es+WqyCLwMe1zjVQgUW9TmKvG7owtzAOkfPyzbfr4u9jVsCVwQvL2PbTVBIlMuzRCGQv/wPpOQoSIyNYsnkWSVNj1YoRSMfs9ftwJE4+McGuX+/CbwefJczzNNX6xkf3rmXOUF8rpkXMtUwpJ+1mPNlZ7K9LzPr1u0GE+9/pynw/Yv3/k4/+dnP9d57v9SM08npxQXbvgo8Qf1yrBvX39aQW0xvM59NmGkttCTq1GpYJgLK4Lj9byw8+ORjrdhNzFlmEmXTsxO1xBZjNyOcPofkDWQkHYje8Hg9BzNDWOkNtV5kt3j7S5aBRXOuGh9HzMauG6psWndd8/1VHq/r4ApQNRmmvmAcQQGyC4TtkxTSXouqZbEWnUd2Q73tqGbVajVp1DoyrYMrBgglXy5a8jZEknzpoT95Zzj+coG/qVOv5+Wbxi3mPbYz3ejP1Y89vPOBPvzwQ/m9gm91/ABoslhJLCkThO/m/PDwAKvBcsI6/4TtphmKwKVVjzuDFkK9bz8gmlI/yJToo3GF4txguZir4mzhCaeNAQZ9+NGHyotcJYRfv3YTZbqhHIuTaGdmGzK72Ozl7y7zP/LlitBdxHF0XHMqmLAGLkiHV1F6txvwsnltmjWBXVfQ2SpqVkf8rdCt/wt8gVkdJEvIo0YRmAyM09uL4PgdSL70NJcOakBzylGmcpxJ+G7M0ef1wLpOp3X02jc7LOVRmBsxC6VNx7oMgRiF68pkfFw+jrNtVqxWU42xCiuUIuG9H+zv6w6XQjEETgaPdO+Te7p2cE3f+9739ed/9mf6oz/4gX7wgx9wjnAfn2GhNjQa7JTM/JWyGJRA7P9VYM1ZhZt14XRW3EbOOKtwx/PeJx/q9PSs8zsMRRKHX4eHh3rrm9/q9tQRHBWav54UTrDDJdFfEJmZzFA+J+BKvcS3Q83sXzYTZuxM3YHQpQAolsOVJq9NLlCCJcIuMO99hyxpmDfqYd4LlkmfZAWCdwvrv30eUDADkwPRG5913zDNp71XBoph1HQCnadsNdeMUHgjhisF8A0mrDOQ5Tpx5e1Egl8ondwp2xQ1zFZhKqNVamBMw6lZIs/MuC2c6/GjB/rko99oyFnAGCi5uSzYBRRFroyZHEE4HA01HmwpQfCyXmjG/bvjjeVQ+1tb8n8PWXH9en5+qpJjaT9VzJn5N2/f1dHxiW7dvq5bfsp4cF2OP4TYKa3TOcP99v+vwuk1M4++NiQYvEABJvWzTgE8vWjO5T7Cq8i8CwfP99iBDZUmVZArgovLl9hABQMvw19bYb49HSx1PPa0/uPIBdP6MSb33s1R91f2msp7lkKHeF3+2rdbBV8evNB4ORB97vGB+SB8MNgfZnGjkc10s3ehXrZSV97kOj450tK9Wc4A5qz5N25c07e+9S6+w1DOAF86zAKmfgmOViKdLFezNPVZKmKecacx09bBDZV57sWyS6JOcDpblM0H5bPm1p0DbW1v6fY772h7b7fzVybzE9icFBn4EC0eQLQrRctS45CYRg6bdI0Cz6tzzPSFPN+hpa4IHruStqo74ScslBmjgLegob46IOs5jZt8dBs/QmrYBfhsL3H++liCCD1mdlnfEdERD1ldnvfhfTKI7puirg+PHTb1PL0Bz9ukPU4QAalanreKCDishaawEbRXehXg1/MOjUKv63kknz+OpwNyepHX5ZNgYuvLglbkmEyYpfm5Ts+P5eud/9JJhkJcu3kXIjJ5cOY2nDYWHDT57Pe8t77xrnLq+QBWWIaK3YH/u8TtwcCLFbNc3q7HcXSMGQKv1d8aqNyJGh+MNMZ6GOjPFk91Njtim3qi46Pj7oj7/mef6f69T5WxcH740cc6Oz2V31H41finn3wi/yNfTzibOH5yKv+bje6nHHNt/t7Pf9Fddj198lSPHj+QK+DTz447pwzxy5nv0BF4+YL/ndC6fJMmrPsJM+uKkLMEXFYjSpdA9JonhKCAEDo8ryl/XVZylJcFzkdEo/mzBnqSetu5DHxejB569OWwUQT3DSLVGU9nbntgcCjJ9DzvzGDudl5pu2iouaakFzD1y6j5bKHo3jyz6/D6TRXDsaIFuX+/xAFs8PZjDJj0Unt7+1iRhTKWjB7bwglHyeenx/ItYqAOyJ338nReFOwcFpxcrhBoTZtc3e80oIwhZJ2AppM5t5WPVde1To5P9fD+Q/3tX/1Qbd3o4b3PdMHO5RSFuM/W9oP3P9DRk2eanE30t//+h/pf/vW/gWmJOuf667/8K/3mg9/o6OlTPX3Cbeh8pZ//6Fd6cp+zjPVwO9LM1PWrVwKrk/z/+orWduVrYVFZDuvK6zzpTTh0JXidK59vTLpsGraVi9MankmDw1xZGehj3W9AJuvGr7yd164A3hHWlAZCYFIwycu4jFQPZyZnHfM6m+beYWqWGoY5lmwl4ycwNUOIyrNC1w+v6fbNm/K7g4yDo4zGiQskdwAN5G4Ci7KHbzClfVLNjqLkunqxnOuEJabolYq0o9lll0mOu2F5oIHcQixnS1kbFY3BAkvW9MBgXKEGo1ItyjoY9FlCxrp955ZiDNrZ3eHGdKUWZ3N7Z1t73JMMh8POsuyzu/mdH/wO3vxCWT/onW++LS8bjcfdP6xZsux95/vf0vGzE70uXBXsenkIyuGdCIlCt2xmfPgAPLoCFMvhSlaXNAVJXSNdDV7X4Wqe4/Z+/LBvflIJcai3GxWi13qhvcEdGM+6Ci58B0cSKGBZ6awAPONLHQnwVm4lvI4ug3fYshgtEOAcc+/fonZuPUg3DpiG6pV9xRAUWe/nXCr5cBpm6oo2/ksrIcbOsbz/6SfqDUZyxairSs+ePFEvDjUa7qgCm9PVYEX8fMLbLzisalAI/72GDKULnTUwPPsp63Its6DBuK/D2zvgzRDyWO+8+w39wR//obI807vf+aau4WiO9w50k53O93/nd3Rw7VD7B/v6gz/5Pf3xP/gTlflAbq3+8B/+gb7xrXd089YN3bh9Q4Otnm6+fahv/8439KYQ6F8KqlkaytAqmNdMvFyZuw/SLx77fFZXaAqSvHAD+kqhxUk8f7To6va2MumlDpwOdZj1uWDq6hLJve4O+OBhtqlTjIwPM15y0PNQsaaPMmamVc/z3JZP/DeaWd+zvFCD6voZwYAZ3+v1NGAGkoV5b+ToHnO2cMAVdQxBfg5RozQu6KIYKFhUpFJDP2cnx5j8BiuzYEa38pkaY0a6oo+VGl8cqbtWSlBDb1ZEtbHiTmJCvFATFnLvP+Ur5T2YYq0Ukxpgjtk0lqiUNwoseTFknUIEjspnfpxsC7n9qyyqhtaUFyifyXcGvkXUZaBbUgZkitZTHnqk4QrdCfrMgt4UvK2D88dBKJPXhUIsBrT6xxXwumRvwocAABAASURBVA5Xsrokl7845bUwipo8XWk1uyqfropeTwVEeoErgfsCJR+e7oAxuUUQFqBmJrqQ3BrU3Amkeqn9YqWtYsmAQUIfDfnn5yedwFZsAWMEmUwVsz3DSgSYaCGqh2IMhiP5DM+zTNu7u/IyUMgxZVmOsLekvFSJgC645fTTyRgjJ5UX3bofUYQBN5E1StCypU1qZWYdpI6TUgYe1hBM/hxYIjyPUQpuD2sc3iZdqEoTZvAFF1gTdhFzBFiw/Us6x3pN6gltlqqov2Q5jFbLz/8jy+XVOEB13apTjGkVwIP4WIJCt/NofFgdXWZOX/f5pS8fQ4s00+VYvrQBFXxZcuWMOHa7dwfq7WQStE6fVaqXazp0GcJl/DwyUpFcXwZcCTrBkwfNMIUESmAwomRQo9hqK2u0HWpdZ2bd7TfaK02R9uoC2JCkz+zELKtgZgw5etTo2o0bGvWKrpa/YoiKCMrMNOXw6MLvFfx3Evjm0SGnh/lopzu5TE2lnGVm7+CAdX4p/6suLYwuBqVU1GqzStYRQf8IxfE7mFkngBZmts4lz7wEyKRmi/pUarlVZNMnY4wVM/FiVaActcym1FkwPqxIaOXCz57H4lty8x9N1AEMcrAwPfiUA8GtDotci6J6t2ZU8MQbADIvS17Ua+F/osBBUHNZ4bWRK6OfYWSW4JfUG+XK2Uv3d3ImRcRCVKoWzfO24XmKhHfJpJMDnzBAWsKlBRruJ3aCiMhA9jlN3MolP1XcxYRuxQuNwgpGLOWzS7A0Wq4iDVSdN3rw0Wd0ulQeoi44HIrM4OFom5kHcu8IvGbeOyLA2oxGIxy0kbawDj0OoVoUadv/AQyDX3A2UXPa2JB3hCd/gdVprFFjtfw3qRLCGW6NlRU5whMkJ2LrICgwKSKmspXRr3f5KpD9/AngjZprnLfaynO5MF3YDt6ui5/Xfjnh+D3HY9dLVxBvk1yYcpok/3bQVwgJHiXamhnt7Etb1JxfNCjyME/y/mkm0czMlDHLR9cLxSxwYVWp6YQrBV0JPjj3BbpME/NCguddjRpiAsTssN5uO3NQiCHa7ruJltPFEKLmzbnqtFIwFMGGOn16rKNHj3G6DgQNqrt1/ql8Xx5DUAmH5nXSAp9gPr3AZ6gkC9riNNLA9+izT7WP77DPDkRFnxWihJ6qO730Pb//w5sca5L1TMOdEfQuVfRy9TmJjBYl+UiMeP2YmfrFSL18i4xNvseG0ugloKoCtPTiAL8pg9Y+bV590qsZ3Ti97VW4Wsm3tQleXs17XdrrOI51WVIIBkTwGyCCXQIRj6NsIGdj8Fy+EYvgyxXFLz1mphDh2bVczqGLhyslGnpaHhx15CsA1PUsZbw36Ui6YPbtolVmBhII1DokLMFFdQQ3+Yag4KVQ5jgT2uS3hnNM/v17nyjgDwzHY8xWTi0pV6PVYqYzfAD/Y97L+VQlZw+JncJgvIVvscInmKBIK0F/N6vnsynnFRP18DPUazsnss/pZJH3VGR9FUUpg3lrgnTJvKSG9bbh3MFiAleUKUJDphynLqLADiKYrZUjKFMMUeK75t5Bl8EZ/ypcFsnzr6Y33x47BMdHBU8TvfExc+4xAvjpdZGVpHV1T5Pd9bUpq7ECbg0qLMKioa2398J1k5fenu3KlkA0ulGqwneoWQKCMzhnvEUmbbaQJNVZiEucjilD4OPwYn3xvESeU5Qwe5AtZ1q0XMGojblXCHJzXRSFTjkq9u+9fXyF8Q7NEkJcdUIuc9pICP1cLZQWLA1ZXmjQH8pvH4c7+ywbYxk4F2whJ2encotQIPQyDpXFXHW7QHA5M3gE7T2ZBZkxAPD6Y2Z8C/yN8liozIYyClrW8CrNGUmlBgtH1uWTcBIXWjQXLGdTLbl9hDTovix+TeTlL7IdO5whMwGb/BijQqeomxx1OL2KwyY3IVzmE/QKugynNUCPdbBqQ/ft5dxEM3Z19UqU3MFPNcvQMr51/xucmzihBEuur88eLjQ/Y9z4W54XYpA6JQiCSMmVo4xitkjwTx5cMeiOZAsI4r2TFsKWqtICQtZKklmpQbaj0GSazSfyq+ODazckk/xGsfuNJtb+mjOIGmdyyYnjHEtQ4QP0hwP5RdMBF0oZRJmZzs7ONNreV8+PmhFXg7WYTlxhWkXWuyG+wXRxgio2lNbywYQYZZZJMDMldcHjDYSQ0zaXLEiCML0IxqfDOscbJ8ZWw/iZkpp19pX3i7pXMl9KWscr93nWCuE41xU2bZ0uZNMJ1IXrs7uBdu+tYpb7jPdWLtwCYfthlacdXKdcNhG6vWyNWd2oyFLLTg5GyKHrp0mqFg13ErVWFw2TJ7CjaNXfKnT+ZK7gRAVaOsINYmcTGJ4/3Y4C5p1xlOkztyugTYN/sGyml59RZRjIw3K5QJtr+Qx3Rw+O6Oadt7R3cChPz3ECXTkSFLZNq/PzUy0Xc5VYBPcn4Hz3P9U4Q4ZbOxBtcqfR/67TcLQF8T2Jff9sdablcsYB0rYKlogQghq2lUt2Oy3+jdPiECx2DPI04lUD3XVnDbwHz90Ag+pqJjJMZkYsYv/2+GWAfH15SAzZ2zu8vnYSSgO0DkldfV/rfZY7uAJckvISApfbBtaUrou7uq20OK8Q9uUYIXZxUmvBUXRTJZVbUXk/KqGJg92Cc4daIZrEJMO0qrMKEXwoEDONBI8B6w6DVlbIHT4zg2yjfk7bQr04Uj9ixhVZ4yvJS01arKbymZyxDNy6/Rad5d1WUARDcD7jG0zU2TlC5X4A6sDfqLGgEU7kAXcT7WomKO7+qMSKk5PIYUdkz/zk6L7MTIf7d7S7dyjH5wpQpyXCrpjN1s02usLylSpQ1DyUCrKuvOmWBDjvFZ5DUoJpDpssMwZy+UER5ergMus10VWcnjYFxmr2Ao+uBrIjR9M+s4vL2OXhPKeoq7np1z8cjYOnHTzt4Omr4IqwnNQ6f7zQ4qzpLqZq1pRyFNXfzlQMMmX4fz5n2CCqPyoVvGNXCO/ckTW8UCre6ydztWhWqjHRDaycsV6tSwwm91EEnMHQVx57MjNAKvJC4xFnAmUfZZhg5oeKHPkmzJbP/MVi1VmNVTNHYCsNcASDYDLnB17uSjLmYsowEQX+hluRi4sTIUtZ0XZLUFkONBrtKC9LNewjaA2ltVpGFk0oaQKjwC/NOO5uVaDwA+WdUgwUUNyuwmtfIJDJzF5busl8udie118Lz/u3rqqZdWVmHndZL15ezeFFzvNUYla2dYtZr7jCb1HCN1R83mKdSBCwmFSiN/XGuRoserWsNdhHCUaZIkpgQcy9qP523vkNkfOE4Epgaxzd27tz8I8Ae4e20o2i0ciWOsgrhM/sIb+F6d4uWJSZpwxiW4UQuuvh8+MzBFIozwEunjJ2ERWnjhW+Ql5kqriOPr84kt8t7HEfMOgPtPQjazz+Ms+76+OYxw7XU66Jl/VcoWAAbB2XXFod7N9SFgvV+CwJdZCTgPIkGOFj6rZVHPLEIJlVOIATTeupLuh3jhWq2lJ1m+EgmuZNEKuVXg2gYkxXc9Pzj01ZN3RyvV/RP0naeD0H0be6sKnffXzBa1Pv6JMLHX860+xpq9W84TxgpdNP5zoh7+jjic7uLfSM+PiTGXlzed7Jvbk234uLCr8gqRwU6u9m3Q1lLMJLPRuf5Th2StHC98CSAfEv1ek+jHfB+nvATGRp0Q1M825hGuFYeMNVy6zuTC0VL58G6+HJBs76HwP/8Ne/0ni8peFgIHcYvTwvChUoyOT8Qu0qKAuFptMpwmixHrkiSuMniqt6pvuPP0AZpurTvugXCtFgrsFz06C3pVUzg/1X7ZguQ2CZWHVl1MYKJKCm7UoR5Q4ottlchhK581zgeTsf5rWxczCUxGh7ieqVyIXv8Ep29+mCNDPxqHWE5JrBcRmp1z9e18HbOmxq2TLT1o2+BgdRw4NSw2uFRtd7Gl/rafvGQCO+t28OtNXllV3e+LDsvj3v4JtjHbw7UlYGBWSWoQhmazq8HwcRjJlTIOD5xRIeeca6DqkXT/BkzHV/bpzJN4o0CiBz8KLk2JI4QKrlQm7Y9oWQUWQqEHiNYjjawWCoGQ7j9HwiM5P/NOwmHty7p9NnHEo9eyKyQdRqa7yjEGLnHzz45J7cWmwdbHOgNNQ+W9Lt4XW84VbXr99Smfc1iLsqbECfLx7HVbPNbNH0FfGS+wbPcwgmvYDEmAAOZqJJGKHO6rmz5r7Hsk5ay5NBPkePklx+Oj4HLzJTN4YX38Y4gq4GL3O4mnc17WVXYeUWtB9kCDJAYERrcyZkBlyNI8J2cKF3MeWbOjntxdi8H7PLBB+edCDZPe6DDQYDhW6n0GW9eHkzaIBxQY1lejxfaL6cYEHWnIghV8n+PlLWti2zd6EG4v3fRzqWuqqJgvrDkc4x/QnF+e/+4l/pL/6Hv9AHv/lAn3zyMc7lUhfTc0xUjvMyoO5A/reWGpSowbfYGm/LYiCvlZ85jAd70BO1t31Dezs3xbmyVmlGbIoqpI40k4dgkSgpXP7wAe1U6er41+vBaB4A+C5Bx4zDmCbZ87Ze7vD61utchtolvJ6Df/j4HZQQLjR53heB4yiL3mUVJ9rh8vOVaNPHJtvbbtINFrrrd5PxhthxxCH88sSrdVxBoiWY0LK2V6qY9Y8/PZLPbhe+M94ZboawaLzwE0G2hudnx2qo28BIg6sFzl2R58ywpPliqdF4qJ//4qf6BKtwPpl128fFqsIDaSQIQQ5yH8MPlhrwDAe7GpcHGvU4pJLU4Ke0zHivu2wm5LRacRjUsFwlvtaPYzFoR/hgzkK+zn7+9vLnH59LQAboTSWmInh/0OHj9YpXGe3frwNv7/le18HTazDFkKkftxQN5dWL4PXcCnns4CUrju4lk5lJctDXDgEZeHOHL2tsKGnQleBdukWInoCqxC5iFGrt47TtXB/r/NlUF8cTzS7mmk3mOH8r+fmA0el8NlO/P+pMfMN2cX//wKXBEjGT//eDf/5nf6q3797Vt7/zTd1+566Gw1zDQV9FMUBkLA0o1Ln/IQ72Oltbu9phu7g9PICBTqKhULU8RIRbhiFM3UZGqED38KIwQXPXKSUZjC9in9xXn3XdTa43cdh8P4/hQYZCJAvQ9zz3pYS3c3gp88rHC3rWmSt2T1Mc2JQi47FOKXij5Ib/Y/JDphbBe7ssy1HoNa0uTAe9IXjZVdhUMzOZ2eYTfHBnjfJ53vMEA0GMUiTHrzk78KEz+3p44DfKpGv9qMN+rp2tPe1e20H4K50dnenowTNdnExw/ibKi1Jb2zt0LIQ/1ZSloWY7V6HdCz9lXK50cHiglrzx1r729q9hJQbMvqCDg2t6+vSR7n36gfyXSFrV2tk/lP/LaUMQksmDvxssQI0fkKDRx5QYgJe9CoF2OY5pcG23+Grxl347/8xMGdzxPurWhAvxpe1eV8HMFMAjQtsmdjQLnNRWTRsBlYMjAAAMoklEQVQZ2aCDAI15SFDboiRSok3FzmtytNTyomaX5VB16XrZIlQfPQj/Hp/A5iDkLAcZW7CeGm2HSlvADuD/2dgoSxpkAabkMgus6z0UYltbB1vqDUq2PCvlWaEYggIDbvAf8jxX2evLLJAfdf3WDV2/ua+MhXh7Z08127qWXUoWcjWk+2w7Dd9gfLCjfJipPx4p5TkHXA3bwUY1dRPWIlimgvOMlnTFTqZCKWoOmORaos8HM5OZPS/wpMPzjMuE5zlcfj6PzNZtfakwlgvXOw7u5LHT0DBhEkr5vMHrEuBA/l0JSaTsAl/w3SpyPb5kN9Sg4LBOwRL8ooinQfkyJmF3PjBLWk0bTY+XujhaaPJ0oXrRdnRQ9Ws9ToPD6xqV8D5s20L7kZmbrbQXK+3njfbyVv7LrmZrhmwaJyUFBFewbPTH7NPZFfhJ12K27H7BxJeKEKN2uFjq9XoqsBgN/kNrS5SgRutb/I4HWi6nyoqhRqNt9XCUDlhSdg6uK+R9FKAGzpg9F5wBzIAFcKE6reg9gaOibNb5CnC3I+0qmS4sh67glVeioME5bQGSr5R+/jMEX6ISgkscWKWuO1eIiuPuiiXUFeLzrS5zLlnnpn/JLWLdiukWlIVCsgxFTSjAStICwdZ8G6CuL2OkW9wmOvR3o/ocDA12Sw33CzVNyzFzze0t9ND6ix4fo8MX1fGyTmGRW9j131SKtXrc3kU0PVpX7K+XwBmZmJULHMXJxRlmbqViECT26Bf4EdPzlap5rdMnU52fTDlO3tH27r4mp2dacRp2/OSpPvrg17ImMpCFBqORdm7eUG0LFKNVlrXqVmdbyeRQ0/8Cxag0Q6GmNfjxRVpoSNDZMjOpACORUfLUy+BMcLia620rrqIbNVezvzAdYyZdalvSgnG3KGZCXI4jXRaZXg2e45CFJIcVJ7cWMuoHGVbt1frrb1OgEcZYRT9j4vGNRY1lUI+TxD4XSqNdbPhC7N6gIakLr46zy/war5rDN981BXcYW46BA7PADEquIElXemnblnuHWslnFekERAgtcQR746K7ZMqswBrkOnl6IuNncnGuFTeS9bLR8dFT5Thke9f2tY9PMN4rlPVDJ2xhIm0DsNlJcFIMoWf4Lg6mORZiqSXOV516VInA5nGuOGy+N/HLseOMIWP2ZYI8efAhOnj6KvjYW8ZohvAAVE5Nt1ws1ba5jLEGhcsmr++768+kYJLfMq6XZKnBibxs+LloQ4u3XRcmOf9mpxW8l1yhW6zDJZvWVd7w3uDY4Px8NQOf4EfA8jVCBwLE1QxuMzB1IfkMBIsL3TtvmZ0VF0WJPP+lkhpn0K1Ew9ar1y/UY80p0d4Mp7OHH/Drn3+IVZipbZKePn6orb2xbn/ntvq7A2W9DKczU8aVrAg+NqLPPT6YDYjRRxQjx3JErEmdCuobdBO95nnR7kWhKTBoBCna6eXg4/KxJOTq0GI719B0FZmHXauIZAcZyqSSpQq/h/W9q3D58raXyRcROGkmp8kzAxPP46vwunari6SHvzrV0w8uNHmy0NOPLjhiblUxuXy52LTf4N18f/U4yajcMumIMPJov5tCY2auiUxaM4U1DaKdCbPZOdvDZwgQP4HDpdPjo24LeYSQp5MzdhAz+ZlCgynf3t/R8CDwbVotKtodK8Qg4/AiL3KcyxJtbL1vBXMRixlneh0zukqXr6sDphmq0YBn085k5iBideF1+My8zhq83KGr3L3W+S38cMUwW393RbxMQXkomUVRTncPRfYdQJ0MOvQ80Kwbywb3JvYKZtbx1uCrGMELUEd3YuI8/vhEH/7ooX791/f14DdPtb0/1ME7I+29PZRPuouzueJIylg6RNjg99iBrJceulzjTvQGvFTIRyvjvS4IVEFYUS0zwdNrhAyQ75YloWaL47Pb/1bgBecAXs+3fr5zqFCMHhdMWRY1mU402tvRs8l9nU+PUZAJZxEXciuxfbijrd1dlomSjg2LEGXmREjOWLpiCUrdFspNove3poPqr3m8aY43XrMOL4EWgbym2tfKMjNoCoAhzNTFwYnrsKR1nijrZlEi11CMdX6NdXB6PVcEUMmBZBd72iFhbc28nzVI4Ns0EtxvpWF/qFvfONA3f++W3v79axoeFipGWSf8rVul7nx/Vzu3RlqFyCSSWto7gFYOoPlaT0o51lJd29AJm9lgZpJMIQRlmMGc7V1ihAwXRrTkFTpDGS7Oz7qdg18m+XFzH+LdkjT4HUv/XcbjE12cnCkrolxGRTFSEUZqJoF79VrG/loKSoygrZOiWuFjafqs0vG9ic4fLjQjXS/oOeml4CQ6eKahDHmolVuryjvyzEvwOg6Xn2IYm2SXvvrt9Rx8rOtKCR6YPM/shXIk+vHyaLnMDDxYUJzYaLVq+u9oeIVe78fB223A+evpTT6o/PM55PCtRPixXNPgBV7XoUvzgovCXUMZjL6lqpsQBSUGvP7xfhy81HE5eDowRmlNeGjwBZxAI9PMZGaKcT1znUEVDqAfDw+5fSzxBfy3lWLM1B8Mtb29291GJpRpyeFSapLqeav5aqY4bDQ4lAb7mYpBphxncfpsqflxo7MnM81PGl088e9a1elKvgoffmNLw4NCy2mlC5TCD1ycTqejhfHNZjexGYkEvQyF77pVN0tIahOupjd5m5hhdm033y9iI+kgyj1eC75z3KBBlwFVpT86RUlydlQt1sGVAh2/rPH5yMzAqU6RrpaS/fzT8T7/eEOiYPZkLOvr34ISk62FFsdbqGGytSjnG5q+JnutCF4QsrxQRLhm5t8doQkuOnh+XvTUGww0GI7k/y+013IF2tndU6TdfD7XkEul8WhLF6enqvAT9jht7HEOMdoda7w3VLkV1NvOtH2rr1gm+WGTC1nORBTInaHYN8XC5Fuo3beGKrcjyrLQclLLgwuj5oDGPXr/dnCSnZ4c5iSZagQCOsbgpQ7JXy9B14ZGDPFKPWmTb0ahXg4+WXwGuaA2/XstM9504TuyEh/CWzUIokZHKmhpKfO8DfgS27YUYg09z5ubgcM/vgC8ioNX8dhXL4/9e5OOONcJvN5/w4WYl22g7nZgmy89H6sIrTPiElkwez0xZiZnQlGiDL1+l25Z8/y3jk5YCj765BOdIPzIcvLg4UM95hxhjiI0cMBqhN/vyS2M5DNLnexzziV6O5n272x1FmPr+qC7px9fK7uDFQtrWixIg91cg+1Cs5Oq+9Wt5WlSaAoFi7oaIFMZ9X2meDohjFdkIM+/2ubL02sMifFu2proRGIGtmo6C2GK0BKD2zR1fbhS+gXfehQoPbSsUApXjjVG2uOHOV9FSGQ6kHz+mOx5epPwOhvwvKtp/15DomWlYM0ljWJyBCCXoCMBrqArNkdLDsE87T5Xk0S7UlIQdBkJycyegy6DGXkyZXlJxSgzI53r+ORYpxwmPXj0SO+//4H+5m/+Vr96/1e6//ABhAQtZytZlclqU0I5XCnM7BKrR9BH5FkdwOcupkpy4ojpTP29XIOdQt7e/zLZ+f2l6gltW6meJp09nsn9DhG8vSuEaAsKciQzPvT64EUOV0u9b7BfzerSZqYARMsYT6sWgRqog0G4EspRyZewBIJAfiTbrUWGxYqY8xZBLJtAzaAQoiQq6eVAU3VAttPvaZJf+HidDXjFNU0JJXWajP6Mnhpob7q8jgJTlzYamJkylrma8bRYj2BmMjOK1MVm9jz2wfnAPXbw4+bJxYXGW1uazRcd8RW7jevXrqksS52fnWp3f1t5LDrfoUUDO+aangezFx+JUTs8L7yS8GohmIpxkFuJyNa04oz++JOpTj6c6/GHZxLK9uTDc044W7oxBpkp8FPR75SyOeCzUl8j+Dhf0GQdLySTgGCRt8ksSDK1VGw4iHJImGhdCR39JmiSNkrR5TEmM7tSE9Lhg2d4dtv4WPxrDXSxTvD2ciJtYk+/CqBf94kSZliJgLANtUgsT5uySPeupIGT2OB1OPFt1soQOnxm1OhS65czxX2D1JlKU4uj6cL+8KNP5VfV//Sf/hP9w//8H+oPu7/M9nv67d/+vq7tu0O51I237mrv8LrEzJhxNe0HVGus67d35bD++oK3eZnJed8wGP+diIz9teFbHOBsbt3saffmUEefnusZCjJ7wgyAsb5+9+m7xzruZnqFclxlqq4Ez3fYZJnRn22+PH7pQ6FTCM9P8pLMchVcoEXLPPNzYFTqhIBAGixEAtS11OeCozh7NlG9aroaKa2rOO9RmW7ybfIcr5duYk9vwPO8T49fAIRcVniRJxlK45DZUv8bAAAA//8LXtM4AAAABklEQVQDAPYHeuvyKJ4cAAAAAElFTkSuQmCC\"","/** Miniaturas de `src/assets/imagenes` por mapa base; una nueva se agrega a esa carpeta. */\nconst URLS_IMAGENES_BASEMAP = import.meta.glob(\n \"../../../assets/imagenes/*.png\",\n { eager: true, query: \"?url\", import: \"default\" },\n) as Record<string, string>;\n\n/** Archivo de `src/assets/imagenes` que ilustra cada código ArcGIS de mapa base. */\nconst ARCHIVO_IMAGEN_BASEMAP: Record<string, string> = {\n \"streets-vector\": \"calles\",\n \"topo-vector\": \"topografico\",\n satellite: \"imagenes_satelitales\",\n hybrid: \"hibrido\",\n \"streets-navigation-vector\": \"navegacion\",\n \"gray-vector\": \"gris_claro\",\n \"dark-gray-vector\": \"gris_oscuro\",\n \"streets-night-vector\": \"calles_nocturno\",\n \"streets-relief-vector\": \"calle_con_relieve\",\n terrain: \"terreno\",\n oceans: \"oceanos\",\n osm: \"openStreetMap\",\n};\n\n/** URL de la miniatura del mapa base `codigo`; `undefined` si no tiene imagen. */\nexport function imagenBasemap(codigo: string): string | undefined {\n const archivo = ARCHIVO_IMAGEN_BASEMAP[codigo];\n if (!archivo) return undefined;\n\n const sufijo = `/${archivo}.png`;\n for (const [ruta, url] of Object.entries(URLS_IMAGENES_BASEMAP)) {\n if (ruta.endsWith(sufijo)) return url;\n }\n /* istanbul ignore next -- todo código mapeado tiene su archivo en assets/imagenes */\n return undefined;\n}\n","import { cn } from \"@/shared/lib/cn\";\nimport { imagenBasemap } from \"../utils/basemap-imagenes\";\n\n/** Props de `MiniaturaBasemap`. */\ninterface MiniaturaBasemapProps {\n codigo: string;\n seleccionado: boolean;\n className: string;\n}\n\n/** Miniatura de un mapa base; si no hay imagen para el código, un degradado. */\nexport function MiniaturaBasemap({\n codigo,\n seleccionado,\n className,\n}: MiniaturaBasemapProps) {\n const imagen = imagenBasemap(codigo);\n\n if (imagen) {\n return (\n <img\n src={imagen}\n alt=\"\"\n aria-hidden=\"true\"\n className={cn(\"shrink-0 rounded-lg object-cover\", className)}\n />\n );\n }\n\n return (\n <span\n aria-hidden=\"true\"\n className={cn(\n \"shrink-0 rounded-lg bg-linear-to-br\",\n seleccionado ? \"from-sky-200 to-sky-400\" : \"from-slate-200 to-slate-400\",\n className,\n )}\n />\n );\n}\n","import { cn } from \"@/shared/lib/cn\";\nimport type { ItemGaleriaMapas } from \"../types\";\nimport { CLASES_REALCE_BOTON } from \"../styles/controles.estilos\";\nimport { MiniaturaBasemap } from \"./MiniaturaBasemap\";\n\n/** Props de `ListaMapasBase`. */\ninterface ListaMapasBaseProps {\n items: readonly ItemGaleriaMapas[];\n valorActual: string;\n onSeleccionar: (codigo: string) => void;\n className?: string;\n}\n\n/** Lista de mapas base con miniatura, para el desplegable de escritorio y la hoja responsive. */\nexport function ListaMapasBase({\n items,\n valorActual,\n onSeleccionar,\n className,\n}: ListaMapasBaseProps) {\n return (\n <ul\n role=\"listbox\"\n className={cn(\n \"scrollbar-fina flex flex-1 flex-col gap-2.75 overflow-y-auto pr-1\",\n className,\n )}\n >\n {items.map((item) => {\n const seleccionado = item.codigo === valorActual;\n return (\n <li key={item.codigo}>\n <button\n type=\"button\"\n role=\"option\"\n aria-selected={seleccionado}\n onClick={() => onSeleccionar(item.codigo)}\n className={cn(\n \"flex h-10 w-full items-center gap-1.25 rounded-lg px-2 text-left hover:bg-slate-50 hover:shadow-md\",\n CLASES_REALCE_BOTON,\n seleccionado && \"bg-sky-50\",\n )}\n >\n <MiniaturaBasemap\n codigo={item.codigo}\n seleccionado={seleccionado}\n className=\"size-7\"\n />\n <span className=\"text-sm font-medium text-slate-800\">\n {item.nombre}\n </span>\n </button>\n </li>\n );\n })}\n </ul>\n );\n}\n","import { useState } from \"react\";\nimport { cn } from \"@/shared/lib/cn\";\nimport type { ItemGaleriaMapas } from \"../types\";\nimport {\n CLASES_BOTON_CERRAR,\n CLASES_BOTON_CONTROL,\n CLASES_BOTON_CONTROL_REPOSO,\n CLASES_BOTON_CONTROL_SELECCIONADO,\n} from \"../styles/controles.estilos\";\nimport { IconoCerrar } from \"./iconos\";\nimport { ListaMapasBase } from \"./ListaMapasBase\";\nimport { MiniaturaBasemap } from \"./MiniaturaBasemap\";\nimport { Tooltip } from \"./Tooltip\";\n\n/** Props de `SelectorBasemap`. */\ninterface SelectorBasemapProps {\n items: readonly ItemGaleriaMapas[];\n valor: string;\n onSeleccionar: (codigo: string) => void;\n /** Nombre de la herramienta: nombre accesible del botón y título del tooltip. */\n titulo: string;\n /** Descripción de la herramienta para el tooltip. */\n descripcion?: string;\n /** Controla el desplegable desde el padre; si se omite, maneja su propio estado. */\n abierto?: boolean;\n onToggle?: () => void;\n}\n\n/** Selector del mapa base a partir de la galería del contrato. */\nexport function SelectorBasemap({\n items,\n valor,\n onSeleccionar,\n titulo,\n descripcion,\n abierto: abiertoControlado,\n onToggle,\n}: SelectorBasemapProps) {\n // Estado propio, solo usado cuando el padre no controla el desplegable.\n const [abiertoPropio, setAbiertoPropio] = useState(false);\n const abierto = abiertoControlado ?? abiertoPropio;\n const alternar = onToggle ?? (() => setAbiertoPropio((estado) => !estado));\n\n const actual = items.find((item) => item.codigo === valor) ?? items[0];\n\n if (!actual) return null;\n\n return (\n <div data-superficie-modal=\"basemap\" className=\"relative\">\n {/* Botón que abre el desplegable; muestra la miniatura del mapa base activo. */}\n <Tooltip\n titulo={titulo}\n descripcion={descripcion}\n alineacion=\"inicio\"\n deshabilitado={abierto}\n >\n <button\n type=\"button\"\n aria-label={titulo}\n aria-haspopup=\"dialog\"\n aria-expanded={abierto}\n onClick={alternar}\n className={cn(\n CLASES_BOTON_CONTROL,\n abierto ? CLASES_BOTON_CONTROL_SELECCIONADO : CLASES_BOTON_CONTROL_REPOSO,\n )}\n >\n <MiniaturaBasemap codigo={actual.codigo} seleccionado className=\"size-7\" />\n </button>\n </Tooltip>\n\n {/* El diálogo permanece fijo: solo se cierra con su botón de cierre. */}\n {abierto && (\n <div\n role=\"dialog\"\n aria-labelledby=\"titulo-mapas-base\"\n className=\"absolute bottom-0 left-full z-20 ml-2 flex h-72 w-56 flex-col gap-1.25 rounded-[15px] border border-slate-200 bg-white p-2.5 shadow-2xl\"\n >\n {/* Cabecera con título y botón de cierre. */}\n <div className=\"relative flex items-center justify-center\">\n <h2 id=\"titulo-mapas-base\" className=\"text-sm font-bold text-slate-900\">\n Mapas base\n </h2>\n <button\n type=\"button\"\n aria-label=\"Cerrar\"\n onClick={alternar}\n className={cn(\"absolute right-0\", CLASES_BOTON_CERRAR)}\n >\n <IconoCerrar className=\"size-4\" />\n </button>\n </div>\n\n <ListaMapasBase\n items={items}\n valorActual={actual.codigo}\n onSeleccionar={onSeleccionar}\n />\n </div>\n )}\n </div>\n );\n}\n","import type { Ref } from \"react\";\r\nimport { cn } from \"@/shared/lib/cn\";\r\nimport type Graphic from \"@arcgis/core/Graphic\";\r\nimport type { CoordenadasPuntero } from \"../hooks/useCoordenadasPuntero\";\r\nimport type {\r\n AplicacionInfo,\r\n CampoConsulta,\r\n CapaConsultable,\r\n EstadosCapas,\r\n FiltroConsulta,\r\n GrupoServicios,\r\n HerramientaMapa,\r\n ItemGaleriaMapas,\r\n ItemLeyenda,\r\n ResultadoConsultaCapa,\r\n ResultadosConsultaCapas,\r\n ValoresDistintosCampo,\r\n VistaMapa,\r\n} from \"../types\";\r\nimport {\r\n CLASES_BOTON_CONTROL_REPOSO,\r\n CLASES_BOTON_CONTROL_SELECCIONADO,\r\n CLASES_REALCE_BOTON,\r\n} from \"../styles/controles.estilos\";\r\nimport { BarraHerramientas } from \"./BarraHerramientas\";\r\nimport { BotonTridimensional } from \"./BotonTridimensional\";\r\nimport { IconoHerramienta } from \"./iconos\";\r\nimport { LecturaCoordenadas } from \"./LecturaCoordenadas\";\r\nimport { ModalConsulta } from \"./ModalConsulta\";\r\nimport { ModalCoordenadas } from \"./ModalCoordenadas\";\r\nimport { ModalMedicion, type ModalMedicionHandle } from \"./ModalMedicion\";\r\nimport { ModalProyeccion } from \"./ModalProyeccion\";\r\nimport { PanelCapas } from \"./PanelCapas\";\r\nimport { PanelMetadata } from \"./PanelMetadata\";\r\nimport { SelectorBasemap } from \"./SelectorBasemap\";\r\nimport { Tooltip } from \"./Tooltip\";\r\n\r\n/** Definiciones de medición requeridas por `ModalMedicion`. */\r\ninterface DefinicionesMedicion {\r\n distancia: HerramientaMapa;\r\n area: HerramientaMapa;\r\n}\r\n\r\n/** Props de `ControlesEscritorio`. */\r\ninterface ControlesEscritorioProps {\r\n vista: VistaMapa;\r\n /** Factor de escala de las modales de herramienta en pantallas grandes; `1` es el tamaño de diseño. */\r\n escalaInterfaz: number;\r\n\r\n // Barra de herramientas y estado de la herramienta activa.\r\n herramientasBarra: readonly HerramientaMapa[];\r\n codigoActivo?: string;\r\n codigoPadreActivo?: string;\r\n soportada: (codigo: string) => boolean;\r\n onAlternar: (codigo: string) => void;\r\n onAlternarSubHerramienta: (subCodigo: string) => void;\r\n coordenadasPuntero: CoordenadasPuntero | null;\r\n\r\n // Panel de capas.\r\n panelCapasAbierto: boolean;\r\n onCerrarPanelCapas: () => void;\r\n gruposResueltos: readonly GrupoServicios[];\r\n estados: EstadosCapas;\r\n escala?: number;\r\n onCambioServicio: (nombre: string, visible: boolean) => void;\r\n onCambioOpacidad: (nombre: string, opacidad: number) => void;\r\n onCambioOpacidadCapa: (nombre: string, identificador: string, opacidad: number) => void;\r\n onCambioCapa: (nombre: string, identificador: string, visible: boolean) => void;\r\n onZoomCapa: (\r\n nombre: string,\r\n identificador: string,\r\n minScale?: number,\r\n maxScale?: number,\r\n ) => void;\r\n onDescargarCapa: (\r\n nombre: string,\r\n identificador: string,\r\n etiqueta: string,\r\n ) => Promise<void>;\r\n onObtenerLeyenda: (\r\n nombre: string,\r\n identificador: string,\r\n etiqueta: string,\r\n ) => Promise<ItemLeyenda[]>;\r\n\r\n // Coordenadas seleccionadas (herramienta \"get-coordinates\").\r\n coordenadasSeleccion: CoordenadasPuntero | null;\r\n onCerrarCoordenadas: () => void;\r\n\r\n // Modal de proyección.\r\n modalProyeccionAbierta: boolean;\r\n onCerrarProyeccion: () => void;\r\n\r\n // Modal de consulta por atributos.\r\n modalConsultaAbierta: boolean;\r\n onCerrarConsulta: () => void;\r\n capasConsultables: readonly CapaConsultable[];\r\n onCamposDeCapa: (\r\n nombreServicio: string,\r\n identificador: string,\r\n ) => Promise<CampoConsulta[]>;\r\n onValoresDistintos: (\r\n nombreServicio: string,\r\n identificador: string,\r\n campo: string,\r\n ) => Promise<ValoresDistintosCampo>;\r\n onEjecutarConsulta: (\r\n nombreServicio: string,\r\n identificador: string,\r\n filtro: FiltroConsulta,\r\n ) => Promise<ResultadoConsultaCapa>;\r\n onResultadoConsulta: (resultado: ResultadoConsultaCapa, capa: CapaConsultable) => void;\r\n /** Resultados por capa consultada (una pestaña por capa, ej. Línea y Torre). */\r\n resultadosConsulta: ResultadosConsultaCapas;\r\n /** Filas marcadas (checkbox) de la tabla de resultados. */\r\n seleccionadosConsulta: ReadonlySet<Graphic>;\r\n onAlternarFilaResultado: (grafico: Graphic) => void;\r\n onAlternarTodosResultado: () => void;\r\n /** Acerca la vista a una fila ya marcada, sin desmarcarla (lupa por fila). */\r\n onZoomFilaResultado: (grafico: Graphic) => void;\r\n /** Cierra una pestaña de resultados sin afectar las demás. */\r\n onQuitarPestanaResultado: (clave: string) => void;\r\n /** Cambia cuál pestaña de resultados se ve. */\r\n onCambiarPestanaResultado: (clave: string) => void;\r\n\r\n // Modal de medición.\r\n modalMedicionAbierta: boolean;\r\n medicionDefs: DefinicionesMedicion | null;\r\n tridimensional: boolean;\r\n onCerrarMedicion: () => void;\r\n /** Ref imperativa para que la acción \"clear\" limpie las mediciones de la modal. */\r\n medicionRef?: Ref<ModalMedicionHandle>;\r\n\r\n // Metadatos.\r\n herramientaMetadata?: HerramientaMapa;\r\n panelMetadataAbierto: boolean;\r\n onAlternarMetadata: () => void;\r\n onCerrarMetadata: () => void;\r\n aplicacion: AplicacionInfo;\r\n\r\n // Mapa base.\r\n herramientaBaseMap?: HerramientaMapa;\r\n galeria: readonly ItemGaleriaMapas[];\r\n basemapActual: string;\r\n onSeleccionarBasemap: (codigo: string) => void;\r\n panelBaseMapAbierto: boolean;\r\n onAlternarPanelBaseMap: () => void;\r\n\r\n // 3D.\r\n herramientaTridimensional?: HerramientaMapa;\r\n onAlternarTridimensional: () => void;\r\n}\r\n\r\n/** Controles del visor en escritorio: barra inferior derecha, mapa base/metadatos/3D y modales. */\r\nexport function ControlesEscritorio({\r\n vista,\r\n escalaInterfaz,\r\n herramientasBarra,\r\n codigoActivo,\r\n codigoPadreActivo,\r\n soportada,\r\n onAlternar,\r\n onAlternarSubHerramienta,\r\n coordenadasPuntero,\r\n panelCapasAbierto,\r\n onCerrarPanelCapas,\r\n gruposResueltos,\r\n estados,\r\n escala,\r\n onCambioServicio,\r\n onCambioOpacidad,\r\n onCambioOpacidadCapa,\r\n onCambioCapa,\r\n onZoomCapa,\r\n onDescargarCapa,\r\n onObtenerLeyenda,\r\n coordenadasSeleccion,\r\n onCerrarCoordenadas,\r\n modalProyeccionAbierta,\r\n onCerrarProyeccion,\r\n modalConsultaAbierta,\r\n onCerrarConsulta,\r\n capasConsultables,\r\n onCamposDeCapa,\r\n onValoresDistintos,\r\n onEjecutarConsulta,\r\n onResultadoConsulta,\r\n resultadosConsulta,\r\n seleccionadosConsulta,\r\n onAlternarFilaResultado,\r\n onAlternarTodosResultado,\r\n onZoomFilaResultado,\r\n onQuitarPestanaResultado,\r\n onCambiarPestanaResultado,\r\n modalMedicionAbierta,\r\n medicionDefs,\r\n tridimensional,\r\n onCerrarMedicion,\r\n medicionRef,\r\n herramientaMetadata,\r\n panelMetadataAbierto,\r\n onAlternarMetadata,\r\n onCerrarMetadata,\r\n aplicacion,\r\n herramientaBaseMap,\r\n galeria,\r\n basemapActual,\r\n onSeleccionarBasemap,\r\n panelBaseMapAbierto,\r\n onAlternarPanelBaseMap,\r\n herramientaTridimensional,\r\n onAlternarTridimensional,\r\n}: ControlesEscritorioProps) {\r\n return (\r\n <>\r\n {/* Esquina inferior derecha: controles apilados sobre la barra. */}\r\n <div\r\n data-superficie-modal=\"capas\"\r\n className=\"absolute bottom-3 right-3 z-20 flex flex-col items-end gap-2\"\r\n >\r\n {/* Panel de capas. */}\r\n {panelCapasAbierto && (\r\n <PanelCapas\r\n grupos={gruposResueltos}\r\n estados={estados}\r\n escala={escala}\r\n onCambioServicio={onCambioServicio}\r\n onCambioOpacidad={onCambioOpacidad}\r\n onCambioOpacidadCapa={onCambioOpacidadCapa}\r\n onCambioCapa={onCambioCapa}\r\n onZoomCapa={onZoomCapa}\r\n onDescargarCapa={onDescargarCapa}\r\n onObtenerLeyenda={onObtenerLeyenda}\r\n onCerrar={onCerrarPanelCapas}\r\n />\r\n )}\r\n {/* Modal con las coordenadas del punto marcado. */}\r\n {codigoActivo === \"get-coordinates\" && coordenadasSeleccion && (\r\n <ModalCoordenadas\r\n coordenadas={coordenadasSeleccion}\r\n onCerrar={onCerrarCoordenadas}\r\n />\r\n )}\r\n {/* Barra de herramientas. */}\r\n <BarraHerramientas\r\n herramientas={herramientasBarra}\r\n codigoActivo={codigoActivo}\r\n codigoPadreActivo={codigoPadreActivo}\r\n codigosResaltados={[\r\n ...(panelCapasAbierto ? [\"layer\"] : []),\r\n ...(modalMedicionAbierta ? [\"measurement-tools\"] : []),\r\n ...(modalProyeccionAbierta ? [\"project\"] : []),\r\n ...(modalConsultaAbierta ? [\"query\"] : []),\r\n ]}\r\n onAlternar={onAlternar}\r\n onAlternarSubHerramienta={onAlternarSubHerramienta}\r\n soportada={soportada}\r\n />\r\n {/* Lectura de coordenadas del puntero. */}\r\n <LecturaCoordenadas coordenadas={coordenadasPuntero} className=\"mr-5\" />\r\n </div>\r\n\r\n {/* Modal arrastrable para proyectar coordenadas entre sistemas. */}\r\n {modalProyeccionAbierta && (\r\n <div data-superficie-modal=\"proyeccion\" className=\"relative\">\r\n <ModalProyeccion\r\n vista={vista}\r\n onCerrar={onCerrarProyeccion}\r\n escalaInterfaz={escalaInterfaz}\r\n />\r\n </div>\r\n )}\r\n\r\n {/* Modal arrastrable con las herramientas de medición (solo en 2D). */}\r\n {modalMedicionAbierta && !tridimensional && medicionDefs && vista.type === \"2d\" && (\r\n <div data-superficie-modal=\"medicion\" className=\"relative\">\r\n <ModalMedicion\r\n ref={medicionRef}\r\n vista={vista}\r\n distancia={medicionDefs.distancia}\r\n area={medicionDefs.area}\r\n onCerrar={onCerrarMedicion}\r\n escalaInterfaz={escalaInterfaz}\r\n />\r\n </div>\r\n )}\r\n\r\n {/* Modal de consulta por atributos: alterna formulario/tabla de resultados por pestaña (ver `ModalConsulta`). */}\r\n {modalConsultaAbierta && (\r\n <div data-superficie-modal=\"consulta\" className=\"relative\">\r\n <ModalConsulta\r\n escalaInterfaz={escalaInterfaz}\r\n capasConsultables={capasConsultables}\r\n onCamposDeCapa={onCamposDeCapa}\r\n onValoresDistintos={onValoresDistintos}\r\n onEjecutarConsulta={onEjecutarConsulta}\r\n onCerrar={onCerrarConsulta}\r\n onResultado={onResultadoConsulta}\r\n resultadosConsulta={resultadosConsulta}\r\n seleccionadosResultado={seleccionadosConsulta}\r\n onAlternarFilaResultado={onAlternarFilaResultado}\r\n onAlternarTodosResultado={onAlternarTodosResultado}\r\n onZoomFilaResultado={onZoomFilaResultado}\r\n onQuitarPestanaResultado={onQuitarPestanaResultado}\r\n onCambiarPestanaResultado={onCambiarPestanaResultado}\r\n />\r\n </div>\r\n )}\r\n\r\n {/* Inferior izquierda: metadatos, mapa base y modo 3D, alineados con\r\n la barra (que va por encima de la lectura de coordenadas). */}\r\n {(herramientaMetadata || herramientaBaseMap || herramientaTridimensional) && (\r\n <div className=\"absolute bottom-8 left-3 z-10 flex flex-col items-start gap-1\">\r\n {/* Botón pequeño de metadatos: alterna el panel con la descripción. */}\r\n {herramientaMetadata && (\r\n <div data-superficie-modal=\"metadata\" className=\"relative\">\r\n <Tooltip\r\n titulo={herramientaMetadata.nombre}\r\n descripcion={herramientaMetadata.descripcion}\r\n alineacion=\"inicio\"\r\n deshabilitado={panelMetadataAbierto}\r\n >\r\n <button\r\n type=\"button\"\r\n aria-label={herramientaMetadata.nombre}\r\n aria-haspopup=\"dialog\"\r\n aria-expanded={panelMetadataAbierto}\r\n aria-pressed={panelMetadataAbierto}\r\n onClick={onAlternarMetadata}\r\n className={cn(\r\n \"grid size-8 place-items-center rounded-xl text-[#9EA0A2]\",\r\n CLASES_REALCE_BOTON,\r\n panelMetadataAbierto\r\n ? CLASES_BOTON_CONTROL_SELECCIONADO\r\n : CLASES_BOTON_CONTROL_REPOSO,\r\n )}\r\n >\r\n <IconoHerramienta\r\n codigo=\"metadata\"\r\n rutaIcono={herramientaMetadata.rutaIcono}\r\n className=\"size-5\"\r\n />\r\n </button>\r\n </Tooltip>\r\n\r\n {panelMetadataAbierto && (\r\n <PanelMetadata aplicacion={aplicacion} onCerrar={onCerrarMetadata} />\r\n )}\r\n </div>\r\n )}\r\n {herramientaBaseMap && (\r\n <SelectorBasemap\r\n items={galeria}\r\n valor={basemapActual}\r\n onSeleccionar={onSeleccionarBasemap}\r\n titulo={herramientaBaseMap.nombre}\r\n descripcion={herramientaBaseMap.descripcion}\r\n abierto={panelBaseMapAbierto}\r\n onToggle={onAlternarPanelBaseMap}\r\n />\r\n )}\r\n {/* Botón de modo 3D. */}\r\n {herramientaTridimensional && (\r\n <BotonTridimensional\r\n herramienta={herramientaTridimensional}\r\n activo={tridimensional}\r\n onClick={onAlternarTridimensional}\r\n />\r\n )}\r\n </div>\r\n )}\r\n </>\r\n );\r\n}\r\n","import { useCallback, useState } from \"react\";\r\n\r\n/** Parámetros de `useHojaInferiorArrastrable`. */\r\ninterface OpcionesHojaInferior {\r\n /** Anclajes como fracción (0–1) del contenedor, de menor a mayor. */\r\n readonly puntosAnclaje: readonly number[];\r\n /** Alto del contenedor de referencia (px), normalmente el del propio mapa. */\r\n readonly alturaContenedor: number;\r\n /** Índice de `puntosAnclaje` con el que abre la hoja. Por defecto, el del medio. */\r\n readonly anclaInicial?: number;\r\n}\r\n\r\n/** Valor devuelto por `useHojaInferiorArrastrable`. */\r\ninterface HojaInferiorArrastrable {\r\n /** Alto actual de la hoja (px), siempre entre el primer y el último anclaje. */\r\n readonly altura: number;\r\n /** Índice del punto de anclaje vigente dentro de `puntosAnclaje`. */\r\n readonly indiceAnclaje: number;\r\n /** `onPointerDown` del asa de arrastre. */\r\n readonly alArrastrar: (evento: React.PointerEvent<HTMLElement>) => void;\r\n}\r\n\r\n/** Alto (px) de una hoja inferior arrastrable en vertical que salta al anclaje más cercano. */\r\nexport function useHojaInferiorArrastrable({\r\n puntosAnclaje,\r\n alturaContenedor,\r\n anclaInicial = Math.floor((puntosAnclaje.length - 1) / 2),\r\n}: OpcionesHojaInferior): HojaInferiorArrastrable {\r\n const [indiceAnclaje, setIndiceAnclaje] = useState(anclaInicial);\r\n const [alturaArrastre, setAlturaArrastre] = useState<number | null>(null);\r\n\r\n const alturaDeAnclaje = useCallback(\r\n (indice: number) => puntosAnclaje[indice] * alturaContenedor,\r\n [puntosAnclaje, alturaContenedor],\r\n );\r\n\r\n const indiceMasCercano = useCallback(\r\n (altura: number) => {\r\n let mejorIndice = 0;\r\n let mejorDistancia = Infinity;\r\n puntosAnclaje.forEach((fraccion, indice) => {\r\n const distancia = Math.abs(fraccion * alturaContenedor - altura);\r\n if (distancia < mejorDistancia) {\r\n mejorDistancia = distancia;\r\n mejorIndice = indice;\r\n }\r\n });\r\n return mejorIndice;\r\n },\r\n [puntosAnclaje, alturaContenedor],\r\n );\r\n\r\n const alArrastrar = useCallback(\r\n (evento: React.PointerEvent<HTMLElement>) => {\r\n // No arrastrar cuando se pulsa un control dentro del asa.\r\n if ((evento.target as HTMLElement).closest(\"button\")) return;\r\n\r\n const asa = evento.currentTarget;\r\n asa.setPointerCapture(evento.pointerId);\r\n\r\n const yInicial = evento.clientY;\r\n const alturaInicial = alturaDeAnclaje(indiceAnclaje);\r\n const minimo = alturaDeAnclaje(0);\r\n const maximo = alturaDeAnclaje(puntosAnclaje.length - 1);\r\n\r\n // Valor actual del arrastre, sin esperar al render: necesario porque los\r\n // listeners (pointermove/pointerup) no se re-suscriben por setState y así\r\n // se evita hacer setState dentro del actualizador de otro setState.\r\n let alturaArrastreActual: number | null = null;\r\n\r\n const alMover = (e: PointerEvent) => {\r\n // Arrastrar hacia arriba (Y menor) agranda la hoja.\r\n const propuesta = alturaInicial - (e.clientY - yInicial);\r\n alturaArrastreActual = Math.min(Math.max(propuesta, minimo), maximo);\r\n setAlturaArrastre(alturaArrastreActual);\r\n };\r\n const finalizar = (e: PointerEvent) => {\r\n asa.releasePointerCapture(e.pointerId);\r\n asa.removeEventListener(\"pointermove\", alMover);\r\n asa.removeEventListener(\"pointerup\", finalizar);\r\n asa.removeEventListener(\"pointercancel\", finalizar);\r\n setIndiceAnclaje(\r\n indiceMasCercano(alturaArrastreActual ?? alturaInicial),\r\n );\r\n setAlturaArrastre(null);\r\n };\r\n\r\n asa.addEventListener(\"pointermove\", alMover);\r\n asa.addEventListener(\"pointerup\", finalizar);\r\n asa.addEventListener(\"pointercancel\", finalizar);\r\n },\r\n [alturaDeAnclaje, indiceAnclaje, puntosAnclaje.length, indiceMasCercano],\r\n );\r\n\r\n return {\r\n altura: alturaArrastre ?? alturaDeAnclaje(indiceAnclaje),\r\n indiceAnclaje,\r\n alArrastrar,\r\n };\r\n}\r\n","import type { ReactNode } from \"react\";\nimport { cn } from \"@/shared/lib/cn\";\nimport { useHojaInferiorArrastrable } from \"@/shared/hooks/useHojaInferiorArrastrable\";\nimport {\n CLASES_ASA_HOJA_INFERIOR,\n CLASES_BOTON_CERRAR,\n CLASES_HOJA_INFERIOR,\n PUNTOS_ANCLAJE_HOJA_INFERIOR,\n} from \"../styles/controles.estilos\";\nimport { IconoArrastrar, IconoCerrar } from \"./iconos\";\n\n/** Props de `PanelInferior`. */\ninterface PanelInferiorProps {\n titulo: string;\n onCerrar: () => void;\n /** Alto (px) del contenedor del mapa: define los puntos de anclaje de la hoja. */\n alturaContenedor: number;\n children: ReactNode;\n}\n\n/** Hoja inferior responsive con tres alturas; se arrastra desde el asa y se cierra con la «X». */\nexport function PanelInferior({\n titulo,\n onCerrar,\n alturaContenedor,\n children,\n}: PanelInferiorProps) {\n const { altura, alArrastrar } = useHojaInferiorArrastrable({\n puntosAnclaje: PUNTOS_ANCLAJE_HOJA_INFERIOR,\n alturaContenedor,\n });\n\n return (\n <div\n role=\"dialog\"\n aria-labelledby=\"titulo-panel-inferior\"\n className={CLASES_HOJA_INFERIOR}\n style={{ height: altura }}\n >\n {/* Asa de arrastre: cambia la altura entre los puntos de anclaje. */}\n <div className={CLASES_ASA_HOJA_INFERIOR} onPointerDown={alArrastrar}>\n <IconoArrastrar className=\"h-1.5 w-10 text-slate-300\" />\n </div>\n\n {/* Cabecera con título y botón de cierre. */}\n <div className=\"relative flex shrink-0 items-center justify-center px-5 pb-2\">\n <h2 id=\"titulo-panel-inferior\" className=\"text-sm font-bold text-slate-900\">\n {titulo}\n </h2>\n <button\n type=\"button\"\n aria-label=\"Cerrar\"\n onClick={onCerrar}\n className={cn(\"absolute right-5\", CLASES_BOTON_CERRAR)}\n >\n <IconoCerrar className=\"size-4\" />\n </button>\n </div>\n\n <div className=\"min-h-0 flex-1 overflow-y-auto px-5 pb-3\">{children}</div>\n </div>\n );\n}\n","import { cn } from \"@/shared/lib/cn\";\nimport type {\n EstadosCapas,\n GrupoServicios,\n HerramientaMapa,\n ItemGaleriaMapas,\n ItemLeyenda,\n} from \"../types\";\nimport {\n CLASES_BOTON_CONTROL,\n CLASES_BOTON_CONTROL_REPOSO,\n CLASES_BOTON_CONTROL_SELECCIONADO,\n} from \"../styles/controles.estilos\";\nimport { ArbolCapas } from \"./ArbolCapas\";\nimport { BarraHerramientas } from \"./BarraHerramientas\";\nimport { BotonTridimensional } from \"./BotonTridimensional\";\nimport { ListaMapasBase } from \"./ListaMapasBase\";\nimport { MiniaturaBasemap } from \"./MiniaturaBasemap\";\nimport { PanelInferior } from \"./PanelInferior\";\nimport { Tooltip } from \"./Tooltip\";\n\n/** Props de `ControlesResponsive`. */\ninterface ControlesResponsiveProps {\n /** Alto (px) del contenedor del mapa: define los anclajes de la hoja inferior. */\n alturaContenedor: number;\n\n // Barra reducida.\n herramientasBarra: readonly HerramientaMapa[];\n codigoActivo?: string;\n soportada: (codigo: string) => boolean;\n onAlternar: (codigo: string) => void;\n\n // Mapa base.\n herramientaBaseMap?: HerramientaMapa;\n galeria: readonly ItemGaleriaMapas[];\n basemapActual: string;\n onSeleccionarBasemap: (codigo: string) => void;\n panelBaseMapAbierto: boolean;\n onAlternarPanelBaseMap: () => void;\n\n // Capas.\n panelCapasAbierto: boolean;\n onCerrarPanelCapas: () => void;\n gruposResueltos: readonly GrupoServicios[];\n estados: EstadosCapas;\n escala?: number;\n onCambioServicio: (nombre: string, visible: boolean) => void;\n onCambioOpacidad: (nombre: string, opacidad: number) => void;\n onCambioOpacidadCapa: (nombre: string, identificador: string, opacidad: number) => void;\n onCambioCapa: (nombre: string, identificador: string, visible: boolean) => void;\n onZoomCapa: (\n nombre: string,\n identificador: string,\n minScale?: number,\n maxScale?: number,\n ) => void;\n onDescargarCapa: (\n nombre: string,\n identificador: string,\n etiqueta: string,\n ) => Promise<void>;\n onObtenerLeyenda: (\n nombre: string,\n identificador: string,\n etiqueta: string,\n ) => Promise<ItemLeyenda[]>;\n\n // 3D.\n herramientaTridimensional?: HerramientaMapa;\n tridimensional: boolean;\n onAlternarTridimensional: () => void;\n}\n\n/**\n * Controles del visor en responsive, agrupados abajo al centro. \"Mapa base\" y\n * \"Capas\" comparten una hoja inferior (ver `usePanelesInferiores`).\n */\nexport function ControlesResponsive({\n alturaContenedor,\n herramientasBarra,\n codigoActivo,\n soportada,\n onAlternar,\n herramientaBaseMap,\n galeria,\n basemapActual,\n onSeleccionarBasemap,\n panelBaseMapAbierto,\n onAlternarPanelBaseMap,\n panelCapasAbierto,\n onCerrarPanelCapas,\n gruposResueltos,\n estados,\n escala,\n onCambioServicio,\n onCambioOpacidad,\n onCambioOpacidadCapa,\n onCambioCapa,\n onZoomCapa,\n onDescargarCapa,\n onObtenerLeyenda,\n herramientaTridimensional,\n tridimensional,\n onAlternarTridimensional,\n}: ControlesResponsiveProps) {\n const basemapActivo =\n galeria.find((item) => item.codigo === basemapActual) ?? galeria[0];\n\n return (\n <>\n {/* Fila inferior centrada: mapa base, barra reducida y 3D. */}\n <div className=\"absolute inset-x-3 bottom-3 z-20 flex items-center justify-center gap-2\">\n {herramientaBaseMap && basemapActivo && (\n <Tooltip\n titulo={herramientaBaseMap.nombre}\n descripcion={herramientaBaseMap.descripcion}\n alineacion=\"inicio\"\n deshabilitado={panelBaseMapAbierto}\n >\n <button\n type=\"button\"\n aria-label={herramientaBaseMap.nombre}\n aria-haspopup=\"dialog\"\n aria-expanded={panelBaseMapAbierto}\n onClick={onAlternarPanelBaseMap}\n className={cn(\n CLASES_BOTON_CONTROL,\n panelBaseMapAbierto\n ? CLASES_BOTON_CONTROL_SELECCIONADO\n : CLASES_BOTON_CONTROL_REPOSO,\n )}\n >\n <MiniaturaBasemap\n codigo={basemapActivo.codigo}\n seleccionado\n className=\"size-7\"\n />\n </button>\n </Tooltip>\n )}\n\n <BarraHerramientas\n variante=\"responsive\"\n herramientas={herramientasBarra}\n codigoActivo={codigoActivo}\n codigosResaltados={panelCapasAbierto ? [\"layer\"] : []}\n onAlternar={onAlternar}\n // La barra reducida (`GRUPOS_BARRA_RESPONSIVE`) no incluye herramientas\n // con submenú, así que esto nunca se invoca; se reusa `onAlternar` en\n // vez de fabricar un no-op solo para satisfacer el tipo.\n onAlternarSubHerramienta={onAlternar}\n soportada={soportada}\n />\n\n {herramientaTridimensional && (\n <BotonTridimensional\n herramienta={herramientaTridimensional}\n activo={tridimensional}\n onClick={onAlternarTridimensional}\n />\n )}\n </div>\n\n {/* Hoja inferior compartida: mapa base o capas, mutuamente excluyentes. */}\n {panelBaseMapAbierto && (\n <PanelInferior\n titulo=\"Mapas base\"\n onCerrar={onAlternarPanelBaseMap}\n alturaContenedor={alturaContenedor}\n >\n <ListaMapasBase\n items={galeria}\n valorActual={basemapActivo?.codigo ?? \"\"}\n onSeleccionar={onSeleccionarBasemap}\n />\n </PanelInferior>\n )}\n {panelCapasAbierto && (\n <PanelInferior\n titulo=\"Capas y Servicios\"\n onCerrar={onCerrarPanelCapas}\n alturaContenedor={alturaContenedor}\n >\n <ArbolCapas\n grupos={gruposResueltos}\n estados={estados}\n escala={escala}\n onCambioServicio={onCambioServicio}\n onCambioOpacidad={onCambioOpacidad}\n onCambioOpacidadCapa={onCambioOpacidadCapa}\n onCambioCapa={onCambioCapa}\n onZoomCapa={onZoomCapa}\n onDescargarCapa={onDescargarCapa}\n onObtenerLeyenda={onObtenerLeyenda}\n />\n </PanelInferior>\n )}\n </>\n );\n}\n","import { cn } from \"@/shared/lib/cn\";\r\n\r\n/** Bloque de carga con pulso (decorativo: el contenedor expone `role=\"status\"`). */\r\nexport function Skeleton({ className }: { className?: string }) {\r\n return (\r\n <span\r\n aria-hidden=\"true\"\r\n className={cn(\r\n \"block animate-pulse rounded-md bg-slate-200/80\",\r\n className,\r\n )}\r\n />\r\n );\r\n}\r\n","import { cn } from \"@/shared/lib/cn\";\r\nimport { Skeleton } from \"@/shared/components/Skeleton\";\r\n\r\n/** Esqueleto del visor (mapa, barra y botones); paneles y modales tienen el suyo. */\r\nexport function VisorMapaSkeleton({ className }: { className?: string }) {\r\n return (\r\n <div\r\n role=\"status\"\r\n aria-label=\"Cargando el visor de mapa\"\r\n className={cn(\"relative overflow-hidden bg-slate-100\", className)}\r\n >\r\n {/* Barra de herramientas (esquina inferior derecha). */}\r\n <Skeleton className=\"absolute bottom-3 right-3 h-11.75 w-64 max-w-[calc(100%-1.5rem)] rounded-[15px]\" />\r\n\r\n {/* Mapa base y modo 3D (esquina inferior izquierda). */}\r\n <div className=\"absolute bottom-8 left-3 flex flex-col gap-1\">\r\n <Skeleton className=\"size-10 rounded-xl\" />\r\n <Skeleton className=\"size-10 rounded-xl\" />\r\n </div>\r\n </div>\r\n );\r\n}\r\n","import type { CSSProperties } from \"react\";\r\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\r\nimport * as reactiveUtils from \"@arcgis/core/core/reactiveUtils\";\r\nimport { cn } from \"@/shared/lib/cn\";\r\nimport { descargarArchivo } from \"@/shared/helpers/descargar-archivo\";\r\nimport { formatearDuracion } from \"@/shared/helpers/formato-duracion\";\r\nimport { useAlerta } from \"../context/alertas.context\";\r\nimport { useCoordenadasPuntero } from \"../hooks/useCoordenadasPuntero\";\r\nimport { useCoordenadasSeleccion } from \"../hooks/useCoordenadasSeleccion\";\r\nimport { useElevarSuperficies } from \"../hooks/useElevarSuperficies\";\r\nimport { useEstadosCapas } from \"../hooks/useEstadosCapas\";\r\nimport { useGestorCapas } from \"../hooks/useGestorCapas\";\r\nimport { useHerramientaActiva } from \"../hooks/useHerramientaActiva\";\r\nimport { useModoResponsive } from \"../hooks/useModoResponsive\";\r\nimport { usePanelesInferiores } from \"../hooks/usePanelesInferiores\";\r\nimport { useResaltadoConsulta } from \"../hooks/useResaltadoConsulta\";\r\nimport { useResultadosConsulta } from \"../hooks/useResultadosConsulta\";\r\nimport { useVistaArcgis } from \"../hooks/useVistaArcgis\";\r\nimport {\r\n DescargaCanceladaError,\r\n DescargaDemasiadoLentaError,\r\n DescargaMuyPesadaError,\r\n DescargaNoSoportadaError,\r\n} from \"../services/layers/descarga-capa\";\r\nimport { mensajeErrorServicio } from \"../services/layers/error-servicio\";\r\nimport type { FalloServicio } from \"../services/layers/gestor-capas\";\r\nimport {\r\n obtenerParametrosConsulta,\r\n obtenerParametrosDescarga,\r\n ParametrosGeneralesError,\r\n} from \"../services/parametros-generales\";\r\nimport { agruparHerramientasMedicion } from \"../services/tools/agrupar-herramientas\";\r\nimport { estaSoportadaConHijos } from \"../services/tools/herramientas.registry\";\r\nimport { esAccion, ejecutarAccion } from \"../services/tools/acciones.registry\";\r\nimport type {\r\n AplicacionInfo,\r\n CodigoHerramienta,\r\n DefinicionMapa,\r\n FiltroConsulta,\r\n GrupoServicios,\r\n ItemGaleriaMapas,\r\n ParametrosConsulta,\r\n ServicioGis,\r\n VistaMapa,\r\n} from \"../types\";\r\nimport { capasActivasConsultables } from \"../utils/capas-activas\";\r\nimport { useEscalaInterfaz } from \"../utils/mapa-helpers\";\r\nimport { filtrarHerramientasBarra } from \"../utils/filtrar-barra\";\r\nimport { reagruparServicios, resolverServicios } from \"../utils/resolver-servicios\";\r\nimport { ControlesEscritorio } from \"./ControlesEscritorio\";\r\nimport { ControlesResponsive } from \"./ControlesResponsive\";\r\nimport type { ModalMedicionHandle } from \"./ModalMedicion\";\r\nimport { VisorMapaSkeleton } from \"./VisorMapaSkeleton\";\r\nimport { CLASE_RAIZ_MAPA } from \"../styles/raiz.estilos\";\r\n\r\n/** Props de `MapaView`. */\r\ninterface MapaViewProps {\r\n definicion: DefinicionMapa;\r\n /** Datos de la aplicación (`configuracion.aplicacion`) para el panel de metadatos. */\r\n aplicacion: AplicacionInfo;\r\n galeria: readonly ItemGaleriaMapas[];\r\n servicios: readonly ServicioGis[];\r\n /** Servicios agrupados tal como los publica el backend (para el panel de capas). */\r\n grupos: readonly GrupoServicios[];\r\n /** Herramientas a ocultar. Ocultar una medición oculta también `\"measurement-tools\"`. */\r\n herramientasDeshabilitadas?: readonly CodigoHerramienta[];\r\n /** Se llama con la vista de ArcGIS cada vez que queda lista (también al alternar 2D/3D). */\r\n onListo?: (vista: VistaMapa) => void;\r\n className?: string;\r\n}\r\n\r\n// Al saltar al límite de escala de una capa (`zoomACapa`), el motor redondea\r\n// al nivel de zoom (LOD) más cercano y puede quedarse justo del lado de fuera\r\n// de rango. Este margen empuja el salto un poco más adentro del rango válido.\r\nconst MARGEN_ESCALA = 0.9;\r\n\r\n/** Visor principal del mapa: monta la vista de ArcGIS y sus controles. */\r\nexport function MapaView({\r\n definicion,\r\n aplicacion,\r\n galeria,\r\n servicios,\r\n grupos,\r\n herramientasDeshabilitadas,\r\n onListo,\r\n className,\r\n}: MapaViewProps) {\r\n const { configuracion } = definicion;\r\n\r\n // Modo de layout según el ancho real del contenedor (no del viewport): el\r\n // visor es un widget embebible y puede quedar angosto en pantallas anchas.\r\n const {\r\n ref: seccionRef,\r\n ancho: anchoContenedor,\r\n alto: altoContenedor,\r\n responsive: modoResponsive,\r\n } = useModoResponsive<HTMLElement>();\r\n // Escala de la interfaz superpuesta en pantallas grandes, según el ancho\r\n // del contenedor (no de la pantalla: en modo integrado puede ser angosto).\r\n const escalaInterfaz = useEscalaInterfaz(anchoContenedor);\r\n // El contenedor raíz también enlaza las superficies modales (z-index); se\r\n // mantiene sincronizado con la ref del modo responsive.\r\n const { raizRef, elevarModal, elevarSuperficie } =\r\n useElevarSuperficies<HTMLElement>();\r\n const combinarRefRaiz = useCallback(\r\n (elemento: HTMLElement | null) => {\r\n seccionRef(elemento);\r\n raizRef.current = elemento;\r\n },\r\n [seccionRef, raizRef],\r\n );\r\n\r\n // Modo 3D: activa la vista `SceneView` en lugar de `MapView`.\r\n const [tridimensional, setTridimensional] = useState(false);\r\n const alternarTridimensional = useCallback(\r\n () => setTridimensional((activo) => !activo),\r\n [],\r\n );\r\n\r\n // Vista de ArcGIS y gestor de capas asociados al contenedor.\r\n const { contenedorRef, vista, error, cambiarBasemap, irAInicio } = useVistaArcgis(\r\n configuracion,\r\n tridimensional,\r\n );\r\n // Avisa al anfitrión cuando hay una vista nueva; el callback va en una ref\r\n // para no relanzar el efecto si el anfitrión lo recrea en cada render.\r\n const onListoRef = useRef(onListo);\r\n useEffect(() => {\r\n onListoRef.current = onListo;\r\n }, [onListo]);\r\n useEffect(() => {\r\n if (vista) onListoRef.current?.(vista);\r\n }, [vista]);\r\n\r\n const alerta = useAlerta();\r\n const reportarFallos = useCallback(\r\n (fallos: readonly FalloServicio[]) => {\r\n const mensajes = fallos\r\n .map(\r\n ({ servicio, error: fallo }) =>\r\n `${servicio.nombre}: ${mensajeErrorServicio(fallo)}`,\r\n )\r\n .join(\"\\n\");\r\n\r\n alerta.mostrar({\r\n titulo: \"Servicios con errores\",\r\n mensaje: <span className=\"whitespace-pre-line\">{mensajes}</span>,\r\n });\r\n },\r\n [alerta],\r\n );\r\n const { gestorRef, capasDescubiertas } = useGestorCapas(\r\n vista,\r\n servicios,\r\n reportarFallos,\r\n );\r\n const [escala, setEscala] = useState<number>();\r\n useEffect(() => {\r\n if (!vista) return;\r\n // `initial: true` publica la escala actual al suscribirse, así no hace\r\n // falta un `setEscala` suelto en el cuerpo del efecto.\r\n const manejador = reactiveUtils.watch(\r\n () => vista.scale,\r\n (valor) => setEscala(valor),\r\n { initial: true },\r\n );\r\n return () => manejador.remove();\r\n }, [vista]);\r\n\r\n // Mapa base seleccionado; se aplica a la vista cuando cambia.\r\n const [basemapActual, setBasemapActual] = useState(configuracion.basemap);\r\n useEffect(() => {\r\n if (vista) cambiarBasemap(basemapActual);\r\n }, [vista, basemapActual, cambiarBasemap]);\r\n\r\n // Avisa si el contrato no trae ninguna capa: el mapa base funciona, pero no\r\n // hay servicios que mostrar. `ProveedorAlertas` de-duplica por título, así que\r\n // el aviso no se repite mientras siga en pantalla.\r\n const sinCapas = grupos.every((grupo) => grupo.servicios.length === 0);\r\n useEffect(() => {\r\n if (!vista || !sinCapas) return;\r\n alerta.mostrar({\r\n titulo: \"Sin capas\",\r\n mensaje:\r\n \"El mapa no tiene capas configuradas. Puedes navegar por el mapa base, \" +\r\n \"pero no hay servicios que mostrar.\",\r\n });\r\n }, [vista, sinCapas, alerta]);\r\n\r\n // Completa cada servicio con las subcapas descubiertas si el contrato no las\r\n // trae, y reagrupa los resueltos respetando la estructura del backend\r\n // (grupos → servicios) para alimentar el árbol del panel de capas.\r\n const serviciosResueltos = useMemo(\r\n () => resolverServicios(servicios, capasDescubiertas),\r\n [servicios, capasDescubiertas],\r\n );\r\n const gruposResueltos = useMemo(\r\n () => reagruparServicios(grupos, serviciosResueltos),\r\n [grupos, serviciosResueltos],\r\n );\r\n\r\n // Estado de visibilidad y opacidad de cada capa.\r\n const {\r\n estados,\r\n onCambioServicio,\r\n onCambioOpacidad,\r\n onCambioOpacidadCapa,\r\n onCambioCapa,\r\n } = useEstadosCapas(serviciosResueltos, gestorRef);\r\n\r\n // Capas activas consultables por la herramienta \"Consultar\": se recalcula\r\n // solo cuando cambia la lista resuelta de servicios o la visibilidad.\r\n const capasConsultables = useMemo(\r\n () => capasActivasConsultables(serviciosResueltos, estados),\r\n [serviciosResueltos, estados],\r\n );\r\n\r\n // Ocultar una sola sub-herramienta de medición oculta el grupo (la modal necesita ambas).\r\n const herramientasDeshabilitadasEfectivas = useMemo(() => {\r\n const codigos = new Set<string>(herramientasDeshabilitadas ?? []);\r\n if (codigos.has(\"measure-distance\") || codigos.has(\"measure-area\")) {\r\n codigos.add(\"measurement-tools\");\r\n }\r\n return codigos;\r\n }, [herramientasDeshabilitadas]);\r\n\r\n // Herramientas del contrato tras aplicar el filtro del consumidor.\r\n const herramientasHabilitadas = useMemo(\r\n () =>\r\n definicion.herramientas.filter(\r\n (h) => !herramientasDeshabilitadasEfectivas.has(h.codigo),\r\n ),\r\n [definicion.herramientas, herramientasDeshabilitadasEfectivas],\r\n );\r\n\r\n // Herramientas habilitadas con las de medición agrupadas en un submenú.\r\n const herramientas = useMemo(\r\n () => agruparHerramientasMedicion(herramientasHabilitadas),\r\n [herramientasHabilitadas],\r\n );\r\n\r\n // Herramientas que se muestran en la barra genérica (ver `filtrarHerramientasBarra`).\r\n const herramientasBarra = useMemo(\r\n () => filtrarHerramientasBarra(herramientas, tridimensional, modoResponsive),\r\n [herramientas, tridimensional, modoResponsive],\r\n );\r\n\r\n // Definiciones de las sub-herramientas de medición para la modal.\r\n const medicionDefs = useMemo(() => {\r\n const distancia = herramientasHabilitadas.find(\r\n (h) => h.codigo === \"measure-distance\",\r\n );\r\n const area = herramientasHabilitadas.find((h) => h.codigo === \"measure-area\");\r\n return distancia && area ? { distancia, area } : null;\r\n }, [herramientasHabilitadas]);\r\n\r\n // Herramientas que se muestran fuera de la barra (esquina inferior izquierda).\r\n const herramientaBaseMap = useMemo(\r\n () => herramientas.find((h) => h.codigo === \"base-map\"),\r\n [herramientas],\r\n );\r\n const herramientaTridimensional = useMemo(\r\n () => herramientas.find((h) => h.codigo === \"three-dimensional\"),\r\n [herramientas],\r\n );\r\n const herramientaMetadata = useMemo(\r\n () => herramientas.find((h) => h.codigo === \"metadata\"),\r\n [herramientas],\r\n );\r\n\r\n // Contenedor donde los widgets de ArcGIS montan su UI (medición, etc.).\r\n const uiRef = useRef<HTMLDivElement | null>(null);\r\n const obtenerContenedorUI = useCallback(() => uiRef.current, []);\r\n\r\n // Coordenadas del puntero en tiempo real.\r\n const coordenadasPuntero = useCoordenadasPuntero(vista);\r\n\r\n // Herramienta activa y sus acciones de alternado.\r\n const { codigoActivo, codigoPadreActivo, alternar, alternarSubHerramienta } =\r\n useHerramientaActiva(vista, herramientas, obtenerContenedorUI);\r\n\r\n // Coordenadas del punto marcado por la herramienta `get-coordinates`.\r\n const coordenadasSeleccion = useCoordenadasSeleccion(\r\n vista,\r\n codigoActivo === \"get-coordinates\",\r\n );\r\n\r\n // Referencia a la modal de medición: mantiene su propio controlador de\r\n // ArcGIS fuera de `codigoActivo` (se abre como acción instantánea), así\r\n // que \"clear\" necesita pedirle explícitamente que limpie sus mediciones.\r\n const medicionRef = useRef<ModalMedicionHandle | null>(null);\r\n\r\n // Resultado de la última consulta ejecutada (herramienta \"Consultar\") y su\r\n // resaltado en el mapa: viven en `MapaView`, no en `ModalConsulta`, para que\r\n // el panel de resultados y el resaltado sobrevivan si el formulario se cierra.\r\n const resaltadoConsulta = useResaltadoConsulta(vista);\r\n const {\r\n resultados: resultadosConsulta,\r\n seleccionados: seleccionadosConsulta,\r\n onResultado: onResultadoConsulta,\r\n onQuitarPestana: onQuitarPestanaResultado,\r\n onCambiarPestana: onCambiarPestanaResultado,\r\n onAlternarFila: onAlternarFilaResultado,\r\n onZoomFila: onZoomFilaResultado,\r\n onAlternarTodos: onAlternarTodosResultado,\r\n limpiar: limpiarResultadosConsulta,\r\n } = useResultadosConsulta(vista, resaltadoConsulta);\r\n\r\n // Acción \"clear\": sale de la herramienta actual (su controlador limpia lo\r\n // suyo), limpia la medición de la modal si está en curso, y limpia además\r\n // todos los resultados/resaltados de consulta (todas las pestañas).\r\n const limpiar = useCallback(() => {\r\n if (codigoActivo) alternar(codigoActivo);\r\n medicionRef.current?.limpiar();\r\n limpiarResultadosConsulta();\r\n }, [codigoActivo, alternar, limpiarResultadosConsulta]);\r\n\r\n // Estado de los paneles de capas y mapa base: independientes en escritorio,\r\n // mutuamente excluyentes (una sola hoja inferior) en responsive.\r\n const {\r\n panelCapasAbierto,\r\n panelBaseMapAbierto,\r\n togglePanelCapas,\r\n togglePanelBaseMap,\r\n } = usePanelesInferiores(modoResponsive);\r\n\r\n // \"Zoom a la capa\" (lupa del panel): lleva la vista a la extensión real de la\r\n // subcapa y, si a esa escala la capa seguiría fuera de rango (atenuada),\r\n // acerca hasta su escala mínima para que se dibuje. Es \"ir a donde se ve\".\r\n const zoomACapa = useCallback(\r\n async (\r\n nombreServicio: string,\r\n identificador: string,\r\n minScale?: number,\r\n maxScale?: number,\r\n ) => {\r\n /* istanbul ignore next -- la lupa solo existe con la vista ya montada */\r\n if (!vista) return;\r\n try {\r\n const extent = await gestorRef.current?.extentDeCapa(\r\n nombreServicio,\r\n identificador,\r\n vista.spatialReference,\r\n );\r\n if (!extent) return;\r\n\r\n // Encuadra la extensión; si aun así la capa quedaría fuera de escala,\r\n // un segundo salto la deja dentro de su rango visible.\r\n await vista.goTo(extent);\r\n // `minScale` = límite más alejado, `maxScale` = más cercano; 0 = sin límite.\r\n const alejadaMax = minScale ?? 0;\r\n const cercanaMax = maxScale ?? 0;\r\n // Se pide ~10% más adentro del rango: el LOD redondeado podría quedar afuera.\r\n if (alejadaMax > 0 && vista.scale > alejadaMax) {\r\n await vista.goTo({\r\n target: extent.center,\r\n scale: alejadaMax * MARGEN_ESCALA,\r\n });\r\n } else if (cercanaMax > 0 && vista.scale < cercanaMax) {\r\n await vista.goTo({\r\n target: extent.center,\r\n scale: cercanaMax / MARGEN_ESCALA,\r\n });\r\n }\r\n } catch (error: unknown) {\r\n console.warn(\"No se pudo hacer zoom a la capa.\", error);\r\n }\r\n },\r\n [gestorRef, vista],\r\n );\r\n\r\n // Descarga el GeoJSON de la subcapa en la extensión visible; los avisos usan `ProveedorAlertas`.\r\n // Los límites y tiempos se piden a BD en cada descarga: un cambio aplica sin redesplegar.\r\n const descargarCapa = useCallback(\r\n async (nombreServicio: string, identificador: string, etiqueta: string) => {\r\n /* istanbul ignore next -- el botón solo existe con la vista ya montada */\r\n if (!vista) return;\r\n try {\r\n const parametros = await obtenerParametrosDescarga();\r\n const resultado = await gestorRef.current?.descargarCapa(\r\n nombreServicio,\r\n identificador,\r\n vista.extent,\r\n parametros,\r\n // Solo WFS: ante una zona densa pregunta si seguir; si no, se corta la descarga.\r\n (cantidad) =>\r\n new Promise<boolean>((resolve) => {\r\n alerta.mostrar({\r\n titulo: \"Descarga grande\",\r\n mensaje:\r\n `La zona visible tiene más de ${cantidad.toLocaleString(\"es\")} ` +\r\n \"elementos; la descarga puede demorar más de lo normal o no \" +\r\n \"completarse. ¿Deseas continuar de todas formas?\",\r\n textoBoton: \"Sí\",\r\n textoCancelar: \"No\",\r\n alConfirmar: () => resolve(true),\r\n alCancelar: () => resolve(false),\r\n });\r\n }),\r\n );\r\n if (!resultado) return;\r\n\r\n descargarArchivo(\r\n `${nombreServicio} - ${etiqueta}.geojson`,\r\n JSON.stringify(resultado.geojson),\r\n \"application/geo+json\",\r\n );\r\n if (resultado.incompleta) {\r\n alerta.mostrar({\r\n titulo: \"Descarga incompleta\",\r\n mensaje:\r\n \"Hay demasiados elementos en la zona visible; acerca el zoom \" +\r\n \"para traerlos todos.\",\r\n });\r\n }\r\n } catch (error: unknown) {\r\n if (error instanceof ParametrosGeneralesError) {\r\n // Sin parámetros de BD no se descarga: no hay valores por defecto en el front.\r\n console.error(\"No se pudieron obtener los parámetros de descarga.\", error);\r\n alerta.mostrar({\r\n titulo: \"Descarga no disponible\",\r\n mensaje:\r\n \"No se pudieron obtener los parámetros de descarga. Inténtalo más tarde.\",\r\n });\r\n return;\r\n }\r\n if (error instanceof DescargaCanceladaError) {\r\n // El usuario ya vio y respondió el aviso de \"Descarga grande\": no\r\n // hace falta otro aviso, simplemente se corta en silencio.\r\n return;\r\n }\r\n if (error instanceof DescargaDemasiadoLentaError) {\r\n alerta.mostrar({\r\n titulo: \"Descarga demasiado lenta\",\r\n mensaje:\r\n `La descarga superó el tiempo máximo de ${formatearDuracion(error.tiempoMaximoMs)} ` +\r\n \"y se canceló. \" +\r\n \"Acerca el zoom para traer menos elementos.\",\r\n });\r\n return;\r\n }\r\n if (error instanceof DescargaMuyPesadaError) {\r\n alerta.mostrar({\r\n titulo: \"Descarga muy pesada\",\r\n mensaje:\r\n \"Con este nivel de zoom hay demasiados elementos y la descarga \" +\r\n \"no se pudo completar. Acerca el zoom para reducir la cantidad \" +\r\n \"de elementos y volver a intentar.\",\r\n });\r\n return;\r\n }\r\n if (error instanceof DescargaNoSoportadaError) {\r\n alerta.mostrar({\r\n titulo: \"Descarga no disponible\",\r\n mensaje: \"Este servicio no permite descargar datos.\",\r\n });\r\n return;\r\n }\r\n console.warn(\"No se pudo descargar la capa.\", error);\r\n alerta.mostrar({\r\n titulo: \"Error al descargar\",\r\n mensaje: \"No fue posible completar la descarga. Inténtalo de nuevo.\",\r\n });\r\n }\r\n },\r\n [gestorRef, vista, alerta],\r\n );\r\n\r\n // Leyenda de una capa activa del panel: delega en el gestor, que resuelve el\r\n // mecanismo (REST `/legend`, renderer o `GetLegendGraphic`) según su tipo.\r\n const obtenerLeyendaCapa = useCallback(\r\n (nombreServicio: string, identificador: string, etiqueta: string) =>\r\n gestorRef.current?.leyendaDeCapa(nombreServicio, identificador, etiqueta) ??\r\n Promise.resolve([]),\r\n [gestorRef],\r\n );\r\n\r\n // Herramienta \"Consultar\": las tres operaciones delegan en el gestor, que\r\n // resuelve el mecanismo (FeatureLayer/REST ArcGIS o WFS GeoServer) según el\r\n // tipo de la capa, igual que `zoomACapa`/`descargarCapa`/`obtenerLeyendaCapa`.\r\n const camposDeCapaConsulta = useCallback(\r\n (nombreServicio: string, identificador: string) =>\r\n gestorRef.current?.camposDeCapa(nombreServicio, identificador) ??\r\n Promise.resolve([]),\r\n [gestorRef],\r\n );\r\n // Los topes de la consulta se piden a BD en cada uso: un cambio aplica sin redesplegar.\r\n const valoresDistintosDeCampoConsulta = useCallback(\r\n async (nombreServicio: string, identificador: string, campo: string) => {\r\n const sinValores = { valores: [], truncado: false };\r\n let parametros: ParametrosConsulta;\r\n try {\r\n parametros = await obtenerParametrosConsulta();\r\n } catch (error: unknown) {\r\n // Sin parámetros no se piden valores; el combo sigue aceptando texto libre.\r\n console.error(\"No se pudieron obtener los parámetros de consulta.\", error);\r\n return sinValores;\r\n }\r\n return (\r\n gestorRef.current?.valoresDistintosDeCampo(\r\n nombreServicio,\r\n identificador,\r\n campo,\r\n parametros,\r\n ) ?? sinValores\r\n );\r\n },\r\n [gestorRef],\r\n );\r\n const ejecutarConsultaCapa = useCallback(\r\n async (nombreServicio: string, identificador: string, filtro: FiltroConsulta) => {\r\n let parametros: ParametrosConsulta;\r\n try {\r\n parametros = await obtenerParametrosConsulta();\r\n } catch (error: unknown) {\r\n // `ModalConsulta` muestra el mensaje del error en el formulario.\r\n console.error(\"No se pudieron obtener los parámetros de consulta.\", error);\r\n throw new Error(\r\n \"No se pudieron obtener los parámetros de consulta. Inténtalo más tarde.\",\r\n { cause: error },\r\n );\r\n }\r\n return (\r\n gestorRef.current?.ejecutarConsulta(\r\n nombreServicio,\r\n identificador,\r\n filtro,\r\n parametros,\r\n vista?.spatialReference,\r\n ) ?? {\r\n campos: [],\r\n graficos: [],\r\n extent: null,\r\n filasDevueltas: 0,\r\n incompleto: false,\r\n }\r\n );\r\n },\r\n [gestorRef, vista],\r\n );\r\n\r\n // Estado de la modal de herramientas de medición. Los widgets de medición son\r\n // 2D: en modo 3D la modal se oculta (sin perder que estaba abierta) y vuelve\r\n // al regresar a 2D; solo la «X» la cierra de verdad.\r\n const [modalMedicionAbierta, setModalMedicionAbierta] = useState(false);\r\n const toggleModalMedicion = useCallback(() => {\r\n setModalMedicionAbierta((abierta) => !abierta);\r\n }, []);\r\n\r\n // Modal de proyección independiente de `codigoActivo`: solo la «X» la cierra.\r\n const [modalProyeccionAbierta, setModalProyeccionAbierta] = useState(false);\r\n const toggleModalProyeccion = useCallback(() => {\r\n setModalProyeccionAbierta((abierta) => !abierta);\r\n }, []);\r\n\r\n // Modal de consulta: igual que la de proyección; al cerrarla se vacían los resultados.\r\n const [modalConsultaAbierta, setModalConsultaAbierta] = useState(false);\r\n const toggleModalConsulta = useCallback(() => {\r\n if (modalConsultaAbierta) limpiarResultadosConsulta();\r\n setModalConsultaAbierta((abierta) => !abierta);\r\n }, [modalConsultaAbierta, limpiarResultadosConsulta]);\r\n const cerrarModalConsulta = useCallback(() => {\r\n setModalConsultaAbierta(false);\r\n limpiarResultadosConsulta();\r\n }, [limpiarResultadosConsulta]);\r\n\r\n // Al abrir \"Medición\", \"Proyectar\" o \"Consultar\", su superficie pasa al frente.\r\n useEffect(() => {\r\n if (modalMedicionAbierta) elevarSuperficie(\"medicion\");\r\n }, [modalMedicionAbierta, elevarSuperficie]);\r\n useEffect(() => {\r\n if (modalProyeccionAbierta) elevarSuperficie(\"proyeccion\");\r\n }, [modalProyeccionAbierta, elevarSuperficie]);\r\n useEffect(() => {\r\n if (modalConsultaAbierta) elevarSuperficie(\"consulta\");\r\n }, [modalConsultaAbierta, elevarSuperficie]);\r\n // \"Capas\" también debe poder pasar al frente al abrirse, igual que las\r\n // demás modales (antes se quedaba siempre detrás).\r\n useEffect(() => {\r\n if (panelCapasAbierto) elevarSuperficie(\"capas\");\r\n }, [panelCapasAbierto, elevarSuperficie]);\r\n\r\n // Estado del panel de metadatos (herramienta `metadata`, esquina inf. izq.).\r\n const [panelMetadataAbierto, setPanelMetadataAbierto] = useState(false);\r\n const togglePanelMetadata = useCallback(() => {\r\n setPanelMetadataAbierto((abierto) => !abierto);\r\n }, []);\r\n\r\n // Enruta el clic: ejecuta la acción registrada o alterna la herramienta.\r\n const manejarClicHerramienta = useCallback(\r\n (codigo: string) => {\r\n const herramienta = herramientas.find((item) => item.codigo === codigo);\r\n if (vista && herramienta && esAccion(codigo)) {\r\n ejecutarAccion(\r\n codigo,\r\n {\r\n vista,\r\n irAInicio,\r\n limpiar,\r\n togglePanelCapas,\r\n toggleModalMedicion,\r\n toggleModalProyeccion,\r\n toggleModalConsulta,\r\n togglePanelMetadata,\r\n alternarTridimensional,\r\n },\r\n herramienta.configuracion,\r\n );\r\n return;\r\n }\r\n alternar(codigo);\r\n },\r\n [\r\n vista,\r\n herramientas,\r\n irAInicio,\r\n limpiar,\r\n togglePanelCapas,\r\n toggleModalMedicion,\r\n toggleModalProyeccion,\r\n toggleModalConsulta,\r\n togglePanelMetadata,\r\n alternarTridimensional,\r\n alternar,\r\n ],\r\n );\r\n\r\n return (\r\n <section\r\n ref={combinarRefRaiz}\r\n aria-label={definicion.descripcion}\r\n className={cn(CLASE_RAIZ_MAPA, \"relative overflow-hidden bg-slate-900\", className)}\r\n style={{ width: configuracion.width, height: configuracion.height }}\r\n onPointerDownCapture={elevarModal}\r\n >\r\n {/* Contenedor donde ArcGIS monta la vista 2D o 3D. */}\r\n <div ref={contenedorRef} className=\"absolute inset-0\" />\r\n\r\n {/* Estado de error de carga. */}\r\n {error && (\r\n <div className=\"absolute inset-0 grid place-items-center bg-slate-950/60 p-6\">\r\n <div className=\"max-w-xs text-center text-slate-300\">\r\n <p className=\"font-medium text-white\">No se pudo cargar el mapa</p>\r\n <p className=\"mt-1 text-sm\">Revisa tu conexión e inténtalo de nuevo.</p>\r\n </div>\r\n </div>\r\n )}\r\n\r\n {/* Esqueleto mientras se inicializa la vista. */}\r\n {!vista && !error && <VisorMapaSkeleton className=\"absolute inset-0\" />}\r\n\r\n {vista && (\r\n <>\r\n {/* Anclaje superior centrado para la UI de los widgets de ArcGIS. */}\r\n <div\r\n ref={uiRef}\r\n className=\"pointer-events-none absolute left-1/2 top-3 z-10 w-[min(92vw,420px)] -translate-x-1/2 *:pointer-events-auto\"\r\n />\r\n\r\n {/* Propaga la escala de la interfaz a todo lo que monten los controles;\r\n `display: contents` no agrega caja ni afecta `fixed`/`absolute`. */}\r\n <div\r\n className=\"contents escala-interfaz\"\r\n style={\r\n { \"--factor-escala-interfaz\": escalaInterfaz } as unknown as CSSProperties\r\n }\r\n >\r\n {modoResponsive ? (\r\n <ControlesResponsive\r\n alturaContenedor={altoContenedor ?? 0}\r\n herramientasBarra={herramientasBarra}\r\n codigoActivo={codigoActivo}\r\n soportada={(codigo) =>\r\n estaSoportadaConHijos(codigo, herramientas) || esAccion(codigo)\r\n }\r\n onAlternar={manejarClicHerramienta}\r\n herramientaBaseMap={herramientaBaseMap}\r\n galeria={galeria}\r\n basemapActual={basemapActual}\r\n onSeleccionarBasemap={setBasemapActual}\r\n panelBaseMapAbierto={panelBaseMapAbierto}\r\n onAlternarPanelBaseMap={togglePanelBaseMap}\r\n panelCapasAbierto={panelCapasAbierto}\r\n onCerrarPanelCapas={togglePanelCapas}\r\n gruposResueltos={gruposResueltos}\r\n estados={estados}\r\n escala={escala}\r\n onCambioServicio={onCambioServicio}\r\n onCambioOpacidad={onCambioOpacidad}\r\n onCambioOpacidadCapa={onCambioOpacidadCapa}\r\n onCambioCapa={onCambioCapa}\r\n onZoomCapa={zoomACapa}\r\n onDescargarCapa={descargarCapa}\r\n onObtenerLeyenda={obtenerLeyendaCapa}\r\n herramientaTridimensional={herramientaTridimensional}\r\n tridimensional={tridimensional}\r\n onAlternarTridimensional={() =>\r\n manejarClicHerramienta(\"three-dimensional\")\r\n }\r\n />\r\n ) : (\r\n <ControlesEscritorio\r\n vista={vista}\r\n escalaInterfaz={escalaInterfaz}\r\n herramientasBarra={herramientasBarra}\r\n codigoActivo={codigoActivo}\r\n codigoPadreActivo={codigoPadreActivo}\r\n soportada={(codigo) =>\r\n estaSoportadaConHijos(codigo, herramientas) || esAccion(codigo)\r\n }\r\n onAlternar={manejarClicHerramienta}\r\n onAlternarSubHerramienta={alternarSubHerramienta}\r\n coordenadasPuntero={coordenadasPuntero}\r\n panelCapasAbierto={panelCapasAbierto}\r\n onCerrarPanelCapas={togglePanelCapas}\r\n gruposResueltos={gruposResueltos}\r\n estados={estados}\r\n escala={escala}\r\n onCambioServicio={onCambioServicio}\r\n onCambioOpacidad={onCambioOpacidad}\r\n onCambioOpacidadCapa={onCambioOpacidadCapa}\r\n onCambioCapa={onCambioCapa}\r\n onZoomCapa={zoomACapa}\r\n onDescargarCapa={descargarCapa}\r\n onObtenerLeyenda={obtenerLeyendaCapa}\r\n coordenadasSeleccion={coordenadasSeleccion}\r\n onCerrarCoordenadas={() => alternar(\"get-coordinates\")}\r\n modalProyeccionAbierta={modalProyeccionAbierta}\r\n onCerrarProyeccion={() => setModalProyeccionAbierta(false)}\r\n modalConsultaAbierta={modalConsultaAbierta}\r\n onCerrarConsulta={cerrarModalConsulta}\r\n capasConsultables={capasConsultables}\r\n onCamposDeCapa={camposDeCapaConsulta}\r\n onValoresDistintos={valoresDistintosDeCampoConsulta}\r\n onEjecutarConsulta={ejecutarConsultaCapa}\r\n onResultadoConsulta={onResultadoConsulta}\r\n resultadosConsulta={resultadosConsulta}\r\n seleccionadosConsulta={seleccionadosConsulta}\r\n onAlternarFilaResultado={onAlternarFilaResultado}\r\n onAlternarTodosResultado={onAlternarTodosResultado}\r\n onZoomFilaResultado={onZoomFilaResultado}\r\n onQuitarPestanaResultado={onQuitarPestanaResultado}\r\n onCambiarPestanaResultado={onCambiarPestanaResultado}\r\n modalMedicionAbierta={modalMedicionAbierta}\r\n medicionDefs={medicionDefs}\r\n tridimensional={tridimensional}\r\n onCerrarMedicion={() => setModalMedicionAbierta(false)}\r\n medicionRef={medicionRef}\r\n herramientaMetadata={herramientaMetadata}\r\n panelMetadataAbierto={panelMetadataAbierto}\r\n onAlternarMetadata={() => manejarClicHerramienta(\"metadata\")}\r\n onCerrarMetadata={() => setPanelMetadataAbierto(false)}\r\n aplicacion={aplicacion}\r\n herramientaBaseMap={herramientaBaseMap}\r\n galeria={galeria}\r\n basemapActual={basemapActual}\r\n onSeleccionarBasemap={setBasemapActual}\r\n panelBaseMapAbierto={panelBaseMapAbierto}\r\n onAlternarPanelBaseMap={togglePanelBaseMap}\r\n herramientaTridimensional={herramientaTridimensional}\r\n onAlternarTridimensional={() =>\r\n manejarClicHerramienta(\"three-dimensional\")\r\n }\r\n />\r\n )}\r\n </div>\r\n </>\r\n )}\r\n </section>\r\n );\r\n}\r\n","import { useEffect, useMemo, useRef } from \"react\";\nimport { MensajeError } from \"@/shared/components/MensajeError\";\nimport { cn } from \"@/shared/lib/cn\";\nimport { useConfiguracionAplicacion } from \"../context/configuracion.context\";\nimport { ErrorToken, type MotivoErrorToken } from \"../services/proveedor-token\";\nimport {\n aplanarServicios,\n buscarDefinicionPorModo,\n type CodigoHerramienta,\n type ModoMapa,\n type VistaMapa,\n} from \"../types\";\nimport { MapaView } from \"./MapaView\";\nimport { VisorMapaSkeleton } from \"./VisorMapaSkeleton\";\n\n/** Props de `VisorMapa`. */\ninterface VisorMapaProps {\n /** Definición del backend que se muestra (`mapas[].nombre`). */\n modo: ModoMapa;\n herramientasDeshabilitadas?: readonly CodigoHerramienta[];\n onListo?: (vista: VistaMapa) => void;\n /** Se llama si el visor no puede mostrarse (token, backend o contrato sin mapa). */\n onError?: (error: Error) => void;\n /** Tamaño y posición del visor (también de sus estados de carga y error). */\n className?: string;\n}\n\n/** Texto para el usuario según por qué falló el token; el detalle técnico va a `onError`. */\nconst MENSAJES_TOKEN: Record<MotivoErrorToken, string> = {\n \"sin-configurar\": \"Falta configurar el token de acceso del mapa.\",\n controlador:\n \"No se pudo obtener el token de acceso. Inténtalo de nuevo o contacta con el administrador.\",\n vacio: \"El servicio de tokens no devolvió un token de acceso.\",\n rechazado: \"El token de acceso no es válido o ya expiró.\",\n};\n\n/**\n * Visor completo a partir de `ProveedorConfiguracion`: muestra el esqueleto\n * mientras carga, el error (con reintento) si falla, o el `MapaView` del modo.\n */\nexport function VisorMapa({\n modo,\n herramientasDeshabilitadas,\n onListo,\n onError,\n className,\n}: VisorMapaProps) {\n const { datos, cargando, error, recargar } = useConfiguracionAplicacion();\n\n const definicion = datos ? buscarDefinicionPorModo(datos.mapas, modo) : undefined;\n const sinMapa = !cargando && !error && !definicion;\n const servicios = useMemo(\n () => (datos ? aplanarServicios(datos.gruposServicios) : []),\n [datos],\n );\n\n // Error que se reporta al anfitrión: el de carga o un contrato sin mapa.\n const errorVisor = useMemo(\n () =>\n error ??\n (sinMapa ? new Error(`El backend no publicó un mapa en modo ${modo}.`) : undefined),\n [error, sinMapa, modo],\n );\n const onErrorRef = useRef(onError);\n useEffect(() => {\n onErrorRef.current = onError;\n }, [onError]);\n useEffect(() => {\n if (errorVisor) onErrorRef.current?.(errorVisor);\n }, [errorVisor]);\n\n // Cargando la configuración: esqueleto del visor.\n if (cargando) {\n return <VisorMapaSkeleton className={className} />;\n }\n\n // Error de carga, con opción de reintentar. Al usuario solo se le detalla\n // el motivo cuando es el token; el resto queda en el mensaje genérico.\n if (error) {\n return (\n <div className={cn(\"grid place-items-center bg-slate-950 p-6\", className)}>\n <div className=\"space-y-3 text-center\">\n {error instanceof ErrorToken ? (\n <MensajeError titulo=\"Sin acceso al mapa\" mensaje={MENSAJES_TOKEN[error.motivo]} />\n ) : (\n <MensajeError />\n )}\n <button\n type=\"button\"\n onClick={recargar}\n className=\"rounded-lg border border-white/10 px-3 py-1.5 text-xs font-medium text-slate-300 transition hover:bg-white/10\"\n >\n Reintentar\n </button>\n </div>\n </div>\n );\n }\n\n // El contrato no trae un mapa para este modo.\n if (!datos || !definicion) {\n return (\n <div className={cn(\"grid place-items-center bg-slate-950 p-6\", className)}>\n <MensajeError\n titulo=\"Sin mapa disponible\"\n mensaje={`El backend no publicó un mapa en modo ${modo}.`}\n />\n </div>\n );\n }\n\n return (\n <MapaView\n definicion={definicion}\n aplicacion={datos.aplicacion}\n galeria={datos.galeriaMapas}\n servicios={servicios}\n grupos={datos.gruposServicios}\n herramientasDeshabilitadas={herramientasDeshabilitadas}\n onListo={onListo}\n className={className}\n />\n );\n}\n","/** Estilos de `ModalAlerta`, réplica de `DialogoConfirmacion`; los colores van en hex. */\n\n/** Fondo oscurecido a pantalla completa, por encima de todo (modales del visor: z-40). */\nexport const CLASES_FONDO_ALERTA =\n \"fixed inset-0 z-50 flex items-center justify-center bg-[#1f2733]/40 p-4\";\n\n/** Tarjeta blanca centrada (~308×137, ref. diseño de formularios). */\nexport const CLASES_TARJETA_ALERTA =\n \"relative flex max-w-[calc(100vw-2rem)] min-h-[137.12px] w-[307.87px] flex-col \" +\n \"rounded-[10px] bg-white px-5 py-4 shadow-[0_4px_16px_rgba(30,85,126,0.30)]\";\n\n/** Botón de cerrar (aspa) de la esquina superior derecha. */\nexport const CLASES_CERRAR_ALERTA =\n \"absolute right-3 top-3 grid size-5 place-items-center rounded-md text-[#1f2733] \" +\n \"transition hover:bg-[#eef0f4] focus-visible:outline-2 focus-visible:outline-offset-1 \" +\n \"focus-visible:outline-[#1e86d1]\";\n\n/** Título centrado de la cabecera. */\nexport const CLASES_TITULO_ALERTA =\n \"px-4 text-center text-sm font-bold text-[#1f2733]\";\n\n/** Texto del cuerpo del aviso. */\nexport const CLASES_MENSAJE_ALERTA = \"text-xs leading-snug text-[#6b7280]\";\n\n/** Botón principal (\"Entendido\" o \"Sí\" en modo confirmación), con el degradado de acento. */\nexport const CLASES_BOTON_ALERTA =\n \"inline-flex h-5.75 min-w-12.5 items-center justify-center rounded-[10px] px-3 \" +\n \"bg-linear-[235deg] from-[#0092ff] to-[#005899] text-xs font-semibold text-white \" +\n \"shadow-[1px_1px_3px_0_rgba(0,0,0,0.3)] transition duration-150 ease-out \" +\n \"hover:brightness-95 hover:-translate-y-0.5 active:translate-y-0 \" +\n \"focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[#005899]\";\n\n/** Botón secundario (\"No\"), solo en modo confirmación: mismo azul, en contorno. */\nexport const CLASES_BOTON_ALERTA_SECUNDARIO =\n \"inline-flex h-5.75 min-w-12.5 items-center justify-center rounded-[10px] px-3 \" +\n \"border border-[#005899] text-xs font-semibold text-[#005899] \" +\n \"transition duration-150 ease-out hover:bg-[#005899]/5 hover:-translate-y-0.5 \" +\n \"active:translate-y-0 focus-visible:outline-2 focus-visible:outline-offset-2 \" +\n \"focus-visible:outline-[#005899]\";\n","import type { ReactNode } from \"react\";\r\nimport { useEffect, useId, useRef } from \"react\";\r\nimport { createPortal } from \"react-dom\";\r\nimport { cn } from \"@/shared/lib/cn\";\r\nimport {\r\n CLASES_BOTON_ALERTA,\r\n CLASES_BOTON_ALERTA_SECUNDARIO,\r\n CLASES_CERRAR_ALERTA,\r\n CLASES_FONDO_ALERTA,\r\n CLASES_MENSAJE_ALERTA,\r\n CLASES_TARJETA_ALERTA,\r\n CLASES_TITULO_ALERTA,\r\n} from \"../styles/alertas.estilos\";\r\nimport { CLASE_RAIZ_MAPA } from \"../styles/raiz.estilos\";\r\nimport { IconoAlerta, IconoCerrar } from \"./iconos\";\r\n\r\n/** Props de `ModalAlerta`. */\r\ninterface ModalAlertaProps {\r\n /** Título breve de la cabecera. */\r\n titulo: string;\r\n /** Cuerpo del aviso (acepta ReactNode para resaltar parte del texto). */\r\n mensaje: ReactNode;\r\n /** Texto del botón principal. Por defecto \"Entendido\", o \"Sí\" en modo confirmación. */\r\n textoBoton?: string;\r\n /** Solo en modo confirmación: texto del botón secundario. Por defecto \"No\". */\r\n textoCancelar?: string;\r\n /** Con manejador, el aviso es de confirmación (dos botones); sin él, informativo. */\r\n alConfirmar?: () => void;\r\n /** Se invoca al cerrar/declinar (botón secundario, aspa, Escape o clic en el fondo). */\r\n alCerrar: () => void;\r\n}\r\n\r\n/**\r\n * Aviso centrado en portal, informativo (\"Entendido\") o de confirmación (\"No\"/\"Sí\").\r\n * Cerrar por cualquier vía cuenta como \"No\".\r\n */\r\nexport function ModalAlerta({\r\n titulo,\r\n mensaje,\r\n textoBoton,\r\n textoCancelar = \"No\",\r\n alConfirmar,\r\n alCerrar,\r\n}: ModalAlertaProps) {\r\n const esConfirmacion = alConfirmar != null;\r\n const etiquetaBoton = textoBoton ?? (esConfirmacion ? \"Sí\" : \"Entendido\");\r\n const idTitulo = useId();\r\n const idMensaje = useId();\r\n const botonRef = useRef<HTMLButtonElement>(null);\r\n\r\n useEffect(() => {\r\n const alPulsar = (evento: KeyboardEvent) => {\r\n if (evento.key === \"Escape\") alCerrar();\r\n };\r\n document.addEventListener(\"keydown\", alPulsar);\r\n\r\n // Bloquea el scroll del fondo mientras el aviso está abierto.\r\n const overflowPrevio = document.body.style.overflow;\r\n document.body.style.overflow = \"hidden\";\r\n\r\n // Lleva el foco al botón de cierre para que Escape/Enter funcionen de una.\r\n botonRef.current?.focus();\r\n\r\n return () => {\r\n document.removeEventListener(\"keydown\", alPulsar);\r\n document.body.style.overflow = overflowPrevio;\r\n };\r\n }, [alCerrar]);\r\n\r\n return createPortal(\r\n <div className={cn(CLASE_RAIZ_MAPA, CLASES_FONDO_ALERTA)} onClick={alCerrar}>\r\n <div\r\n role=\"alertdialog\"\r\n aria-modal=\"true\"\r\n aria-labelledby={idTitulo}\r\n aria-describedby={idMensaje}\r\n className={CLASES_TARJETA_ALERTA}\r\n onClick={(evento) => evento.stopPropagation()}\r\n >\r\n <button\r\n type=\"button\"\r\n aria-label=\"Cerrar\"\r\n onClick={alCerrar}\r\n className={CLASES_CERRAR_ALERTA}\r\n >\r\n <IconoCerrar className=\"size-3\" />\r\n </button>\r\n\r\n <h2 id={idTitulo} className={CLASES_TITULO_ALERTA}>\r\n {titulo}\r\n </h2>\r\n\r\n <div className=\"mt-3 flex items-center gap-3\">\r\n <IconoAlerta className=\"size-6\" />\r\n <p id={idMensaje} className={CLASES_MENSAJE_ALERTA}>\r\n {mensaje}\r\n </p>\r\n </div>\r\n\r\n <div className=\"mt-auto flex justify-end gap-2 pt-4\">\r\n {esConfirmacion && (\r\n <button\r\n ref={botonRef}\r\n type=\"button\"\r\n onClick={alCerrar}\r\n className={CLASES_BOTON_ALERTA_SECUNDARIO}\r\n >\r\n {textoCancelar}\r\n </button>\r\n )}\r\n <button\r\n ref={esConfirmacion ? null : botonRef}\r\n type=\"button\"\r\n onClick={alConfirmar ?? alCerrar}\r\n className={CLASES_BOTON_ALERTA}\r\n >\r\n {etiquetaBoton}\r\n </button>\r\n </div>\r\n </div>\r\n </div>,\r\n document.body,\r\n );\r\n}\r\n","import { useCallback, useMemo, useState } from \"react\";\nimport type { PropsConHijos } from \"@/shared/types\";\nimport type { Alerta } from \"../context/alertas.context\";\nimport { ContextoAlertas } from \"../context/alertas.context\";\nimport { ModalAlerta } from \"../components/ModalAlerta\";\n\n/** Contador para generar identificadores únicos de aviso sin depender de `crypto`. */\nlet contadorAlertas = 0;\n\n/** Cola de avisos que muestra el primero con `ModalAlerta`; se usa con `useAlerta().mostrar(...)`. */\nexport function ProveedorAlertas({ children }: PropsConHijos) {\n const [cola, setCola] = useState<Alerta[]>([]);\n\n const mostrar = useCallback((alerta: Omit<Alerta, \"id\">) => {\n setCola((actual) => {\n // Evita apilar el mismo aviso (p. ej. un reintento que falla en bucle).\n if (actual.some((a) => a.titulo === alerta.titulo)) return actual;\n contadorAlertas += 1;\n return [...actual, { ...alerta, id: `alerta-${contadorAlertas}` }];\n });\n }, []);\n\n const cerrar = useCallback((id: string) => {\n setCola((actual) => actual.filter((a) => a.id !== id));\n }, []);\n\n const valor = useMemo(() => ({ mostrar, cerrar }), [mostrar, cerrar]);\n const activa = cola[0];\n\n return (\n <ContextoAlertas.Provider value={valor}>\n {children}\n {activa && (\n <ModalAlerta\n titulo={activa.titulo}\n mensaje={activa.mensaje}\n textoBoton={activa.textoBoton}\n textoCancelar={activa.textoCancelar}\n alConfirmar={\n activa.alConfirmar &&\n (() => {\n activa.alConfirmar?.();\n cerrar(activa.id);\n })\n }\n alCerrar={() => {\n activa.alCancelar?.();\n cerrar(activa.id);\n }}\n />\n )}\n </ContextoAlertas.Provider>\n );\n}\n","import { useCallback, useEffect, useState } from \"react\";\r\n\r\n/** Estado estándar de una carga asíncrona única. */\r\nexport interface RecursoAsync<T> {\r\n datos: T | undefined;\r\n error: Error | undefined;\r\n cargando: boolean;\r\n recargar: () => void;\r\n}\r\n\r\n/** Estado interno de la carga como unión discriminada. */\r\ntype EstadoCarga<T> =\r\n { tipo: \"cargando\" } | { tipo: \"listo\"; datos: T } | { tipo: \"error\"; error: Error };\r\n\r\n/**\r\n * Encapsula la carga de un recurso asíncrono con cancelación segura\r\n * (ignora respuestas de efectos desmontados) y reintento manual.\r\n */\r\nexport function useRecursoAsync<T>(\r\n cargar: () => Promise<T>,\r\n deps: readonly unknown[] = [],\r\n): RecursoAsync<T> {\r\n const [estado, setEstado] = useState<EstadoCarga<T>>({ tipo: \"cargando\" });\r\n // Contador de reintentos: al incrementarlo se relanza el efecto.\r\n const [intentos, setIntentos] = useState(0);\r\n\r\n useEffect(() => {\r\n // `vigente` descarta la respuesta si el efecto ya se limpió.\r\n let vigente = true;\r\n\r\n Promise.resolve()\r\n .then(() => {\r\n if (vigente) setEstado({ tipo: \"cargando\" });\r\n return cargar();\r\n })\r\n .then((resultado) => {\r\n if (!vigente) return;\r\n setEstado({ tipo: \"listo\", datos: resultado });\r\n })\r\n .catch((causa: unknown) => {\r\n if (!vigente) return;\r\n setEstado({\r\n tipo: \"error\",\r\n error: causa instanceof Error ? causa : new Error(String(causa)),\r\n });\r\n });\r\n\r\n return () => {\r\n vigente = false;\r\n };\r\n // El llamador controla las dependencias explícitamente.\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [...deps, intentos]);\r\n\r\n // Fuerza un nuevo intento de carga.\r\n const recargar = useCallback(() => setIntentos((n) => n + 1), []);\r\n\r\n // Proyecta la unión discriminada al contrato plano `RecursoAsync`.\r\n return {\r\n datos: estado.tipo === \"listo\" ? estado.datos : undefined,\r\n error: estado.tipo === \"error\" ? estado.error : undefined,\r\n cargando: estado.tipo === \"cargando\",\r\n recargar,\r\n };\r\n}\r\n","import type {\n ConfiguracionAplicacion,\n GrupoServicios,\n PlataformaGis,\n ServicioGis,\n TipoServicioGis,\n} from \"../types\";\nimport { obtenerEntorno } from \"@/shared/entorno\";\nimport { fetchJson, HttpError } from \"@/shared/helpers/http\";\nimport { ErrorToken } from \"./proveedor-token\";\n\n/** Entrega un JWT para `clientId` (demo: `firmarToken`; librería: controlador del anfitrión). */\nexport type ProveedorTokenAcceso = (clientId: string) => Promise<string>;\n\n/** Devuelve el vencimiento más próximo de los tokens GIS (epoch ms). */\nexport function validateToken(\n configuracion: ConfiguracionAplicacion,\n): number | undefined {\n const expiraciones = configuracion.gruposServicios.flatMap((grupo) =>\n grupo.servicios.flatMap((servicio) =>\n servicio.token && typeof servicio.expires === \"number\" ? [servicio.expires] : [],\n ),\n );\n return expiraciones.length > 0 ? Math.min(...expiraciones) : undefined;\n}\n\n/** Endpoint del backend que devuelve la configuración de la aplicación. */\nconst RUTA_CONSULTAR_APLICACION = \"/api/Aplicaciones/consultar_aplicacion\";\n\n/** `tipoServicio` tal como lo envía el backend, antes de normalizar. */\ntype TipoServicioGisCrudo =\n \"MAP\" | \"FEATURE\" | \"TILE\" | \"WMS\" | \"WMTS\" | \"WFS\" | \"API_FEATURES\";\n\n/** Servicio tal como llega del backend, con el tipo aún sin normalizar. */\ntype ServicioGisCrudo = Omit<ServicioGis, \"tipoServicio\"> & {\n tipoServicio: TipoServicioGisCrudo;\n};\n\n/** Configuración tal como llega del backend, antes de normalizar. */\ninterface ConfiguracionAplicacionCruda extends Omit<\n ConfiguracionAplicacion,\n \"gruposServicios\"\n> {\n gruposServicios: Array<\n Omit<GrupoServicios, \"servicios\"> & {\n servicios: ServicioGisCrudo[];\n }\n >;\n}\n\n/** `plataformaGis` + `tipoServicio` crudo → tipo interno del contrato. */\nconst TIPOS_POR_PLATAFORMA: Record<\n PlataformaGis,\n Partial<Record<TipoServicioGisCrudo, TipoServicioGis>>\n> = {\n ARCGIS: {\n MAP: \"ARCGIS_MAP\",\n FEATURE: \"ARCGIS_FEATURE\",\n TILE: \"ARCGIS_TILE\",\n },\n GEOSERVER: {\n WMS: \"OGC_WMS\",\n WMTS: \"OGC_WMTS\",\n WFS: \"OGC_WFS\",\n API_FEATURES: \"OGC_API_FEATURES\",\n },\n};\n\n/** Traduce el tipo crudo del backend al tipo interno según la plataforma. */\nfunction normalizarTipoServicio(servicio: ServicioGisCrudo): TipoServicioGis {\n const tipo = TIPOS_POR_PLATAFORMA[servicio.plataformaGis]?.[servicio.tipoServicio];\n if (!tipo) {\n throw new Error(\n `Combinación de servicio no soportada: ${servicio.plataformaGis} + ${servicio.tipoServicio}.`,\n );\n }\n return tipo;\n}\n\n/** Resuelve URLs WMS relativas (proxy del backend) contra `baseUrl`. */\nfunction resolverUrlWms(url: string, baseUrl: string): string {\n if (/^http:\\/\\//i.test(url)) {\n throw new Error(\n `La URL del servicio WMS \"${url}\" no es segura (http); solo se admite https.`,\n );\n }\n if (/^https:\\/\\//i.test(url)) return url;\n return new URL(url, `${baseUrl.replace(/\\/+$/, \"\")}/`).href;\n}\n\n/** Normaliza tipos de servicio y resuelve URLs WMS relativas. */\nfunction normalizarConfiguracion(\n cruda: ConfiguracionAplicacionCruda,\n baseUrl: string,\n): ConfiguracionAplicacion {\n return {\n ...cruda,\n gruposServicios: cruda.gruposServicios.map((grupo) => ({\n ...grupo,\n servicios: grupo.servicios.map((servicio) => {\n const tipoServicio = normalizarTipoServicio(servicio);\n return {\n ...servicio,\n tipoServicio,\n url:\n tipoServicio === \"OGC_WMS\"\n ? resolverUrlWms(servicio.url, baseUrl)\n : servicio.url,\n };\n }),\n })),\n };\n}\n\n/**\n * Obtiene la configuración del visor del backend (JWT Bearer) y normaliza tipos y\n * URLs de servicios. Requiere `apiBaseUrl` en el entorno (`configurarEntorno`).\n */\nexport async function obtenerConfiguracionAplicacion(\n clientId: string,\n getAccessToken: ProveedorTokenAcceso,\n): Promise<ConfiguracionAplicacion> {\n const baseUrl = obtenerEntorno().apiBaseUrl;\n if (!baseUrl) {\n throw new Error(\n \"apiBaseUrl no está configurado; el visor requiere backend.\",\n );\n }\n\n // Token de acceso para identificar la aplicación ante el backend.\n const token = (await getAccessToken(clientId)).trim();\n if (!token) {\n throw new Error(\"El proveedor de tokens retornó un token de acceso vacío.\");\n }\n\n // Consulta el contrato crudo y lo normaliza; un 401/403 es un token rechazado.\n let cruda: ConfiguracionAplicacionCruda;\n try {\n cruda = await fetchJson<ConfiguracionAplicacionCruda>(RUTA_CONSULTAR_APLICACION, {\n method: \"POST\",\n headers: { Authorization: `Bearer ${token}` },\n });\n } catch (error: unknown) {\n if (error instanceof HttpError && (error.status === 401 || error.status === 403)) {\n throw new ErrorToken(\n \"rechazado\",\n `El backend rechazó el token de acceso (${error.status}).`,\n { cause: error },\n );\n }\n throw error;\n }\n\n return normalizarConfiguracion(cruda, baseUrl);\n}\n","import { useEffect, useState } from \"react\";\r\nimport { useAlerta } from \"../context/alertas.context\";\r\nimport { validateToken } from \"../services/configuracion-aplicacion\";\r\nimport type { ConfiguracionAplicacion, ServicioGis } from \"../types\";\r\n\r\n/** Renueva antes del vencimiento para evitar peticiones GIS con un token límite. */\r\nconst MARGEN_RENOVACION_MS = 30_000;\r\n\r\n/** Conserva el contrato cargado y reemplaza solo credenciales de servicios existentes. */\r\nfunction reemplazarCredenciales(\r\n actual: ConfiguracionAplicacion,\r\n renovada: ConfiguracionAplicacion,\r\n): ConfiguracionAplicacion {\r\n const nuevas = new Map<string, ServicioGis>();\r\n renovada.gruposServicios.forEach((grupo) =>\r\n grupo.servicios.forEach((servicio) => nuevas.set(servicio.nombre, servicio)),\r\n );\r\n\r\n return {\r\n ...actual,\r\n gruposServicios: actual.gruposServicios.map((grupo) => ({\r\n ...grupo,\r\n servicios: grupo.servicios.map((servicio) => {\r\n const nueva = nuevas.get(servicio.nombre);\r\n return nueva\r\n ? {\r\n ...servicio,\r\n token: nueva.token,\r\n expires: nueva.expires,\r\n ssl: nueva.ssl,\r\n }\r\n : servicio;\r\n }),\r\n })),\r\n };\r\n}\r\n\r\n/** Renueva los tokens GIS antes de que venzan y devuelve la configuración actualizada. */\r\nexport function useRenovacionToken(\r\n datosBase: ConfiguracionAplicacion | undefined,\r\n cargar: () => Promise<ConfiguracionAplicacion>,\r\n): ConfiguracionAplicacion | undefined {\r\n const [configuracionRenovada, setConfiguracionRenovada] =\r\n useState<ConfiguracionAplicacion>();\r\n const datos = configuracionRenovada ?? datosBase;\r\n\r\n // Para avisar al usuario si la renovación de tokens falla. `ProveedorAlertas`\r\n // ya de-duplica por título, así que un reintento en bucle no apila modales.\r\n const alerta = useAlerta();\r\n\r\n useEffect(() => {\r\n if (!datos) return;\r\n\r\n const expires = validateToken(datos);\r\n if (expires === undefined) return;\r\n\r\n const espera = Math.max(1_000, expires - Date.now() - MARGEN_RENOVACION_MS);\r\n let activo = true;\r\n let temporizador: number;\r\n\r\n const renovar = async () => {\r\n try {\r\n const nueva = await cargar();\r\n /* istanbul ignore else -- `!activo` es un desmontaje concurrente */\r\n if (activo) {\r\n setConfiguracionRenovada((actual) =>\r\n reemplazarCredenciales(actual ?? datos, nueva),\r\n );\r\n }\r\n } catch (error: unknown) {\r\n console.error(\"No fue posible renovar los tokens GIS.\", error);\r\n alerta.mostrar({\r\n titulo: \"Sesión GIS\",\r\n mensaje:\r\n \"No se pudieron renovar las credenciales de los servicios GIS. \" +\r\n \"Algunas capas podrían dejar de cargar; recarga la página si el \" +\r\n \"problema persiste.\",\r\n });\r\n /* istanbul ignore else -- `!activo` es un desmontaje concurrente */\r\n if (activo) {\r\n temporizador = window.setTimeout(renovar, MARGEN_RENOVACION_MS);\r\n }\r\n }\r\n };\r\n\r\n temporizador = window.setTimeout(renovar, espera);\r\n return () => {\r\n activo = false;\r\n window.clearTimeout(temporizador);\r\n };\r\n }, [cargar, datos, alerta]);\r\n\r\n return datos;\r\n}\r\n","import { useCallback, useMemo } from \"react\";\r\nimport type { PropsConHijos } from \"@/shared/types\";\r\nimport { useRecursoAsync } from \"@/shared/hooks/useRecursoAsync\";\r\nimport { ContextoConfiguracion } from \"../context/configuracion.context\";\r\nimport { useRenovacionToken } from \"../hooks/useRenovacionToken\";\r\nimport {\r\n obtenerConfiguracionAplicacion,\r\n type ProveedorTokenAcceso,\r\n} from \"../services/configuracion-aplicacion\";\r\n\r\ninterface ProveedorConfiguracionProps extends PropsConHijos {\r\n /** Identifica la aplicación anfitriona ante el backend. */\r\n clientId: string;\r\n /** Emite el JWT del contrato frontend/backend para `clientId`. */\r\n getAccessToken: ProveedorTokenAcceso;\r\n}\r\n\r\n/**\r\n * Carga una única vez la configuración del visor y la expone al árbol.\r\n * Es el único componente que conoce el servicio de configuración.\r\n */\r\nexport function ProveedorConfiguracion({\r\n children,\r\n clientId,\r\n getAccessToken,\r\n}: ProveedorConfiguracionProps) {\r\n const cargar = useCallback(\r\n () => obtenerConfiguracionAplicacion(clientId, getAccessToken),\r\n [clientId, getAccessToken],\r\n );\r\n const { datos: datosBase, error, cargando, recargar } = useRecursoAsync(cargar, [\r\n cargar,\r\n ]);\r\n const datos = useRenovacionToken(datosBase, cargar);\r\n\r\n // Objeto estable: solo cambia cuando cambia alguno de sus campos, así los\r\n // consumidores del contexto no se re-renderizan en cada render del proveedor.\r\n const valor = useMemo(\r\n () => ({ datos, error, cargando, recargar }),\r\n [datos, error, cargando, recargar],\r\n );\r\n\r\n return (\r\n <ContextoConfiguracion.Provider value={valor}>\r\n {children}\r\n </ContextoConfiguracion.Provider>\r\n );\r\n}\r\n","import esriConfig from \"@arcgis/core/config\";\nimport { guardarEntorno, type EntornoMapa } from \"@/shared/entorno\";\n\nexport type { EntornoMapa } from \"@/shared/entorno\";\nexport { obtenerEntorno } from \"@/shared/entorno\";\n\n/**\n * Configura el visor en tiempo de ejecución: guarda la URL del backend y\n * aplica al SDK de ArcGIS la API key y la ruta de assets, si vienen.\n */\nexport function configurarEntorno(cambios: EntornoMapa): void {\n guardarEntorno(cambios);\n if (cambios.arcgisApiKey) esriConfig.apiKey = cambios.arcgisApiKey;\n if (cambios.arcgisAssetsPath) esriConfig.assetsPath = cambios.arcgisAssetsPath;\n}\n","import type { CSSProperties } from \"react\";\nimport { useCallback, useEffect, useMemo, useRef } from \"react\";\nimport { cn } from \"@/shared/lib/cn\";\nimport { VisorMapa } from \"@/features/maps/components/VisorMapa\";\nimport { ProveedorAlertas } from \"@/features/maps/providers/ProveedorAlertas\";\nimport { ProveedorConfiguracion } from \"@/features/maps/providers/ProveedorConfiguracion\";\nimport { configurarEntorno } from \"@/features/maps/services/entorno\";\nimport {\n crearProveedorToken,\n type OrigenToken,\n} from \"@/features/maps/services/proveedor-token\";\nimport { CLASE_RAIZ_MAPA } from \"@/features/maps/styles/raiz.estilos\";\nimport {\n MODO_MAPA,\n type CodigoHerramienta,\n type ModoMapa,\n type VistaMapa,\n} from \"@/features/maps/types\";\n\n/** Props de `MapaCoreIsa`. El token sale de `urlToken` o `getAccessToken` (uno es obligatorio). */\nexport interface MapaCoreIsaProps extends OrigenToken {\n /** Base URL del backend de Core ISA (p. ej. `https://back.isa.co`). */\n apiBaseUrl: string;\n /** Identificador de la aplicación anfitriona ante el backend. */\n clientId: string;\n /** Mapa del backend que se muestra; por defecto `\"FULLSCREEN\"`. */\n modo?: ModoMapa;\n /** Clave opcional de ArcGIS Location Platform; sin ella, usar el basemap `osm`. */\n arcgisApiKey?: string;\n /** Ruta de los assets del SDK de ArcGIS; por defecto, el CDN de Esri. */\n arcgisAssetsPath?: string;\n /** Herramientas a ocultar por código (p. ej. `[\"three-dimensional\", \"metadata\"]`). */\n herramientasDeshabilitadas?: readonly CodigoHerramienta[];\n /** Se llama con la vista de ArcGIS cada vez que queda lista. */\n onListo?: (vista: VistaMapa) => void;\n /** Se llama si el mapa no puede mostrarse (token, backend o contrato sin mapa). */\n onError?: (error: Error) => void;\n /** Clases del contenedor; el mapa ocupa todo su alto y ancho. */\n className?: string;\n style?: CSSProperties;\n}\n\n/**\n * Mapa de Core ISA listo para embeber: carga la configuración del backend con\n * el token del anfitrión y muestra el visor con sus herramientas. Sin token\n * válido no hay mapa: se muestra el error y se avisa por `onError`.\n */\nexport function MapaCoreIsa({\n apiBaseUrl,\n clientId,\n urlToken,\n getAccessToken,\n modo = MODO_MAPA.pantallaCompleta,\n arcgisApiKey,\n arcgisAssetsPath,\n herramientasDeshabilitadas,\n onListo,\n onError,\n className,\n style,\n}: MapaCoreIsaProps) {\n // El entorno se aplica durante el render (es idempotente): los efectos de\n // los hijos, que ya piden la configuración, corren antes que los del padre.\n configurarEntorno({ apiBaseUrl, arcgisApiKey, arcgisAssetsPath });\n\n // `getAccessToken` va en una ref: si el anfitrión lo recrea en cada render,\n // el proveedor sigue siendo el mismo y la configuración no se vuelve a pedir.\n const getAccessTokenRef = useRef(getAccessToken);\n useEffect(() => {\n getAccessTokenRef.current = getAccessToken;\n }, [getAccessToken]);\n const getAccessTokenEstable = useCallback(\n (id: string) => getAccessTokenRef.current!(id),\n [],\n );\n const tieneGetAccessToken = getAccessToken !== undefined;\n const proveedorToken = useMemo(\n () =>\n // La ref se lee al pedir el token (asíncrono), nunca durante el render.\n // eslint-disable-next-line react-hooks/refs\n crearProveedorToken({\n urlToken,\n getAccessToken: tieneGetAccessToken ? getAccessTokenEstable : undefined,\n }),\n [urlToken, tieneGetAccessToken, getAccessTokenEstable],\n );\n\n return (\n <div className={cn(CLASE_RAIZ_MAPA, \"relative h-full w-full\", className)} style={style}>\n <ProveedorAlertas>\n {/* `key`: otro backend es otra configuración, así que se vuelve a cargar. */}\n <ProveedorConfiguracion\n key={apiBaseUrl}\n clientId={clientId}\n getAccessToken={proveedorToken}\n >\n <VisorMapa\n modo={modo}\n herramientasDeshabilitadas={herramientasDeshabilitadas}\n onListo={onListo}\n onError={onError}\n className=\"h-full w-full\"\n />\n </ProveedorConfiguracion>\n </ProveedorAlertas>\n </div>\n );\n}\n"],"x_google_ignoreList":[0],"mappings":"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"}
|