Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion gui/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
// FOUT guard: set <html lang> before first paint so :lang() font stacks apply immediately.
// Mirrors detectInitial() + LOCALES in src/i18n/shared.ts.
var langMap = { en: "en", de: "de", fr: "fr", ko: "ko", zh: "zh-CN", "zh-TW": "zh-TW", ru: "ru", ja: "ja", tr: "tr", vi: "vi" };
langMap.pt = "pt-BR";
var stored = null;
try {
stored = localStorage.getItem("ocx-lang");
Expand All @@ -29,7 +30,7 @@
if (nav.indexOf("zh") === 0) {
locale = /tw|hk|mo|hant/.test(nav) ? "zh-TW" : "zh";
} else {
locale = ["de", "fr", "ko", "ru", "ja", "tr", "vi"].filter(function (c) { return nav.indexOf(c) === 0; })[0] || "en";
locale = ["de", "fr", "ko", "ru", "ja", "tr", "vi", "pt"].filter(function (c) { return nav.indexOf(c) === 0; })[0] || "en";
}
}
document.documentElement.lang = langMap[locale];
Expand Down
2 changes: 2 additions & 0 deletions gui/src/components/QuotaBars.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,8 @@ function bcp47(locale: Locale): string {
return "tr-TR";
case "vi":
return "vi-VN";
case "pt":
return "pt-BR";
default: {
const _exhaustive: never = locale;
return _exhaustive;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ function bcp47(locale: Locale): string {
case "ja": return "ja-JP";
case "tr": return "tr-TR";
case "vi": return "vi-VN";
case "pt": return "pt-BR";
default: {
const _exhaustive: never = locale;
return _exhaustive;
Expand Down
2 changes: 2 additions & 0 deletions gui/src/i18n/catalogs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { ru } from "./ru";
import { ja } from "./ja";
import { tr } from "./tr";
import { vi } from "./vi";
import { pt } from "./pt";
import { LAB_CATALOG_OVERRIDES, type LabLocale } from "./lab-translations";

/** React-free locale catalog registry for formatters and other shared helpers. */
Expand All @@ -33,6 +34,7 @@ export const DICTS: Record<Locale, Record<TKey, string>> = {
ja: withLabTranslations("ja", ja),
tr: withLabTranslations("tr", tr),
vi: withLabTranslations("vi", vi),
pt: withLabTranslations("pt", pt),
};

/** Native language names shown by the language picker, kept inside i18n rather than UI metadata. */
Expand Down
65 changes: 64 additions & 1 deletion gui/src/i18n/lab-translations.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { TKey } from "./en";

export type LabLocale = "en" | "de" | "fr" | "ko" | "zh" | "zh-TW" | "ru" | "ja" | "tr" | "vi";
export type LabLocale = "en" | "de" | "fr" | "ko" | "zh" | "zh-TW" | "ru" | "ja" | "tr" | "vi" | "pt";
export type LabCatalogKey = Exclude<Extract<TKey, `lab.${string}`>, `lab.production.${string}`>;
export type LabSupplementKey =
| "subjectKindUnknown"
Expand Down Expand Up @@ -514,6 +514,56 @@ const vi: Record<LabCatalogKey, string> = {
"lab.layer.task_effectiveness": "Hiệu quả tác vụ",
};

const pt: Record<LabCatalogKey, string> = {
"lab.title": "Laboratório de Compatibilidade",
"lab.subtitle": "Matriz de vereditos de compatibilidade somente leitura, gerada a partir das evidências da projeção do laboratório.",
"lab.loadFailed": "Não foi possível carregar os dados do laboratório de compatibilidade",
"lab.projectionUnavailable": "A projeção do laboratório não está disponível. Execute primeiro os testes de conformidade ou as sondagens ao vivo.",
"lab.projectionIncompatible": "O esquema da projeção do laboratório é incompatível. Reconstrua a projeção.",
"lab.statusTitle": "Status da projeção",
"lab.matrixTitle": "Matriz de compatibilidade",
"lab.verdictsTitle": "Registros de veredito",
"lab.filter.layer": "Camada de evidência",
"lab.filter.verdict": "Veredito",
"lab.filter.subject": "ID do sujeito",
"lab.filter.all": "Todos",
"lab.col.subject": "Sujeito",
"lab.col.layer": "Camada",
"lab.col.suite": "Suíte",
"lab.col.verdict": "Veredito",
"lab.col.asOf": "Em",
"lab.col.protocol": "Conformidade de protocolo",
"lab.col.live": "Compatibilidade da rota ao vivo",
"lab.col.task": "Eficácia nas tarefas",
"lab.empty": "Ainda não há vereditos de compatibilidade na projeção.",
"lab.subjectKind": "Tipo",
"lab.observationCount": "Observações",
"lab.eventCount": "Eventos",
"lab.verdictCount": "Vereditos",
"lab.subjectCount": "Sujeitos",
"lab.builtAt": "Gerada em",
"lab.loading": "Carregando evidências de compatibilidade…",
"lab.loadMore": "Carregar mais",
"lab.detailTitle": "Detalhes do veredito",
"lab.detailClose": "Fechar",
"lab.detailSubject": "Sujeito",
"lab.detailObservations": "Observações",
"lab.detailEvents": "Eventos de evidência",
"lab.detailArtifacts": "Metadados dos artefatos",
"lab.detailLoadFailed": "Não foi possível carregar os detalhes do veredito",
"lab.refresh": "Atualizar",
"lab.verdict.UNKNOWN": "Desconhecido",
"lab.verdict.CLAIMED": "Declarado",
"lab.verdict.PROBED": "Sondado",
"lab.verdict.VERIFIED": "Verificado",
"lab.verdict.DEGRADED": "Degradado",
"lab.verdict.BLOCKED": "Bloqueado",
"lab.verdict.UNSUPPORTED": "Não suportado",
"lab.layer.protocol_conformance": "Conformidade de protocolo",
"lab.layer.live_route_compatibility": "Compatibilidade da rota ao vivo",
"lab.layer.task_effectiveness": "Eficácia nas tarefas",
};

export const LAB_CATALOG_OVERRIDES: Record<LabLocale, Record<LabCatalogKey, string>> = {
en,
de,
Expand All @@ -525,6 +575,7 @@ export const LAB_CATALOG_OVERRIDES: Record<LabLocale, Record<LabCatalogKey, stri
ja,
tr,
vi,
pt,
};

const supplements: Record<LabLocale, Record<LabSupplementKey, string>> = {
Expand Down Expand Up @@ -648,6 +699,18 @@ const supplements: Record<LabLocale, Record<LabSupplementKey, string>> = {
"community.activeRecords": "Bản ghi đang hoạt động",
"community.revokedRecords": "Bản ghi đã thu hồi",
},
pt: {
subjectKindUnknown: "Desconhecido",
"artifact.present": "Presente",
"artifact.corrupt": "Corrompido",
"artifact.purged_unavailable": "Removido / indisponível",
selectVerdict: "Ver veredito de {subject}",
"community.title": "Evidências da comunidade",
"community.notLocalVerdict": "Contexto somente leitura não confiável. Não incluído neste veredito local.",
"community.bundles": "Pacotes",
"community.activeRecords": "Registros ativos",
"community.revokedRecords": "Registros revogados",
},
};

export function labSupplement(
Expand Down
27 changes: 27 additions & 0 deletions gui/src/i18n/log-guard-labels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,33 @@ const LABELS: Record<Locale, Record<LogGuardLabelKey, string>> = {
"error.database_error": "Không thể cập nhật cơ sở dữ liệu nhật ký Codex.",
"error.config_write_failed": "Cơ sở dữ liệu đã thay đổi nhưng OpenCodex không thể lưu cài đặt bảo vệ. Vui lòng sửa lỗi lưu trữ cấu hình, sau đó chạy Sửa chữa.",
},
pt: {
compact: 'Compactar',
compactComplete: "Compactação concluída (lógico / recuperado em disco)",
pagesUnit: "páginas",
compactPartial: "Compactação parcial (lógico / recuperado em disco)",
confirmCompact: 'Confirmar compactação',
cancel: 'Cancelar',
inspectionOnly: 'Somente inspeção',
externalSqliteHome: 'Armazenamento SQLite externo',
inspectionUnavailable: "A inspeção do log de diagnóstico não está disponível.",
metricsSkippedLarge: "Métricas de linhas ignoradas: o banco de dados excede {threshold} e a varredura travaria o proxy.",
protection: "Proteção",
compat: "Compatibilidade",
quiet: "Silencioso",
disable: "Desativar proteção",
repair: "Reparar proteção",
applying: "Aplicando proteção…",
"error.generic": "Não foi possível alterar a proteção de logs do Codex.",
"error.codex_running": "Feche o Codex antes de alterar a proteção de logs.",
"error.process_enumeration_failed": "Não foi possível verificar se o Codex está parado. A proteção não foi alterada.",
"error.busy": "O banco de dados de logs do Codex está ocupado. Feche o Codex e tente novamente.",
"error.unsupported_schema": "Este esquema de logs do Codex não é suportado para proteção.",
"error.trigger_collision": "Um nome de trigger reservado do Log Guard já está em uso. A proteção não foi alterada.",
"error.unsafe_path": "O caminho do banco de dados de logs do Codex falhou na verificação de segurança.",
"error.database_error": "Não foi possível atualizar o banco de dados de logs do Codex.",
"error.config_write_failed": "O banco de dados foi alterado, mas o OpenCodex não conseguiu salvar a configuração de proteção. Corrija o armazenamento de configuração e execute Reparar.",
},
};

export function logGuardLabel(locale: Locale, key: LogGuardLabelKey): string {
Expand Down
12 changes: 12 additions & 0 deletions gui/src/i18n/log-guard-operation-labels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,18 @@ const LABELS: Record<Locale, Record<LogGuardOperationLabelKey, string>> = {
"error.auto_vacuum_not_incremental": "Cơ sở dữ liệu nhật ký Codex này không được định cấu hình cho tính năng incremental vacuum, do đó không thể thu hồi dung lượng nếu không xây dựng lại hoàn toàn.",
"error.integrity_check_failed": "Cơ sở dữ liệu nhật ký Codex không vượt qua được kiểm tra tính toàn vẹn. Không có dung lượng nào được thu hồi.",
},
pt: {
applying: "Aplicando alteração do Log Guard…",
"error.generic": "Não foi possível atualizar o armazenamento de logs do Codex.",
"error.codex_running": "Feche o Codex antes de alterar o armazenamento de logs do Codex.",
"error.process_enumeration_failed": "Não foi possível verificar se o Codex está parado. A operação do Log Guard não foi iniciada.",
"error.busy": "O banco de dados de logs do Codex está ocupado. Feche o Codex e tente novamente.",
"error.unsupported_schema": "Este esquema de logs do Codex não é suportado para esta operação.",
"error.unsafe_path": "O caminho do banco de dados de logs do Codex falhou na verificação de segurança.",
"error.database_error": "Não foi possível atualizar o banco de dados de logs do Codex.",
"error.auto_vacuum_not_incremental": "Este banco de dados de logs do Codex não está configurado para incremental vacuum; por isso, não é possível recuperar espaço sem uma reconstrução completa.",
"error.integrity_check_failed": "O banco de dados de logs do Codex falhou na verificação de integridade. Nenhum espaço foi recuperado.",
},
};

export function logGuardOperationLabel(locale: Locale, key: LogGuardOperationLabelKey): string {
Expand Down
5 changes: 5 additions & 0 deletions gui/src/i18n/log-guard-state-labels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ const LABELS: Record<Locale, StateLabels> = {
protection: { off: "Tắt", active: "Đang hoạt động", drifted: "Cần sửa chữa", unsupported: "Không được hỗ trợ", unknown: "Không xác định" },
mode: { off: "Tắt", compat: "Tương thích", quiet: "Yên tĩnh", collision: "Không xác định" },
},
pt: {
schema: { compatible: "Compatível", missing: "Banco de dados não encontrado", unreadable: "Banco de dados indisponível", unsupported: "Não suportado" },
protection: { off: "Desativada", active: "Ativa", drifted: "Requer reparo", unsupported: "Não suportada", unknown: "Desconhecida" },
mode: { off: "Desativado", compat: "Compatibilidade", quiet: "Silencioso", collision: "Desconhecido" },
},
};

export function logGuardSchemaStateLabel(locale: Locale, state: LogGuardSchemaState): string {
Expand Down
40 changes: 39 additions & 1 deletion gui/src/i18n/native-main-translations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -382,4 +382,42 @@ export const NATIVE_MAIN_TRANSLATIONS = {
"nativeMain.confirm": "Xác nhận thay đổi đăng nhập gốc",
"nativeMain.unavailable": "Không thể thay đổi hồ sơ. Hãy kiểm tra mã chẩn đoán trước khi tiếp tục."
},
} satisfies Record<"en" | "de" | "fr" | "ko" | "zh" | "zh-TW" | "ru" | "ja" | "tr" | "vi", Record<NativeMainTKey, string>>;
"pt": {
"nativeMain.title": "Login principal do Codex nativo",
"nativeMain.manage": "Gerenciar login principal",
"nativeMain.close": "Fechar o gerenciador de login principal",
"nativeMain.separate": "Estes controles alteram o login do Codex nativo, não a conta selecionada para a próxima requisição do Pool.",
"nativeMain.home": "CODEX_HOME efetivo",
"nativeMain.current": "Perfil ativo registrado",
"nativeMain.unregistered": "Não registrado",
"nativeMain.physicalHint": "Este diretório home pertence ao servidor do OpenCodex, que pode ser outro computador. O backend verifica o login físico antes de qualquer troca.",
"nativeMain.busyOther": "Outra operação de login nativo está em andamento. Conclua ou cancele-a primeiro.",
"nativeMain.working": "Processando…",
"nativeMain.changed": "O diretório home, o perfil ativo ou o estado de recuperação mudou. Revise o estado atualizado e confirme novamente.",
"nativeMain.error": "Não foi possível confirmar a operação. Leia o estado atualizado antes de tentar de novo; uma resposta perdida não prova que houve reversão. Use o comando de diagnóstico no servidor abaixo.",
"nativeMain.doctorHint": "Execute {cmd} no servidor para ver os detalhes.",
"nativeMain.saved": "Login atual salvo como perfil. O login físico não foi alterado.",
"nativeMain.restart": "Troca de login concluída. Reinicie o Codex nativo usando o CODEX_HOME exibido antes de continuar.",
"nativeMain.done": "Operação concluída. O servidor não solicitou a reinicialização do Codex nativo.",
"nativeMain.refreshFailed": "Não foi possível atualizar todas as informações da conta. Uma alteração já concluída não foi desfeita. Atualize antes de outra operação.",
"nativeMain.refresh": "Atualizar status",
"nativeMain.unsupported": "Este armazenamento de credenciais não é suportado. O gerenciamento de perfis nativos exige o armazenamento de credenciais em arquivo.",
"nativeMain.recoveryHint": "Uma transação interrompida precisa de recuperação. Recuperar conclui a reconciliação; restaurar reverte a transação pendente. Nenhuma das ações é executada até você confirmar.",
"nativeMain.recover": "Recuperar alteração interrompida",
"nativeMain.rollback": "Restaurar transação pendente",
"nativeMain.empty": "Nenhum perfil nativo registrado ainda. Salve primeiro o login atual.",
"nativeMain.active": "Ativo",
"nativeMain.switchTo": "Trocar o login nativo para {label}",
"nativeMain.switch": "Trocar",
"nativeMain.restore": "Voltar ao perfil exibido anteriormente: {label}",
"nativeMain.restoreHint": "Este atalho seleciona o perfil exibido antes da sua última troca, não um histórico de transações verificado pelo servidor. Ele é mantido apenas nesta página.",
"nativeMain.label": "Rótulo do perfil",
"nativeMain.save": "Salvar atual como perfil",
"nativeMain.saveHint": "Para um login ativo já registrado, salvar atualiza o rótulo. Não adiciona um novo login.",
"nativeMain.confirmHint": "Isto altera apenas o login nativo no diretório home abaixo. Feche primeiro o Codex nativo naquele computador. Este painel não edita estratégia do Pool, membros, chaves de provedor nem dados de tarefas/histórico.",
"nativeMain.stopped": "Parei o Codex nativo que usa este CODEX_HOME e entendo que pode ser necessário reiniciá-lo.",
"nativeMain.cancel": "Cancelar",
"nativeMain.confirm": "Confirmar alteração do login nativo",
"nativeMain.unavailable": "As alterações de perfil estão indisponíveis. Verifique o código de diagnóstico antes de continuar."
},
} satisfies Record<"en" | "de" | "fr" | "ko" | "zh" | "zh-TW" | "ru" | "ja" | "tr" | "vi" | "pt", Record<NativeMainTKey, string>>;
Loading
Loading