From 92fbdd952e981118b95288ae76992a9d5a64350b Mon Sep 17 00:00:00 2001 From: "D. Ror" Date: Tue, 9 May 2023 15:25:55 -0400 Subject: [PATCH 1/4] Add Portuguese and fallbacks --- public/locales/pt/translation.json | 411 +++++++++++++++++++++++++++++ src/i18n.ts | 7 +- src/types/writingSystem.ts | 3 + 3 files changed, 420 insertions(+), 1 deletion(-) create mode 100644 public/locales/pt/translation.json diff --git a/public/locales/pt/translation.json b/public/locales/pt/translation.json new file mode 100644 index 0000000000..92e7c68fc4 --- /dev/null +++ b/public/locales/pt/translation.json @@ -0,0 +1,411 @@ +{ + "generic": { + "404Title": "404: Página não encontrada", + "404Text": "Clique em The Combine para voltar à página inicial.", + "loadingTitle": "Carregando...", + "loadingText": "Por favor aguarde enquanto The Combine processa seus dados." + }, + "landingPage": { + "subtitle": "Um aplicativo para colher palavras juntos", + "privacyPolicy": "Política de Privacidade", + "descriptionP1": "As palavras são os blocos de construção da língua, essenciais tanto para a comunicação de informações como para compartilhar a cultura. Um dicionário, cheio de palavras e seus significados, é um recurso linguístico fundamental, ajudando a documentar e preservar o idioma para as futuras gerações dentro da comunidade e fornecendo uma ponte para a comunicação com outras comunidades. Entretanto, muitas comunidades linguísticas minoritárias em todo o mundo carecem deste recurso no seu idioma, o que as coloca em desvantagem.", + "descriptionP2": "The Combine é uma ferramenta fácil de usar no processo de Coleta Rápida de Palavras (RWC), um método para reunir as palavras que servirão de base para um dicionário bilíngüe. No centro do processo de RWC estão os falantes nativos de uma determinada comunidade linguística. Um grupo de 4 a 6 falantes nativos, ao qual é apresentado um domínio semântico de cada vez, fala o máximo de palavras de sua língua que possam pensar relacionadas a esse domínio. The Combine facilita a inserção destas palavras num banco de dados, juntamente com traduções, gravações de áudio e notas, para captar melhor sua forma e significado.", + "descriptionP3": "As pessoas que possuem pouco conhecimento lingüístico prévio e experiência limitada com computadores podem aprender rapidamente a usar as principais funções de coleta de palavras do The Combine. As palavras resultantes podem então ser organizadas e editadas dentro do The Combine antes de exportar os dados para uso em outras ferramentas como o FLEx.", + "descriptionP4": "Cadastre-se para começar com sua coleção de palavras!" + }, + "treeView": { + "findDomain": "Encontrar um domínio", + "domainNotFound": "Domínio não encontrado" + }, + "addWords": { + "selectEntry": "Selecione uma entrada", + "selectSense": "Selecione um sentido", + "newEntryFor": "Nova entrada para: ", + "newSenseFor": "Novo sentido para: ", + "senseInWord": "A palavra já tem este sentido neste domínio semântico", + "deleteRow": "Excluir esta linha", + "deleteRowWarning": "Esta linha será permanentemente apagada!", + "addNote": "Adicionar uma nota", + "domain": "Domínio", + "domainTitle": "Domínio: {{ val1 }} ({{ val2 }})", + "gloss": "Glosa", + "glosses": "Glosas", + "pressEnter": "Pressione enter para salvar a palavra", + "vernacular": "Vernáculo", + "wordInDatabase": "Esta palavra já está no banco de dados" + }, + "appBar": { + "dataEntry": "entrada de dados", + "dataCleanup": "limpeza de dados", + "statistics": "data statistics" + }, + "login": { + "title": "Entrar", + "name": "Seu Nome", + "username": "Nome de usuário", + "password": "Senha", + "passwordRequirements": "A senha deve conter 8 caracteres ou mais.", + "forgotPassword": "Esqueceu a senha?", + "login": "Login", + "failed": "Falha ao fazer o login. Por favor, verifique seu nome de usuário e a senha.", + "backToLogin": "Voltar para o login", + "signUp": "Cadastrar-se", + "signUpNew": "Cadastrar Novo Usuário", + "signUpSuccess": "Usuário Criado", + "signUpFailed": "Falha no cadastro", + "usernameInvalid": "Este nome de usuário é muito curto ou já está ocupado", + "usernameRequirements": "O nome de usuário deve ter 3 caracteres ou mais.", + "emailTaken": "Já existe um usuário com esse endereço de e-mail", + "networkError": "Erro de rede", + "loggingIn": "Fazendo login...", + "required": "Obrigatório", + "confirmPassword": "Confirmar Senha", + "confirmPasswordError": "As senhas não combinam", + "email": "E-mail", + "emailError": "Por favor, insira um e-mail válido" + }, + "passwordReset": { + "emailOrUsername": "Email OU Nome de usuário", + "resetRequestTitle": "Reinicializar pedido de senha", + "resetTitle": "Redefinir Senha", + "resetRequestInstructions": "Nós enviaremos um link de reinicialização da sua conta para o seu e-mail", + "submit": "Confirmar", + "resetFail": "Erro de redefinição de senha", + "notFoundError": "Não foi encontrada nenhuma correspondência", + "backToLogin": "Voltar para Login" + }, + "userMenu": { + "siteSettings": "Configurações do site", + "projectSettings": "Configurações do Projeto", + "userSettings": "Configurações de Usuário", + "logout": "Sair", + "userGuide": "Guia do Usuário" + }, + "createProject": { + "name": "Nome do Projeto", + "upload?": "Carregar dados existentes?", + "uploadFormat": "O arquivo deve ser uma pasta zipada que contenha um <1>Lexicon Interchange FormaT (LIFT) projeto.", + "create": "Criar Projeto", + "fileSelected": "Arquivo selecionado", + "success": "Projeto Criado!", + "nameTaken": "Nome tomado" + }, + "selectProject": { "title": "Selecionar Projeto" }, + "siteSettings": { + "archiveProjectText": "Este projeto não será acessível a nenhum utilizador.", + "restoreProjectText": "Alguém provavelmente tinha uma boa razão para arquivar este projeto. Tens a certeza que o queres restaurar?", + "deleteUser": { + "confirm": "Confirmar exclusão de usuário do banco de dados combinado", + "toastSuccess": "Usuário excluído com sucesso", + "toastFailure": "Falha em excluir usuário" + }, + "populateUsers": { "toastFailure": "Falha no preenchimento dos usuários" }, + "banners": { + "title": "Banners", + "loginBanner": "Banner de Login", + "announcementBanner": "Banner de Anúncio" + } + }, + "userSettings": { "updateSuccess": "Configurações atualizadas com sucesso." }, + "projectExport": { + "cannotExportEmpty": "O projeto está vazio. Não é possível exportar um projeto sem palavras.", + "downloadInProgress": "Download em progresso", + "exportFailed": "A exportação falhou", + "exportInProgress": "Exportação em curso" + }, + "projectSettings": { + "language": { + "header": "Idioma", + "vernacular": "Vernáculo", + "vernacularLanguage": "Língua Vernacular", + "analysis": "Análise", + "analysisLanguage": "Linguagem de Análise", + "semanticDomains": "Domínios Semânticos", + "semanticDomainsDefault": "(Definir o idioma do navegador como padrão)", + "languages": "Idiomas", + "bcp47": "Código BCP 47", + "name": "Nome", + "font": "Fonte", + "addAnalysisLanguage": "Adicione uma linguagem de análise alternativa", + "makeDefaultAnalysisLanguage": "Faça desta a linguagem de análise padrão", + "deleteAnalysisLanguage": "Elimine esta linguagem de análise", + "getGlossLanguages": "Encontre todos os códigos de idioma usados nos dados atuais", + "addAnalysisLanguageFailed": "Falha ao adicionar o idioma da análise", + "makeDefaultAnalysisLanguageFailed": "Falha ao tornar idioma de análise padrão", + "deleteAnalysisLanguageFailed": "Falha ao excluir o idioma da análise", + "updateSemDomWritingSystemFailed": "Falha na atualização do idioma dos domínios semânticos" + }, + "name": "Nome do Projeto", + "projectList": "Projetos", + "userList": "Usuários", + "userManagement": { + "makeAdminWarning": "Definir este usuário como administrador de projeto?", + "makeOwnerWarning": "Transferir a propriedade do projeto para este usuário?", + "removeAdminWarning": "Remover o administrador do projeto deste usuário?", + "removeUserWarning": "Remover esse usuário do projeto?", + "userRemovedToastSuccess": "Usuário Removido!", + "userRemovedToastFailure": "Falha ao Remover Usuário.", + "makeAdminToastSuccess": "Este Usuário foi configurado como Administrador de Projetos!", + "makeAdminToastFailure": "Falha ao definir usuário como administrador do projeto.", + "removeAdminToastSuccess": "Removido Administrador do Projeto do Usuário!", + "removeAdminToastFailure": "Falha ao remover o administrador do projeto do usuário.", + "makeOwnerToastSuccess": "Propriedade do Projeto Transferida!", + "makeOwnerToastFailure": "Falha ao transferir propriedade do projeto.", + "manageUser": "Gerenciar Usuário", + "reverseOrder": "Ordem Reversa" + }, + "import": { + "header": "Importar Dados", + "body": "Os dados importados serão adicionados a este projeto. The Combine não tentará deduplicar, sobrescrever ou sincronizar.", + "chooseFile": "Escolha Arquivo", + "done": "Concluído!", + "notAllowed": "Você já importou um arquivo Lift para este projeto." + }, + "user": { + "currentUsers": "Usuários atuais", + "usersAndRoles": "Usuários e Funções", + "addUser": "Adicionar usuário", + "selectUser": "Escolher um usuário", + "selectRole": "Escolher sua função", + "confirmUser": "Selecionar este usuário", + "roles": { + "typist": "Digitador", + "cleaner": "Revisor", + "admin": "Administrador" + }, + "archive": "Arquivar Projeto", + "archiveToastSuccess": "Projeto Arquivado!" + }, + "schedule": { + "workshopSchedule": "Workshop Schedule", + "startDate": "Start Date", + "endDate": "End Date", + "selectedDateAlert": "The start date must be before the end date", + "setDays": "Set the range of days for the workshop", + "editDays": "Flexibly adjust the workshop schedule", + "removeDays": "Remove all days from workshop", + "removeAll": "Are you sure you want to remove all the dates?" + }, + "exportProject": { "label": "Exportar Projeto" }, + "autocomplete": { + "label": "Autocomplemento", + "off": "Desativado", + "on": "Ativado", + "hint": "Na Entrada de Dados, o programa irá sugerir verbetes existentes que são similares ao verbete no vernáculo que está sendo digitado." + }, + "definitions": { + "label": "Exibir Definições", + "hint": "Em Revisar Verbetes, exibir uma coluna de Definições; em Mesclar Duplicações, exibir a Definição abaixo da Glosa." + }, + "invite": { + "inviteByEmailLabel": "Convidar por e-mail", + "userExists": "Esse usuário já está registrado!", + "or": "OU", + "searchPlaceholder": "Procurar...", + "searchTitle": "Encontrar usuários", + "emailLabel": "E-mail", + "messageLabel": "Mensagem", + "toastSuccess": "Adicionado Utilizador!", + "toastFail": "Falha ao adicionar usuário!" + } + }, + "goal": { + "selector": { + "selectOption": "Selecionar esta meta", + "past": "Você concluiu:", + "present": "Nossa recomendação:", + "other": "Outras opções:", + "noHistory": "Nada ainda", + "done": "Tudo pronto" + }, + "progress": "Passo {{ val1 }} de {{ val2 }}", + "progressMerge": "Merge Set {{ val1 }} of {{ val2 }}" + }, + "createStrWordInv": { "title": "Criar Inventário de Palavra Estrutural" }, + "handleFlags": { "title": "Bandeiras de identificadores" }, + "spellCheckGloss": { "title": "Verificar Ortografia do Glossário" }, + "validateChars": { "title": "Validar Caracteres" }, + "validateStrWords": { "title": "Validar os Caracteres Estruturais" }, + "reviewEntries": { + "title": "Revisar Verbetes", + "sense": "Sentido", + "noVernacular": "Nenhuma entrada do vernáculo!", + "noDefinition": "Esta definição está vazia", + "noGloss": "Nenhuma entrada de glosas", + "noDomain": "Nenhum domínio selecionado", + "noNote": "Nenhuma nota", + "deleteWordWarning": "Esta palavra será apagada permanentemente!", + "deleteDisabled": "This was imported with data that The Combine doesn't handle, so it may not be deleted.", + "error": { + "gloss": "As glosas não podem ser deixadas em branco", + "domain": "Os domínios não podem ser deixados em branco", + "senses": "Não é possível salvar uma entrada sem sentidos", + "vernacular": "O vernáculo não pode ser deixado em branco" + }, + "columns": { + "definitions": "Definições", + "delete": "Excluir", + "domains": "Domínios", + "flag": "Flag", + "glosses": "Glosas", + "note": "Nota", + "pronunciations": "Pronunciations", + "senses": "Sentidos", + "vernacular": "Vernáculo" + }, + "materialTable": { + "body": { + "edit": "Edit", + "emptyDataSourceMessage": "No entries to display", + "filter": "Filter" + }, + "pagination": { + "labelDisplayedRows": "{from}-{to} de {count}", + "labelRows": "linhas", + "labelRowsPerPage": "Rows per page:", + "first": "Primeira página", + "last": "Última página", + "next": "Next Page", + "previous": "Previous Page" + }, + "toolbar": { "search": "Search" } + } + }, + "charInventory": { + "title": "Criar Inventário de Caracteres", + "characters": "caracteres", + "examples": "Exemplos", + "occurrences": "{{ val }} ocorrências", + "status": "status", + "sortBy": "Ordenar por", + "characterSet": { + "title": "Conjunto de Caracteres do Vernáculo:", + "help": "Definir os caracteres que são válidos para este idioma", + "addButton": "Adicionar Caracteres", + "addButtonTitle": "Adicionar os caracteres da caixa ao conjunto de caracteres", + "deleteButton": "Excluir Selecionados", + "deleteButtonTitle": "Remover os caracteres selecionados do conjunto de caracteres", + "acceptedCharacters": "Caracteres Aceitos", + "rejectedCharacters": "Caracteres Rejeitados", + "noCharacters": "Nenhum caractere ainda! Digite os caracteres na caixa abaixo para começar.", + "required": "Adicionar caracteres, digitando nesta caixa", + "advanced": "Avançado", + "occurrences": "ocorrências", + "find": "Localizar", + "replace": "Substituir", + "replaceWith": "Substituir por", + "replaceAll": "Substituir todas as ocorrências de", + "findAndReplace": "Localizar & Substituir", + "apply": "aplicar", + "charDetails": "(Detalhes de Caracteres não foram implementados.)" + }, + "sampleWords": { + "title": "Palavras de Exemplo", + "description": "Aqui estão algumas palavras que não se encaixam no seu conjunto atual de caracteres:", + "ignore": "Ignorar esta palavra por enquanto", + "add": "Adicionar os caracteres desta palavra ao conjunto" + }, + "dialog": { + "title": "Alterações não salvas", + "content": "Descartar alterações feitas no conjunto de caracteres?", + "yes": "sim", + "no": "não" + }, + "changes": { + "noChanges": "Não foram feitas alterações neste objetivo.", + "more": "mais" + } + }, + "mergeDups": { + "title": "Mesclar Duplicações", + "helpText": { + "dragCard": "Arraste um cartão aqui para mesclar.", + "root": "Arrastar as palavras aqui para começar a mesclar", + "dups": "Arrastar palavras duplicadas aqui", + "sense": "Arrastar novo sentido aqui", + "saveAndContinue": "Salvar alterações e carregar um novo conjunto de palavras", + "skip": "Descartar alterações e carregar um novo conjunto de palavras", + "list": "Arrastar esta palavra para a direita para começar a mesclar com outras palavras", + "noDups": "Nada para mesclar.", + "delete": "Excluir o significado", + "deleteDialog": "Excluir este o significado?", + "protectedSense": "This sense was imported with data that The Combine doesn't handle, so it cannot be deleted or dropped into another sense. You may still move this sense or drop other senses into this one to merge them.", + "protectedWord": "This word was imported with data that The Combine doesn't handle, so to prevent deletion, its final sense cannot be removed." + }, + "completed": { "number": "Número de fusões concluídas: " }, + "continueDialog": { + "title": "Continuar a mesclagem?", + "yes": "sim", + "no": "não" + }, + "undo": { + "undo": "Desfazer Mesclar", + "undoDialog": "Desfazer esta mesclagem?", + "undoDisabled": "Desfazer Indisponível" + } + }, + "flags": { + "add": "Adicionar sinalização", + "edit": "Editar sinalização", + "remove": "Remover sinalização", + "save": "Salvar sinalização", + "text": "Texto: " + }, + "buttons": { + "accept": "Aceitam", + "accepted": "Aceito", + "add": "Adicionar", + "archive": "Arquivar", + "browse": "Procurar", + "cancel": "Cancelar", + "clearText": "Limpar texto", + "confirm": "Confirmar", + "delete": "Excluir", + "deletePermanently": "Eliminar permanentemente?", + "done": "Concluído", + "exit": "Sair", + "export": "Exportar", + "invite": "Convite", + "makeAdmin": "Definir como Administrador", + "makeOwner": "Definir como proprietário", + "proceedWithCaution": "Proceda com cautela!", + "reject": "Rejeição", + "rejected": "Rejeitado", + "removeAdmin": "Remover o Administrador do Projeto", + "removeFromProject": "Remover do Projeto", + "reset": "Redefinir", + "restore": "Restaurar", + "save": "Salvar", + "saveAndContinue": "Salvar & Continuar", + "skip": "Pular", + "undecided": "Indeterminado", + "upload": "Carregar" + }, + "pronunciations": { + "recordTooltip": "Pressione e segure para gravar.", + "playTooltip": "Pressione para reproduzir, clique em shift para excluir.", + "noMicAccess": "Erro de gravação: Não foi possível acessar um microfone.", + "deleteRecording": "Eliminar Gravação" + }, + "statistics": { + "title": "Data Statistics: {{ val }}", + "domainProgress": "Domain Progress", + "domainsCollected": "Domains Collected: {{ val }}", + "wordsCollected": "Words Collected: {{ val }}", + "percent": "{{ val }}%", + "view": { + "user": "Words per User", + "domain": "Words per Domain", + "day": "Words per Day", + "workshop": "Workshop Progress" + }, + "column": { + "domainNumber": "Número de domínio:", + "domainName": "Nome de domínio:", + "username": "Usuário:", + "domainCount": "Domínios:", + "senseCount": "Palavras:" + }, + "axisLabel": { "date": "Date", "words": "Words Collected" } + } +} diff --git a/src/i18n.ts b/src/i18n.ts index 5a59ff5b64..b703a70316 100644 --- a/src/i18n.ts +++ b/src/i18n.ts @@ -28,7 +28,12 @@ i18n supportedLngs: uiWritingSystems.map((ws) => ws.bcp47), // nonExplicitSupportedLngs will (e.g.) use 'es' if the browser is 'es-MX' nonExplicitSupportedLngs: true, - fallbackLng: Bcp47Code.Default, + fallbackLng: { + es: [Bcp47Code.Pt], + it: [Bcp47Code.Es, Bcp47Code.Pt], + pt: [Bcp47Code.Es], + default: [Bcp47Code.Default], + }, interpolation: { escapeValue: false }, }, setDir // Callback function to set the direction ("ltr" vs "rtl") after i18n has initialized diff --git a/src/types/writingSystem.ts b/src/types/writingSystem.ts index 933b2218c4..f6ee14f0a6 100644 --- a/src/types/writingSystem.ts +++ b/src/types/writingSystem.ts @@ -6,6 +6,7 @@ export enum Bcp47Code { En = "en", Es = "es", Fr = "fr", + Pt = "pt", } const writingSystem = { @@ -13,6 +14,7 @@ const writingSystem = { [Bcp47Code.En]: newWritingSystem(Bcp47Code.En, "English"), [Bcp47Code.Es]: newWritingSystem(Bcp47Code.Es, "Español"), [Bcp47Code.Fr]: newWritingSystem(Bcp47Code.Fr, "Français"), + [Bcp47Code.Pt]: newWritingSystem(Bcp47Code.Pt, "Português"), }; export const defaultWritingSystem = writingSystem[Bcp47Code.Default]; @@ -23,6 +25,7 @@ export const uiWritingSystems = [ writingSystem[Bcp47Code.En], writingSystem[Bcp47Code.Es], writingSystem[Bcp47Code.Fr], + writingSystem[Bcp47Code.Pt], ]; // This list should cover the languages in deploy/scripts/semantic_domains/xml/ From 07b9af87294b707bfa15356a884b4f8a1840652d Mon Sep 17 00:00:00 2001 From: "D. Ror" Date: Tue, 9 May 2023 15:41:13 -0400 Subject: [PATCH 2/4] Update translations and remove untranslated strings to allow fallbacks --- public/locales/ar/translation.json | 153 +++--------- public/locales/es/translation.json | 375 +++++++++++++++-------------- public/locales/fr/translation.json | 258 +++++++------------- 3 files changed, 308 insertions(+), 478 deletions(-) diff --git a/public/locales/ar/translation.json b/public/locales/ar/translation.json index ec2b0f0296..8c6a91c2bf 100644 --- a/public/locales/ar/translation.json +++ b/public/locales/ar/translation.json @@ -1,22 +1,7 @@ { - "generic": { - "404Title": "404: Page not found", - "404Text": "Click on the combine to go back home.", - "loadingTitle": "Loading...", - "loadingText": "Please wait while The Combine processes your data." - }, - "landingPage": { - "subtitle": "A Web App for Harvesting Words Together", - "privacyPolicy": "Privacy Policy", - "descriptionP1": "Words are the building blocks of language, vital to both communicating information and sharing culture. A dictionary, filled with words and their meanings, is a fundamental language resource, helping to document and preserve the language for future generations within the community and providing a bridge for communication with other communities. But many minority-language communities around the world have no such resource in their language, putting them at a disadvantage.", - "descriptionP2": "The Combine is an easy-to-use tool in the Rapid Word Collection (RWC) process—a method of gathering the words that will serve as the backbone for a bilingual dictionary. At the heart of the RWC process are native speakers from a particular language community. Presented with one semantic domain at a time, a group of 4-6 native speakers comes up with as many words in their language as they can think of that are related to that domain. The Combine facilitates the entry of these words into a database, along with translations, audio recordings, and notes, to more fully capture their form and meaning.", - "descriptionP3": "People with little prior linguistic knowledge and limited computer experience can be quickly trained to use The Combine's main word-harvesting capabilities. Then the resulting words can be organized and edited within The Combine before exporting the data to use in other tools such as FLEx.", - "descriptionP4": "Sign up to get started with your word collection!" - }, - "treeView": { - "findDomain": "Find a domain", - "domainNotFound": "Domain not found" - }, + "generic": {}, + "landingPage": {}, + "treeView": {}, "addWords": { "selectEntry": "حدد إدخالاً", "selectSense": "حدد الإحساس", @@ -44,10 +29,6 @@ "login": "تسجيل الدخول", "failed": "فشل تسجيل الدخول. يرجى التحقق من اسم المستخدم وكلمة المرور.", "backToLogin": "العودة لتسجيل الدخول", - "signUp": "Sign Up", - "signUpNew": "Sign Up New User", - "signUpSuccess": "User Created", - "signUpFailed": "Failed to sign up", "usernameInvalid": "اسم المستخدم هذا قصير جداً أو مأخوذ مسبقاً", "usernameRequirements": "اسم المستخدم يجب أن يكون 3 أحرف أو أكثر.", "emailTaken": "يوجد بالفعل مستخدم بهذا البريد الإلكتروني", @@ -78,8 +59,6 @@ }, "createProject": { "name": "اسم المسروع", - "upload?": "Upload existing data?", - "uploadFormat": "File must be a zipped folder containing a <1>Lexicon Interchange FormaT (LIFT) project.", "create": "إنشاء مشروع", "fileSelected": "تم تحديد الملف", "success": "تم إنشاء المشروع!", @@ -94,21 +73,11 @@ "toastSuccess": "تم حذف المستخدم بنجاح", "toastFailure": "فشل في حذف المستخدم" }, - "populateUsers": { "toastFailure": "Failed to populate users" }, - "banners": { - "title": "Banners", - "loginBanner": "Login Banner", - "announcementBanner": "Announcement Banner" - } - }, - "userSettings": { - "contact": "Contact info", - "phone": "Phone number", - "updateSuccess": "تم تحديث الإعدادات بنجاح." + "populateUsers": {}, + "banners": {} }, + "userSettings": { "updateSuccess": "تم تحديث الإعدادات بنجاح." }, "projectExport": { - "cannotExportEmpty": "Project is empty. You cannot export a project with no words.", - "downloadInProgress": "Download in progress", "exportFailed": "فشل التصدير", "exportInProgress": "جار التصدير" }, @@ -119,43 +88,20 @@ "vernacularLanguage": "اللغة الإغريقية", "analysis": "التحليل", "analysisLanguage": "لغة التحليل", - "semanticDomains": "Semantic Domains", - "semanticDomainsDefault": "(Default to browser language)", - "languages": "Languages", "bcp47": "BCP 47 Code", "name": "الاسم", "font": "خط", "addAnalysisLanguage": "إضافة لغة تحليل بديلة.", "makeDefaultAnalysisLanguage": "جعل هذا لغة التحليل الافتراضية.", "deleteAnalysisLanguage": "حذف لغة التحليل هذه.", - "getGlossLanguages": "العثور على جميع رموز اللغة المستخدمة في البيانات الحالية.", - "addAnalysisLanguageFailed": "Failed to add analysis language", - "makeDefaultAnalysisLanguageFailed": "Failed to make default analysis language", - "deleteAnalysisLanguageFailed": "Failed to delete analysis language", - "updateSemDomWritingSystemFailed": "Failed to update semantic domains language" + "getGlossLanguages": "العثور على جميع رموز اللغة المستخدمة في البيانات الحالية." }, "name": "اسم المسروع", "projectList": "مشاريع", "userList": "المستخدمون", - "userManagement": { - "makeAdminWarning": "Make this user a project admin?", - "makeOwnerWarning": "Transfer project ownership to this user?", - "removeAdminWarning": "Remove project admin from this user?", - "removeUserWarning": "Remove this user from the project?", - "userRemovedToastSuccess": "User Removed!", - "userRemovedToastFailure": "Failed to Remove User.", - "makeAdminToastSuccess": "User Given Project Admin!", - "makeAdminToastFailure": "Failed to give project admin to user.", - "removeAdminToastSuccess": "Removed Project Admin from User!", - "removeAdminToastFailure": "Failed to remove project admin from user.", - "makeOwnerToastSuccess": "Transferred Project Ownership!", - "makeOwnerToastFailure": "Failed to transfer project ownership.", - "manageUser": "Manage User", - "reverseOrder": "Reverse Order" - }, + "userManagement": {}, "import": { "header": "استيراد البيانات", - "body": "Imported data will be added to this project. The Combine will make no attempt to deduplicate, overwrite, or sync.", "chooseFile": "اختر ملف", "done": "تم!", "notAllowed": "لقد قمت بالفعل باستيراد ملف LIFT إلى هذا المشروع." @@ -167,24 +113,14 @@ "selectUser": "اختر المستخدم", "selectRole": "اختر دور المستخدم", "confirmUser": "حدد هذا المستخدم", - "roles": { "typist": "الكاتب", "cleaner": "المنظف", "admin": "المدير" }, - "archive": "Archive Project", - "archiveToastSuccess": "Project Archived!" + "roles": { "typist": "الكاتب", "cleaner": "المنظف", "admin": "المدير" } }, + "schedule": {}, "exportProject": { "label": "تصدير المشروع" }, - "autocomplete": { - "label": "إكمال تلقائي", - "off": "مغلق", - "on": "على", - "hint": "In Data Entry, suggest existing Vernaculars similar to the Vernacular being typed." - }, - "definitions": { - "label": "Display Definitions", - "hint": "In Review Entries, show a Definitions column; in Merge Duplicates, show the Definition below the Gloss." - }, + "autocomplete": { "label": "إكمال تلقائي", "off": "مغلق", "on": "على" }, + "definitions": {}, "invite": { "inviteByEmailLabel": "دعوة بواسطة البريد الإلكتروني", - "userExists": "This user is already registered!", "or": "أو", "searchPlaceholder": "بحث...", "searchTitle": "البحث عن المستخدمين", @@ -202,19 +138,17 @@ "other": "خيارات أخرى:", "noHistory": "لا شيء حتى الآن", "done": "أكتمل الكل" - }, - "progress": { "step": "الخطوة", "stepMerge": "Merge Set", "of": "من" } + } }, "createStrWordInv": { "title": "إنشاء قائمة جرد الكلمات الهيكلية" }, "handleFlags": { "title": "التعامل مع الأعلام" }, "spellCheckGloss": { "title": "معجم التدقيق الإملائي" }, "validateChars": { "title": "التحقق من صحة الأحرف" }, - "validateStrWords": { "title": "Validate Structural Characters" }, + "validateStrWords": {}, "reviewEntries": { "title": "مراجعة المدخلات", "sense": "معنى", "noVernacular": "لا يوجد مدخلات عامية!", - "noDefinition": "No definitions input", "noGloss": "لا إدخال لمعان", "noDomain": "لم يتم تحديد مجال", "noNote": "لا توجد ملاحظة", @@ -224,7 +158,13 @@ "domain": "لا يمكن ترك المجالات فارغة", "senses": "لا يمكن حفظ إدخال بدون حواس", "vernacular": "لا يمكن ترك اللغة العامية فارغة" - } + }, + "columns": { + "delete": "حذف", + "glosses": "اللمعان", + "vernacular": "العامية" + }, + "materialTable": { "body": {}, "pagination": {}, "toolbar": {} } }, "charInventory": { "title": "إنشاء جرد الشخصية", @@ -247,12 +187,7 @@ "advanced": "إعدادات متقدمة", "occurrences": "مرات الحدوث", "find": "البحث", - "replace": "Replace", - "replaceWith": "Replace with", - "replaceAll": "Replace all occurences of", - "findAndReplace": "Find & Replace", - "apply": "تطبيق", - "charDetails": "(Character Details has not been implemented.)" + "apply": "تطبيق" }, "sampleWords": { "title": "كلمات بسيطة", @@ -266,64 +201,37 @@ "yes": "نعم", "no": "لا" }, - "changes": { "noChanges": "No changes made in this goal.", "more": "more" } + "changes": {} }, "mergeDups": { "title": "دمج التكرارات", "helpText": { - "dragCard": "Drag a card here to merge.", "root": "اسحب الكلمات هنا لبدء دمجها", "dups": "اسحب الكلمات المكررة هنا", "sense": "اسحب حس جديد هنا", - "saveAndContinue": "Save changes and load a new set of words", - "skip": "Discard changes and load a new set of words", - "list": "اسحب هذه الكلمة إلى اليمين لبدء دمجها مع كلمات أخرى", - "noDups": "Nothing to merge.", - "delete": "Delete sense", - "deleteDialog": "Delete this sense?" + "list": "اسحب هذه الكلمة إلى اليمين لبدء دمجها مع كلمات أخرى" }, - "completed": { "number": "Number of merges completed: " }, - "continueDialog": { - "title": "Continue merging?", - "yes": "نعم", - "no": "لا" - }, - "undo": { - "undo": "Undo Merge", - "undoDialog": "Undo this merge?", - "undoDisabled": "Undo Unavailable" - } - }, - "flags": { - "add": "Add flag", - "edit": "Edit flag", - "remove": "Remove flag", - "save": "Save flag", - "text": "Text: " + "completed": {}, + "continueDialog": { "yes": "نعم", "no": "لا" }, + "undo": {} }, + "flags": {}, "buttons": { "accept": "يقبل", "accepted": "مقبول", - "add": "أضف ", + "add": "أضف", "archive": "أرشيف", "browse": "تصفح", "cancel": "إلغاء", - "clearText": "Clear text", "confirm": "تأكيد", "delete": "حذف", "deletePermanently": "حذف بشكل دائم؟", "done": "تم", - "exit": "Exit", "export": "تصدير", "invite": "يستدعي", - "makeAdmin": "Make Admin", - "makeOwner": "Make Owner", "proceedWithCaution": "تقدم بحذر!", "reject": "يرفض", "rejected": "مرفوض", - "removeAdmin": "Remove Project Admin", - "removeFromProject": "Remove from Project", - "reset": "Reset", "restore": "إستعادة", "save": "حفظ", "saveAndContinue": "احفظ واستمر", @@ -336,5 +244,6 @@ "playTooltip": "اضغط للعب ، انقر فوق التحول للحذف.", "noMicAccess": "خطأ في التسجيل: تعذر الوصول إلى الميكروفون.", "deleteRecording": "حذف التسجيل" - } + }, + "statistics": { "view": {}, "column": {}, "axisLabel": {} } } diff --git a/public/locales/es/translation.json b/public/locales/es/translation.json index 4693c0c2bf..b37a662833 100644 --- a/public/locales/es/translation.json +++ b/public/locales/es/translation.json @@ -1,35 +1,36 @@ { "generic": { - "404Title": "404: Page not found", - "404Text": "Click on the combine to go back home.", - "loadingTitle": "Loading...", - "loadingText": "Please wait while The Combine processes your data." + "404Title": "404: Página no encontrada", + "404Text": "Haga clic en la cosechadora para volver al inicio.", + "loadingTitle": "Cargando...", + "loadingText": "Por favor, espere mientras The Combine procesa sus datos." }, "landingPage": { - "subtitle": "A Web App for Harvesting Words Together", - "privacyPolicy": "Privacy Policy", - "descriptionP1": "Words are the building blocks of language, vital to both communicating information and sharing culture. A dictionary, filled with words and their meanings, is a fundamental language resource, helping to document and preserve the language for future generations within the community and providing a bridge for communication with other communities. But many minority-language communities around the world have no such resource in their language, putting them at a disadvantage.", - "descriptionP2": "The Combine is an easy-to-use tool in the Rapid Word Collection (RWC) process—a method of gathering the words that will serve as the backbone for a bilingual dictionary. At the heart of the RWC process are native speakers from a particular language community. Presented with one semantic domain at a time, a group of 4-6 native speakers comes up with as many words in their language as they can think of that are related to that domain. The Combine facilitates the entry of these words into a database, along with translations, audio recordings, and notes, to more fully capture their form and meaning.", - "descriptionP3": "People with little prior linguistic knowledge and limited computer experience can be quickly trained to use The Combine's main word-harvesting capabilities. Then the resulting words can be organized and edited within The Combine before exporting the data to use in other tools such as FLEx.", - "descriptionP4": "Sign up to get started with your word collection!" + "subtitle": "Una aplicación web para recopilar rápidamente muchos conjuntos de palabras", + "privacyPolicy": "Política de privacidad", + "descriptionP1": "Las palabras son los bloques de construcción de la lengua, vitales tanto para comunicar información como para compartir la cultura. Un diccionario, lleno de palabras y sus significados, es un recurso lingüístico fundamental, que ayuda a documentar y preservar la lengua para las generaciones futuras dentro de la comunidad y proporciona un puente para la comunicación con otras comunidades. Sin embargo, muchas comunidades lingüísticas minoritarias de todo el mundo carecen de este recurso en su lengua, lo que las coloca en una situación de desventaja.", + "descriptionP2": "The Combine es una herramienta fácil de usar en el proceso de Recopilación Rápida de Palabras (RWC), un método para reunir las palabras que servirán de base para un diccionario bilingüe. En el centro del proceso de RWC se encuentran los hablantes nativos de una determinada comunidad lingüística. Un grupo de 4 a 6 hablantes nativos, a los que se les presenta un dominio semántico a la vez, proponen todas las palabras de su lengua que se les ocurran relacionadas con ese dominio. El Combine facilita la introducción de estas palabras en una base de datos, junto con traducciones, grabaciones de audio y notas, para captar mejor su forma y significado.", + "descriptionP3": "Las personas con poco conocimiento lingüístico previo y una experiencia informática limitada pueden aprender rápidamente a utilizar las principales funciones de recopilación de palabras de The Combine. A continuación, las palabras resultantes pueden organizarse y editarse dentro de The Combine antes de exportar los datos para utilizarlos en otras herramientas como FLEx.", + "descriptionP4": "¡Inscríbase para comenzar con su colección de palabras!" }, "treeView": { - "findDomain": "Find a domain", - "domainNotFound": "Domain not found" + "findDomain": "Buscar un dominio", + "domainNotFound": "Dominio no encontrado" }, "addWords": { - "selectEntry": "Escoger una entrada", - "selectSense": "Escoger un sentido", - "newEntryFor": "Nuevo entrada para: ", - "newSenseFor": "Sentido nuevo para: ", - "senseInWord": "La palabra ya tiene este sentido en este dominio", + "selectEntry": "Seleccionar una entrada", + "selectSense": "Seleccionar un sentido", + "newEntryFor": "Nueva entrada para: ", + "newSenseFor": "Nuevo sentido para: ", + "senseInWord": "La palabra ya tiene este sentido en este dominio semántico", "deleteRow": "Borrar esta fila", "deleteRowWarning": "¡Esta fila se eliminará permanentemente!", - "addNote": "Add a note", + "addNote": "Agregar una nota", "domain": "Dominio", + "domainTitle": "Dominio: {{ val1 }} ({{ val2 }})", "gloss": "Glosa", "glosses": "Glosas", - "pressEnter": "Presione enter para guardar la palabra", + "pressEnter": "Presione Enter para guardar la palabra", "vernacular": "Vernáculo", "wordInDatabase": "Esta palabra ya está en la base de datos" }, @@ -38,19 +39,19 @@ "dataCleanup": "limpieza de datos" }, "login": { - "title": "Iniciar sesión", - "name": "Tu Nombre", + "title": "Iniciar Sesión", + "name": "Su nombre", "username": "Nombre de usuario", "password": "Contraseña", - "passwordRequirements": "La contraseña debe tener 8 caracteres o más.", - "forgotPassword": "¿Se te olvidó tu contraseña?", + "passwordRequirements": "La contraseña debe tener 8 carácteres o más.", + "forgotPassword": "¿Olvidó su contraseña?", "login": "Iniciar sesión", "failed": "Error al iniciar sesión. Por favor verifique su nombre de usuario y contraseña.", "backToLogin": "Volver al inicio de sesión", - "signUp": "Sign Up", - "signUpNew": "Sign Up New User", + "signUp": "Registrarse", + "signUpNew": "Registrar un nuevo usuario", "signUpSuccess": "Usuario creado", - "signUpFailed": "Failed to sign up", + "signUpFailed": "Error al registrarse", "usernameInvalid": "Este nombre de usuario es demasiado corto o ya está en uso", "usernameRequirements": "El nombre de usuario debe tener 3 caracteres o más.", "emailTaken": "Este correo electrónico ya está en uso", @@ -60,186 +61,167 @@ "confirmPassword": "Confirmar contraseña", "confirmPasswordError": "Las contraseñas no coinciden", "email": "Correo electrónico", - "emailError": "Por favor, ingrese un correo electrónico válido" + "emailError": "Por favor, ingrese un correo electrónico válida" }, "passwordReset": { "emailOrUsername": "Correo electrónico o nombre de usuario", - "resetRequestTitle": "Restablecer solicitud de contraseña", + "resetRequestTitle": "Solicitud de restablecimiento de contraseña", "resetTitle": "Restablecer la contraseña", - "resetRequestInstructions": "Le enviaremos un enlace de restablecimiento único para su cuenta a su correo electrónico", + "resetRequestInstructions": "Le enviaremos a su correo electrónico un enlace para restablecer su cuenta una sola vez", "submit": "Enviar", - "resetFail": "Error de restablecimiento de contraseña", - "notFoundError": "No se encontraron coincidencias", - "backToLogin": "Atrás para iniciar sesión" + "resetFail": "Error al restablecer la contraseña", + "notFoundError": "No se encontraron coincidencia", + "backToLogin": "Volver al inicio de sesión" }, "userMenu": { "siteSettings": "Configuración del sitio", "projectSettings": "Configuración del proyecto", "userSettings": "Configuración de usuario", - "logout": "Cerrar sesión", - "userGuide": "User Guide" + "logout": "Cerrar Sesión", + "userGuide": "Guía del usuario" }, "createProject": { - "name": "Nombre del proyecto", - "upload?": "Upload existing data?", - "uploadFormat": "File must be a zipped folder containing a <1>Lexicon Interchange FormaT (LIFT) project.", - "create": "Crear un proyecto", + "name": "Nombre del Proyecto", + "upload?": "¿Cargar los datos existentes?", + "uploadFormat": "El archivo debe ser una carpeta comprimida que contenga un proyecto <1>Lexicon Interchange FormaT (LIFT).", + "create": "Crear Proyecto", "fileSelected": "Archivo seleccionado", "success": "¡Proyecto creado!", "nameTaken": "Nombre tomado" }, - "selectProject": { - "title": "Seleccionar un proyecto" - }, + "selectProject": { "title": "Seleccionar Proyecto" }, "siteSettings": { "archiveProjectText": "Este proyecto no será accesible para ningún usuario.", "restoreProjectText": "Alguien probablemente tuvo una buena razón para archivar este proyecto. ¿Seguro que quieres restaurarlo?", "deleteUser": { - "confirm": "Confirm Deleting User from The Combine Database", - "toastSuccess": "User successfully deleted", - "toastFailure": "Failed to delete user" - }, - "populateUsers": { - "toastFailure": "Failed to populate users" + "confirm": "Confirmar la eliminación del usuario de la base de datos de Combine", + "toastSuccess": "Usuario eliminado con éxito", + "toastFailure": "Error al eliminar el usuario" }, + "populateUsers": { "toastFailure": "Fallo al rellenar los usuarios" }, "banners": { "title": "Banners", - "loginBanner": "Login Banner", - "announcementBanner": "Announcement Banner" + "loginBanner": "Banner de inicio de sesión", + "announcementBanner": "Banner de anuncios" } }, "userSettings": { - "updateSuccess": "Settings successfully updated." + "updateSuccess": "Configuración actualizada correctamente." }, "projectExport": { - "cannotExportEmpty": "Project is empty. You cannot export a project with no words.", - "downloadInProgress": "Download in progress", - "exportFailed": "Export failed", - "exportInProgress": "Export in progress" + "cannotExportEmpty": "El proyecto está vacío. No se puede exportar un proyecto sin palabras.", + "downloadInProgress": "Descarga en proceso", + "exportFailed": "Error al exportar", + "exportInProgress": "Exportación en curso" }, "projectSettings": { "language": { - "header": "Lenguaje", + "header": "Idioma", "vernacular": "Vernáculo", - "vernacularLanguage": "Lenguaje vernácula", + "vernacularLanguage": "Idioma vernáculo", "analysis": "Análisis", - "analysisLanguage": "Lenguaje de análisis", - "semanticDomains": "Semantic Domains", - "semanticDomainsDefault": "(Default to browser language)", - "languages": "Languages", - "bcp47": "BCP 47", + "analysisLanguage": "Idioma de análisis", + "semanticDomains": "Dominios semánticos", + "semanticDomainsDefault": "(Por defecto, el idioma del navegador)", + "languages": "Idiomas", + "bcp47": "Código BCP 47", "name": "Nombre", - "font": "Font", - "addAnalysisLanguage": "Add an alternate analysis language", - "makeDefaultAnalysisLanguage": "Make this the default analysis language", - "deleteAnalysisLanguage": "Delete this analysis language", - "getGlossLanguages": "Find all language codes used in the current data", - "addAnalysisLanguageFailed": "Failed to add analysis language", - "makeDefaultAnalysisLanguageFailed": "Failed to make default analysis language", - "deleteAnalysisLanguageFailed": "Failed to delete analysis language", - "updateSemDomWritingSystemFailed": "Failed to update semantic domains language" + "font": "Fuente", + "addAnalysisLanguage": "Agregar un idioma de análisis alternativo", + "makeDefaultAnalysisLanguage": "Haga que este sea el idioma de análisis por defecto.", + "deleteAnalysisLanguage": "Eliminar este idioma de análisis.", + "getGlossLanguages": "Encuentre todos los códigos de idioma utilizados en los datos actuales.", + "addAnalysisLanguageFailed": "No se ha podido añadir el lenguaje de análisis", + "makeDefaultAnalysisLanguageFailed": "Fallo en el análisis de la lengua por defecto", + "deleteAnalysisLanguageFailed": "Fallo en la eliminación del lenguaje de análisis", + "updateSemDomWritingSystemFailed": "Fallo en la actualización del lenguaje de los dominios semánticos" }, - "name": "Nombre del proyecto", + "name": "Nombre del Proyecto", "projectList": "Proyectos", - "userList": "Usarios", + "userList": "Usuarios", "userManagement": { - "makeAdminWarning": "Make this user a project admin?", - "makeOwnerWarning": "Transfer project ownership to this user?", - "removeAdminWarning": "Remove project admin from this user?", - "removeUserWarning": "Remove this user from the project?", - "userRemovedToastSuccess": "User Removed!", - "userRemovedToastFailure": "Failed to Remove User.", - "makeAdminToastSuccess": "User Given Project Admin!", - "makeAdminToastFailure": "Failed to give project admin to user.", - "removeAdminToastSuccess": "Removed Project Admin from User!", - "removeAdminToastFailure": "Failed to remove project admin from user.", - "makeOwnerToastSuccess": "Transferred Project Ownership!", - "makeOwnerToastFailure": "Failed to transfer project ownership.", - "manageUser": "Manage User", - "reverseOrder": "Reverse Order" + "makeAdminWarning": "¿Hacer de este usuario un administrador del proyecto?", + "makeOwnerWarning": "¿Transferir la propiedad del proyecto a este usuario?", + "removeAdminWarning": "¿Eliminar la administración del proyecto de este usuario?", + "removeUserWarning": "¿Quitar a este usuario del proyecto?", + "userRemovedToastSuccess": "¡Usuario eliminado!", + "userRemovedToastFailure": "Error al eliminar el usuario.", + "makeAdminToastSuccess": "¡Usuario dado de administración del proyecto!", + "makeAdminToastFailure": "No se ha podido dar la administración del proyecto al usuario.", + "removeAdminToastSuccess": "¡Se ha eliminado la administración de proyectos del usuario!", + "removeAdminToastFailure": "No se ha podido eliminar la administración del proyecto del usuario.", + "makeOwnerToastSuccess": "¡Transferencia de la responsabilidad del proyecto!", + "makeOwnerToastFailure": "No se ha transferido la responsabilidad del proyecto.", + "manageUser": "Administrar usuario", + "reverseOrder": "Orden inverso" }, "import": { - "header": "Importar información", - "body": "Los datos importados se agregarán a este proyecto. The Combine no intentará deduplicar, sobrescribir ni sincronizar.", - "chooseFile": "Escoger Archivo", + "header": "Importar datos", + "body": "Los datos importados se añadirán a este proyecto. El Combine no hará ningún intento de deduplicar, sobrescribir o sincronizar.", + "chooseFile": "Elegir archivo", "done": "¡Hecho!", "notAllowed": "Ya ha importado un archivo Lift a este proyecto." }, "user": { - "currentUsers": "Usarios actuales", - "usersAndRoles": "Usarios y roles", - "addUser": "Añadir usario", - "selectUser": "Escoger un usario", + "currentUsers": "Usuarios actuales", + "usersAndRoles": "Usuarios y roles", + "addUser": "Agregar usuario", + "selectUser": "Escoger un usuario", "selectRole": "Escoger rol", - "confirmUser": "Seleccionar este usario", + "confirmUser": "Seleccionar este usuario", "roles": { "typist": "Mecanógrafo", "cleaner": "Limpiador", "admin": "Administrador" }, - "archive": "Archive Project", - "archiveToastSuccess": "Project Archived!" - }, - "exportProject": { - "label": "Exportar el proyecto" + "archive": "Archivar el proyecto", + "archiveToastSuccess": "¡Proyecto archivado!" }, + "schedule": {}, + "exportProject": { "label": "Exportar el proyecto" }, "autocomplete": { "label": "Autocompletar", "off": "Apagado", "on": "Encendido", - "hint": "In Data Entry, suggest existing Vernaculars similar to the Vernacular being typed." + "hint": "En la entrada de datos, sugiera las lenguas vernáculas existentes similares a la lengua vernácula que se está escribiendo." }, "definitions": { - "label": "Display Definitions", - "hint": "In Review Entries, show a Definitions column; in Merge Duplicates, show the Definition below the Gloss." + "label": "Mostrar definiciones", + "hint": "En Revisar Entradas, mostrar una columna de Definiciones; en Combinar Duplicados, mostrar la Definición debajo de la Glosa." }, "invite": { "inviteByEmailLabel": "Invitar por correo electrónico", - "userExists": "This user is already registered!", + "userExists": "¡Este usuario ya está registrado!", "or": "O", "searchPlaceholder": "Buscar...", - "searchTitle": "Encontrar usarios", + "searchTitle": "Buscar usuarios", "emailLabel": "Correo electrónico", "messageLabel": "Mensaje", - "toastSuccess": "¡Usario añadido!", - "toastFail": "¡Error al añadir usuario!" + "toastSuccess": "¡Usuario agregado!", + "toastFail": "¡Error al agregar usuario!" } }, "goal": { "selector": { "selectOption": "Selecciona este objectivo", - "past": "Completó:", + "past": "Se completó:", "present": "Nuestra recomendación:", - "other": "Otras opciónas:", - "noHistory": "Nada ahora", - "done": "Esta listo" + "other": "Otras opciones:", + "noHistory": "Nada aún", + "done": "Todo listo" }, - "progress": { - "step": "Paso", - "stepMerge": "Merge Set", - "of": "de" - } - }, - "createStrWordInv": { - "title": "Crear inventario de palabras estructurales" - }, - "handleFlags": { - "title": "Banderas de la manija" - }, - "spellCheckGloss": { - "title": "Corregir la ortografía del glosario" - }, - "validateChars": { - "title": "Validar caracteres" - }, - "validateStrWords": { - "title": "Validar caracteres estructurales" + "progress": "Paso {{ val1 }} de {{ val2 }}" }, + "createStrWordInv": { "title": "Crear inventario de palabras estructurales" }, + "handleFlags": { "title": "Manejar banderas" }, + "spellCheckGloss": { "title": "Corregir la ortografía del glosario" }, + "validateChars": { "title": "Validar caracteres" }, + "validateStrWords": { "title": "Validar los caracteres estructurales" }, "reviewEntries": { "title": "Revisar entradas", "sense": "Sentido", - "noVernacular": "¡No tenemos un vernáculo!", - "noDefinition": "No hay entrada de definiciones", + "noVernacular": "¡No hay entrada vernácula!", + "noDefinition": "No hay definiciones", "noGloss": "No hay entrada de glosas", "noDomain": "Ningún dominio seleccionado", "noNote": "Sin nota", @@ -247,8 +229,31 @@ "error": { "gloss": "Las glosas no pueden dejarse en blanco", "domain": "Los dominios no pueden dejarse en blanco", - "senses": "No guardar entrada sin sentidos", + "senses": "No se puede guardar una entrada sin sentidos", "vernacular": "El vernáculo no puede dejarse en blanco" + }, + "columns": { + "definitions": "Definiciones", + "delete": "Eliminar", + "domains": "Dominios", + "glosses": "Glosas", + "note": "Nota", + "pronunciations": "Pronunciaciones", + "senses": "Sentidos", + "vernacular": "Vernáculo" + }, + "materialTable": { + "body": { "edit": "Editar" }, + "pagination": { + "labelDisplayedRows": "{from}-{to} de {count}", + "labelRows": "filas", + "labelRowsPerPage": "Filas por página:", + "first": "Primera página", + "last": "Última página", + "next": "Página siguiente", + "previous": "Página anterior" + }, + "toolbar": { "search": "Buscar" } } }, "charInventory": { @@ -261,7 +266,7 @@ "characterSet": { "title": "Conjunto de caracteres vernáculos:", "help": "Define los caracteres que son válidos para este idioma", - "addButton": "Añadir caracteres", + "addButton": "Agregar caracteres", "addButtonTitle": "Agregar los caracteres del cuadro al conjunto de caracteres", "deleteButton": "Eliminar seleccionados", "deleteButtonTitle": "Eliminar los caracteres seleccionados del conjunto de caracteres", @@ -271,17 +276,17 @@ "required": "Agrega caracteres ingresándolos en este cuadro", "advanced": "Avanzado", "occurrences": "ocurrencias", - "find": "Encontrar", - "replace": "Replace", + "find": "Buscar", + "replace": "Reemplazar", "replaceWith": "Reemplazar con", - "replaceAll": "Replace all occurences of", - "findAndReplace": "Find & Replace", + "replaceAll": "Reemplazar todas las ocurrencias de", + "findAndReplace": "Buscar y Reemplazar", "apply": "aplicar", - "charDetails": "(Character Details has not been implemented.)" + "charDetails": "(Los detalles de los caracteres no se han implementado.)" }, "sampleWords": { "title": "Palabras de muestra", - "description": "Aquí hay algunas palabras que no se ajustan a tu conjunto de caracteres actual:", + "description": "Aquí hay algunas palabras que no se ajustan a su conjunto de caracteres actual:", "ignore": "Ignorar esta palabra por ahora", "add": "Agregar los caracteres de esta palabra al conjunto" }, @@ -292,79 +297,89 @@ "no": "no" }, "changes": { - "noChanges": "No changes made in this goal.", - "more": "more" + "noChanges": "No se han realizado cambios en este objetivo.", + "more": "más" } }, "mergeDups": { - "title": "Fusionar duplicados", + "title": "Combinar duplicados", "helpText": { - "dragCard": "Drag a card here to merge.", - "root": "Arrastra las palabras aquí para comenzar a fusionarlas", + "dragCard": "Arrastre una tarjeta aquí para combinarla.", + "root": "Arrastra las palabras aquí para comenzar a combinarlas", "dups": "Arrastra las palabras duplicadas aquí", "sense": "Arrastra un nuevo sentido aquí", - "saveAndContinue": "Save changes and load a new set of words", - "skip": "Discard changes and load a new set of words", - "list": "Arrastra esta palabra hacia la derecha para comenzar a combinarla con otras palabras", - "noDups": "Nothing to merge.", - "delete": "Delete sense", - "deleteDialog": "Delete this sense?" - }, - "completed": { - "number": "Number of merges completed: " + "saveAndContinue": "Guardar los cambios y cargar un nuevo conjunto de palabras", + "skip": "Descartar los cambios y cargar un nuevo conjunto de palabras", + "list": "Arrastre esta palabra hacia la derecha para comenzar a combinarla con otras palabras", + "noDups": "No hay nada que combinar.", + "delete": "Borrar el sentido", + "deleteDialog": "¿Borrar este sentido?" }, + "completed": { "number": "Número de fusiones realizadas: " }, "continueDialog": { - "title": "Continue merging?", + "title": "¿Continuar con la fusión?", "yes": "si", "no": "no" }, "undo": { - "undo": "Undo Merge", - "undoDialog": "Undo this merge?", - "undoDisabled": "Undo Unavailable" + "undo": "Deshacer la fusión", + "undoDialog": "¿Deshacer esta fusión?", + "undoDisabled": "Deshacer no disponible" } }, "flags": { - "add": "Add flag", - "edit": "Edit flag", - "remove": "Remove flag", - "save": "Save flag", - "text": "Text: " + "add": "Añadir bandera", + "edit": "Editar bandera", + "remove": "Eliminar bandera", + "save": "Guardar bandera", + "text": "Texto: " }, "buttons": { "accept": "Aceptar", "accepted": "Aceptado", - "add": "Añadir", + "add": "Agregar", "archive": "Archivar", "browse": "Navegar", "cancel": "Cancelar", - "clearText": "Clear text", + "clearText": "Borrar el texto", "confirm": "Confirmar", "delete": "Eliminar", - "deletePermanently": "¿Eliminar para siempre?", - "done": "Hecho", - "exit": "Exit", + "deletePermanently": "¿Eliminar permanentemente?", + "done": "Terminado", + "exit": "Salir", "export": "Exportar", "invite": "Invitar", - "makeAdmin": "Make Admin", - "makeOwner": "Make Owner", - "proceedWithCaution": "¡Proceder con precaución!", + "makeAdmin": "Hazle administrador", + "makeOwner": "Hazle dueño", + "proceedWithCaution": "¡Procede con precaución!", "reject": "Rechazar", "rejected": "Rechazado", - "removeAdmin": "Remove Project Admin", - "removeFromProject": "Remove from Project", - "reset": "Reset", + "removeAdmin": "Eliminar administrador del proyecto", + "removeFromProject": "Eliminar del proyecto", + "reset": "Restablecer", "restore": "Restaurar", "save": "Guardar", - "saveAndContinue": "Ahorrar y continuar", - "skip": "Omitir", - "undecided": "Indeciso", - "upload": "Cargar" + "saveAndContinue": "Guardar y Continuar", + "skip": "Saltar", + "undecided": "No decidido", + "upload": "Subir" }, "pronunciations": { "recordTooltip": "Mantenga presionado para grabar.", - "playTooltip": "Presiona para jugar; presiona shift para eliminar.", - "noMicAccess": "Error de grabación: no se pudo acceder a un micrófono.", + "playTooltip": "Haz clic para reproducir; presiona Shift más clic para eliminar.", + "noMicAccess": "Error de grabación: No se pudo acceder a un micrófono.", "deleteRecording": "Eliminar grabación" + }, + "statistics": { + "percent": "{{ val }}%", + "view": {}, + "column": { + "domainNumber": "Número de dominio:", + "domainName": "Nombre de dominio:", + "username": "Usuario:", + "domainCount": "Dominios:", + "senseCount": "Palabras:" + }, + "axisLabel": { "date": "Fecha" } } } diff --git a/public/locales/fr/translation.json b/public/locales/fr/translation.json index 674444b640..f60988e774 100644 --- a/public/locales/fr/translation.json +++ b/public/locales/fr/translation.json @@ -1,31 +1,29 @@ { "generic": { - "404Title": "404: Page not found", - "404Text": "Click on the combine to go back home.", - "loadingTitle": "Loading...", - "loadingText": "Please wait while The Combine processes your data." + "404Title": "Erreur 404 - Page non trouvée", + "404Text": "Cliquez sur la moissonneuse-batteuse pour revenir à la maison.", + "loadingTitle": "Chargement...", + "loadingText": "Veuillez patienter pendant que le Combine traite vos données." }, "landingPage": { - "subtitle": "A Web App for Harvesting Words Together", - "privacyPolicy": "Privacy Policy", - "descriptionP1": "Words are the building blocks of language, vital to both communicating information and sharing culture. A dictionary, filled with words and their meanings, is a fundamental language resource, helping to document and preserve the language for future generations within the community and providing a bridge for communication with other communities. But many minority-language communities around the world have no such resource in their language, putting them at a disadvantage.", - "descriptionP2": "The Combine is an easy-to-use tool in the Rapid Word Collection (RWC) process—a method of gathering the words that will serve as the backbone for a bilingual dictionary. At the heart of the RWC process are native speakers from a particular language community. Presented with one semantic domain at a time, a group of 4-6 native speakers comes up with as many words in their language as they can think of that are related to that domain. The Combine facilitates the entry of these words into a database, along with translations, audio recordings, and notes, to more fully capture their form and meaning.", - "descriptionP3": "People with little prior linguistic knowledge and limited computer experience can be quickly trained to use The Combine's main word-harvesting capabilities. Then the resulting words can be organized and edited within The Combine before exporting the data to use in other tools such as FLEx.", - "descriptionP4": "Sign up to get started with your word collection!" + "subtitle": "Une application web pour récolter des mots ensemble", + "privacyPolicy": "Politique de confidentialité", + "descriptionP1": "Les mots sont les fondements de la langue, essentiels à la communication de l’information et au partage de la culture. Un dictionnaire, rempli de mots et de significations, est une ressource linguistique fondamentale, aidant à documenter et à préserver la langue pour les générations futures au sein de la communauté et fournissant un pont pour la communication avec d'autres communautés. Malheureusement, de nombreuses communautés de langue minoritaire dans le monde ne disposent pas de telles ressources dans leur langue. Ceci les désavantage.", + "descriptionP2": "La combinaison est un outil facile à utiliser dans le processus Rapid Word Collection (RWC) — une méthode de collecte des mots qui servira de base à un dictionnaire bilingue. Au cœur du processus du RWC se trouvent les locuteurs natifs d’une communauté linguistique particulière. Présenté avec un champ sémantique à la fois un groupe de 4-6 locuteurs natifs arrive avec autant de mots dans leur langue qu'ils peuvent le penser sont liés à ce domaine. La combinaison facilite l'entrée de ces mots dans une base de données, ainsi que les traductions, enregistrements audio, et notes, pour mieux saisir leur forme et leur signification." }, "treeView": { - "findDomain": "Find a domain", - "domainNotFound": "Domain not found" + "findDomain": "Chercher un domaine", + "domainNotFound": "Champ sémantique introuvable" }, "addWords": { "selectEntry": "Choisissez une entrée", "selectSense": "Choisissez un sens", "newEntryFor": "Nouvelle entrée pour : ", "newSenseFor": "Nouveau sens pour : ", - "senseInWord": "Le mot a déjà ce sens dans ce domaine", + "senseInWord": "Le mot a déjà ce sens dans ce champ sémantique", "deleteRow": "Effacer cette ligne", "deleteRowWarning": "Cette ligne sera supprimée définitivement !", - "addNote": "Add a note", + "addNote": "Ajouter une remarque", "domain": "Domaine", "gloss": "Glose", "glosses": "Gloses", @@ -33,10 +31,7 @@ "vernacular": "Vernaculaire", "wordInDatabase": "Ce mot est déjà dans la base de données" }, - "appBar": { - "dataEntry": "saisie", - "dataCleanup": "nettoyage des données" - }, + "appBar": { "dataEntry": "saisie", "dataCleanup": "nettoyage des données" }, "login": { "title": "Ouvrir une session", "name": "Votre nom", @@ -44,13 +39,11 @@ "password": "Mot de passe", "passwordRequirements": "Le mot de passe doit comporter 8 caractères ou plus.", "forgotPassword": "Mot de passe oublié ?", - "login": "Se connecter", + "login": "Connexion", "failed": "N'a pas réussi à se connecter. Veuillez vérifier votre nom d'utilisateur et votre mot de passe.", "backToLogin": "Retour au login", - "signUp": "Sign Up", - "signUpNew": "Sign Up New User", - "signUpSuccess": "Utilisateur a été créé", - "signUpFailed": "Failed to sign up", + "signUp": "S'inscrire", + "signUpFailed": "Échec de l'inscription", "usernameInvalid": "Ce nom d'utilisateur est trop court ou est déjà utilisé", "usernameRequirements": "Le nom d'utilisateur doit contenir 3 caractères ou plus.", "emailTaken": "Un utilisateur avec cet email existe déjà", @@ -63,59 +56,47 @@ "emailError": "Veuillez entrer un email valide" }, "passwordReset": { - "emailOrUsername": "E-mail ou nom d'utilisateur", - "resetRequestTitle": "Réinitialiser la demande de mot de passe", - "resetTitle": "Réinitialisez le mot de passe", + "emailOrUsername": "Email ou nom d'utilisateur", + "resetRequestTitle": "Demande de réinitialisation du mot de passe", + "resetTitle": "Réinitialiser le mot de passe", "resetRequestInstructions": "Nous vous enverrons un lien de réinitialisation unique pour votre compte à votre email", "submit": "Soumettre", "resetFail": "Erreur de réinitialisation du mot de passe", - "notFoundError": "Pas de résultat trouvé", - "backToLogin": "Retour connexion" + "notFoundError": "Aucun résultat trouvé", + "backToLogin": "Retour au login" }, "userMenu": { "siteSettings": "Paramètres du site", "projectSettings": "Paramètres du projet", "userSettings": "Réglages utilisateur", - "logout": "Se déconnecter", - "userGuide": "User Guide" + "logout": "Déconnexion", + "userGuide": "Guide d’utilisateur" }, "createProject": { "name": "Nom du projet", - "upload?": "Upload existing data?", - "uploadFormat": "File must be a zipped folder containing a <1>Lexicon Interchange FormaT (LIFT) project.", "create": "Créer un projet", "fileSelected": "Fichier sélectionné", "success": "Projet créé !", "nameTaken": "Nom pris" }, - "selectProject": { - "title": "Sélectionner un projet" - }, + "selectProject": { "title": "Sélectionner un projet" }, "siteSettings": { "archiveProjectText": "Ce projet ne sera accessible à aucun utilisateur.", - "restoreProjectText": "Quelqu'un avait probablement une bonne raison de archiver ce projet. Voulez-vous vraiment le restaurer ?", + "restoreProjectText": "Quelqu'un avait probablement une bonne raison d'archiver ce projet. Voulez-vous vraiment le restaurer ?", "deleteUser": { - "confirm": "Confirm Deleting User from The Combine Database", - "toastSuccess": "User successfully deleted", - "toastFailure": "Failed to delete user" + "confirm": "Confirmer la suppression d'un utilisateur de la base de données Combine", + "toastSuccess": "Utilisateur supprimé avec succès", + "toastFailure": "Échec de la suppression de l'utilisateur" }, - "populateUsers": { - "toastFailure": "Failed to populate users" - }, - "banners": { - "title": "Banners", - "loginBanner": "Login Banner", - "announcementBanner": "Announcement Banner" - } + "populateUsers": {}, + "banners": {} }, "userSettings": { - "updateSuccess": "Settings successfully updated." + "updateSuccess": "Les paramètres ont été mis à jour avec succès." }, "projectExport": { - "cannotExportEmpty": "Project is empty. You cannot export a project with no words.", - "downloadInProgress": "Download in progress", - "exportFailed": "Export failed", - "exportInProgress": "Export in progress" + "exportFailed": "\t\nL'exportation a échoué", + "exportInProgress": "Exportation en cours" }, "projectSettings": { "language": { @@ -124,51 +105,32 @@ "vernacularLanguage": "Langue vernaculaire", "analysis": "Analyse", "analysisLanguage": "Langue d'analyse", - "semanticDomains": "Semantic Domains", - "semanticDomainsDefault": "(Default to browser language)", - "languages": "Languages", - "bcp47": "BCP 47", + "semanticDomains": "Champs sémantiques", + "semanticDomainsDefault": "(Utiliser la langue du navigateur)", + "languages": "Langues", + "bcp47": "Code BCP 47", "name": "Nom", - "font": "Font", - "addAnalysisLanguage": "Add an alternate analysis language", - "makeDefaultAnalysisLanguage": "Make this the default analysis language", - "deleteAnalysisLanguage": "Delete this analysis language", - "getGlossLanguages": "Find all language codes used in the current data", - "addAnalysisLanguageFailed": "Failed to add analysis language", - "makeDefaultAnalysisLanguageFailed": "Failed to make default analysis language", - "deleteAnalysisLanguageFailed": "Failed to delete analysis language", - "updateSemDomWritingSystemFailed": "Failed to update semantic domains language" + "font": "Police", + "addAnalysisLanguage": "Ajouter un langage d'analyse alternatif", + "makeDefaultAnalysisLanguage": "Faire de cette langue la langue d'analyse par défaut", + "deleteAnalysisLanguage": "Supprimer cette langue d'analyse", + "getGlossLanguages": "Trouvez tous les codes de langue utilisés dans les données actuelles", + "updateSemDomWritingSystemFailed": "Impossible de mettre à jour la langue des champs sémantiques" }, "name": "Nom du projet", "projectList": "Projets", "userList": "Utilisateurs", - "userManagement": { - "makeAdminWarning": "Make this user a project admin?", - "makeOwnerWarning": "Transfer project ownership to this user?", - "removeAdminWarning": "Remove project admin from this user?", - "removeUserWarning": "Remove this user from the project?", - "userRemovedToastSuccess": "User Removed!", - "userRemovedToastFailure": "Failed to Remove User.", - "makeAdminToastSuccess": "User Given Project Admin!", - "makeAdminToastFailure": "Failed to give project admin to user.", - "removeAdminToastSuccess": "Removed Project Admin from User!", - "removeAdminToastFailure": "Failed to remove project admin from user.", - "makeOwnerToastSuccess": "Transferred Project Ownership!", - "makeOwnerToastFailure": "Failed to transfer project ownership.", - "manageUser": "Manage User", - "reverseOrder": "Reverse Order" - }, + "userManagement": { "userRemovedToastSuccess": "Utilisateur supprimé !" }, "import": { "header": "Importer des données", - "body": "Les données importées seront ajoutées à ce projet. The Combine n'essaiera pas de dédupliquer, d'écraser ou de synchroniser.", - "chooseFile": "Choisissez Fichier", - "done": "Achevé !", + "chooseFile": "Choisir un fichier", + "done": "Achevé!", "notAllowed": "Vous avez déjà importé un fichier LIFT dans ce projet." }, "user": { "currentUsers": "Utilisateurs actuels", "usersAndRoles": "Utilisateurs et rôles", - "addUser": "Ajouter utilisateur", + "addUser": "Ajouter un utilisateur", "selectUser": "Choisissez un utilisateur", "selectRole": "Choisissez leur rôle", "confirmUser": "Sélectionnez cet utilisateur", @@ -177,31 +139,21 @@ "cleaner": "Nettoyant", "admin": "Admin" }, - "archive": "Archive Project", - "archiveToastSuccess": "Project Archived!" - }, - "exportProject": { - "label": "Exporter le projet" - }, - "autocomplete": { - "label": "Autocomplet", - "off": "Éteint", - "on": "Allumé", - "hint": "In Data Entry, suggest existing Vernaculars similar to the Vernacular being typed." - }, - "definitions": { - "label": "Display Definitions", - "hint": "In Review Entries, show a Definitions column; in Merge Duplicates, show the Definition below the Gloss." + "archive": "Archiver ce projet", + "archiveToastSuccess": "Projet archivé !" }, + "schedule": {}, + "exportProject": { "label": "Exporter le projet" }, + "autocomplete": { "label": "Autocomplet", "off": "Éteint", "on": "Allumé" }, + "definitions": {}, "invite": { "inviteByEmailLabel": "Inviter par email", - "userExists": "This user is already registered!", "or": "OU", "searchPlaceholder": "Chercher...", "searchTitle": "Rechercher utilisateurs", "emailLabel": "Email", "messageLabel": "Message", - "toastSuccess": "Utilisateur Ajouté !", + "toastSuccess": "Utilisateur ajouté !", "toastFail": "Échec de l'ajout de l'utilisateur !" } }, @@ -213,35 +165,19 @@ "other": "Autres options :", "noHistory": "Rien pour l'instant", "done": "Tout est fait" - }, - "progress": { - "step": "Étape", - "stepMerge": "Merge Set", - "of": "sur" } }, - "createStrWordInv": { - "title": "Créer un inventaire des mots grammaticaux" - }, - "handleFlags": { - "title": "Gérer les drapeaux" - }, - "spellCheckGloss": { - "title": "Vérifier l'orthographe du glossaire" - }, - "validateChars": { - "title": "Valider les caractères" - }, - "validateStrWords": { - "title": "Validate Structural Characters" - }, + "createStrWordInv": { "title": "Créer un inventaire des mots grammaticaux" }, + "handleFlags": { "title": "Gérer les drapeaux" }, + "spellCheckGloss": { "title": "Vérifier l'orthographe du glossaire" }, + "validateChars": { "title": "Valider les caractères" }, + "validateStrWords": { "title": "Valider les caractères structurels" }, "reviewEntries": { "title": "Examiner les entrées", "sense": "Sens", "noVernacular": "Pas d'entrée vernaculaire !", - "noDefinition": "Pas d'entrée de définitions", "noGloss": "Pas d'entrée de gloses", - "noDomain": "Aucun domaine sélectionné", + "noDomain": "Aucun champ sémantique sélectionné", "noNote": "Pas de note", "deleteWordWarning": "Ce mot sera définitivement supprimé !", "error": { @@ -249,7 +185,13 @@ "domain": "Les domaines ne peuvent pas être laissés vides", "senses": "Ne pas enregistrer entrée sans sens", "vernacular": "Le vernaculaire ne peut pas être laissé vide" - } + }, + "columns": { + "delete": "Effacer", + "glosses": "Gloses", + "vernacular": "Vernaculaire" + }, + "materialTable": { "body": {}, "pagination": {}, "toolbar": {} } }, "charInventory": { "title": "Créer un inventaire de caractères", @@ -263,21 +205,16 @@ "help": "Définir les caractères valides pour cette langue", "addButton": "Ajouter des caractères", "addButtonTitle": "Ajouter les caractères de la boîte au jeu de caractères", - "deleteButton": "Supprimer sélectionné", + "deleteButton": "Supprimer Sélectionné", "deleteButtonTitle": "Supprimer les caractères sélectionnés du jeu de caractères", "acceptedCharacters": "Caractères approuvés", "rejectedCharacters": "Caractères rejetés", - "noCharacters": "Aucun caractère existe ! Tapez les caractères dans la case ci-dessous pour commencer.", + "noCharacters": "Aucun caractère existe. Tapez les caractères dans la case ci-dessous pour commencer.", "required": "Ajouter des caractères en les saisissant dans cette case", "advanced": "Avancé", "occurrences": "occurrences", "find": "Rechercher", - "replace": "Replace", - "replaceWith": "Remplacer avec", - "replaceAll": "Replace all occurences of", - "findAndReplace": "Find & Replace", - "apply": "appliquer", - "charDetails": "(Character Details has not been implemented.)" + "apply": "appliquer" }, "sampleWords": { "title": "Exemples de mots", @@ -291,46 +228,21 @@ "yes": "oui", "no": "non" }, - "changes": { - "noChanges": "No changes made in this goal.", - "more": "more" - } + "changes": {} }, "mergeDups": { "title": "Fusionner les doublons", "helpText": { - "dragCard": "Drag a card here to merge.", "root": "Faites glisser les mots ici pour commencer à les fusionner", "dups": "Faites glisser les mots en double ici", "sense": "Faites glisser un nouveau sens ici", - "saveAndContinue": "Save changes and load a new set of words", - "skip": "Discard changes and load a new set of words", - "list": "Faites glisser ce mot vers la droite pour commencer à le fusionner avec d'autres mots", - "noDups": "Nothing to merge.", - "delete": "Delete sense", - "deleteDialog": "Delete this sense?" - }, - "completed": { - "number": "Number of merges completed: " + "list": "Faites glisser ce mot vers la droite pour commencer à le fusionner avec d'autres mots" }, - "continueDialog": { - "title": "Continue merging?", - "yes": "oui", - "no": "non" - }, - "undo": { - "undo": "Undo Merge", - "undoDialog": "Undo this merge?", - "undoDisabled": "Undo Unavailable" - } - }, - "flags": { - "add": "Add flag", - "edit": "Edit flag", - "remove": "Remove flag", - "save": "Save flag", - "text": "Text: " + "completed": {}, + "continueDialog": { "yes": "oui", "no": "non" }, + "undo": {} }, + "flags": {}, "buttons": { "accept": "Accepter", "accepted": "Acceptée", @@ -338,33 +250,27 @@ "archive": "Archiver", "browse": "Parcourir", "cancel": "Annuler", - "clearText": "Clear text", "confirm": "Confirmer", "delete": "Effacer", "deletePermanently": "Effacer pour toujours ?", - "done": "Achevé", - "exit": "Exit", + "done": "Terminé", "export": "Exporter", "invite": "Inviter", - "makeAdmin": "Make Admin", - "makeOwner": "Make Owner", - "proceedWithCaution": "Procéder avec prudence !", + "proceedWithCaution": "Procédez avec prudence!", "reject": "Rejeter", "rejected": "Rejeté", - "removeAdmin": "Remove Project Admin", - "removeFromProject": "Remove from Project", - "reset": "Reset", "restore": "Restaurer", "save": "Enregistrer", - "saveAndContinue": "Enregistrer et continuer", + "saveAndContinue": "Enregistrer & continuez", "skip": "Sauter", "undecided": "Incertain", "upload": "Télécharger" }, "pronunciations": { "recordTooltip": "Maintenez le bouton enfoncée pour enregistrer.", - "playTooltip": "Clic pour lire; Maj + clic pour effacer.", + "playTooltip": "Appuyez sur pour lire, Maj + clic pour effacer.", "noMicAccess": "Erreur d'enregistrement : Impossible d'accéder à un microphone.", "deleteRecording": "Effacer enregistrement" - } + }, + "statistics": { "view": {}, "column": {}, "axisLabel": {} } } From 59f6ce948181d78b182e2743a5fcceb3bbbe7ae8 Mon Sep 17 00:00:00 2001 From: "D. Ror" Date: Tue, 9 May 2023 15:58:30 -0400 Subject: [PATCH 3/4] Fix fallbacks --- public/locales/pt/translation.json | 50 ++++++------------------------ src/i18n.ts | 13 +++----- src/types/writingSystem.ts | 12 +++++++ 3 files changed, 25 insertions(+), 50 deletions(-) diff --git a/public/locales/pt/translation.json b/public/locales/pt/translation.json index 92e7c68fc4..abc5f4d1a4 100644 --- a/public/locales/pt/translation.json +++ b/public/locales/pt/translation.json @@ -36,8 +36,7 @@ }, "appBar": { "dataEntry": "entrada de dados", - "dataCleanup": "limpeza de dados", - "statistics": "data statistics" + "dataCleanup": "limpeza de dados" }, "login": { "title": "Entrar", @@ -176,16 +175,7 @@ "archive": "Arquivar Projeto", "archiveToastSuccess": "Projeto Arquivado!" }, - "schedule": { - "workshopSchedule": "Workshop Schedule", - "startDate": "Start Date", - "endDate": "End Date", - "selectedDateAlert": "The start date must be before the end date", - "setDays": "Set the range of days for the workshop", - "editDays": "Flexibly adjust the workshop schedule", - "removeDays": "Remove all days from workshop", - "removeAll": "Are you sure you want to remove all the dates?" - }, + "schedule": {}, "exportProject": { "label": "Exportar Projeto" }, "autocomplete": { "label": "Autocomplemento", @@ -218,8 +208,7 @@ "noHistory": "Nada ainda", "done": "Tudo pronto" }, - "progress": "Passo {{ val1 }} de {{ val2 }}", - "progressMerge": "Merge Set {{ val1 }} of {{ val2 }}" + "progress": "Passo {{ val1 }} de {{ val2 }}" }, "createStrWordInv": { "title": "Criar Inventário de Palavra Estrutural" }, "handleFlags": { "title": "Bandeiras de identificadores" }, @@ -235,7 +224,6 @@ "noDomain": "Nenhum domínio selecionado", "noNote": "Nenhuma nota", "deleteWordWarning": "Esta palavra será apagada permanentemente!", - "deleteDisabled": "This was imported with data that The Combine doesn't handle, so it may not be deleted.", "error": { "gloss": "As glosas não podem ser deixadas em branco", "domain": "Os domínios não podem ser deixados em branco", @@ -246,29 +234,20 @@ "definitions": "Definições", "delete": "Excluir", "domains": "Domínios", - "flag": "Flag", "glosses": "Glosas", "note": "Nota", - "pronunciations": "Pronunciations", "senses": "Sentidos", "vernacular": "Vernáculo" }, "materialTable": { - "body": { - "edit": "Edit", - "emptyDataSourceMessage": "No entries to display", - "filter": "Filter" - }, + "body": {}, "pagination": { "labelDisplayedRows": "{from}-{to} de {count}", "labelRows": "linhas", - "labelRowsPerPage": "Rows per page:", "first": "Primeira página", - "last": "Última página", - "next": "Next Page", - "previous": "Previous Page" + "last": "Última página" }, - "toolbar": { "search": "Search" } + "toolbar": {} } }, "charInventory": { @@ -328,9 +307,7 @@ "list": "Arrastar esta palavra para a direita para começar a mesclar com outras palavras", "noDups": "Nada para mesclar.", "delete": "Excluir o significado", - "deleteDialog": "Excluir este o significado?", - "protectedSense": "This sense was imported with data that The Combine doesn't handle, so it cannot be deleted or dropped into another sense. You may still move this sense or drop other senses into this one to merge them.", - "protectedWord": "This word was imported with data that The Combine doesn't handle, so to prevent deletion, its final sense cannot be removed." + "deleteDialog": "Excluir este o significado?" }, "completed": { "number": "Número de fusões concluídas: " }, "continueDialog": { @@ -388,17 +365,8 @@ "deleteRecording": "Eliminar Gravação" }, "statistics": { - "title": "Data Statistics: {{ val }}", - "domainProgress": "Domain Progress", - "domainsCollected": "Domains Collected: {{ val }}", - "wordsCollected": "Words Collected: {{ val }}", "percent": "{{ val }}%", - "view": { - "user": "Words per User", - "domain": "Words per Domain", - "day": "Words per Day", - "workshop": "Workshop Progress" - }, + "view": {}, "column": { "domainNumber": "Número de domínio:", "domainName": "Nome de domínio:", @@ -406,6 +374,6 @@ "domainCount": "Domínios:", "senseCount": "Palavras:" }, - "axisLabel": { "date": "Date", "words": "Words Collected" } + "axisLabel": {} } } diff --git a/src/i18n.ts b/src/i18n.ts index b703a70316..dae76216ff 100644 --- a/src/i18n.ts +++ b/src/i18n.ts @@ -4,7 +4,7 @@ import LanguageDetector from "i18next-browser-languagedetector"; import Backend from "i18next-http-backend"; import { initReactI18next } from "react-i18next"; -import { Bcp47Code, uiWritingSystems } from "types/writingSystem"; +import { i18nextFallbacks, i18nextLangs } from "types/writingSystem"; // declare custom type options so the return is always a string. declare module "i18next" { @@ -19,21 +19,16 @@ i18n .use(initReactI18next) .init( { - //debug: true, // Uncomment to troubleshoot + debug: true, // Uncomment to troubleshoot returnNull: false, // detection: options, // ignoring localStorage and cookies for the detection order lets the user change languages // more easily (just switch in the browser and reload, instead of clearing all site data) detection: { order: ["queryString", "path", "navigator"] }, - supportedLngs: uiWritingSystems.map((ws) => ws.bcp47), + supportedLngs: i18nextLangs, // nonExplicitSupportedLngs will (e.g.) use 'es' if the browser is 'es-MX' nonExplicitSupportedLngs: true, - fallbackLng: { - es: [Bcp47Code.Pt], - it: [Bcp47Code.Es, Bcp47Code.Pt], - pt: [Bcp47Code.Es], - default: [Bcp47Code.Default], - }, + fallbackLng: i18nextFallbacks, interpolation: { escapeValue: false }, }, setDir // Callback function to set the direction ("ltr" vs "rtl") after i18n has initialized diff --git a/src/types/writingSystem.ts b/src/types/writingSystem.ts index f6ee14f0a6..d56f71a453 100644 --- a/src/types/writingSystem.ts +++ b/src/types/writingSystem.ts @@ -35,6 +35,18 @@ export const semDomWritingSystems = [ writingSystem[Bcp47Code.Fr], ]; +export const i18nextFallbacks = { + es: [Bcp47Code.Pt, Bcp47Code.Default], + it: [Bcp47Code.Es, Bcp47Code.Pt, Bcp47Code.Default], + pt: [Bcp47Code.Es, Bcp47Code.Default], + default: [Bcp47Code.Default], +}; + +// Add any lang covered in ini18nextFallbacks +export const i18nextLangs = uiWritingSystems + .map((ws) => ws.bcp47) + .concat(["it"]); + export function newWritingSystem( bcp47 = "", name = "", From 176ebc70fb7cc5f312a306a520e8ae887e8d7c7c Mon Sep 17 00:00:00 2001 From: "D. Ror" Date: Tue, 9 May 2023 16:05:19 -0400 Subject: [PATCH 4/4] Cleanup comments --- src/i18n.ts | 8 ++++---- src/types/writingSystem.ts | 19 +++++++++---------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/i18n.ts b/src/i18n.ts index dae76216ff..c99ca01d9d 100644 --- a/src/i18n.ts +++ b/src/i18n.ts @@ -4,7 +4,7 @@ import LanguageDetector from "i18next-browser-languagedetector"; import Backend from "i18next-http-backend"; import { initReactI18next } from "react-i18next"; -import { i18nextFallbacks, i18nextLangs } from "types/writingSystem"; +import { i18nFallbacks, i18nLangs } from "types/writingSystem"; // declare custom type options so the return is always a string. declare module "i18next" { @@ -19,16 +19,16 @@ i18n .use(initReactI18next) .init( { - debug: true, // Uncomment to troubleshoot + //debug: true, // Uncomment to troubleshoot returnNull: false, // detection: options, // ignoring localStorage and cookies for the detection order lets the user change languages // more easily (just switch in the browser and reload, instead of clearing all site data) detection: { order: ["queryString", "path", "navigator"] }, - supportedLngs: i18nextLangs, + supportedLngs: i18nLangs, // nonExplicitSupportedLngs will (e.g.) use 'es' if the browser is 'es-MX' nonExplicitSupportedLngs: true, - fallbackLng: i18nextFallbacks, + fallbackLng: i18nFallbacks, interpolation: { escapeValue: false }, }, setDir // Callback function to set the direction ("ltr" vs "rtl") after i18n has initialized diff --git a/src/types/writingSystem.ts b/src/types/writingSystem.ts index d56f71a453..e7b32d1ffa 100644 --- a/src/types/writingSystem.ts +++ b/src/types/writingSystem.ts @@ -2,11 +2,11 @@ import { WritingSystem } from "api/models"; export enum Bcp47Code { Default = "en", - Ar = "ar", - En = "en", - Es = "es", - Fr = "fr", - Pt = "pt", + Ar = "ar", // Arabic + En = "en", // English + Es = "es", // Spanish + Fr = "fr", // French + Pt = "pt", // Portuguese } const writingSystem = { @@ -35,17 +35,16 @@ export const semDomWritingSystems = [ writingSystem[Bcp47Code.Fr], ]; -export const i18nextFallbacks = { +// Used by i18n for missing translations. +export const i18nFallbacks = { es: [Bcp47Code.Pt, Bcp47Code.Default], it: [Bcp47Code.Es, Bcp47Code.Pt, Bcp47Code.Default], pt: [Bcp47Code.Es, Bcp47Code.Default], default: [Bcp47Code.Default], }; -// Add any lang covered in ini18nextFallbacks -export const i18nextLangs = uiWritingSystems - .map((ws) => ws.bcp47) - .concat(["it"]); +// Add support for langs covered in i18nFallbacks above. +export const i18nLangs = uiWritingSystems.map((ws) => ws.bcp47).concat(["it"]); export function newWritingSystem( bcp47 = "",