M14: complete Brazilian Portuguese catalog

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
johnpetersa19
2026-10-21 08:14:32 -03:00
co-authored by Copilot App
parent 4164951453
commit 4eaba2bbcd
7 changed files with 300 additions and 16 deletions
+1 -1
View File
@@ -63,7 +63,7 @@ licence = "MIT OR Apache-2.0"
licence_file = "LICENSE-MIT"
kind = "translation"
usage = "Brazilian Portuguese UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs"
sha256 = "cef0d22341d0722f029c6543fc846fce164331b7ad8f693a6754b7567b9d9e95"
sha256 = "6aa676a4e1cf1ad97e7e5dae6d9e8f1536e4ff5fea94683f4de585ebb1fbb59c"
[[asset]]
path = "crates/ui-egui/src/i18n/es.tsv"
+5 -3
View File
@@ -132,8 +132,8 @@ What's strong and missing in each: [target-app-parity.md](docs/target-app-parity
## Languages
Twelve key languages (historical % snapshot vs 2,143 keys, except Vietnamese vs the current
union). Detail and script notes: [localization-parity.md](docs/localization-parity.md).
Twelve key languages (historical % snapshot vs 2,143 keys, except Vietnamese and Brazilian
Portuguese vs the current union). Detail and script notes: [localization-parity.md](docs/localization-parity.md).
| Language | Code | Strings | Status |
|---|---|---|---|
@@ -143,7 +143,7 @@ union). Detail and script notes: [localization-parity.md](docs/localization-pari
| Hindi | `hi` | 0% | none |
| Arabic | `ar` | 100% | partial (layout not mirrored) |
| French | `fr` | 99.3% | partial |
| Portuguese (Brazil) | `pt-br` | 99.4% | partial |
| Portuguese (Brazil) | `pt-br` | 100% of current union | partial |
| Indonesian | `id` | 0% | none |
| Japanese | `ja` | 99.1% | partial |
| German | `de` | 99.3% | partial |
@@ -172,6 +172,8 @@ Ranked; detail and the full milestone table in [docs/roadmap.md](docs/roadmap.md
## Progress log
- **2026-10-21 (M14, Brazilian Portuguese):** Completed the `pt-br` catalog against the current 2,674-key union, including signature validation and accessibility messages; no build or compilation run. Localization remains partial because help and unpredictable engine/OS error details are not translated.
- **2026-10-19 (M14, #3373):** The main menu and its long submenus scroll in short windows, keeping their commands reachable. Estimates unchanged.
- **2026-10-19 (M3, #3387):** Save-prompt shortcuts yield to later consent and utility dialogs; a synthetic UI regression checks that an edited document stays open. Estimates unchanged.
+22
View File
@@ -1182,6 +1182,28 @@ mod tests {
}
}
#[test]
fn brazilian_portuguese_covers_catalog_union() {
let pt = Lang::from_code("pt-br").expect("pt-br registered");
let pt_catalog = pt.catalog();
for language in LANGUAGES.iter().filter(|language| !language.source.is_empty()) {
let (entries, errors) = catalog::parse_entries(language.source, language.plural_forms());
assert!(errors.is_empty(), "{} catalog: {errors:?}", language.code);
for entry in entries {
let covered = match entry.context.as_str() {
"" => pt_catalog.plain(&entry.source).is_some(),
"@id" => pt_catalog.id(&entry.source).is_some(),
"@plural" => {
let (one, other) = entry.source.split_once('|').expect("validated plural source");
pt_catalog.plural(one, other, 0).is_some()
}
context => pt_catalog.contextual(context, &entry.source).is_some(),
};
assert!(covered, "Brazilian Portuguese lacks {} / {:?}", entry.context, entry.source);
}
}
}
/// Check direct lookups and multiline literals as well as ordinary tl!("literal") calls,
/// following the complete-catalog check for Simplified Chinese.
#[test]
+258
View File
@@ -2448,3 +2448,261 @@ animation effects Off Desativados
Make properties default Tornar propriedades padrão
Pages selected Páginas selecionadas
Page properties Propriedades da página
# Remaining keys from the current catalog union, translated from their English meaning (2026-10-21).
on page {label} na página {label}
A font isn't embedded Uma fonte não está incorporada
A {} action isn't allowed A ação {} não é permitida
A {} annotation has additional actions A anotação {} tem ações adicionais
A {} annotation has no appearance stream A anotação {} não tem fluxo de aparência
A {} annotation isn't set to print, or is hidden A anotação {} não está configurada para impressão ou está oculta
Accessibility Report Relatório de acessibilidade
Add the PDFs to combine Adicione os PDFs que deseja combinar
Added the first {n} PDFs in {folder} Os primeiros {n} PDFs de {folder} foram adicionados
Always Sempre
Automatically Automaticamente
CRL Signing Assinatura de CRL
Certificate Signing Assinatura de certificado
Change Author Alterar autor
Change Keywords Alterar palavras-chave
Change Subject Alterar assunto
Change Title Alterar título
Choose a digital ID. Escolha uma identidade digital.
Choose a file… Escolher um arquivo…
Choose a folder… Escolher uma pasta…
Choose… Escolher…
Color Cor
Comment Comentário
Comment and review Comentar e revisar
Copied to clipboard Copiado para a área de transferência
Copy to clipboard Copiar para a área de transferência
Create folder Criar pasta
Create links Criar links
Creator Criador
Cut and stack needs Two-sided: Off. Print single-sided sheets. Recortar e empilhar requer Frente e verso: desativado. Imprima em folhas de um só lado.
Data Encipherment Criptografia de dados
Decipher Only Somente descriptografia
Detailed Report Relatório detalhado
DeviceCMYK is used, but the PDF/A output intent isn't a CMYK profile O DeviceCMYK está em uso, mas o perfil de saída do PDF/A não é um perfil CMYK
DeviceRGB is used, but the PDF/A output intent isn't an RGB profile O DeviceRGB está em uso, mas o perfil de saída do PDF/A não é um perfil RGB
Digital Signature Assinatura digital
Disabled Desativado
Document properties (⌘D) Propriedades do documento (⌘D)
Drop PDFs or folders here, or choose them. Solte PDFs ou pastas aqui, ou selecione-os.
Duplicate Duplicar
Enabled Ativado
Encipher Only Somente criptografia
English Inglês
Enter a URL Informe uma URL
Enter a name. Informe um nome.
Enter a page number Informe o número da página
Enter the field names Informe os nomes dos campos
Error Erro
Every PDF in the folder Todos os PDFs da pasta
Every PDF in the folder and the folders inside it Todos os PDFs da pasta e de suas subpastas
Field "{}" on page {p} has no description (tooltip) O campo "{}" na página {p} não tem descrição (dica de ferramenta)
Filename Nome do arquivo
Flatten Fill & Sign Achatar Preencher e assinar
Folder Pasta
Font Fonte
Font (unnamed) on page {p} doesn't map its characters to Unicode A fonte (sem nome) na página {p} não mapeia seus caracteres para Unicode
Font {} on page {p} doesn't map its characters to Unicode A fonte {} na página {p} não mapeia seus caracteres para Unicode
Form field on page {p} isn't tagged O campo de formulário na página {p} não está marcado com tag
Help… Ajuda…
H{n} follows an H{d}; headings should not skip levels H{n} vem depois de H{d}; os títulos não devem pular níveis
Import Importar
Information Informações
Key Agreement Acordo de chaves
Key Encipherment Cifragem de chaves
Loading… Carregando…
Mouse wheel scroll speed Velocidade de rolagem da roda do mouse
Move Mover
Never Nunca
New bookmark (⌘B) Novo marcador (⌘B)
Next Próximo
Next (⌘G) Próximo (⌘G)
No PDFs found in {folder} Nenhum PDF encontrado em {folder}
No document language is set Nenhum idioma foi definido para o documento
No page has text: the document appears to be images of pages Nenhuma página contém texto: o documento parece ser composto por imagens de páginas
No results Nenhum resultado
Non-Repudiation Não repúdio
On Ativado
Only the document's owner can change its security (open it with the permissions password) Somente o proprietário do documento pode alterar sua segurança (abra-o com a senha de permissões)
Open a PDF (⌘O) Abrir um PDF (⌘O)
Open folder Abrir pasta
Organize Organizar
Page {n} Página {n}
Page {n} of {total} Página {n} de {total}
Page {p} doesn't tab in structure order A ordem de tabulação da página {p} não segue a ordem da estrutura
Page {p}: {n} untagged content item Página {p}: {n} item de conteúdo sem tag
Page {p}: {n} untagged content items Página {p}: {n} itens de conteúdo sem tag
Page {} has additional actions A página {} tem ações adicionais
Panel layout could not be restored: {error} Não foi possível restaurar o layout dos painéis: {error}
Panel move was not applied: {error} A movimentação do painel não foi aplicada: {error}
Paste Colar
PdfCraft can't check this signature yet: {}. O PdfCraft ainda não pode verificar esta assinatura: {}.
Previous Anterior
Previous (⇧⌘G) Anterior (⇧⌘G)
Print (⌘P) Imprimir (⌘P)
Producer Produtor
Refresh Atualizar
Rendering… Renderizando…
Report created Relatório criado
Rev. {rev}: Certified by an unknown signer Rev. {rev}: certificada por um signatário desconhecido
Rev. {rev}: Certified by {name} Rev. {rev}: certificada por {name}
Rev. {rev}: Signed by an unknown signer Rev. {rev}: assinada por um signatário desconhecido
Rev. {rev}: Signed by {name} Rev. {rev}: assinada por {name}
Rotate view clockwise (⇧⌘+) Girar a visualização no sentido horário (⇧⌘+)
Rule Name Nome da regra
Save (M4) Salvar (M4)
Save as {level} Salvar como {level}
Save changes? Salvar as alterações?
Save file Salvar arquivo
Search results Resultados da pesquisa
Select all Selecionar tudo
Signature is invalid A assinatura é inválida
Signature is valid A assinatura é válida
Signature validity is unknown A validade da assinatura é desconhecida
Signing time is from the clock on the signer's computer. O horário da assinatura vem do relógio do computador do signatário.
Still rendering — this page is unusually complex… Ainda renderizando — esta página é excepcionalmente complexa…
Success Sucesso
System Sistema
Text recognition isn't installed: its models are missing (run `cargo xtask models`, or set PDFCRAFT_MODELS). O reconhecimento de texto não está instalado: faltam os modelos (execute `cargo xtask models` ou defina PDFCRAFT_MODELS).
The ECDSA signature is not in canonical DER (trailing bytes, padding or a missing sign byte); it was read anyway. A assinatura ECDSA não está no formato DER canônico (há bytes excedentes, preenchimento ou falta o byte de sinal); mesmo assim, ela foi lida.
The ECDSA signature is the raw r and s values instead of a DER sequence; it was read anyway. A assinatura ECDSA contém os valores brutos de r e s em vez de uma sequência DER; mesmo assim, ela foi lida.
The RSA signature value does not have the length of the key's modulus (leading zero bytes dropped or added); it was read anyway. O valor da assinatura RSA não tem o mesmo comprimento do módulo da chave (bytes zero iniciais foram removidos ou adicionados); mesmo assim, ele foi lido.
The RSA signature's DigestInfo has no NULL parameter (older signers write it so); it was read anyway. O DigestInfo da assinatura RSA não tem o parâmetro NULL (assinantes mais antigos o incluem); mesmo assim, ele foi lido.
The certificate of {} does not allow this many CA certificates below it (path length), so it is not used to vouch for {}. O certificado de {} não permite essa quantidade de certificados de AC abaixo dele (comprimento do caminho), então não é usado para atestar a validade de {}.
The certificate of {} is not a CA certificate that may issue certificates, so it is not used to vouch for {}. O certificado de {} não é um certificado de AC autorizado a emitir certificados, então não é usado para atestar a validade de {}.
The certificate of {} was not valid at the time of signing, so it is not used to vouch for {}. O certificado de {} não era válido no momento da assinatura, então não é usado para atestar a validade de {}.
The checker found problems which may prevent the document from being fully accessible. A verificação encontrou problemas que podem impedir que o documento seja totalmente acessível.
The document has been altered or corrupted since the signature was applied. O documento foi alterado ou corrompido desde que a assinatura foi aplicada.
The document has been altered or corrupted since the timestamp was applied. O documento foi alterado ou corrompido desde que o carimbo de data e hora foi aplicado.
The document has been altered since this signature was applied in ways it does not permit ({}). O documento foi alterado de maneiras não permitidas ({}), depois que esta assinatura foi aplicada.
The document has been altered since this timestamp was applied in ways it does not permit ({}). O documento foi alterado de maneiras não permitidas ({}), depois que este carimbo de data e hora foi aplicado.
The document has been modified since this signature was applied, but the changes are permitted ({}). O documento foi modificado depois que esta assinatura foi aplicada, mas as alterações são permitidas ({}).
The document has been modified since this timestamp was applied, but the changes are permitted ({}). O documento foi modificado depois que este carimbo de data e hora foi aplicado, mas as alterações são permitidas ({}).
The document has no tags (structure tree) O documento não tem tags (árvore de estrutura)
The document has no title O documento não tem título
The document isn't marked as tagged (MarkInfo Marked) O documento não está marcado como etiquetado (MarkInfo Marked)
The document isn't tagged, so none of its content is O documento não está etiquetado, portanto nenhum conteúdo está
The document's embedded revocation information shows that the signer's certificate has not been revoked. As informações de revogação incorporadas ao documento indicam que o certificado do signatário não foi revogado.
The embedded timestamp token is valid and its authority is trusted; trusted time is {}. O token de carimbo de data e hora incorporado é válido e sua autoridade é confiável; o horário confiável é {}.
The font {} isn't embedded A fonte {} não está incorporada
The metadata doesn't identify the file as {} Os metadados não identificam o arquivo como {}
The password is incorrect. A senha está incorreta.
The password must have at least 6 characters. A senha deve ter pelo menos 6 caracteres.
The password must have at least 8 characters. A senha deve ter pelo menos 8 caracteres.
The passwords do not match. As senhas não correspondem.
The security settings don't allow screen readers to read the text As configurações de segurança não permitem que leitores de tela leiam o texto
The signature algorithm and the SignerInfo's digest algorithm name different hashes; the signature was made with the SignerInfo's. O algoritmo de assinatura e o algoritmo de resumo do SignerInfo indicam hashes diferentes; a assinatura foi feita com o hash indicado pelo SignerInfo.
The signature carries an unverified timestamp ({}): the timestamp authority is not in your list of trusted certificates, so the signing time claimed by the signer is used instead. A assinatura contém um carimbo de data e hora não verificado ({}): a autoridade de carimbo de data e hora não está na sua lista de certificados confiáveis, então será usado o horário de assinatura informado pelo signatário.
The signature contents are not hexadecimal. O conteúdo da assinatura não está em hexadecimal.
The signature could not be checked ({}). Não foi possível verificar a assinatura ({}).
The signature could not be read ({}). Não foi possível ler a assinatura ({}).
The signature could not be verified ({}). Não foi possível validar a assinatura ({}).
The signature has no valid byte range. A assinatura não tem um intervalo de bytes válido.
The signature includes an embedded timestamp. A assinatura inclui um carimbo de data e hora incorporado.
The signature is BER-encoded (indefinite lengths) rather than DER; it was read leniently. A assinatura está codificada em BER (comprimentos indefinidos), e não em DER; ela foi lida de forma permissiva.
The signature uses the legacy adbe.x509.rsa_sha1 format. A assinatura usa o formato legado adbe.x509.rsa_sha1.
The signature value does not match the signer's certificate: the signature is corrupt. O valor da assinatura não corresponde ao certificado do signatário: a assinatura está corrompida.
The signature's byte range does not exclude exactly its contents. O intervalo de bytes da assinatura não exclui exatamente o conteúdo dela.
The signature's byte range does not match the file. O intervalo de bytes da assinatura não corresponde ao arquivo.
The signature's timestamp token could not be verified ({}). Não foi possível validar o token de carimbo de data e hora da assinatura ({}).
The signature's timestamp token does not cover the signature value. O token de carimbo de data e hora da assinatura não abrange o valor da assinatura.
The signed content is a constructed (segmented) OCTET STRING, as BER allows; it was read anyway. O conteúdo assinado é uma OCTET STRING construída (segmentada), como permite o BER; mesmo assim, foi lido.
The signer's certificate does not allow digital signatures (its key usage has neither digital signature nor non-repudiation). O certificado do signatário não permite assinaturas digitais (o uso da chave não inclui assinatura digital nem não repúdio).
The signer's certificate has been revoked ({}). O certificado do signatário foi revogado ({}).
The signer's certificate has critical extensions PdfCraft does not recognize ({}). O certificado do signatário tem extensões críticas que o PdfCraft não reconhece ({}).
The signer's certificate is not in the signature. O certificado do signatário não está incluído na assinatura.
The signer's certificate is not issued for signing documents (its extended key usage has no document-signing purpose). O certificado do signatário não foi emitido para assinar documentos (o uso estendido da chave não inclui essa finalidade).
The signer's certificate was not valid at the time of signing. O certificado do signatário não era válido no momento da assinatura.
The signer's identity is unknown because it has not been included in your list of trusted certificates and none of its parent certificates are trusted certificates. A identidade do signatário é desconhecida porque não foi incluída na sua lista de certificados confiáveis e nenhum dos certificados na cadeia acima dela é confiável.
The signer's identity is valid. A identidade do signatário é válida.
The timestamp authority's certificate was not valid at the time of timestamping. O certificado da autoridade de carimbo de data e hora não era válido no momento da emissão do carimbo.
The timestamp contents are not hexadecimal. O conteúdo do carimbo de data e hora não está em hexadecimal.
The timestamp has no valid byte range. O carimbo de data e hora não tem um intervalo de bytes válido.
The timestamp token could not be read ({}). Não foi possível ler o token de carimbo de data e hora ({}).
The timestamp token is valid and its authority is trusted. O token de carimbo de data e hora é válido e sua autoridade é confiável.
The timestamp token is valid, but the timestamp authority is not in your list of trusted certificates. O token de carimbo de data e hora é válido, mas a autoridade não está na sua lista de certificados confiáveis.
The timestamp's byte range does not exclude exactly its contents. O intervalo de bytes do carimbo de data e hora não exclui exatamente o conteúdo dele.
The timestamp's byte range does not match the file. O intervalo de bytes do carimbo de data e hora não corresponde ao arquivo.
The window shows the file name, not the title (Initial View > Show) A janela exibe o nome do arquivo, e não o título (Exibição inicial > Mostrar)
Theme Tema
There is no folder to save the digital ID in. Não há uma pasta para salvar a identidade digital.
This document has not been modified since this signature was applied. Este documento não foi modificado desde que esta assinatura foi aplicada.
This document has not been modified since this timestamp was applied. Este documento não foi modificado desde que este carimbo de data e hora foi aplicado.
This file changed on disk. Reload it to see the new version; your unsaved changes will be lost. Este arquivo foi alterado no disco. Recarregue-o para ver a nova versão; suas alterações não salvas serão perdidas.
This signature uses RIPEMD-160, a legacy 160-bit hash algorithm that is no longer recommended for signatures. It still validates, but it should not be relied on. Esta assinatura usa RIPEMD-160, um algoritmo de hash legado de 160 bits que não é mais recomendado para assinaturas. Ela ainda é validada, mas não deve ser considerada confiável.
This signature uses SHA-1, a weak hash algorithm: collisions in it have been demonstrated. It still validates because many documents signed years ago use it, but it should not be relied on. Esta assinatura usa SHA-1, um algoritmo de hash fraco para o qual já foram demonstradas colisões. Ela ainda é validada porque muitos documentos assinados há anos o utilizam, mas não deve ser considerada confiável.
Unsigned signature field Campo de assinatura não assinado
Unsigned signature field: {name} Campo de assinatura não assinado: {name}
Warning Aviso
Zoom in (⌘+) Ampliar (⌘+)
Zoom in / out (also pinch or ⌘-scroll) Ampliar / reduzir (também com pinça ou rolagem com ⌘)
Zoom out (⌘−) Reduzir (⌘−)
alternate text hides an annotation inside it o texto alternativo oculta uma anotação em seu interior
alternate text on an element with no page content texto alternativo em um elemento sem conteúdo na página
comments comentários
document security store repositório de segurança do documento
document structure estrutura do documento
form fill preenchimento de formulário
its alternate text is inside another element's and will never be read seu texto alternativo está dentro do texto de outro elemento e nunca será lido
links links
metadata metadados
no alternate text sem texto alternativo
no header cells (TH) sem células de cabeçalho (TH)
no summary sem resumo
not in a TR fora de uma TR
not in a Table, THead, TBody or TFoot fora de uma Table, THead, TBody ou TFoot
not in an L (list) fora de uma L (lista)
not in an LI (list item) fora de um LI (item de lista)
of de
other changes outras alterações
page content conteúdo da página
page {n} is out of range (1–{count}) a página {n} está fora do intervalo (1–{count})
pages added or removed páginas adicionadas ou removidas
rows have between {min} and {max} columns as linhas têm entre {min} e {max} colunas
the first heading is an H{n}; headings should not skip levels o primeiro título é H{n}; os títulos não devem pular níveis
the signed version could not be read não foi possível ler a versão assinada
{n} pages and no bookmarks {n} páginas e nenhum marcador
{page} is not a page number or label {page} não é um número nem um rótulo de página
{ty} element on page {p}: {what} elemento {ty} na página {p}: {what}
{ty} element: {what} elemento {ty}: {what}
{who}, certificate issued by an unknown issuer. {who}, certificado emitido por uma autoridade desconhecida.
{who}, certificate issued by {issuer}. {who}, certificado emitido por {issuer}.
{} annotation on page {p} isn't tagged A anotação {} na página {p} não está marcada com tag
{} annotations aren't allowed As anotações {} não são permitidas
… and {n} more … e mais {n}
@plural Delete {n} field|Delete {n} fields Excluir {n} campo|Excluir {n} campos
@plural {n} byte|{n} bytes {n} byte|{n} bytes
@plural {n} comment|{n} comments {n} comentário|{n} comentários
@plural {n} file|{n} files {n} arquivo|{n} arquivos
@plural {n} image optimized|{n} images optimized {n} imagem otimizada|{n} imagens otimizadas
@plural {n} item discarded|{n} items discarded {n} item descartado|{n} itens descartados
@plural {n} pixel|{n} pixels {n} pixel|{n} pixels
@plural {n} result|{n} results {n} resultado|{n} resultados
calendar weekday Fr Sex
calendar weekday Mo Seg
calendar weekday Sa Sáb
calendar weekday Su Dom
calendar weekday Th Qui
calendar weekday Tu Ter
calendar weekday We Qua
certificate Basic constraints Restrições básicas
certificate Intended usage Uso pretendido
certificate Issued by Emitido por
certificate Issued to Emitido para
certificate Issuer Emissor
certificate Key usage Uso da chave
certificate Public key Chave pública
certificate SHA-1 digest Resumo SHA-1
certificate SHA-256 digest Resumo SHA-256
certificate Self-signed Autoassinado
certificate Serial number Número de série
certificate Valid from Válido desde
certificate Valid to Válido até
certificate Validity ends Fim da validade
certificate Validity starts Início da validade
certificate Version Versão
theme Appearance Aparência
Can't render this file because it contains an unexpected character in line 9 and column 16.
+8 -6
View File
@@ -2,6 +2,7 @@
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-13 · **Change:** minor (Vietnamese 100% of current key union; native-speaker community review; twelve-language mean ≈68%) · **Target:** Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS)
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-14 · **Change:** minor (Italian count after completing its catalog) · **Target:** Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS)
> **Last reviewed:** 2026-10-21 · **Last updated:** 2026-10-21 · **Change:** minor (Brazilian Portuguese now covers the 2,674-key catalog union; twelve-language mean still rounds to ≈68%) · **Target:** Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS)
Per-language status of PdfCraft's interface against Acrobat Pro's. How translations work and how to
add a language: [localization.md](localization.md). Summary in [ROADMAP.md](../ROADMAP.md).
@@ -10,10 +11,10 @@ add a language: [localization.md](localization.md). Summary in [ROADMAP.md](../R
- **Strings translated** is measured: the catalogs in `crates/ui-egui/src/i18n/<code>.tsv`, counted
as distinct `(context, English)` keys with a non-empty translation. The **current** denominator is
the union of keys across all catalogs (**2,590** plain keys as of 2026-10-13, plus language-specific
context rows such as Vietnamese `theme`/`Appearance`). The twelve-language percentage table below
still quotes the **historical 2,143-key snapshot** from 2026-10-10 for every language except
Vietnamese (re-measured against the current union). English is built in.
the union of keys across all catalogs (**2,674 distinct keys as of 2026-10-21**, including
language-specific context rows such as Vietnamese `theme`/`Appearance`). The twelve-language
percentage table below still quotes the **historical 2,143-key snapshot** from 2026-10-10 except
for Vietnamese and Brazilian Portuguese (measured against the current union). English is built in.
- **Not counted:** error details from the engine and the operating system, which are shown in
English inside a translated frame; there is no translated user documentation or help yet (Acrobat
ships localized help).
@@ -35,12 +36,12 @@ add a language: [localization.md](localization.md). Summary in [ROADMAP.md](../R
| Hindi | `hi` | 0 | none | Devanagari not tested (egui shapes Telugu conjuncts, so shaping is likely workable); no Devanagari face in craft-fonts | no | none | no | 10–18 |
| Arabic | `ar` | 2,143 (100%) | dialogs and tooltips; no help | Letters joined and lines reordered at load, but **layout not mirrored**, wrapped lines break at the wrong end, typed text runs left to right (`localization.md` §Arabic) | no | partial | yes (Middle East edition) | 25–45 |
| French | `fr` | 2,128 (99.3%) | dialogs and tooltips; no help | Latin | no | partial | yes | 1–2 |
| Portuguese (Brazil) | `pt-br` | 2,130 (99.4%) | dialogs and tooltips; no help | Latin | community (#288) | partial | yes | 1–2 |
| Portuguese (Brazil) | `pt-br` | 2,674 (100% of current union) | dialogs and tooltips; no help | Latin | community (#288) | partial | yes | 1–2 |
| Indonesian | `id` | 0 | none | Latin | no | none | no | 3–5 |
| Japanese | `ja` | 2,123 (99.1%) | dialogs and tooltips; no help | BIZ UDPGothic from craft-fonts; IME patched on macOS, Windows, X11, Wayland; vertical text renders but can't be edited | no | partial | yes | 4–8 |
| German | `de` | 2,128 (99.3%) | dialogs and tooltips; no help | Latin | community, in progress (#828: terminology, clipping) | partial | yes | 2–4 |
| Korean | `ko` | 0 | none | Hangul IME patched (Microsoft and Apple Korean, `vendor/README.md` winit 3, 6, 9, 10); no Hangul UI face in craft-fonts | no | none | yes | 6–10 |
| Vietnamese | `vi` | 2,591 (100% of current union + theme Appearance) | dialogs and tooltips; no help | Latin with stacked diacritics; bundled Inter covers them (fonts test) | community | partial | no | 2–4 |
| Vietnamese | `vi` | 2,674 (100% of current union) | dialogs and tooltips; no help | Latin with stacked diacritics; bundled Inter covers them (fonts test) | community | partial | no | 2–4 |
**Localization dimension ≈ 68%**: the mean over the twelve, counting a catalog's percentage but only
60% for Chinese and Arabic until their script problems are fixed, and 0 for Hindi, Indonesian and
@@ -82,6 +83,7 @@ Acrobat languages PdfCraft lacks: Danish, Dutch, Finnish, Norwegian, Swedish, He
| Date | Change | Summary |
|---|---|---|
| 2026-10-21 | minor | Brazilian Portuguese (`pt-br`) now covers all 2,674 distinct keys in the current catalog union; no help or engine/OS error-detail localization; twelve-language mean still rounds to ≈ 68% |
| 2026-10-13 | minor | Vietnamese (`vi`) catalog: 2,591 entries (100% of current key union + `theme`/`Appearance`); twelve-language mean ≈ 68%; native-speaker community review; registered with `plural_none` |
| 2026-10-14 | minor | Italian: 2,528 entries after adding the 201 keys the other catalogs had and the code looks up |
| 2026-10-12 | minor | Added current counts for Kazakh, Polish, Slovenian, Greek, Turkish and Lithuanian; retained existing language assessments and the original percentage snapshot |
+3 -3
View File
@@ -24,7 +24,7 @@ The Ukrainian catalog has 2,047 entries, written from the meaning of the English
The Lithuanian catalog has 2,585 entries and three integer plural forms. Calendar headings use standalone month names; dates use genitive forms. Coverage tests check commands/tools, scanned literal and direct lookups, and source/context keys in the other bundled catalogs. Calendar, inspector and password-dialog UI regressions check dynamic labels and preserve document values. A native Lithuanian-speaking contributor has reviewed the translation.
The Vietnamese catalog has 2,591 entries and one plural form (`plural_none`). Preferences theme `Appearance` uses context `theme` → `Giao diện`; object/comment/signature appearance stays plain `Diện mạo`. Form fields use `Trường`; redaction apply wording states permanent removal. Calendar months are numeric (`Tháng 1`…`12` / `tháng 1`…`12`). Coverage tests require every current command, UI literal, bundled key and credit label. A native Vietnamese-speaking contributor has reviewed the translation. Status stays `partial`: no translated help, and engine/OS details stay English inside a translated frame.
The Vietnamese catalog has 2,674 entries and one plural form (`plural_none`), covering the current catalog-key union. Preferences theme `Appearance` uses context `theme` → `Giao diện`; object/comment/signature appearance stays plain `Diện mạo`. Form fields use `Trường`; redaction apply wording states permanent removal. Calendar months are numeric (`Tháng 1`…`12` / `tháng 1`…`12`). Coverage tests require every current command, UI literal, bundled key and credit label. A native Vietnamese-speaking contributor has reviewed the translation. Status stays `partial`: no translated help, and engine/OS details stay English inside a translated frame.
Edit text reads Hebrew lines in typing order and writes them back in drawing order (`crates/edit/src/bidi.rs`); letters the page's own font lacks are drawn with the craft-fonts `Hebr` face (Noto Sans Hebrew) as Type 3 glyphs, and a build without one says so. Hebrew points (niqqud) can't be written yet in Edit text. Add text (#128) draws Hebrew with the same face through the shaped path Arabic and Thai use: right to left with numbers and Latin in place, points kept on their letter, and typing order for copy and search. The craft-fonts revision pinned for CI and releases has no `Hebr` face yet, so until one is added releases report that error instead of drawing the missing letters, and refuse Hebrew in Add text.
@@ -32,7 +32,7 @@ Japanese interface text uses BIZ UDPGothic from [craft-fonts](https://github.com
Japanese interface text uses BIZ UDPGothic from [craft-fonts](https://github.com/storytold/craft-fonts), an optional build input that every release includes (`CRAFT_FONTS_DIR`; see the README). A build made without it has no Japanese face, so Japanese labels show replacement boxes. Chinese is drawn with the same craft-fonts CJK faces (in Simplified Chinese the `Hans` faces come first, so a line never mixes faces with different baselines), so a character none of them has shows a replacement box (and every Chinese character does in a build without craft-fonts). Russian, Bulgarian, Czech, Brazilian Portuguese, German, Spanish, French, Hungarian, Italian and Slovenian need only the bundled Latin faces (tested in `tests/fonts.rs`). Slovenian has four plural forms: one (1, 101, 201…), two (2, 102…), few (3, 4, 103…) and other (everything else, including 0, 5–20 and 21+), so `@plural` entries list four forms (`1 stran`, `2 strani`, `3 strani`, `5 strani`). Hungarian uses the same one/other plural rule as English: 1 is singular, and every other count — including 0 — is the other form. After a numeral the noun stays singular (`1 oldal`, `2 oldal`). Telugu is drawn with a craft-fonts `Telu` face (Noto Sans Telugu, kept in the web build too), whose conjuncts egui shapes; a build without one shows Telugu labels as replacement boxes, and the release-pinned craft-fonts input has no Telugu face yet.
Japanese interface text uses BIZ UDPGothic from [craft-fonts](https://github.com/storytold/craft-fonts), an optional build input that every release includes (`CRAFT_FONTS_DIR`; see the README). A build made without it has no Japanese face, so Japanese labels show replacement boxes. Chinese is drawn with the same craft-fonts CJK faces (in Simplified Chinese the `Hans` faces come first, so a line never mixes faces with different baselines), so a character none of them has shows a replacement box (and every Chinese character does in a build without craft-fonts). Until craft-fonts has an allowed `Hans` face, the desktop app draws a Chinese interface with a Chinese face already installed on the machine (Microsoft YaHei or JhengHei on Windows, PingFang, Hiragino Sans GB or STHeiti on macOS, WenQuanYi or Droid Sans Fallback on Linux; never Noto CJK or Source Han), placed before the Japanese faces so a line keeps one face (#826). The web build has no installed fonts to fall back on. Russian, Bulgarian, Czech, Brazilian Portuguese, German, Spanish, French, Hungarian and Italian need only the bundled Latin faces (tested in `tests/fonts.rs`). Hungarian uses the same one/other plural rule as English: 1 is singular, and every other count — including 0 — is the other form. After a numeral the noun stays singular (`1 oldal`, `2 oldal`). Telugu is drawn with a craft-fonts `Telu` face (Noto Sans Telugu, kept in the web build too), whose conjuncts egui shapes; a build without one shows Telugu labels as replacement boxes, and the release-pinned craft-fonts input has no Telugu face yet.
The Brazilian Portuguese catalog has 2,000 entries: the ~1,826-entry gist André Cardoso posted in [#288](https://github.com/storytold/pdfcraft/issues/288), the labels added since, and a review of the existing wording. Portuguese, like French, treats 0 and 1 as singular (`1 página`, `2 páginas`).
The Brazilian Portuguese catalog has 2,674 entries and covers the current union of catalog keys. It began with the ~1,826-entry gist André Cardoso posted in [#288](https://github.com/storytold/pdfcraft/issues/288), with labels added since and the existing wording reviewed. Portuguese, like French, treats 0 and 1 as singular (`1 página`, `2 páginas`).
## Arabic and right-to-left text
@@ -53,7 +53,7 @@ Arabic glyphs come from the craft-fonts `Arab` face (Noto Sans Arabic, kept in t
File names and document titles in Arabic or Hebrew are drawn with a craft-fonts `Arab` face when the build input has one; on desktop, a character no embedded face has is drawn with one font already installed on the machine (`PDFCRAFT_SYSTEM_FONTS=0` turns this off). The tab strip, the recent-files list and Properties show such names in display order; other places (bookmarks, comments, search results) have the glyphs but may order mixed-direction text wrongly.
Japanese, Simplified Chinese, French, German and Brazilian Portuguese coverage tests, following PhotoCraft's complete-catalog approach, check every registered command, All tools label and `tl!("literal")` in the UI source. Simplified Chinese also checks direct `i18n::t` calls and multiline literals, plus the About tabs, contributor name modes, sort options, table headers and model columns. Generated history labels, contributor summaries and diagnostics are tested with user-supplied names and error details. Catalog coverage does not guarantee glyph coverage: the release-pinned craft-fonts input currently has no `Hans` face, and the web build embeds only BIZ UDPGothic Regular. Chinese font delivery remains separate work, as discussed in [#112](https://github.com/storytold/pdfcraft/pull/112) and [#140](https://github.com/storytold/pdfcraft/pull/140).
Japanese, Simplified Chinese, French, German and Brazilian Portuguese coverage tests, following PhotoCraft's complete-catalog approach, check every registered command, All tools label and `tl!("literal")` in the UI source. Brazilian Portuguese also checks every key in the union of the bundled catalogs. Simplified Chinese additionally checks direct `i18n::t` calls and multiline literals, plus the About tabs, contributor name modes, sort options, table headers and model columns. Generated history labels, contributor summaries and diagnostics are tested with user-supplied names and error details. Catalog coverage does not guarantee glyph coverage: the release-pinned craft-fonts input currently has no `Hans` face, and the web build embeds only BIZ UDPGothic Regular. Chinese font delivery remains separate work, as discussed in [#112](https://github.com/storytold/pdfcraft/pull/112) and [#140](https://github.com/storytold/pdfcraft/pull/140).
German labels keep nouns capitalized, including tool names inserted into notices. The certificate viewer uses the `certificate` context for `Subject` (the certificate holder), while document properties keep the plain translation (the topic). Search hints reserve room for the shortcut, and Home cards limit their title and description to the available rows; hovering shows the full text when it is shortened.
+3 -3
View File
@@ -151,10 +151,10 @@ total matches the parity estimate.
| M13 | Automation (MCP, Action Wizard, CLI) + AI providers | 60–120 | 45% | 25–45 | Done: MCP resources (document info, text, page images); headless tool table (123 tools incl. signing, optimizing, initial view, links, stamps, data exchange, comment review, forms authoring and scripts, redaction, sanitize, print, add content), opt-in MCP server over stdio, CLI `run`/`tools` (closed stdout pipes exit cleanly), UI control channel with drag. Missing: Action Wizard, AI providers<br>Done since: CLI run and MCP reject missing, empty, repeated and option-valued --root arguments before any tool/script execution or MCP initialization. A single-hyphen directory name remains valid; synthetic CLI regressions preserve a would-be overwritten file. `text_find` also caps the per-page match ranges it materializes at the remaining result limit plus one continuation match. CLI robustness scans visit each directory once through overlapping roots and symlink aliases. |
| M12 | Accessibility, compare, measure, search, XFA | 200–380 | 30% | 90–160 | Done: new `a11y` crate with the Accessibility Checker (all 32 rules, report, Fix/Skip/Explain, options dialog and results panel, agent tools). Locatable figure, annotation and form findings highlight their page bounds.<br>Done since: 2D distance, perimeter and area measurements with persistent viewport calibration, snapping, live information and CSV export; a bounded text-only auto-tag proposal tool; text-only Apply writes marked content, paragraph tags and a parent tree, then opens the Tags panel for review. Missing: mixed-content and field autotag, heading/list/table/figure classification, Order/Content panels, Reading Order tool, compare, geospatial/3D measurement, search index, XFA<br>Done since: CLI info, text and render use dynamic XFA layout pages, with synthetic count/text/pixel and copy-permission regressions (#1645). |
| M13 | Automation (MCP, Action Wizard, CLI) + AI providers | 60–120 | 45% | 25–45 | Done: MCP resources (document info, text, page images); headless tool table (123 tools incl. signing, optimizing, initial view, links, stamps, data exchange, comment review, forms authoring and scripts, redaction, sanitize, print, add content), opt-in MCP server over stdio, CLI `run`/`tools` (closed stdout pipes exit cleanly), UI control channel with drag. Missing: Action Wizard, AI providers<br>Done since: CLI run and MCP reject missing, empty, repeated and option-valued --root arguments before any tool/script execution or MCP initialization. A single-hyphen directory name remains valid; synthetic CLI regressions preserve a would-be overwritten file. `text_find` also caps the per-page match ranges it materializes at the remaining result limit plus one continuation match. |
| M14 | 1.0 polish: performance, localization, installers | 120–250 | 15% | 80–150 | Done: PhotoCraft's translation system (`i18n/`: TSV catalogs, `tl!`, command-id and plural entries, system-language detection, strict catalog tests); every dialog, panel and notice goes through `tl!`. Catalogs of ≈ 2,000–2,140 entries for Japanese, Simplified and Traditional Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian, Brazilian Portuguese and Arabic (logical-order catalog put into display order; layout not yet mirrored); Czech covers the menus. Italian has 2,528 entries: every key of the other catalogs that the code looks up. Signed and notarized macOS builds, signed Windows installers (x64, x86, ARM64), AppImage, deb, rpm, Flatpak and FreeBSD packages. #307 (bounded large-PDF memory): shared resource indexes and parser metadata, lazy inspection, bounded caches; a 9,156-page file inspects in ≈ 1.8 s at ≈ 500 MiB instead of exceeding 10 GiB. Edits let go of the previous working file before writing the next (a 1 GiB file peaks at two copies while editing, not three; gap 13). Shortcut display uses localized modifier/key names across menus, toolbar, palette, Help and tooltips (#496). Lithuanian adds a 2,578-entry catalog and date names, reviewed by a native-speaking contributor. Validated candidate (macOS raster probe; Windows runtime unverified): the Windows policy changes only embedded JetBrains Mono; horizontal alpha-edge energy per ink improves 2.78%, 3.87% and 1.59% at 100%, 125% and 150%, and is down 0.79% at 200%. Inter is pixel-identical; layout hashes, glyph coverage and the 8 MiB atlas are unchanged. Timing and RSS ranges overlap, with no improvement claimed. Estimates unchanged. Candidate #2383 clamps GPU requests to supported limits while retaining the adapter texture extent; synthetic V3D/downlevel and Windows GPU-required tests pass, but Raspberry Pi startup is unverified. Estimates unchanged. Missing: a right-to-left layout, a Chinese UI face in releases, Hindi/Indonesian/Korean/Vietnamese, file-backed input and global memory budgets, performance budgets, keyboard-only operation Linux/Unix UI fallback fonts also use Fontconfig directories, including Nix store paths, with bounded discovery and the existing candidate allowlist; relative includes and digit-prefixed config filtering have isolated regressions. |
| M14 | 1.0 polish: performance, localization, installers | 120–250 | 15% | 80–150 | Done: PhotoCraft's translation system (`i18n/`: TSV catalogs, `tl!`, command-id and plural entries, system-language detection, strict catalog tests); every dialog, panel and notice goes through `tl!`. Catalogs of ≈ 2,000–2,140 entries for Japanese, Simplified and Traditional Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian, Brazilian Portuguese and Arabic (logical-order catalog put into display order; layout not yet mirrored); Czech covers the menus. Italian has 2,528 entries: every key of the other catalogs that the code looks up. Signed and notarized macOS builds, signed Windows installers (x64, x86, ARM64), AppImage, deb, rpm, Flatpak and FreeBSD packages. #307 (bounded large-PDF memory): shared resource indexes and parser metadata, lazy inspection, bounded caches; a 9,156-page file inspects in ≈ 1.8 s at ≈ 500 MiB instead of exceeding 10 GiB. Edits let go of the previous working file before writing the next (a 1 GiB file peaks at two copies while editing, not three; gap 13). Shortcut display uses localized modifier/key names across menus, toolbar, palette, Help and tooltips (#496). Lithuanian adds a 2,578-entry catalog and date names, reviewed by a native-speaking contributor. Validated candidate (macOS raster probe; Windows runtime unverified): the Windows policy changes only embedded JetBrains Mono; horizontal alpha-edge energy per ink improves 2.78%, 3.87% and 1.59% at 100%, 125% and 150%, and is down 0.79% at 200%. Inter is pixel-identical; layout hashes, glyph coverage and the 8 MiB atlas are unchanged. Timing and RSS ranges overlap, with no improvement claimed. Estimates unchanged. Missing: a right-to-left layout, a Chinese UI face in releases, Hindi/Indonesian/Korean/Vietnamese, file-backed input and global memory budgets, performance budgets, keyboard-only operation XDG desktops use the configuration base for preferences with non-overwriting migration and original-data preservation (#1395). |
| M14 | 1.0 polish: performance, localization, installers | 120–250 | 15% | 80–150 | Done: PhotoCraft's translation system (`i18n/`: TSV catalogs, `tl!`, command-id and plural entries, system-language detection, strict catalog tests); every dialog, panel and notice goes through `tl!`. Catalogs of ≈ 2,000–2,140 entries for Japanese, Simplified and Traditional Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian and Arabic (logical-order catalog put into display order; layout not yet mirrored); the 2,674-entry Brazilian Portuguese catalog covers the current key union; Czech covers the menus. Italian has 2,528 entries: every key of the other catalogs that the code looks up. Signed and notarized macOS builds, signed Windows installers (x64, x86, ARM64), AppImage, deb, rpm, Flatpak and FreeBSD packages. #307 (bounded large-PDF memory): shared resource indexes and parser metadata, lazy inspection, bounded caches; a 9,156-page file inspects in ≈ 1.8 s at ≈ 500 MiB instead of exceeding 10 GiB. Edits let go of the previous working file before writing the next (a 1 GiB file peaks at two copies while editing, not three; gap 13). Shortcut display uses localized modifier/key names across menus, toolbar, palette, Help and tooltips (#496). Lithuanian adds a 2,578-entry catalog and date names, reviewed by a native-speaking contributor. Validated candidate (macOS raster probe; Windows runtime unverified): the Windows policy changes only embedded JetBrains Mono; horizontal alpha-edge energy per ink improves 2.78%, 3.87% and 1.59% at 100%, 125% and 150%, and is down 0.79% at 200%. Inter is pixel-identical; layout hashes, glyph coverage and the 8 MiB atlas are unchanged. Timing and RSS ranges overlap, with no improvement claimed. Estimates unchanged. Candidate #2383 clamps GPU requests to supported limits while retaining the adapter texture extent; synthetic V3D/downlevel and Windows GPU-required tests pass, but Raspberry Pi startup is unverified. Estimates unchanged. Missing: a right-to-left layout, a Chinese UI face in releases, Hindi/Indonesian/Korean/Vietnamese, file-backed input and global memory budgets, performance budgets, keyboard-only operation Linux/Unix UI fallback fonts also use Fontconfig directories, including Nix store paths, with bounded discovery and the existing candidate allowlist; relative includes and digit-prefixed config filtering have isolated regressions. |
| M14 | 1.0 polish: performance, localization, installers | 120–250 | 15% | 80–150 | Done: PhotoCraft's translation system (`i18n/`: TSV catalogs, `tl!`, command-id and plural entries, system-language detection, strict catalog tests); every dialog, panel and notice goes through `tl!`. Catalogs of ≈ 2,000–2,140 entries for Japanese, Simplified and Traditional Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian and Arabic (logical-order catalog put into display order; layout not yet mirrored); the 2,674-entry Brazilian Portuguese catalog covers the current key union; Czech covers the menus. Italian has 2,528 entries: every key of the other catalogs that the code looks up. Signed and notarized macOS builds, signed Windows installers (x64, x86, ARM64), AppImage, deb, rpm, Flatpak and FreeBSD packages. #307 (bounded large-PDF memory): shared resource indexes and parser metadata, lazy inspection, bounded caches; a 9,156-page file inspects in ≈ 1.8 s at ≈ 500 MiB instead of exceeding 10 GiB. Edits let go of the previous working file before writing the next (a 1 GiB file peaks at two copies while editing, not three; gap 13). Shortcut display uses localized modifier/key names across menus, toolbar, palette, Help and tooltips (#496). Lithuanian adds a 2,578-entry catalog and date names, reviewed by a native-speaking contributor. Validated candidate (macOS raster probe; Windows runtime unverified): the Windows policy changes only embedded JetBrains Mono; horizontal alpha-edge energy per ink improves 2.78%, 3.87% and 1.59% at 100%, 125% and 150%, and is down 0.79% at 200%. Inter is pixel-identical; layout hashes, glyph coverage and the 8 MiB atlas are unchanged. Timing and RSS ranges overlap, with no improvement claimed. Estimates unchanged. Missing: a right-to-left layout, a Chinese UI face in releases, Hindi/Indonesian/Korean/Vietnamese, file-backed input and global memory budgets, performance budgets, keyboard-only operation XDG desktops use the configuration base for preferences with non-overwriting migration and original-data preservation (#1395). |
| M13 | Automation (MCP, Action Wizard, CLI) + AI providers | 60–120 | 45% | 25–45 | Done: MCP resources (document info, text, page images); headless tool table (123 tools incl. signing, optimizing, initial view, links, stamps, data exchange, comment review, forms authoring and scripts, redaction, sanitize, print, add content), opt-in MCP server over stdio, CLI `run`/`tools` (closed stdout pipes exit cleanly), UI control channel with drag. Missing: Action Wizard, AI providers |
| M14 | 1.0 polish: performance, localization, installers | 120–250 | 15% | 80–150 | Done: PhotoCraft's translation system (`i18n/`: TSV catalogs, `tl!`, command-id and plural entries, system-language detection, strict catalog tests); every dialog, panel and notice goes through `tl!`. Catalogs of ≈ 2,000–2,140 entries for Japanese, Simplified and Traditional Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian, Brazilian Portuguese and Arabic (logical-order catalog put into display order; layout not yet mirrored); Czech covers the menus. Italian has 2,528 entries: every key of the other catalogs that the code looks up. Signed and notarized macOS builds, signed Windows installers (x64, x86, ARM64), AppImage, deb, rpm, Flatpak and FreeBSD packages. #307 (bounded large-PDF memory): shared resource indexes and parser metadata, lazy inspection, bounded caches; a 9,156-page file inspects in ≈ 1.8 s at ≈ 500 MiB instead of exceeding 10 GiB. Edits let go of the previous working file before writing the next (a 1 GiB file peaks at two copies while editing, not three; gap 13). Shortcut display uses localized modifier/key names across menus, toolbar, palette, Help and tooltips (#496). Traditional Chinese accessibility statuses, rule semantics and Taiwan form/table terms have catalog regressions. Long main-menu lists scroll in short windows (#3373). Missing: a right-to-left layout, a Chinese UI face in releases, Hindi/Indonesian/Korean/Vietnamese, file-backed input and global memory budgets, performance budgets, keyboard-only operation |
| M14 | 1.0 polish: performance, localization, installers | 120–250 | 15% | 80–150 | Done: PhotoCraft's translation system (`i18n/`: TSV catalogs, `tl!`, command-id and plural entries, system-language detection, strict catalog tests); every dialog, panel and notice goes through `tl!`. Catalogs of ≈ 2,000–2,140 entries for Japanese, Simplified and Traditional Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian and Arabic (logical-order catalog put into display order; layout not yet mirrored); the 2,674-entry Brazilian Portuguese catalog covers the current key union; Czech covers the menus. Italian has 2,528 entries: every key of the other catalogs that the code looks up. Signed and notarized macOS builds, signed Windows installers (x64, x86, ARM64), AppImage, deb, rpm, Flatpak and FreeBSD packages. #307 (bounded large-PDF memory): shared resource indexes and parser metadata, lazy inspection, bounded caches; a 9,156-page file inspects in ≈ 1.8 s at ≈ 500 MiB instead of exceeding 10 GiB. Edits let go of the previous working file before writing the next (a 1 GiB file peaks at two copies while editing, not three; gap 13). Shortcut display uses localized modifier/key names across menus, toolbar, palette, Help and tooltips (#496). Traditional Chinese accessibility statuses, rule semantics and Taiwan form/table terms have catalog regressions. Long main-menu lists scroll in short windows (#3373). Missing: a right-to-left layout, a Chinese UI face in releases, Hindi/Indonesian/Korean/Vietnamese, file-backed input and global memory budgets, performance budgets, keyboard-only operation |
| | **Total** | **2,085–3,840** | **≈ 49% ready** | **≈ 770–1,400** | Area view of the same work: [target-app-parity.md](target-app-parity.md#by-feature-area) |
## Upcoming milestones, ranked