(function initializeI18n(globalScope) { "use strict"; const DEFAULT_LANGUAGE = "en"; const STORAGE_KEY = "xprov-language"; const TRANSLATIONS = { en: { languageName: "English", pageTitle: "XPro Map Visualizer", applicationMessages: "Application messages", openMapControls: "Open map controls", mapControls: "Map controls", closeMapControls: "Close map controls", mapVisualizer: "Map Visualizer", openSettings: "Open settings", closeSettings: "Close settings", settings: "Settings", applySettings: "Apply", useBrowserDefault: "Use browser default", find: "Find", parcelExample: "e.g. 57 or 2669.1", parcelNumber: "Parcel number", findOnMap: "Find on map", layers: "Layers", waitingForConnection: "Waiting for connection.", loadingPublishedLayers: "Loading published layers.", baseMap: "Base map", softMinimal: "Soft minimal", openStreetMap: "OpenStreetMap", satelliteImagery: "Satellite imagery", language: "Language", applicationLanguage: "Application language", mapView: "Map view", closeFeatureInformation: "Close feature information", resetNorth: "Reset map orientation to north", zoomVisibleLayers: "Zoom to visible layers", copyMapLink: "Copy link to this map view", clipboardUnavailable: "Clipboard access is unavailable.", mapLinkCopied: "Link to this map view copied to your clipboard.", mapLinkCopyFailed: "Unable to copy the map link. Please copy the address from your browser.", zoomArea: "Zoom to area", exitAreaZoom: "Exit area zoom (Esc)", compassRequiresHttps: "Device compass requires HTTPS; HTTP works only on localhost.", compassUnavailable: "Device compass is unavailable on this device.", compassPermissionDenied: "Device compass permission was not granted.", compassOn: "Device compass orientation is on.", compassStartFailed: "Unable to start the device compass.", compassOff: "Device compass orientation is off.", compassTurnOff: "Turn off device compass orientation", compassAlign: "Align map with device compass", dismissMessage: "Dismiss message", enterParcel: "Enter a parcel number to search.", searchingParcel: "Searching for parcel…", searchFailedStatus: "Parcel search failed (status {status}).", noParcelFound: "No parcel found with number “{parcelNumber}”.", foundParcel: "Found parcel {parcelNumber}.", foundParcels: "Found {count} parcels matching {parcelNumber}.", parcelSearchFailed: "Unable to search for that parcel.", loadingWmsLayers: "Loading WMS layers…", wmsLoadFailed: "Unable to load the WMS service.", geoserverConnectionFailed: "GeoServer connection failed (status {status}).", noPublishedLayers: "No published layers were returned by the service.", selectLayerToZoom: "Select a layer with a published extent to zoom to it.", parcel: "Parcel", building: "Building", area: "Area", areaUnavailable: "Area unavailable", inhabited: "Inhabited", viewCorrespondingBuilding: "View corresponding building", associatedParcels: "Associated parcels", viewParcel: "View parcel {parcelNumber}", parcelWithNumber: "Parcel {parcelNumber}", unavailable: "Unavailable", noAssociatedParcels: "No associated parcels were found.", zoomIn: "Zoom in", zoomOut: "Zoom out", attribution: "Attributions", softAttribution: '© OpenStreetMap contributors © CARTO', satelliteAttribution: 'Tiles © Esri — Source: Esri, Maxar, Earthstar Geographics, and the GIS User Community', }, es: { languageName: "Español", pageTitle: "Visualizador de Mapas XPro", applicationMessages: "Mensajes de la aplicación", openMapControls: "Abrir controles del mapa", mapControls: "Controles del mapa", closeMapControls: "Cerrar controles del mapa", mapVisualizer: "Visualizador de Mapas", openSettings: "Abrir configuración", closeSettings: "Cerrar configuración", settings: "Configuración", applySettings: "Aplicar", useBrowserDefault: "Usar el idioma predeterminado del navegador", find: "Buscar", parcelExample: "p. ej., 57 o 2669.1", parcelNumber: "Número de parcela", findOnMap: "Localizar en el mapa", layers: "Capas", waitingForConnection: "Esperando conexión.", loadingPublishedLayers: "Cargando capas publicadas.", baseMap: "Mapa base", softMinimal: "Minimalista suave", openStreetMap: "OpenStreetMap", satelliteImagery: "Imágenes por satélite", language: "Idioma", applicationLanguage: "Idioma de la aplicación", mapView: "Vista del mapa", closeFeatureInformation: "Cerrar información del elemento", resetNorth: "Restablecer la orientación del mapa hacia el norte", zoomVisibleLayers: "Ajustar a las capas visibles", copyMapLink: "Copiar enlace a esta vista del mapa", clipboardUnavailable: "El acceso al portapapeles no está disponible.", mapLinkCopied: "El enlace a esta vista se ha copiado al portapapeles.", mapLinkCopyFailed: "No se pudo copiar el enlace. Copie la dirección desde el navegador.", zoomArea: "Ampliar un área", exitAreaZoom: "Salir de la ampliación de área (Esc)", compassRequiresHttps: "La brújula del dispositivo requiere HTTPS; HTTP solo funciona en localhost.", compassUnavailable: "La brújula no está disponible en este dispositivo.", compassPermissionDenied: "No se concedió permiso para usar la brújula.", compassOn: "La orientación mediante la brújula está activada.", compassStartFailed: "No se pudo iniciar la brújula del dispositivo.", compassOff: "La orientación mediante la brújula está desactivada.", compassTurnOff: "Desactivar la orientación mediante la brújula", compassAlign: "Alinear el mapa con la brújula", dismissMessage: "Descartar mensaje", enterParcel: "Introduzca un número de parcela para buscar.", searchingParcel: "Buscando la parcela…", searchFailedStatus: "La búsqueda de la parcela falló (estado {status}).", noParcelFound: "No se encontró la parcela con el número «{parcelNumber}».", foundParcel: "Se encontró la parcela {parcelNumber}.", foundParcels: "Se encontraron {count} parcelas que coinciden con {parcelNumber}.", parcelSearchFailed: "No se pudo buscar esa parcela.", loadingWmsLayers: "Cargando capas WMS…", wmsLoadFailed: "No se pudo cargar el servicio WMS.", geoserverConnectionFailed: "La conexión con GeoServer falló (estado {status}).", noPublishedLayers: "El servicio no devolvió ninguna capa publicada.", selectLayerToZoom: "Seleccione una capa con extensión publicada para encuadrarla.", parcel: "Parcela", building: "Edificio", area: "Área", areaUnavailable: "Área no disponible", inhabited: "Habitada", viewCorrespondingBuilding: "Ver el edificio correspondiente", associatedParcels: "Parcelas asociadas", viewParcel: "Ver parcela {parcelNumber}", parcelWithNumber: "Parcela {parcelNumber}", unavailable: "No disponible", noAssociatedParcels: "No se encontraron parcelas asociadas.", zoomIn: "Acercar", zoomOut: "Alejar", attribution: "Atribuciones", softAttribution: '© Colaboradores de OpenStreetMap © CARTO', satelliteAttribution: 'Mosaicos © Esri — Fuente: Esri, Maxar, Earthstar Geographics y la comunidad de usuarios de SIG', }, "pt-PT": { languageName: "Português", pageTitle: "Visualizador de Mapas XPro", applicationMessages: "Mensagens da aplicação", openMapControls: "Abrir controlos do mapa", mapControls: "Controlos do mapa", closeMapControls: "Fechar controlos do mapa", mapVisualizer: "Visualizador de Mapas", openSettings: "Abrir definições", closeSettings: "Fechar definições", settings: "Definições", applySettings: "Aplicar", useBrowserDefault: "Usar predefinição do navegador", find: "Pesquisar", parcelExample: "p. ex. 57 ou 2669.1", parcelNumber: "Número da parcela", findOnMap: "Localizar no mapa", layers: "Camadas", waitingForConnection: "A aguardar ligação.", loadingPublishedLayers: "A carregar camadas publicadas.", baseMap: "Mapa base", softMinimal: "Minimalista suave", openStreetMap: "OpenStreetMap", satelliteImagery: "Imagem de satélite", language: "Idioma", applicationLanguage: "Idioma da aplicação", mapView: "Vista do mapa", closeFeatureInformation: "Fechar informação do elemento", resetNorth: "Repor a orientação do mapa para norte", zoomVisibleLayers: "Ajustar às camadas visíveis", copyMapLink: "Copiar ligação para esta vista do mapa", clipboardUnavailable: "O acesso à área de transferência não está disponível.", mapLinkCopied: "A ligação para esta vista foi copiada para a área de transferência.", mapLinkCopyFailed: "Não foi possível copiar a ligação. Copie o endereço a partir do navegador.", zoomArea: "Ampliar uma área", exitAreaZoom: "Sair da ampliação de área (Esc)", compassRequiresHttps: "A bússola do dispositivo requer HTTPS; HTTP funciona apenas em localhost.", compassUnavailable: "A bússola não está disponível neste dispositivo.", compassPermissionDenied: "A permissão para usar a bússola não foi concedida.", compassOn: "A orientação pela bússola está ativa.", compassStartFailed: "Não foi possível iniciar a bússola do dispositivo.", compassOff: "A orientação pela bússola está desativada.", compassTurnOff: "Desativar orientação pela bússola", compassAlign: "Alinhar mapa com a bússola", dismissMessage: "Dispensar mensagem", enterParcel: "Introduza um número de parcela para pesquisar.", searchingParcel: "A pesquisar a parcela…", searchFailedStatus: "A pesquisa da parcela falhou (estado {status}).", noParcelFound: "Não foi encontrada a parcela com o número “{parcelNumber}”.", foundParcel: "Parcela {parcelNumber} encontrada.", foundParcels: "Foram encontradas {count} parcelas correspondentes a {parcelNumber}.", parcelSearchFailed: "Não foi possível pesquisar essa parcela.", loadingWmsLayers: "A carregar camadas WMS…", wmsLoadFailed: "Não foi possível carregar o serviço WMS.", geoserverConnectionFailed: "A ligação ao GeoServer falhou (estado {status}).", noPublishedLayers: "O serviço não devolveu camadas publicadas.", selectLayerToZoom: "Selecione uma camada com extensão publicada para a enquadrar.", parcel: "Parcela", building: "Prédio", area: "Área", areaUnavailable: "Área indisponível", inhabited: "Habitada", viewCorrespondingBuilding: "Ver prédio correspondente", associatedParcels: "Parcelas associadas", viewParcel: "Ver parcela {parcelNumber}", parcelWithNumber: "Parcela {parcelNumber}", unavailable: "Indisponível", noAssociatedParcels: "Não foram encontradas parcelas associadas.", zoomIn: "Ampliar", zoomOut: "Reduzir", attribution: "Atribuições", softAttribution: '© Colaboradores do OpenStreetMap © CARTO', satelliteAttribution: 'Mosaicos © Esri — Fonte: Esri, Maxar, Earthstar Geographics e comunidade de utilizadores de SIG', }, }; function normalizeLanguage(language) { if (typeof language !== "string") { return null; } const normalized = language.replace("_", "-").toLowerCase(); return Object.keys(TRANSLATIONS).find((candidate) => { const candidateNormalized = candidate.toLowerCase(); return candidateNormalized === normalized || candidateNormalized.split("-")[0] === normalized.split("-")[0]; }) || null; } function readStoredLanguage(storage) { try { return normalizeLanguage(storage?.getItem(STORAGE_KEY)); } catch { return null; } } function detectLanguage({ storage, languages = [] } = {}) { const storedLanguage = readStoredLanguage(storage); if (storedLanguage) { return storedLanguage; } for (const language of languages) { const supportedLanguage = normalizeLanguage(language); if (supportedLanguage) { return supportedLanguage; } } return DEFAULT_LANGUAGE; } function detectBrowserLanguage(languages = []) { for (const language of languages) { const supportedLanguage = normalizeLanguage(language); if (supportedLanguage) { return supportedLanguage; } } return DEFAULT_LANGUAGE; } function createI18n({ storage = globalScope.localStorage, languages = globalScope.navigator?.languages || [globalScope.navigator?.language], } = {}) { const browserLanguage = detectBrowserLanguage(languages); let preference = readStoredLanguage(storage); let language = preference || browserLanguage; function translate(key, values = {}) { const template = TRANSLATIONS[language]?.[key] ?? TRANSLATIONS[DEFAULT_LANGUAGE]?.[key] ?? key; return template.replace(/\{(\w+)\}/g, (match, name) => Object.hasOwn(values, name) ? String(values[name]) : match, ); } return { get language() { return language; }, get locale() { return language; }, get preference() { return preference; }, get supportedLanguages() { return Object.keys(TRANSLATIONS); }, setLanguage(nextLanguage) { const useBrowserDefault = nextLanguage == null || nextLanguage === "browser"; preference = useBrowserDefault ? null : normalizeLanguage(nextLanguage) || DEFAULT_LANGUAGE; language = preference || browserLanguage; try { if (preference) { storage?.setItem(STORAGE_KEY, preference); } else { storage?.removeItem(STORAGE_KEY); } } catch { // A blocked storage API must not prevent language selection. } return language; }, t: translate, tp(singularKey, pluralKey, count, values = {}) { return translate(count === 1 ? singularKey : pluralKey, { ...values, count }); }, }; } const exported = { DEFAULT_LANGUAGE, STORAGE_KEY, TRANSLATIONS, normalizeLanguage, detectLanguage, detectBrowserLanguage, createI18n, }; if (typeof module !== "undefined" && module.exports) { module.exports = exported; } globalScope.XProI18n = exported; })(typeof window === "undefined" ? globalThis : window);