i18n(pt): apply review round 3

Three-model review (astra, sol, fable), round 3: 17 of 18 findings
applied (some in own wording, one in part); "Missões espac." rejected.

- pt: layer cards «{label}: camada ativada/desativada», pointer and
  Directions toasts name «A ferramenta "{owner}"», counters after a
  colon where the count can be 1, traffic «sem dados de fluxo» and
  «Fluxo: {percent}% cob», «limite de requisições atingido», FECHAR,
  ANT., PREDEF. VISUAIS, quoted "Nível da rua", infinitive tooltips,
  and more (see docs/translations/pt.md).
- CCTV summary line localizes its CAL, SRC and CONTEXT values through
  existing catalog keys (all locales); codes stay underneath.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
German KhokhlovandClaude Opus 5.5 committed 2026-10-28 22:40:38 +04:00
1 parent 858ce827e5
commit 4048535921
4 files changed
+152 -57

No files matched your search

+46 -46
View File
@@ -17,7 +17,7 @@
"That shape could not be placed.": "Não foi possível colocar essa forma.",
"Could not place the shape: {error}": "Não foi possível colocar a forma: {error}",
"Board cleared.": "Quadro limpo.",
"{owner} is using the pointer — close it first.": "Ponteiro em uso: {owner}. Feche-o primeiro.",
"{owner} is using the pointer — close it first.": "A ferramenta \"{owner}\" está usando o ponteiro — feche-a primeiro.",
"{label} · Detailed outline unavailable": "{label} · Contorno detalhado indisponível",
"Flying to Austin, TX...": "Voando para Austin, TX...",
"Restoring shared view...": "Restaurando a vista compartilhada...",
@@ -187,18 +187,18 @@
"INITIAL M4.4 · RECLASSIFIED M5.2 LANDSLIDE": "INICIAL M4,4 · RECLASSIFICADO COMO DESLIZAMENTO M5,2",
"USGS EVENT us7000tbwb · OPEN SOURCE": "EVENTO USGS us7000tbwb · ABRIR FONTE",
"Open the USGS initial report for the 26 August 2026 Nepal landslide": "Abrir o relatório inicial do USGS sobre o deslizamento de 26 de agosto de 2026 no Nepal",
"Show the Nepal context callout without a border or country fill": "Mostra o destaque de contexto do Nepal sem fronteira nem preenchimento do país",
"Introduce Nepal, draw its border, then reveal the Bhote Koshi incident": "Apresenta o Nepal, desenha sua fronteira e depois revela o incidente do Bhote Koshi",
"Show the Nepal context callout without a border or country fill": "Mostrar o destaque de contexto do Nepal sem fronteira nem preenchimento do país",
"Introduce Nepal, draw its border, then reveal the Bhote Koshi incident": "Apresentar o Nepal, desenhar sua fronteira e depois revelar o incidente do Bhote Koshi",
"CITIES": "CIDADES",
"Keep the regional incident context and introduce nearby city labels": "Mantém o contexto regional do incidente e apresenta os rótulos das cidades próximas",
"Keep the regional incident context and introduce nearby city labels": "Manter o contexto regional do incidente e apresentar os rótulos das cidades próximas",
"PLACES": "LUGARES",
"Introduce the reconstruction scene key places from trigger to downstream": "Apresenta os lugares-chave da cena de reconstrução, do gatilho até rio abaixo",
"Introduce the reconstruction scene key places from trigger to downstream": "Apresentar os lugares-chave da cena de reconstrução, do gatilho até rio abaixo",
"PATH": "PERCURSO",
"Animate the sourced cyan river-centerline route to Trishuli Bazaar": "Anima a rota ciano documentada pelo eixo do rio até Trishuli Bazaar",
"Animate the sourced cyan river-centerline route to Trishuli Bazaar": "Animar a rota ciano documentada pelo eixo do rio até Trishuli Bazaar",
"OVERVIEW": "VISÃO GERAL",
"Keep the completed flood path and location labels visible": "Mantém visíveis o percurso completo da inundação e os rótulos dos locais",
"Keep the completed flood path and location labels visible": "Manter visíveis o percurso completo da inundação e os rótulos dos locais",
"RECORD": "REGISTRO",
"Reveal the trigger record while making a slow camera approach": "Revela o registro do gatilho com uma aproximação lenta da câmera",
"Reveal the trigger record while making a slow camera approach": "Revelar o registro do gatilho com uma aproximação lenta da câmera",
"{speed} kn": "{speed} kt",
"That file is not valid JSON.": "Esse arquivo não é um JSON válido.",
"That JSON file is not GeoJSON.": "Esse arquivo JSON não é GeoJSON.",
@@ -210,7 +210,7 @@
"That file creates more than {limit} map objects (the limit).": "Esse arquivo cria mais de {limit} objetos no mapa (o limite).",
"That file has more than {limit} style definitions and image links after cleanup (the limit).": "Após a limpeza, esse arquivo tem mais de {limit} definições de estilo e links de imagem (o limite).",
"That file has more than {limit} features (the limit).": "Esse arquivo tem mais de {limit} elementos (o limite).",
"That file has more than {limit} points (the limit) across {features} features.": "Esse arquivo tem mais de {limit} pontos (o limite) em {features} elementos.",
"That file has more than {limit} points (the limit) across {features} features.": "Esse arquivo tem mais de {limit} pontos (o limite). Total de elementos: {features}.",
"That file has more than {limit} points (the limit).": "Esse arquivo tem mais de {limit} pontos (o limite).",
"That KMZ unpacks to more than the import limit.": "Descompactado, esse KMZ ultrapassa o limite de importação.",
"That KMZ is damaged and could not be unpacked.": "Esse KMZ está danificado e não pôde ser descompactado.",
@@ -236,7 +236,7 @@
"That file has {count} map objects; the limit is {limit}.": "Esse arquivo tem {count} objetos no mapa; o limite é {limit}.",
"Ground heights could not be read. Try that file again.": "Não foi possível ler as altitudes do terreno. Tente esse arquivo de novo.",
"That file has invalid point graphics.": "Esse arquivo tem gráficos de pontos inválidos.",
"Overpass rate-limited": "Overpass com limite de requisições",
"Overpass rate-limited": "Overpass: limite de requisições atingido",
"Overpass timed out": "Tempo esgotado no Overpass",
"Overpass could not complete the query": "Overpass não conseguiu concluir a consulta",
"Map tiles temporarily unavailable": "Blocos do mapa temporariamente indisponíveis",
@@ -494,7 +494,7 @@
"Focus {label}": "Focar {label}",
"Global Context navigation": "Navegação do contexto global",
"Previous — prior visited contact in the 250 km window": "Anterior — contato visitado anteriormente na janela de 250 km",
"PREVIOUS": "ANTERIOR",
"PREVIOUS": "ANT.",
"FOCUS": "FOCAR",
"Next — nearest unvisited contact in the 250 km window": "Próximo — contato não visitado mais próximo na janela de 250 km",
"NEXT": "PRÓX.",
@@ -515,7 +515,7 @@
"Military flights": "Voos militares",
"AIS vessels": "Embarcações AIS",
"Mapped installations": "Instalações mapeadas",
"syncing {count} city feeds...": "sincronizando {count} feeds de cidades...",
"syncing {count} city feeds...": "sincronizando feeds de cidades: {count}...",
"scanning nearby systems...": "buscando sistemas próximos...",
"GBFS fetch error": "erro ao obter dados GBFS",
"Station {id}": "Estação {id}",
@@ -525,7 +525,7 @@
"⚠️ Not renting": "⚠️ Sem aluguel",
"⚠️ Not returning": "⚠️ Sem devolução",
"HDG {value}° (ESTIMATED)": "HDG {value}° (ESTIMADO)",
"{count} CAMERAS STANDING BY · NO CAMERA SELECTED · CLICK A CAMERA TO ACTIVATE": "{count} CÂMERAS EM ESPERA · NENHUMA CÂMERA SELECIONADA · CLIQUE EM UMA CÂMERA PARA ATIVAR",
"{count} CAMERAS STANDING BY · NO CAMERA SELECTED · CLICK A CAMERA TO ACTIVATE": "CÂMERAS EM ESPERA: {count} · NENHUMA CÂMERA SELECIONADA · CLIQUE EM UMA CÂMERA PARA ATIVAR",
"No cameras available in catalog.": "Nenhuma câmera disponível no catálogo.",
"{city} CCTV": "CCTV {city}",
"FOV {value}° (DATASHEET)": "FOV {value}° (FICHA TÉCNICA)",
@@ -684,9 +684,9 @@
"Place A and B first": "Coloque A e B primeiro",
"action|CLEAR": "LIMPAR",
"Remove the route and both markers": "Remover a rota e os dois marcadores",
"press Escape twice to leave Draw": "pressione Esc duas vezes para sair de Desenho",
"{name} is active — turn {name} off, then set {endpoint}": "{name} está ativo — desative {name} e depois defina {endpoint}",
"{name} is active — {leave}, then set {endpoint}": "{name} está ativo — {leave} e depois defina {endpoint}",
"press Escape twice to leave Draw": "pressione Esc duas vezes para sair de \"Desenho\"",
"{name} is active — turn {name} off, then set {endpoint}": "A ferramenta \"{name}\" está ativa — desative \"{name}\" e depois defina {endpoint}",
"{name} is active — {leave}, then set {endpoint}": "A ferramenta \"{name}\" está ativa — {leave} e depois defina {endpoint}",
"Only the first {count} turns of this route are shown": "Só as primeiras {count} conversões desta rota são mostradas",
"Turn-by-turn directions": "Instruções passo a passo",
"Another map tool is using clicks — close it, then SET A again": "Outra ferramenta do mapa está usando os cliques — feche-a e pressione DEFINIR A de novo",
@@ -815,7 +815,7 @@
"ORBIT REPLAY · {mission}": "REPRISE DA ÓRBITA · {mission}",
"PAUSED · {title}": "PAUSADO · {title}",
"UNSPECIFIED": "NÃO ESPECIFICADO",
"+{count} additional payload records": "+{count} registros de carga útil adicionais",
"+{count} additional payload records": "Outros registros de carga útil: {count}",
"PAYLOAD DATA UNAVAILABLE": "DADOS DA CARGA ÚTIL INDISPONÍVEIS",
"{value} KM DOWNRANGE": "A {value} KM DO LOCAL DE LANÇAMENTO",
"POSITION UNAVAILABLE": "POSIÇÃO INDISPONÍVEL",
@@ -895,7 +895,7 @@
"opening receiver": "abrindo o receptor",
"checking decoder feeds": "verificando os feeds do decodificador",
"WebUSB needs desktop Chrome or Edge": "O WebUSB requer Chrome ou Edge para desktop",
"connect a receiver in Radio": "conecte um receptor em Rádio",
"connect a receiver in Radio": "conecte um receptor em \"Rádio\"",
"receiver is in FM mode": "o receptor está no modo FM",
"listening": "escutando",
"USB error": "erro de USB",
@@ -969,7 +969,7 @@
"Broadcaster stream is unavailable or blocked by the browser.": "O stream da emissora está indisponível ou foi bloqueado pelo navegador.",
"Playback requires a direct click or tap.": "A reprodução exige um clique ou toque direto.",
"Broadcaster stream could not be started.": "Não foi possível iniciar o stream da emissora.",
"Alternative": "Alternativo",
"Alternative": "Alternativa",
"Ambient": "Ambiente",
"Blues": "Blues",
"Classical": "Clássica",
@@ -1032,7 +1032,7 @@
"DOCKED · {name} · +{extra}": "ACOPLADO · {name} · +{extra}",
"DOCKED · {name}": "ACOPLADO · {name}",
"{name} needs the Google 3D map: choose it under MAP SOURCE": "{name} requer o mapa Google 3D: escolha-o em FONTE DO MAPA",
"zoom in to a street to open {name}": "aproxime-se de uma rua para abrir {name}",
"zoom in to a street to open {name}": "aproxime-se de uma rua para abrir o {name}",
"loading coverage...": "carregando cobertura...",
"No street-level imagery within {radius} m of that point": "Nenhuma imagem no nível da rua a até {radius} m desse ponto",
"No street-level imagery within {radius} m of the view centre": "Nenhuma imagem no nível da rua a até {radius} m do centro da vista",
@@ -1111,17 +1111,17 @@
"TomTom flow unavailable": "Fluxo do TomTom indisponível",
"SIMULATED — {reason}": "SIMULADO — {reason}",
"Syncing flow · Roads: {source}": "Sincronizando fluxo · Vias: {source}",
"LIVE · Roads: {source} · Roads without flow hidden": "AO VIVO · Vias: {source} · Vias sem fluxo ocultas",
"LIVE · Roads: {source} · No flow roads in view": "AO VIVO · Vias: {source} · Nenhuma via com fluxo na vista",
"LIVE · Roads: {source} · Flow {percent}%": "AO VIVO · Vias: {source} · Fluxo {percent}%",
"SIMULATED · Roads: {source} · Flow {percent}%": "SIMULADO · Vias: {source} · Fluxo {percent}%",
"LIVE · Roads: {source} · Roads without flow hidden": "AO VIVO · Vias: {source} · Vias sem dados de fluxo ocultas",
"LIVE · Roads: {source} · No flow roads in view": "AO VIVO · Vias: {source} · Nenhuma via com dados de fluxo na vista",
"LIVE · Roads: {source} · Flow {percent}%": "AO VIVO · Vias: {source} · Fluxo: {percent}% cob",
"SIMULATED · Roads: {source} · Flow {percent}%": "SIMULADO · Vias: {source} · Fluxo: {percent}% cob",
"Syncing flow · Roads: OpenStreetMap · Flow: TomTom · Unmatched: simulated": "Sincronizando fluxo · Vias: OpenStreetMap · Fluxo: TomTom · Sem correspondência: simulado",
"LIVE · Roads: OpenStreetMap · Flow: TomTom · {percent}% cov · Unmatched: simulated": "AO VIVO · Vias: OpenStreetMap · Fluxo: TomTom · {percent}% cob · Sem correspondência: simulado",
"LIVE · Roads: OpenStreetMap · Flow: TomTom · {percent}% cov": "AO VIVO · Vias: OpenStreetMap · Fluxo: TomTom · {percent}% cob",
"SIMULATED · Roads: OpenStreetMap · Flow: TomTom (no matches)": "SIMULADO · Vias: OpenStreetMap · Fluxo: TomTom (sem correspondências)",
"SIMULATED — traffic service unreachable": "SIMULADO — serviço de trânsito inacessível",
"SIMULATED — add TomTom key for live": "SIMULADO — adicione a chave do TomTom para dados ao vivo",
"OpenFreeMap tiles rate-limited": "Blocos do OpenFreeMap com limite de requisições",
"OpenFreeMap tiles rate-limited": "Blocos do OpenFreeMap: limite de requisições atingido",
"OpenFreeMap tiles timed out": "Os blocos do OpenFreeMap excederam o tempo limite",
"OpenFreeMap tiles unavailable": "Blocos do OpenFreeMap indisponíveis",
"occupancy|empty": "vazio",
@@ -1231,9 +1231,9 @@
"Hourly global mosaic; usually 2–3 hours delayed": "Mosaico global por hora; normalmente com 2–3 horas de atraso",
"GOES regional clouds; approximately 5-minute updates": "Nuvens regionais do GOES; atualizações a cada 5 minutos aproximadamente",
"Clouds only": "Só nuvens",
"Apply the full cloud brightness key; 100% filter strength": "Aplica o filtro completo de brilho das nuvens; intensidade do filtro 100%",
"Apply the full cloud brightness key; 100% filter strength": "Aplicar o filtro completo de brilho das nuvens; intensidade do filtro 100%",
"Full": "Completa",
"Show the complete infrared image; 0% filter strength": "Mostra a imagem infravermelha completa; intensidade do filtro 0%",
"Show the complete infrared image; 0% filter strength": "Mostrar a imagem infravermelha completa; intensidade do filtro 0%",
"Soft": "Suave",
"Vivid": "Intensa",
"Image opacity; does not alter the observed values": "Opacidade da imagem; não altera os valores observados",
@@ -1282,7 +1282,7 @@
"Reduced motion": "Movimento reduzido",
"Resume": "Retomar",
"Pause": "Pausar",
"Pause visual flow; forecast time does not advance with animation": "Pausa o fluxo visual; o horário da previsão não avança com a animação",
"Pause visual flow; forecast time does not advance with animation": "Pausar o fluxo visual; o horário da previsão não avança com a animação",
"None": "Nenhum",
"Speed": "Velocidade",
"Pressure": "Pressão",
@@ -1475,7 +1475,7 @@
"New anchor ID": "ID da nova âncora",
"Capture camera as anchor": "Capturar a câmera como âncora",
"Anchor added to draft": "Âncora adicionada ao rascunho",
"Set move start to current camera": "Definir o início do movimento na câmera atual",
"Set move start to current camera": "Usar a câmera atual como início do movimento",
"Move added to draft; destination remains the shot camera": "Movimento adicionado ao rascunho; o destino continua sendo a câmera do plano",
"Use ordinary flight": "Usar voo comum",
"Invalid shot JSON": "JSON de plano inválido",
@@ -1500,7 +1500,7 @@
"SDR decoder worker failed": "Falha no processo do decodificador SDR",
"SDR decoder did not start; receiver stopped": "O decodificador SDR não iniciou; receptor parado",
"SDR decoder stopped responding; receiver stopped": "O decodificador SDR parou de responder; receptor parado",
"SDR decoder fell behind; receiver stopped": "O decodificador SDR ficou para trás; receptor parado",
"SDR decoder fell behind; receiver stopped": "O decodificador SDR não acompanhou os dados recebidos; receptor parado",
"WebUSB requires desktop Chrome or Edge": "O WebUSB requer Chrome ou Edge para desktop",
"Waiting for an RTL-SDR device…": "Aguardando um dispositivo RTL-SDR…",
"Browser audio is suspended; press Connect again to resume it": "O áudio do navegador está suspenso; pressione Conectar de novo para retomá-lo",
@@ -1542,7 +1542,7 @@
"unsaved CCTV calibration": "a calibração de CCTV não salva",
"the open cockpit": "a cabine aberta",
"Switching language reloads the page. This will be lost: {items}. Switch anyway?": "Mudar de idioma recarrega a página. Isto será perdido: {items}. Mudar mesmo assim?",
"VISUAL PRESETS": "PREDEFINIÇÕES VISUAIS",
"VISUAL PRESETS": "PREDEF. VISUAIS",
"LOCATION": "LOCAL",
"CONTACTS — nearest planes · vessels · sites": "CONTATOS — aviões · embarcações · locais mais próximos",
"SPACE MISSIONS — launches & orbital assets": "MISSÕES ESPACIAIS — lançamentos e ativos orbitais",
@@ -1554,7 +1554,7 @@
"Copy failed": "Falha ao copiar",
"Return map to straight-down view": "Voltar o mapa à vista de cima",
"Tilt map to oblique view": "Inclinar o mapa para uma vista oblíqua",
"Reset map to north up. Current heading {heading} degrees": "Orientar o mapa com o norte para cima. Rumo atual: {heading} graus",
"Reset map to north up. Current heading {heading} degrees": "Orientar o mapa com o norte para cima. Orientação atual: {heading} graus",
"Tilted view": "Vista inclinada",
"Straight-down view": "Vista de cima",
"North up": "Norte para cima",
@@ -1645,7 +1645,7 @@
"CYCLE ON": "CICLO LIGADO",
"CYCLE OFF": "CICLO DESLIG.",
"Stop automatic page cycling. Previous, Next, and the SIG/NEWS/LOCAL tabs stay available.": "Parar a rotação automática de páginas. Anterior, Próxima e as abas SIG/NOTÍCIAS/LOCAL continuam disponíveis.",
"Cycle briefing pages automatically every 9 seconds (Signals → News → Local). Pauses while you hover or focus the panel. Live signal data refreshes continuously either way.": "Alterna as páginas do briefing automaticamente a cada 9 segundos (Sinais → Notícias → Local). Pausa enquanto você passa o mouse ou foca o painel. Os dados de sinais ao vivo continuam atualizando de qualquer forma.",
"Cycle briefing pages automatically every 9 seconds (Signals → News → Local). Pauses while you hover or focus the panel. Live signal data refreshes continuously either way.": "Alternar as páginas do briefing automaticamente a cada 9 segundos (Sinais → Notícias → Local). A alternância pausa enquanto você passa o mouse ou foca o painel. Os dados de sinais ao vivo continuam sendo atualizados de qualquer forma.",
"ACQUIRING REGIONAL NEWS": "OBTENDO NOTÍCIAS DA ÁREA",
"REGIONAL NEWS UNAVAILABLE": "NOTÍCIAS DA ÁREA INDISPONÍVEIS",
"RESOLVING REGION": "IDENTIFICANDO REGIÃO",
@@ -1958,7 +1958,7 @@
"Station unavailable after directory refresh": "Estação indisponível após atualizar o diretório",
"Radio could not {action} cleanly": "Não foi possível {action} o rádio corretamente",
"Go to expanded Radio section": "Ir para a seção de rádio expandida",
"Expand Radio section in Context": "Expandir a seção de rádio em Contexto",
"Expand Radio section in Context": "Expandir a seção de rádio em \"Contexto\"",
"Close compact Radio controls": "Fechar controles compactos do rádio",
"Open compact Radio controls": "Abrir controles compactos do rádio",
"SYNC": "SINC",
@@ -2019,7 +2019,7 @@
"Point the camera at the ground to use the view": "Aponte a câmera para o chão para usar a vista",
"That point cannot anchor a box": "Esse ponto não pode ancorar uma área",
"Imagery stops at ±{limit}° latitude": "As imagens vão até ±{limit}° de latitude",
"{owner} is using the pointer — close it first": "Ponteiro em uso: {owner}. Feche-o primeiro",
"{owner} is using the pointer — close it first": "A ferramenta \"{owner}\" está usando o ponteiro — feche-a primeiro",
"Box is {size} wide · limit {limit}": "A área tem {size} de largura · limite {limit}",
"View is {size} wide · limit {limit}": "A vista tem {size} de largura · limite {limit}",
"VS BASEMAP": "VS MAPA BASE",
@@ -2167,7 +2167,7 @@
"RETRYING ALPR CAMERAS": "BUSCANDO DE NOVO AS CÂMERAS ALPR",
"FETCHING ALPR CAMERAS": "BUSCANDO CÂMERAS ALPR",
"OVERPASS TEMPORARILY UNAVAILABLE": "OVERPASS TEMPORARIAMENTE INDISPONÍVEL",
"OVERPASS RATE-LIMITED": "OVERPASS COM LIMITE DE REQUISIÇÕES",
"OVERPASS RATE-LIMITED": "OVERPASS: LIMITE DE REQUISIÇÕES ATINGIDO",
"OVERPASS TIMED OUT": "TEMPO ESGOTADO NO OVERPASS",
"OVERPASS COULD NOT COMPLETE THE QUERY": "OVERPASS NÃO CONSEGUIU CONCLUIR A CONSULTA",
"MAP TILES TEMPORARILY UNAVAILABLE": "BLOCOS DO MAPA TEMPORARIAMENTE INDISPONÍVEIS",
@@ -2232,8 +2232,8 @@
"other": "{count} feeds ao vivo"
},
"{feed} {count} ({seconds}s old)": "{feed} {count} (há {seconds} s)",
"Street Level toggle failed": "Não foi possível ativar ou desativar a camada Nível da rua",
"Street Level could not start": "Não foi possível iniciar Nível da rua",
"Street Level toggle failed": "Não foi possível ativar ou desativar a camada \"Nível da rua\"",
"Street Level could not start": "Não foi possível iniciar a camada \"Nível da rua\"",
"SHRINK": "REDUZIR",
"EXPAND": "AMPLIAR",
"Shrink": "Reduzir",
@@ -2253,8 +2253,8 @@
"other": "ÚLTIMOS {count} DIAS"
},
"{window} · SINCE {date}": "{window} · DESDE {date}",
"Turn Street Level off": "Desativar Nível da rua",
"Turn Street Level on": "Ativar Nível da rua",
"Turn Street Level off": "Desativar \"Nível da rua\"",
"Turn Street Level on": "Ativar \"Nível da rua\"",
"{name} imagery on": "Imagens do {name} ativadas",
"{name} imagery off": "Imagens do {name} desativadas",
"Image by {creator}": "Imagem de {creator}",
@@ -2262,7 +2262,7 @@
"OPEN {labels}": "ABRIR {labels}",
"Open {names} at the centre of the view": "Abrir {names} no centro da vista",
"Zoom in to a street to open {names} here": "Aproxime-se de uma rua para abrir {names} aqui",
"Switch Street Level on to draw its coverage.": "Ative Nível da rua para desenhar a cobertura.",
"Switch Street Level on to draw its coverage.": "Ative \"Nível da rua\" para desenhar a cobertura.",
"Every provider is switched off: light a chip to draw its coverage.": "Todos os provedores estão desligados: ative um para desenhar a cobertura dele.",
"Loading this sequence…": "Carregando esta sequência…",
"{n} images in this sequence · Esc clears": {
@@ -2346,7 +2346,7 @@
"Custom": "Personalizado",
"These preferences stay in this browser.": "Estas preferências ficam neste navegador.",
"VOICE SYSTEM ERROR": "ERRO NO SISTEMA DE VOZ",
"DISMISS": "DISPENSAR",
"DISMISS": "FECHAR",
"Check microphone permission and network access, then try again.": "Verifique a permissão do microfone e o acesso à rede, e tente novamente.",
"Gemini returned an oversized audio chunk": "O Gemini retornou um trecho de áudio grande demais",
"Gemini returned an unsupported audio format": "O Gemini retornou um formato de áudio não suportado",
@@ -2525,7 +2525,7 @@
"the flights layer loads by viewport": "a camada de voos carrega conforme a vista",
"distance is ground distance, not overhead": "a distância é medida no solo até o ponto subsatélite, não até o satélite",
"the count is a lower bound because at least one layer reached its retained limit.": "a contagem é um mínimo porque pelo menos uma camada atingiu o limite de retenção.",
"{label} off": "{label}: desativado",
"{label} off": "{label}: camada desativada",
"{label} loading": "{label}: carregando",
"{label} error": "{label}: erro",
"counted the first {returned} loaded records": "foram contados os primeiros {returned} registros carregados",
@@ -2578,7 +2578,7 @@
"{name} is no longer loaded": "{name} não está mais carregado",
"Unknown target layer: {target}": "Camada de destino desconhecida: {target}",
"nominal": "nominal",
"{label} on": "{label}: ativado",
"{label} on": "{label}: camada ativada",
"Frame aircraft": "Enquadrar aeronaves",
"Frame military aircraft": "Enquadrar aeronaves militares",
"Frame ships": "Enquadrar embarcações",
@@ -2949,7 +2949,7 @@
"RESET CAL": "REDEFINIR CAL",
"SCENE SUMMARY": "RESUMO DA CENA",
"STREET LEVEL": "NÍVEL DA RUA",
"Turn Street Level on or off": "Ativar ou desativar Nível da rua",
"Turn Street Level on or off": "Ativar ou desativar \"Nível da rua\"",
"Show the street-level view full screen (Esc shrinks it)": "Mostrar a vista no nível da rua em tela cheia (Esc reduz)",
"Image fit": "Ajuste da imagem",
"FIT": "AJUSTAR",
@@ -3002,6 +3002,6 @@
"EXPLORE MANUALLY": "EXPLORAR MANUALMENTE",
"Begin with a clean globe": "Comece com um globo limpo",
"Don't show this again": "Não mostrar novamente",
"ESC to dismiss": "ESC para dispensar",
"ESC to dismiss": "ESC para fechar",
"Tip: the GEV MIC button in the dock lets you talk to the map.": "Dica: o botão GEV MIC no dock permite falar com o mapa."
}
+60 -11
View File
@@ -1,5 +1,5 @@
import { CCTV_AMBIENT_CARD_MAX } from '../../data/cctvLod.js';
import { t } from '../../i18n/index.js';
import { msg, t } from '../../i18n/index.js';
import { ACTIVE_FRAME_REFRESH_MS, IDLE_FRAME_REFRESH_MS } from './policy.js';
import { headingHudToken, isHeadingEstimated } from './headingConfidence.js';
import {
@@ -8,6 +8,59 @@ import {
isDatasheetFov,
} from './modelSpecs.js';
// The summary line names the CAL badge, the source kind and the view band in
// the page language; the codes underneath stay English.
const CAL_BADGE_LABELS = Object.freeze({
calibrated: msg('CALIBRATED'),
curated: msg('CURATED'),
'raw-prior': msg('RAW PRIOR'),
});
// The same source-kind words as the CCTV panel (src/ui/cctvFrames.js).
const SOURCE_KIND_LABELS = Object.freeze({
snapshot: msg('SNAPSHOT'),
live: msg('LIVE'),
fallback: msg('FALLBACK'),
upstream: msg('UPSTREAM'),
synthetic: msg('SYNTHETIC'),
configured: msg('CONFIGURED'),
seed: msg('SEED'),
image: msg('IMAGE'),
unknown: msg('UNKNOWN'),
});
/** CAL badge id ('raw-prior') as the summary shows it; unknown ids stay codes. */
export function summaryCalLabel(badge) {
const key = String(badge || '');
return CAL_BADGE_LABELS[key]
? t(CAL_BADGE_LABELS[key])
: key.replace('-', ' ').toUpperCase();
}
/** Source kind ('image', 'snapshot') for the summary; HLS, MJPEG… stay codes. */
export function summarySourceLabel(kind) {
const key = String(kind || 'image').toLowerCase();
return SOURCE_KIND_LABELS[key]
? t(SOURCE_KIND_LABELS[key])
: key.toUpperCase();
}
/** View band id ('street', 'city'…) as the HUD names it. */
export function summaryViewBandLabel(band) {
switch (band) {
case 'street':
return t('STREET', { context: 'view band' });
case 'city':
return t('CITY', { context: 'view band' });
case 'regional':
return t('REGIONAL', { context: 'view band' });
case 'global':
return t('GLOBAL', { context: 'view band' });
default:
return String(band || '').toUpperCase();
}
}
export function createPresentation({
state: layerState,
services,
@@ -72,17 +125,13 @@ export function createPresentation({
: t('ISOLATED VIEW'),
layerState._showProjection ? t('PROJ MONITOR') : t('PROJ OFF'),
layerState._coverageMode === 'viewshed' ? t('VIEWSHED') : null,
t('CAL {value}', {
value: calBadge.replace('-', ' ').toUpperCase(),
t('CAL {value}', { value: summaryCalLabel(calBadge) }),
t('SRC {value}', {
value: summarySourceLabel(
health?.sourceKind || active.camera.feedType || 'image',
),
}),
health?.sourceKind
? t('SRC {value}', {
value: String(health.sourceKind).toUpperCase(),
})
: t('SRC {value}', {
value: String(active.camera.feedType || 'image').toUpperCase(),
}),
t('{value} CONTEXT', { value: viewBand.toUpperCase() }),
t('{value} CONTEXT', { value: summaryViewBandLabel(viewBand) }),
// Identified hardware: append the model's datasheet specs + attribution.
active.camera.spec
? t('{spec} · SPECS: CCTV-DATABASE.COM', {
+38
View File
@@ -0,0 +1,38 @@
// The CCTV summary line names the CAL badge, the source kind and the view
// band in the page language; unknown codes stay as uppercase codes.
import assert from 'node:assert/strict';
import test from 'node:test';
import { setLocale } from '../../i18n/index.js';
import {
summaryCalLabel,
summarySourceLabel,
summaryViewBandLabel,
} from './presentation.js';
function inLocale(locale, run) {
setLocale(locale);
try {
return run();
} finally {
setLocale('en');
}
}
test('English keeps the summary codes', () => {
assert.equal(summaryCalLabel('raw-prior'), 'RAW PRIOR');
assert.equal(summarySourceLabel('image'), 'IMAGE');
assert.equal(summarySourceLabel('hls'), 'HLS');
assert.equal(summaryViewBandLabel('street'), 'STREET');
assert.equal(summaryViewBandLabel('none'), 'NONE');
});
test('Portuguese summary values are translated', () => {
inLocale('pt', () => {
assert.equal(summaryCalLabel('raw-prior'), 'ESTIMATIVA BRUTA');
assert.equal(summaryCalLabel('calibrated'), 'CALIBRADA');
assert.equal(summarySourceLabel('IMAGE'), 'IMAGEM');
assert.equal(summarySourceLabel('mjpeg'), 'MJPEG');
assert.equal(summaryViewBandLabel('street'), 'RUA');
assert.equal(summaryViewBandLabel('city'), 'CIDADE');
});
});