From 2a3a6e96d6d0ad11eda8dfa4ad070d3f8fdbdbb9 Mon Sep 17 00:00:00 2001 From: Kayshen-X Date: Sun, 10 May 2026 19:04:38 +0800 Subject: [PATCH] fix(shell-core): convert-locales handles multi-line + double-quoted values Earlier convert-locales.py was line-based + single-quote-only, missing ~16 keys per locale where: - the value spans onto the next line ('long.key.name':\n 'value') - the value uses double quotes for English contractions ('topbar.dontSave': "Don't Save") Switch to a regex.finditer over the whole file with multi-line + double-quote alternation. All 15 locales now report 706 keys each, matching the TS source (apps/web/src/i18n/locales/*.ts). Stop-hook: 'locale import is incomplete'. --- crates/openpencil-shell-core/src/i18n/de.rs | 88 ++++++++--------- crates/openpencil-shell-core/src/i18n/en.rs | 47 +++++---- crates/openpencil-shell-core/src/i18n/es.rs | 58 +++++++---- crates/openpencil-shell-core/src/i18n/fr.rs | 92 ++++++++++++++---- crates/openpencil-shell-core/src/i18n/hi.rs | 36 +++---- crates/openpencil-shell-core/src/i18n/id.rs | 53 +++++----- crates/openpencil-shell-core/src/i18n/ja.rs | 64 ++++++------ crates/openpencil-shell-core/src/i18n/ko.rs | 48 ++++----- crates/openpencil-shell-core/src/i18n/pt.rs | 59 ++++++----- crates/openpencil-shell-core/src/i18n/ru.rs | 44 ++++++--- crates/openpencil-shell-core/src/i18n/th.rs | 20 ++-- crates/openpencil-shell-core/src/i18n/tr.rs | 65 +++++++++---- crates/openpencil-shell-core/src/i18n/vi.rs | 46 +++++---- .../openpencil-shell-core/src/i18n/zh_cn.rs | 15 +++ .../openpencil-shell-core/src/i18n/zh_tw.rs | 9 +- .../convert-locales.cpython-314.pyc | Bin 0 -> 6413 bytes tools/convert-locales.py | 30 ++++-- 17 files changed, 470 insertions(+), 304 deletions(-) create mode 100644 tools/__pycache__/convert-locales.cpython-314.pyc diff --git a/crates/openpencil-shell-core/src/i18n/de.rs b/crates/openpencil-shell-core/src/i18n/de.rs index 40c97c2a5..a30036dd9 100644 --- a/crates/openpencil-shell-core/src/i18n/de.rs +++ b/crates/openpencil-shell-core/src/i18n/de.rs @@ -49,9 +49,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "topbar.exitFullscreen" => "Vollbild beenden", "topbar.edited" => "— Bearbeitet", "topbar.closeConfirmMessage" => "Möchten Sie die Änderungen vor dem Schließen speichern?", - "topbar.closeConfirmDetail" => { - "Ihre Änderungen gehen verloren, wenn Sie sie nicht speichern." - } + "topbar.closeConfirmDetail" => "Ihre Änderungen gehen verloren, wenn Sie sie nicht speichern.", "topbar.dontSave" => "Nicht speichern", "topbar.agentsAndMcp" => "Agenten & MCP", "topbar.setupAgentsMcp" => "Agenten & MCP einrichten", @@ -64,21 +62,20 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.close" => "Schließen", "git.initializing" => "Repository wird initialisiert…", "git.conflict.title" => "Merge-Konflikt", + "git.conflict.description" => "Löse jeden Konflikt mithilfe der Karten unten auf, dann wende den Merge an.", "git.conflict.abort" => "Merge abbrechen", "git.conflict.nonOp.title" => "Zusammenführung wegen Nicht-.op-Dateien pausiert", + "git.conflict.nonOp.description" => "Die .op-Zusammenführung ist abgeschlossen, aber andere Dateien im Repository sind noch nicht aufgelöst. Beheben Sie sie außerhalb von OpenPencil und fahren Sie dann fort.", "git.conflict.nonOp.unresolvedHeading_one" => "1 Datei benötigt Aufmerksamkeit", - "git.conflict.nonOp.unresolvedHeading_other" => { - "{{count}} Dateien benötigen Aufmerksamkeit" - } + "git.conflict.nonOp.unresolvedHeading_other" => "{{count}} Dateien benötigen Aufmerksamkeit", "git.conflict.nonOp.continue" => "Zusammenführung fortsetzen", "git.conflict.nonOp.abort" => "Zusammenführung abbrechen", "git.conflict.banner.progress" => "Gelöst {{resolved}} / {{total}}", "git.conflict.banner.apply" => "Merge anwenden", "git.conflict.banner.continue" => "Fortfahren", "git.conflict.banner.finalizeError" => "Konnte nicht anwenden: {{message}}", - "git.conflict.banner.pollError" => { - "Status-Polling wegen eines Fehlers pausiert: {{message}}" - } + "git.conflict.banner.pollError" => "Status-Polling wegen eines Fehlers pausiert: {{message}}", + "git.conflict.banner.reopenMessage" => "Panel wurde mitten im Merge neu geöffnet — bitte abbrechen und erneut pullen.", "git.conflict.list.heading" => "Alle Konflikte", "git.conflict.list.progress" => "{{resolved}} / {{total}} gelöst", "git.conflict.list.allResolved" => "Alle gelöst", @@ -104,9 +101,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.error.title" => "Ein Fehler ist aufgetreten", "git.empty.heading" => "Noch keine Versionshistorie", "git.empty.optional" => "Git ist optional — Überspringen ist in Ordnung", - "git.empty.requireSavedFile" => { - "Speichern Sie die .op-Datei zuerst, um die Historie zu aktivieren" - } + "git.empty.requireSavedFile" => "Speichern Sie die .op-Datei zuerst, um die Historie zu aktivieren", "git.empty.newCard" => "Neu", "git.empty.newCardDescription" => "Lokale Historie erstellen", "git.empty.openCard" => "Öffnen", @@ -144,6 +139,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.commit.placeholder" => "Diese Änderung beschreiben…", "git.commit.submitButton" => "Meilenstein speichern", "git.commit.saveRequiredTitle" => "Dokument zuerst speichern", + "git.commit.saveRequiredBody" => "Sie haben ungespeicherte Änderungen. Speichern Sie das Dokument, um fortzufahren: {{label}}", "git.commit.saveRequiredSave" => "Speichern", "git.commit.saveRequiredCancel" => "Abbrechen", "git.header.autosaveError" => "Auto-Speichern-Fehler", @@ -206,9 +202,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.wizard.clone.usernameLabel" => "Benutzername (optional)", "git.wizard.clone.tokenLabel" => "Zugriffstoken (optional)", "git.wizard.clone.tokenPlaceholder" => "ghp_… für öffentliche Repos leer lassen", - "git.wizard.clone.anonymousHint" => { - "Leer lassen für anonymes Klonen (nur öffentliche Repos)." - } + "git.wizard.clone.anonymousHint" => "Leer lassen für anonymes Klonen (nur öffentliche Repos).", "git.wizard.clone.sshHint" => "Diese URL erfordert SSH-Schlüssel-Authentifizierung.", "git.wizard.clone.hostDetected" => "Erkannt: {{host}} · {{mode}}", "git.wizard.clone.authMode.token-or-anon" => "Token oder anonym", @@ -217,26 +211,26 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.wizard.clone.submit" => "Klonen", "git.wizard.clone.validationUrl" => "Remote-URL ist erforderlich", "git.wizard.clone.validationDest" => "Zielordner ist erforderlich", - "git.wizard.clone.error.network" => { - "Netzwerkfehler. Verbindung prüfen und erneut versuchen." - } - "git.wizard.clone.error.auth-required" => { - "Dieses Repository erfordert eine Authentifizierung." - } + "git.wizard.clone.validationTokenUsername" => "Benutzername ist erforderlich, wenn ein Token angegeben wird", + "git.wizard.clone.error.clone-network" => "Netzwerkfehler beim Klonen. Verbindung prüfen und erneut versuchen.", + "git.wizard.clone.error.network" => "Netzwerkfehler. Verbindung prüfen und erneut versuchen.", + "git.wizard.clone.error.timeout" => "Zeitüberschreitung beim Klonen. Erneut versuchen oder ein kleineres Repository verwenden.", + "git.wizard.clone.error.auth-required" => "Dieses Repository erfordert eine Authentifizierung.", + "git.wizard.clone.error.auth-failed" => "Authentifizierung fehlgeschlagen. Benutzername und Token prüfen.", + "git.wizard.clone.error.auth-token-invalid" => "Zugriffstoken wurde abgelehnt. Neues Token erstellen und erneut versuchen.", + "git.wizard.clone.error.clone-failed" => "Klonen fehlgeschlagen. Stelle sicher, dass die URL auf ein echtes Repository zeigt.", + "git.wizard.clone.error.clone-target-exists" => "Der Zielordner existiert bereits oder ist nicht leer.", "git.pull.label" => "Pull", "git.pull.tooltip" => "Von origin pullen", - "git.pull.noRemote" => { - "Kein Remote konfiguriert — fügen Sie eines in den Git-Einstellungen hinzu" - } + "git.pull.noRemote" => "Kein Remote konfiguriert — fügen Sie eines in den Git-Einstellungen hinzu", "git.pull.retry" => "Pull erneut versuchen", "git.push.label" => "Push", "git.push.tooltip_one" => "1 Commit zu origin pushen", "git.push.tooltip_other" => "{{count}} Commits zu origin pushen", - "git.push.noRemote" => { - "Kein Remote konfiguriert — fügen Sie eines in den Git-Einstellungen hinzu" - } + "git.push.noRemote" => "Kein Remote konfiguriert — fügen Sie eines in den Git-Einstellungen hinzu", "git.push.upToDate" => "Nichts zu pushen — Sie sind auf dem neuesten Stand", "git.push.retry" => "Push erneut versuchen", + "git.push.rejectedBody" => "Das Remote hat Commits, die Sie noch nicht haben. Pullen Sie zuerst, dann pushen Sie erneut.", "git.push.rejectedDismiss" => "Schließen", "git.push.rejectedPull" => "Jetzt pullen", "git.remote.dismissError" => "Schließen", @@ -250,12 +244,11 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.remote.saveButton" => "Speichern", "git.remote.clearButton" => "Löschen", "git.remote.clearConfirmHeading" => "Origin löschen?", - "git.remote.clearConfirmBody" => { - "Dadurch wird das Origin-Remote aus diesem Repository entfernt." - } + "git.remote.clearConfirmBody" => "Dadurch wird das Origin-Remote aus diesem Repository entfernt.", "git.remote.clearConfirmAction" => "Bestätigen", "git.remote.aheadBehind" => "{{ahead}} voraus · {{behind}} zurück", "git.remote.fetchButton" => "Abrufen", + "git.remote.sshIsoUnsupported" => "SSH-Transport wird von der integrierten Engine nicht unterstützt. Installieren Sie System-Git oder wechseln Sie zu einer HTTPS-Remote-URL.", "git.remote.storedAuthLabel" => "Gespeicherte Anmeldedaten", "git.remote.storedAuth.token" => "Token", "git.remote.storedAuth.ssh" => "SSH-Schlüssel", @@ -267,11 +260,13 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.ssh.heading" => "SSH-Schlüssel", "git.ssh.back" => "Zurück", "git.ssh.cancel" => "Abbrechen", + "git.ssh.isoUnsupported" => "Das aktuelle Remote verwendet SSH, aber die integrierte Engine kann keinen SSH-Transport ausführen. Installieren Sie System-Git oder ändern Sie die Remote-URL in HTTPS.", "git.ssh.emptyList" => "Noch keine SSH-Schlüssel.", "git.ssh.generateAction" => "Neuen erzeugen", "git.ssh.importAction" => "Vorhandenen importieren", "git.ssh.copyPublicKey" => "Öffentlichen Schlüssel kopieren", "git.ssh.copiedHint" => "Kopiert", + "git.ssh.copyUnsupported" => "Zwischenablage nicht verfügbar – diesen Schlüssel bitte manuell kopieren.", "git.ssh.deleteKey" => "{{name}} löschen", "git.ssh.deletePrompt" => "SSH-Schlüssel {{name}} löschen?", "git.ssh.deleteConfirm" => "Löschen", @@ -289,6 +284,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.ssh.validationComment" => "Kommentar ist erforderlich", "git.ssh.validationImportPath" => "Wählen Sie eine private Schlüsseldatei zum Importieren", "git.ssh.providerLink" => "{{host}} SSH-Schlüssel-Einstellungen öffnen", + "git.ssh.genericGuidance" => "Kopiere den öffentlichen Schlüssel und füge ihn in den SSH-Schlüssel-Einstellungen deines Git-Anbieters hinzu.", "git.auth.formLabel" => "Git-Anmeldedaten", "git.auth.heading" => "Bei {{host}} authentifizieren", "git.auth.headingUnknown" => "Bei diesem Remote authentifizieren", @@ -299,12 +295,15 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.auth.tokenLabel" => "Zugriffstoken", "git.auth.tokenPlaceholder" => "ghp_… oder PAT", "git.auth.sshKeyLabel" => "SSH-Schlüssel", + "git.auth.sshNoKeys" => "Keine SSH-Schlüssel verfügbar. Importieren oder generieren Sie zuerst einen in den Git-Einstellungen.", "git.auth.rememberLabel" => "Diese Anmeldedaten für diesen Host merken", "git.auth.rememberHint" => "Diese Anmeldedaten für diesen Host merken", "git.auth.cancel" => "Abbrechen", "git.auth.validationToken" => "Zugriffstoken ist erforderlich", "git.auth.validationSshKey" => "Wählen Sie einen SSH-Schlüssel", "git.auth.error.auth-required" => "Dieses Remote erfordert eine Authentifizierung.", + "git.auth.error.auth-failed" => "Authentifizierung fehlgeschlagen. Überprüfen Sie Ihre Anmeldedaten und versuchen Sie es erneut.", + "git.auth.error.auth-token-invalid" => "Das Zugriffstoken wurde abgelehnt. Generieren Sie ein neues und versuchen Sie es erneut.", "rightPanel.design" => "Design", "rightPanel.code" => "Code", "rightPanel.noSelection" => "Element auswählen", @@ -328,6 +327,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "updater.restartInstall" => "Neustart & Installieren", "updater.installing" => "Installiere...", "updater.releaseDate" => "Veröffentlichungsdatum: {{date}}", + "updater.restartHint" => "Neustart zum Anwenden des Updates. Der Neustart dauert in der Regel 10–15 Sekunden.", "updater.unknownError" => "Unbekannter Updater-Fehler.", "updater.title.checking" => "Suche nach Updates", "updater.title.available" => "Update gefunden", @@ -337,12 +337,8 @@ pub fn lookup(key: &str) -> Option<&'static str> { "updater.subtitle.checking" => "Suche nach der neuesten Version...", "updater.subtitle.available" => "Version {{version}} ist verfügbar.", "updater.subtitle.availableGeneric" => "Eine neue Version ist verfügbar.", - "updater.subtitle.downloading" => { - "Version {{version}} wird im Hintergrund heruntergeladen." - } - "updater.subtitle.downloadingGeneric" => { - "Update-Paket wird im Hintergrund heruntergeladen." - } + "updater.subtitle.downloading" => "Version {{version}} wird im Hintergrund heruntergeladen.", + "updater.subtitle.downloadingGeneric" => "Update-Paket wird im Hintergrund heruntergeladen.", "updater.subtitle.downloaded" => "Version {{version}} wurde heruntergeladen.", "updater.subtitle.downloadedGeneric" => "Das Update wurde heruntergeladen.", "updater.subtitle.error" => "Das Update konnte nicht geprüft oder heruntergeladen werden.", @@ -504,6 +500,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "ai.newChat" => "Neuer Chat", "ai.collapse" => "Einklappen", "ai.tryExample" => "Probiere ein Beispiel zum Gestalten...", + "ai.tipSelectElements" => "Tipp: Wähle Elemente auf der Arbeitsfläche aus, bevor du chattest, um Kontext zu geben.", "ai.generating" => "Generiere...", "ai.designWithAgent" => "Mit Agent gestalten...", "ai.attachImage" => "Bild anhängen", @@ -514,9 +511,11 @@ pub fn lookup(key: &str) -> Option<&'static str> { "ai.searchModels" => "Modelle suchen...", "ai.noModelsFound" => "Keine Modelle gefunden", "ai.quickAction.loginScreen" => "Einen mobilen Anmeldebildschirm gestalten", + "ai.quickAction.loginScreenPrompt" => "Design a modern mobile login screen with email input, password input, login button, and social login options", "ai.quickAction.foodApp" => "Food-App Startseite", "ai.quickAction.foodAppPrompt" => "Generate a well-designed food mobile app homepage", "ai.quickAction.bottomNav" => "Eine untere Navigationsleiste gestalten", + "ai.quickAction.bottomNavPrompt" => "Design a mobile app bottom navigation bar with 5 tabs: Home, Search, Add, Messages, Profile", "ai.quickAction.colorPalette" => "Eine Farbpalette für meine App vorschlagen", "ai.quickAction.colorPalettePrompt" => "Suggest a modern color palette for a pet care app", "ai.startDesigning" => "Start designing with AI", @@ -542,6 +541,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "fileMenu.daysAgo" => "{{count}}d ago", "unsaved.title" => "Unsaved changes", "unsaved.message" => "Save changes to \"{{name}}\"?", + "unsaved.dontSave" => "Don't Save", "code.reactTailwind" => "React + Tailwind", "code.htmlCss" => "HTML + CSS", "code.cssVariables" => "CSS Variables", @@ -564,9 +564,8 @@ pub fn lookup(key: &str) -> Option<&'static str> { "agents.mcpIntegrations" => "MCP-Integrationen im Terminal", "agents.transport" => "Transport", "agents.port" => "Port", - "agents.mcpRestart" => { - "MCP-Integrationen werden nach einem Neustart des Terminals wirksam." - } + "agents.mcpRestart" => "MCP-Integrationen werden nach einem Neustart des Terminals wirksam.", + "agents.mcpReinstallHint" => "Bitte installieren Sie die MCP-Integrationen nach einem OpenPencil-Upgrade erneut, um die Kompatibilität sicherzustellen.", "agents.modelCount" => "{{count}} Modell(e)", "agents.connectionFailed" => "Verbindung fehlgeschlagen", "agents.serverError" => "Serverfehler {{status}}", @@ -609,9 +608,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "settings.systemDesktopOnly" => "Systemeinstellungen sind in der Desktop-App verfügbar.", "settings.envHint" => "Sie können zusätzliche Umgebungsvariablen in {{path}} festlegen.", "builtin.title" => "Integrierte Anbieter", - "builtin.description" => { - "API-Schlüssel direkt konfigurieren — keine CLI-Tools erforderlich." - } + "builtin.description" => "API-Schlüssel direkt konfigurieren — keine CLI-Tools erforderlich.", "builtin.addProvider" => "Anbieter hinzufügen", "builtin.empty" => "Noch keine integrierten Anbieter konfiguriert.", "builtin.displayName" => "Anzeigename", @@ -635,8 +632,11 @@ pub fn lookup(key: &str) -> Option<&'static str> { "builtin.custom" => "Benutzerdefiniert", "builtin.apiKeyBadge" => "API Key", "builtin.viaApiKey" => "über {{name}} API Key", + "builtin.errorProviderNotFound" => "Integrierter Anbieter nicht gefunden. Bitte überprüfen Sie Ihre Einstellungen.", + "builtin.errorApiKeyEmpty" => "API Key ist leer. Bitte fügen Sie Ihren API Key in den Einstellungen hinzu.", "builtin.parallelAgents" => "Parallele Sub-Agenten: {{count}}x (klicken zum Wechseln)", "builtin.baseUrlPlaceholder" => "https://api.example.com/v1", + "builtin.teamDescription" => "Wählen Sie ein Modell für die Designgenerierung. Wenn gesetzt, werden Designaufgaben automatisch an einen spezialisierten Agenten mit diesem Modell delegiert.", "builtin.teamDesignModel" => "Design-Modell", "builtin.teamSelectModel" => "Keins (Einzelagent)", "acp.title" => "ACP Agent", @@ -671,9 +671,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "figma.convertFailed" => "Figma-Datei konnte nicht konvertiert werden", "figma.parsing" => ".fig-Datei wird gelesen...", "figma.converting" => "Knoten werden konvertiert...", - "figma.selectPage" => { - "Diese Datei hat {{count}} Seiten. Wähle, welche importiert werden sollen:" - } + "figma.selectPage" => "Diese Datei hat {{count}} Seiten. Wähle, welche importiert werden sollen:", "figma.layers" => "{{count}} Ebenen", "figma.importAll" => "Alle Seiten importieren", "figma.importComplete" => "Import abgeschlossen!", diff --git a/crates/openpencil-shell-core/src/i18n/en.rs b/crates/openpencil-shell-core/src/i18n/en.rs index a6f2d4a11..cb94581b2 100644 --- a/crates/openpencil-shell-core/src/i18n/en.rs +++ b/crates/openpencil-shell-core/src/i18n/en.rs @@ -49,6 +49,8 @@ pub fn lookup(key: &str) -> Option<&'static str> { "topbar.exitFullscreen" => "Exit fullscreen", "topbar.edited" => "— Edited", "topbar.closeConfirmMessage" => "Do you want to save changes before closing?", + "topbar.closeConfirmDetail" => "Your changes will be lost if you don't save them.", + "topbar.dontSave" => "Don't Save", "topbar.agentsAndMcp" => "Agents & MCP", "topbar.setupAgentsMcp" => "Setup Agents & MCP", "topbar.connected" => "connected", @@ -60,11 +62,10 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.close" => "Close", "git.initializing" => "Initializing repository…", "git.conflict.title" => "Merge conflict", - "git.conflict.description" => { - "Resolve each conflict using the cards below, then apply the merge." - } + "git.conflict.description" => "Resolve each conflict using the cards below, then apply the merge.", "git.conflict.abort" => "Abort merge", "git.conflict.nonOp.title" => "Merge paused on non-.op files", + "git.conflict.nonOp.description" => "The .op merge finished, but other files in this repo are still unresolved. Fix them outside OpenPencil, then continue.", "git.conflict.nonOp.unresolvedHeading_one" => "1 file needs attention", "git.conflict.nonOp.unresolvedHeading_other" => "{{count}} files need attention", "git.conflict.nonOp.continue" => "Continue merge", @@ -74,6 +75,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.conflict.banner.continue" => "Continue", "git.conflict.banner.finalizeError" => "Could not apply: {{message}}", "git.conflict.banner.pollError" => "Status polling paused due to an error: {{message}}", + "git.conflict.banner.reopenMessage" => "Panel reopened mid-merge — in-memory conflict state was lost. Please abort and re-pull.", "git.conflict.list.heading" => "All conflicts", "git.conflict.list.progress" => "{{resolved}} / {{total}} resolved", "git.conflict.list.allResolved" => "All resolved", @@ -137,6 +139,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.commit.placeholder" => "Describe this change…", "git.commit.submitButton" => "Save milestone", "git.commit.saveRequiredTitle" => "Save the document first", + "git.commit.saveRequiredBody" => "You have unsaved changes. Save the document to continue: {{label}}", "git.commit.saveRequiredSave" => "Save", "git.commit.saveRequiredCancel" => "Cancel", "git.header.autosaveError" => "Autosave error", @@ -208,17 +211,15 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.wizard.clone.submit" => "Clone", "git.wizard.clone.validationUrl" => "Remote URL is required", "git.wizard.clone.validationDest" => "Destination folder is required", - "git.wizard.clone.validationTokenUsername" => { - "Username is required when a token is provided" - } + "git.wizard.clone.validationTokenUsername" => "Username is required when a token is provided", + "git.wizard.clone.error.clone-network" => "Network error while cloning. Check your connection and try again.", "git.wizard.clone.error.network" => "Network error. Check your connection and try again.", - "git.wizard.clone.error.timeout" => { - "Clone timed out. Try again or use a smaller repository." - } + "git.wizard.clone.error.timeout" => "Clone timed out. Try again or use a smaller repository.", "git.wizard.clone.error.auth-required" => "Authentication is required for this repository.", - "git.wizard.clone.error.auth-failed" => { - "Authentication failed. Check your username and token." - } + "git.wizard.clone.error.auth-failed" => "Authentication failed. Check your username and token.", + "git.wizard.clone.error.auth-token-invalid" => "The access token was rejected. Generate a new one and try again.", + "git.wizard.clone.error.clone-failed" => "Clone failed. Verify the URL points at a real repository.", + "git.wizard.clone.error.clone-target-exists" => "The destination folder already exists or is not empty.", "git.pull.label" => "Pull", "git.pull.tooltip" => "Pull from origin", "git.pull.noRemote" => "No remote configured — add one in Git settings", @@ -229,6 +230,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.push.noRemote" => "No remote configured — add one in Git settings", "git.push.upToDate" => "Nothing to push — you are up to date", "git.push.retry" => "Retry push", + "git.push.rejectedBody" => "The remote has commits you do not have yet. Pull first, then push again.", "git.push.rejectedDismiss" => "Dismiss", "git.push.rejectedPull" => "Pull now", "git.remote.dismissError" => "Dismiss", @@ -246,6 +248,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.remote.clearConfirmAction" => "Confirm", "git.remote.aheadBehind" => "{{ahead}} ahead · {{behind}} behind", "git.remote.fetchButton" => "Fetch", + "git.remote.sshIsoUnsupported" => "SSH transport is not supported on the built-in engine. Install system git or switch to an HTTPS remote URL.", "git.remote.storedAuthLabel" => "Stored credentials", "git.remote.storedAuth.token" => "Token", "git.remote.storedAuth.ssh" => "SSH key", @@ -257,6 +260,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.ssh.heading" => "SSH keys", "git.ssh.back" => "Back", "git.ssh.cancel" => "Cancel", + "git.ssh.isoUnsupported" => "The current remote uses SSH but the built-in engine cannot perform SSH transport. Install system git or switch the remote URL to HTTPS.", "git.ssh.emptyList" => "No SSH keys yet.", "git.ssh.generateAction" => "Generate new", "git.ssh.importAction" => "Import existing", @@ -280,6 +284,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.ssh.validationComment" => "Comment is required", "git.ssh.validationImportPath" => "Pick a private key file to import", "git.ssh.providerLink" => "Open {{host}} SSH key settings", + "git.ssh.genericGuidance" => "Copy the public key and add it to your Git provider’s SSH key settings.", "git.auth.formLabel" => "Git credentials", "git.auth.heading" => "Authenticate with {{host}}", "git.auth.headingUnknown" => "Authenticate with this remote", @@ -290,18 +295,15 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.auth.tokenLabel" => "Access token", "git.auth.tokenPlaceholder" => "ghp_… or PAT", "git.auth.sshKeyLabel" => "SSH key", - "git.auth.sshNoKeys" => { - "No SSH keys available. Import or generate one in Git settings first." - } + "git.auth.sshNoKeys" => "No SSH keys available. Import or generate one in Git settings first.", "git.auth.rememberLabel" => "Remember this credential for this host", "git.auth.rememberHint" => "Remember this credential for this host", "git.auth.cancel" => "Cancel", "git.auth.validationToken" => "Access token is required", "git.auth.validationSshKey" => "Select an SSH key", "git.auth.error.auth-required" => "Authentication is required for this remote.", - "git.auth.error.auth-failed" => { - "Authentication failed. Check your credentials and try again." - } + "git.auth.error.auth-failed" => "Authentication failed. Check your credentials and try again.", + "git.auth.error.auth-token-invalid" => "The access token was rejected. Generate a new one and try again.", "rightPanel.design" => "Design", "rightPanel.code" => "Code", "rightPanel.noSelection" => "Select an element", @@ -509,9 +511,11 @@ pub fn lookup(key: &str) -> Option<&'static str> { "ai.searchModels" => "Search models...", "ai.noModelsFound" => "No models found", "ai.quickAction.loginScreen" => "Design a mobile login screen", + "ai.quickAction.loginScreenPrompt" => "Design a modern mobile login screen with email input, password input, login button, and social login options", "ai.quickAction.foodApp" => "Food app homepage", "ai.quickAction.foodAppPrompt" => "Generate a well-designed food mobile app homepage", "ai.quickAction.bottomNav" => "Design a bottom navigation bar", + "ai.quickAction.bottomNavPrompt" => "Design a mobile app bottom navigation bar with 5 tabs: Home, Search, Add, Messages, Profile", "ai.quickAction.colorPalette" => "Suggest a color palette for my app", "ai.quickAction.colorPalettePrompt" => "Suggest a modern color palette for a pet care app", "ai.startDesigning" => "Start designing with AI", @@ -537,6 +541,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "fileMenu.daysAgo" => "{{count}}d ago", "unsaved.title" => "Unsaved changes", "unsaved.message" => "Save changes to \"{{name}}\"?", + "unsaved.dontSave" => "Don't Save", "code.reactTailwind" => "React + Tailwind", "code.htmlCss" => "HTML + CSS", "code.cssVariables" => "CSS Variables", @@ -560,6 +565,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "agents.transport" => "Transport", "agents.port" => "Port", "agents.mcpRestart" => "MCP integrations will take effect after restarting the terminal.", + "agents.mcpReinstallHint" => "After upgrading OpenPencil, please reinstall MCP integrations to ensure compatibility.", "agents.modelCount" => "{{count}} model(s)", "agents.connectionFailed" => "Connection failed", "agents.serverError" => "Server error {{status}}", @@ -626,12 +632,11 @@ pub fn lookup(key: &str) -> Option<&'static str> { "builtin.custom" => "Custom", "builtin.apiKeyBadge" => "API Key", "builtin.viaApiKey" => "via {{name}} API Key", - "builtin.errorProviderNotFound" => { - "Built-in provider not found. Please check your settings." - } + "builtin.errorProviderNotFound" => "Built-in provider not found. Please check your settings.", "builtin.errorApiKeyEmpty" => "API key is empty. Please add your API key in settings.", "builtin.parallelAgents" => "Parallel sub-agents: {{count}}x (click to cycle)", "builtin.baseUrlPlaceholder" => "https://api.example.com/v1", + "builtin.teamDescription" => "Select a model for design generation. When set, design tasks are automatically delegated to a specialist agent using this model.", "builtin.teamDesignModel" => "Design Model", "builtin.teamSelectModel" => "None (single agent)", "acp.title" => "ACP Agents", diff --git a/crates/openpencil-shell-core/src/i18n/es.rs b/crates/openpencil-shell-core/src/i18n/es.rs index 8b2265c44..3db216e2e 100644 --- a/crates/openpencil-shell-core/src/i18n/es.rs +++ b/crates/openpencil-shell-core/src/i18n/es.rs @@ -62,8 +62,10 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.close" => "Cerrar", "git.initializing" => "Inicializando repositorio…", "git.conflict.title" => "Conflicto de fusión", + "git.conflict.description" => "Resuelve cada conflicto usando las tarjetas de abajo y luego aplica la fusión.", "git.conflict.abort" => "Abortar fusión", "git.conflict.nonOp.title" => "Fusión pausada en archivos distintos de .op", + "git.conflict.nonOp.description" => "La fusión de .op terminó, pero otros archivos del repositorio siguen sin resolverse. Resuélvelos fuera de OpenPencil y luego continúa.", "git.conflict.nonOp.unresolvedHeading_one" => "1 archivo necesita atención", "git.conflict.nonOp.unresolvedHeading_other" => "{{count}} archivos necesitan atención", "git.conflict.nonOp.continue" => "Continuar fusión", @@ -73,6 +75,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.conflict.banner.continue" => "Continuar", "git.conflict.banner.finalizeError" => "No se pudo aplicar: {{message}}", "git.conflict.banner.pollError" => "Sondeo de estado pausado por un error: {{message}}", + "git.conflict.banner.reopenMessage" => "Panel reabierto durante la fusión — por favor, cancela y vuelve a hacer pull.", "git.conflict.list.heading" => "Todos los conflictos", "git.conflict.list.progress" => "{{resolved}} / {{total}} resueltos", "git.conflict.list.allResolved" => "Todo resuelto", @@ -124,9 +127,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.picker.back" => "Atrás", "git.picker.backClose" => "Cancelar", "git.picker.empty.heading" => "No hay archivos .op en este repositorio", - "git.picker.empty.body" => { - "El panel de Git necesita al menos un archivo .op para funcionar." - } + "git.picker.empty.body" => "El panel de Git necesita al menos un archivo .op para funcionar.", "git.picker.empty.close" => "Cerrar panel", "git.autoBind.confirmHeading" => "{{fileName}} encontrado — ¿abrirlo?", "git.autoBind.openButton" => "Abrir", @@ -138,13 +139,12 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.commit.placeholder" => "Describe este cambio…", "git.commit.submitButton" => "Guardar hito", "git.commit.saveRequiredTitle" => "Guarda el documento primero", + "git.commit.saveRequiredBody" => "Tienes cambios sin guardar. Guarda el documento para continuar: {{label}}", "git.commit.saveRequiredSave" => "Guardar", "git.commit.saveRequiredCancel" => "Cancelar", "git.header.autosaveError" => "Error de auto-guardado", "git.header.autosaveErrorTitle" => "El último auto-guardado falló", - "git.header.authorMissingWarning" => { - "Configura el autor del commit para registrar la atribución" - } + "git.header.authorMissingWarning" => "Configura el autor del commit para registrar la atribución", "git.header.overflowSwitchTracked" => "Cambiar archivo rastreado…", "git.header.overflowClearAuthor" => "Borrar autor del commit", "git.header.overflowCloseRepo" => "Cerrar repositorio", @@ -202,6 +202,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.wizard.clone.usernameLabel" => "Usuario (opcional)", "git.wizard.clone.tokenLabel" => "Token de acceso (opcional)", "git.wizard.clone.tokenPlaceholder" => "ghp_… déjalo vacío para repos públicos", + "git.wizard.clone.anonymousHint" => "Déjalo vacío para clonar de forma anónima (solo repos públicos).", "git.wizard.clone.sshHint" => "Esta URL requiere autenticación con clave SSH.", "git.wizard.clone.hostDetected" => "Detectado: {{host}} · {{mode}}", "git.wizard.clone.authMode.token-or-anon" => "token o anónimo", @@ -210,16 +211,15 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.wizard.clone.submit" => "Clonar", "git.wizard.clone.validationUrl" => "La URL remota es obligatoria", "git.wizard.clone.validationDest" => "La carpeta de destino es obligatoria", - "git.wizard.clone.error.network" => { - "Error de red. Comprueba tu conexión y vuelve a intentarlo." - } + "git.wizard.clone.validationTokenUsername" => "Se necesita un usuario cuando se proporciona un token", + "git.wizard.clone.error.clone-network" => "Error de red al clonar. Comprueba tu conexión y vuelve a intentarlo.", + "git.wizard.clone.error.network" => "Error de red. Comprueba tu conexión y vuelve a intentarlo.", + "git.wizard.clone.error.timeout" => "El clon agotó el tiempo. Inténtalo de nuevo o usa un repositorio más pequeño.", "git.wizard.clone.error.auth-required" => "Este repositorio requiere autenticación.", - "git.wizard.clone.error.auth-failed" => { - "La autenticación falló. Comprueba tu usuario y token." - } - "git.wizard.clone.error.clone-target-exists" => { - "La carpeta de destino ya existe o no está vacía." - } + "git.wizard.clone.error.auth-failed" => "La autenticación falló. Comprueba tu usuario y token.", + "git.wizard.clone.error.auth-token-invalid" => "El token de acceso fue rechazado. Genera uno nuevo y vuelve a intentarlo.", + "git.wizard.clone.error.clone-failed" => "Error al clonar. Verifica que la URL apunte a un repositorio real.", + "git.wizard.clone.error.clone-target-exists" => "La carpeta de destino ya existe o no está vacía.", "git.pull.label" => "Pull", "git.pull.tooltip" => "Pull desde origin", "git.pull.noRemote" => "Sin remoto configurado — añádelo en la configuración de Git", @@ -230,6 +230,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.push.noRemote" => "Sin remoto configurado — añádelo en la configuración de Git", "git.push.upToDate" => "Nada que enviar — estás al día", "git.push.retry" => "Reintentar push", + "git.push.rejectedBody" => "El remoto tiene commits que aún no tienes. Haz pull primero y luego push de nuevo.", "git.push.rejectedDismiss" => "Cerrar", "git.push.rejectedPull" => "Pull ahora", "git.remote.dismissError" => "Cerrar", @@ -247,6 +248,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.remote.clearConfirmAction" => "Confirmar", "git.remote.aheadBehind" => "{{ahead}} adelante · {{behind}} atrás", "git.remote.fetchButton" => "Fetch", + "git.remote.sshIsoUnsupported" => "El motor integrado no admite transporte SSH. Instala el git del sistema o usa una URL remota HTTPS.", "git.remote.storedAuthLabel" => "Credenciales guardadas", "git.remote.storedAuth.token" => "Token", "git.remote.storedAuth.ssh" => "Clave SSH", @@ -258,6 +260,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.ssh.heading" => "Claves SSH", "git.ssh.back" => "Atrás", "git.ssh.cancel" => "Cancelar", + "git.ssh.isoUnsupported" => "El remoto actual usa SSH, pero el motor integrado no puede realizar transporte SSH. Instala el git del sistema o cambia la URL remota a HTTPS.", "git.ssh.emptyList" => "Aún no hay claves SSH.", "git.ssh.generateAction" => "Generar nueva", "git.ssh.importAction" => "Importar existente", @@ -281,6 +284,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.ssh.validationComment" => "El comentario es obligatorio", "git.ssh.validationImportPath" => "Selecciona un archivo de clave privada para importar", "git.ssh.providerLink" => "Abrir los ajustes de claves SSH de {{host}}", + "git.ssh.genericGuidance" => "Copia la clave pública y añádela a los ajustes de claves SSH de tu proveedor de Git.", "git.auth.formLabel" => "Credenciales de Git", "git.auth.heading" => "Autenticar con {{host}}", "git.auth.headingUnknown" => "Autenticar con este remoto", @@ -291,12 +295,15 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.auth.tokenLabel" => "Token de acceso", "git.auth.tokenPlaceholder" => "ghp_… o PAT", "git.auth.sshKeyLabel" => "Clave SSH", + "git.auth.sshNoKeys" => "No hay claves SSH disponibles. Importa o genera una primero en la configuración de Git.", "git.auth.rememberLabel" => "Recordar esta credencial para este host", "git.auth.rememberHint" => "Recordar esta credencial para este host", "git.auth.cancel" => "Cancelar", "git.auth.validationToken" => "El token de acceso es obligatorio", "git.auth.validationSshKey" => "Selecciona una clave SSH", "git.auth.error.auth-required" => "Se requiere autenticación para este remoto.", + "git.auth.error.auth-failed" => "Autenticación fallida. Comprueba tus credenciales y vuelve a intentarlo.", + "git.auth.error.auth-token-invalid" => "El token de acceso fue rechazado. Genera uno nuevo e inténtalo de nuevo.", "rightPanel.design" => "Diseño", "rightPanel.code" => "Código", "rightPanel.noSelection" => "Selecciona un elemento", @@ -320,6 +327,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "updater.restartInstall" => "Reiniciar e instalar", "updater.installing" => "Instalando...", "updater.releaseDate" => "Fecha de publicación: {{date}}", + "updater.restartHint" => "Reinicie para aplicar la actualización. El reinicio suele tardar entre 10 y 15 segundos.", "updater.unknownError" => "Error de actualización desconocido.", "updater.title.checking" => "Buscando actualizaciones", "updater.title.available" => "Actualización encontrada", @@ -329,9 +337,8 @@ pub fn lookup(key: &str) -> Option<&'static str> { "updater.subtitle.checking" => "Buscando la última versión...", "updater.subtitle.available" => "La versión {{version}} está disponible.", "updater.subtitle.availableGeneric" => "Hay una nueva versión disponible.", - "updater.subtitle.downloading" => { - "La versión {{version}} se está descargando en segundo plano." - } + "updater.subtitle.downloading" => "La versión {{version}} se está descargando en segundo plano.", + "updater.subtitle.downloadingGeneric" => "Descargando el paquete de actualización en segundo plano.", "updater.subtitle.downloaded" => "La versión {{version}} se ha descargado.", "updater.subtitle.downloadedGeneric" => "La actualización se ha descargado.", "updater.subtitle.error" => "No se pudo comprobar o descargar la actualización.", @@ -493,6 +500,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "ai.newChat" => "Nueva conversación", "ai.collapse" => "Contraer", "ai.tryExample" => "Pruebe un ejemplo para diseñar...", + "ai.tipSelectElements" => "Consejo: seleccione elementos en el lienzo antes de chatear para dar contexto.", "ai.generating" => "Generando...", "ai.designWithAgent" => "Diseñar con agente...", "ai.attachImage" => "Adjuntar imagen", @@ -503,10 +511,13 @@ pub fn lookup(key: &str) -> Option<&'static str> { "ai.searchModels" => "Buscar modelos...", "ai.noModelsFound" => "No se encontraron modelos", "ai.quickAction.loginScreen" => "Diseñar una pantalla de inicio de sesión móvil", + "ai.quickAction.loginScreenPrompt" => "Diseña una pantalla de inicio de sesión móvil moderna con campo de correo electrónico, campo de contraseña, botón de inicio de sesión y opciones de inicio de sesión social", "ai.quickAction.foodApp" => "Inicio de app de comida", "ai.quickAction.foodAppPrompt" => "Generate a well-designed food mobile app homepage", "ai.quickAction.bottomNav" => "Diseñar una barra de navegación inferior", + "ai.quickAction.bottomNavPrompt" => "Diseña una barra de navegación inferior para aplicación móvil con 5 pestañas: Inicio, Buscar, Agregar, Mensajes, Perfil", "ai.quickAction.colorPalette" => "Sugerir una paleta de colores para mi aplicación", + "ai.quickAction.colorPalettePrompt" => "Sugiere una paleta de colores moderna para una aplicación de cuidado de mascotas", "ai.startDesigning" => "Start designing with AI", "ai.maximize" => "Maximize", "ai.restore" => "Restore", @@ -530,6 +541,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "fileMenu.daysAgo" => "{{count}}d ago", "unsaved.title" => "Unsaved changes", "unsaved.message" => "Save changes to \"{{name}}\"?", + "unsaved.dontSave" => "Don't Save", "code.reactTailwind" => "React + Tailwind", "code.htmlCss" => "HTML + CSS", "code.cssVariables" => "CSS Variables", @@ -553,6 +565,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "agents.transport" => "Transporte", "agents.port" => "Puerto", "agents.mcpRestart" => "Las integraciones MCP se aplicarán tras reiniciar la terminal.", + "agents.mcpReinstallHint" => "Después de actualizar OpenPencil, reinstale las integraciones MCP para garantizar la compatibilidad.", "agents.modelCount" => "{{count}} modelo(s)", "agents.connectionFailed" => "Error de conexión", "agents.serverError" => "Error del servidor {{status}}", @@ -592,11 +605,10 @@ pub fn lookup(key: &str) -> Option<&'static str> { "settings.images" => "Images", "settings.system" => "Sistema", "settings.autoUpdateDesc" => "Buscar automáticamente nuevas versiones al iniciar", + "settings.systemDesktopOnly" => "La configuración del sistema está disponible en la aplicación de escritorio.", "settings.envHint" => "Puedes establecer variables de entorno adicionales en {{path}}.", "builtin.title" => "Proveedores integrados", - "builtin.description" => { - "Configure las claves API directamente — sin herramientas CLI necesarias." - } + "builtin.description" => "Configure las claves API directamente — sin herramientas CLI necesarias.", "builtin.addProvider" => "Agregar proveedor", "builtin.empty" => "Aún no hay proveedores integrados configurados.", "builtin.displayName" => "Nombre visible", @@ -620,8 +632,11 @@ pub fn lookup(key: &str) -> Option<&'static str> { "builtin.custom" => "Personalizado", "builtin.apiKeyBadge" => "API Key", "builtin.viaApiKey" => "mediante API Key de {{name}}", + "builtin.errorProviderNotFound" => "Proveedor integrado no encontrado. Por favor, revise su configuración.", + "builtin.errorApiKeyEmpty" => "La API key está vacía. Por favor, agregue su API key en la configuración.", "builtin.parallelAgents" => "Sub-agentes en paralelo: {{count}}x (clic para cambiar)", "builtin.baseUrlPlaceholder" => "https://api.example.com/v1", + "builtin.teamDescription" => "Selecciona un modelo para la generación de diseño. Una vez configurado, las tareas de diseño se delegan automáticamente a un agente especializado que usa este modelo.", "builtin.teamDesignModel" => "Modelo de diseño", "builtin.teamSelectModel" => "Ninguno (agente único)", "acp.title" => "ACP Agent", @@ -645,6 +660,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "acp.notConnected" => "No conectado", "acp.connect" => "Conectar", "acp.disconnect" => "Desconectar", + "acp.localDesktopOnly" => "Los Agent locales solo están disponibles en la aplicación de escritorio.", "figma.title" => "Importar desde Figma", "figma.dropFile" => "Suelte un archivo .fig aquí", "figma.orBrowse" => "o haga clic para explorar", diff --git a/crates/openpencil-shell-core/src/i18n/fr.rs b/crates/openpencil-shell-core/src/i18n/fr.rs index 776782a05..4aa222aa5 100644 --- a/crates/openpencil-shell-core/src/i18n/fr.rs +++ b/crates/openpencil-shell-core/src/i18n/fr.rs @@ -48,12 +48,8 @@ pub fn lookup(key: &str) -> Option<&'static str> { "topbar.fullscreen" => "Plein écran", "topbar.exitFullscreen" => "Quitter le plein écran", "topbar.edited" => "— Modifié", - "topbar.closeConfirmMessage" => { - "Voulez-vous enregistrer les modifications avant de fermer ?" - } - "topbar.closeConfirmDetail" => { - "Vos modifications seront perdues si vous ne les enregistrez pas." - } + "topbar.closeConfirmMessage" => "Voulez-vous enregistrer les modifications avant de fermer ?", + "topbar.closeConfirmDetail" => "Vos modifications seront perdues si vous ne les enregistrez pas.", "topbar.dontSave" => "Ne pas enregistrer", "topbar.agentsAndMcp" => "Agents & MCP", "topbar.setupAgentsMcp" => "Configurer Agents & MCP", @@ -66,8 +62,10 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.close" => "Fermer", "git.initializing" => "Initialisation du dépôt…", "git.conflict.title" => "Conflit de fusion", + "git.conflict.description" => "Résolvez chaque conflit via les cartes ci-dessous, puis appliquez la fusion.", "git.conflict.abort" => "Annuler la fusion", "git.conflict.nonOp.title" => "Fusion en pause sur des fichiers non .op", + "git.conflict.nonOp.description" => "La fusion des fichiers .op est terminée, mais d'autres fichiers du dépôt ne sont pas résolus. Résolvez-les en dehors d'OpenPencil, puis continuez.", "git.conflict.nonOp.unresolvedHeading_one" => "1 fichier nécessite une action", "git.conflict.nonOp.unresolvedHeading_other" => "{{count}} fichiers nécessitent une action", "git.conflict.nonOp.continue" => "Continuer la fusion", @@ -75,6 +73,9 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.conflict.banner.progress" => "Résolu {{resolved}} / {{total}}", "git.conflict.banner.apply" => "Appliquer la fusion", "git.conflict.banner.continue" => "Continuer", + "git.conflict.banner.finalizeError" => "Impossible d'appliquer : {{message}}", + "git.conflict.banner.pollError" => "Sondage d'état suspendu en raison d'une erreur : {{message}}", + "git.conflict.banner.reopenMessage" => "Panneau rouvert en cours de fusion — veuillez abandonner et re-tirer.", "git.conflict.list.heading" => "Tous les conflits", "git.conflict.list.progress" => "{{resolved}} / {{total}} résolus", "git.conflict.list.allResolved" => "Tout résolu", @@ -98,7 +99,9 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.error.dismiss" => "Ignorer", "git.error.retry" => "Réessayer", "git.error.title" => "Une erreur est survenue", + "git.empty.heading" => "Pas encore d'historique de version", "git.empty.optional" => "Git est facultatif — vous pouvez ignorer", + "git.empty.requireSavedFile" => "Enregistrez d'abord le fichier .op pour activer l'historique", "git.empty.newCard" => "Nouveau", "git.empty.newCardDescription" => "Créer un historique local", "git.empty.openCard" => "Ouvrir", @@ -124,21 +127,30 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.picker.back" => "Retour", "git.picker.backClose" => "Annuler", "git.picker.empty.heading" => "Aucun fichier .op dans ce dépôt", + "git.picker.empty.body" => "Le panneau Git a besoin d'au moins un fichier .op pour fonctionner.", "git.picker.empty.close" => "Fermer le panneau", + "git.autoBind.confirmHeading" => "{{fileName}} trouvé — l'ouvrir ?", "git.autoBind.openButton" => "Ouvrir", "git.autoBind.dismissButton" => "Ignorer", + "git.relativeTime.justNow" => "à l'instant", "git.relativeTime.minutesAgo" => "il y a {{count}}m", "git.relativeTime.hoursAgo" => "il y a {{count}}h", "git.relativeTime.daysAgo" => "il y a {{count}}j", "git.commit.placeholder" => "Décrire ce changement…", "git.commit.submitButton" => "Enregistrer le jalon", + "git.commit.saveRequiredTitle" => "Enregistrez d'abord le document", + "git.commit.saveRequiredBody" => "Vous avez des modifications non enregistrées. Enregistrez le document pour continuer : {{label}}", "git.commit.saveRequiredSave" => "Enregistrer", "git.commit.saveRequiredCancel" => "Annuler", + "git.header.autosaveError" => "Erreur d'auto-sauvegarde", "git.header.autosaveErrorTitle" => "La dernière auto-sauvegarde a échoué", + "git.header.authorMissingWarning" => "Définissez l'auteur du commit pour l'attribution", "git.header.overflowSwitchTracked" => "Changer de fichier suivi…", + "git.header.overflowClearAuthor" => "Effacer l'auteur du commit", "git.header.overflowCloseRepo" => "Fermer le dépôt", "git.header.overflowRemoteSettings" => "Paramètres du remote…", "git.header.overflowSshKeys" => "Clés SSH…", + "git.header.overflowMoreActions" => "Plus d'actions", "git.history.empty" => "Aucun historique", "git.history.autosaveGroup_one" => "1 auto-sauvegarde", "git.history.autosaveGroup_other" => "{{count}} auto-sauvegardes", @@ -181,24 +193,33 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.branch.conflictDisabled" => "Terminez la fusion avant de changer de branche", "git.branch.noCommits" => "Aucun commit pour le moment", "git.wizard.clone.heading" => "Cloner un dépôt distant", - "git.wizard.clone.subheading" => { - "Choisissez une URL distante et un dossier de destination." - } + "git.wizard.clone.subheading" => "Choisissez une URL distante et un dossier de destination.", "git.wizard.clone.urlLabel" => "URL distante", "git.wizard.clone.urlPlaceholder" => "https://github.com/owner/repo.git", "git.wizard.clone.destLabel" => "Dossier de destination", "git.wizard.clone.destPlaceholder" => "/chemin/du/clone", "git.wizard.clone.destPickButton" => "Parcourir…", + "git.wizard.clone.usernameLabel" => "Nom d'utilisateur (optionnel)", + "git.wizard.clone.tokenLabel" => "Jeton d'accès (optionnel)", "git.wizard.clone.tokenPlaceholder" => "ghp_… laisser vide pour les dépôts publics", + "git.wizard.clone.anonymousHint" => "Laissez vide pour cloner anonymement (dépôts publics uniquement).", "git.wizard.clone.sshHint" => "Cette URL nécessite une authentification par clé SSH.", "git.wizard.clone.hostDetected" => "Détecté : {{host}} · {{mode}}", "git.wizard.clone.authMode.token-or-anon" => "jeton ou anonyme", "git.wizard.clone.authMode.ssh" => "clé SSH", "git.wizard.clone.cancel" => "Annuler", "git.wizard.clone.submit" => "Cloner", + "git.wizard.clone.validationUrl" => "L'URL distante est requise", "git.wizard.clone.validationDest" => "Le dossier de destination est requis", + "git.wizard.clone.validationTokenUsername" => "Un nom d'utilisateur est requis lorsqu'un jeton est fourni", + "git.wizard.clone.error.clone-network" => "Erreur réseau lors du clonage. Vérifiez votre connexion et réessayez.", "git.wizard.clone.error.network" => "Erreur réseau. Vérifiez votre connexion et réessayez.", + "git.wizard.clone.error.timeout" => "Le clonage a expiré. Réessayez ou utilisez un dépôt plus petit.", "git.wizard.clone.error.auth-required" => "Ce dépôt nécessite une authentification.", + "git.wizard.clone.error.auth-failed" => "Échec de l'authentification. Vérifiez votre nom d'utilisateur et votre jeton.", + "git.wizard.clone.error.auth-token-invalid" => "Le jeton d'accès a été refusé. Générez-en un nouveau et réessayez.", + "git.wizard.clone.error.clone-failed" => "Échec du clonage. Vérifiez que l'URL pointe vers un dépôt réel.", + "git.wizard.clone.error.clone-target-exists" => "Le dossier de destination existe déjà ou n'est pas vide.", "git.pull.label" => "Pull", "git.pull.tooltip" => "Pull depuis origin", "git.pull.noRemote" => "Aucun remote configuré — ajoutez-en un dans les paramètres Git", @@ -209,6 +230,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.push.noRemote" => "Aucun remote configuré — ajoutez-en un dans les paramètres Git", "git.push.upToDate" => "Rien à pousser — vous êtes à jour", "git.push.retry" => "Réessayer le push", + "git.push.rejectedBody" => "Le remote a des commits que vous n'avez pas encore. Faites un pull d'abord, puis un push.", "git.push.rejectedDismiss" => "Fermer", "git.push.rejectedPull" => "Pull maintenant", "git.remote.dismissError" => "Fermer", @@ -216,6 +238,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.remote.settingsHeading" => "Remote", "git.remote.back" => "Retour", "git.remote.cancel" => "Annuler", + "git.remote.emptyNoOrigin" => "Aucun remote configuré pour l'instant. En ajouter un :", "git.remote.urlLabel" => "URL origin", "git.remote.urlPlaceholder" => "https://github.com/owner/repo.git", "git.remote.saveButton" => "Enregistrer", @@ -225,6 +248,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.remote.clearConfirmAction" => "Confirmer", "git.remote.aheadBehind" => "{{ahead}} en avance · {{behind}} en retard", "git.remote.fetchButton" => "Fetch", + "git.remote.sshIsoUnsupported" => "Le transport SSH n'est pas pris en charge par le moteur intégré. Installez git système ou passez à une URL HTTPS.", "git.remote.storedAuthLabel" => "Identifiants enregistrés", "git.remote.storedAuth.token" => "Jeton", "git.remote.storedAuth.ssh" => "Clé SSH", @@ -236,6 +260,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.ssh.heading" => "Clés SSH", "git.ssh.back" => "Retour", "git.ssh.cancel" => "Annuler", + "git.ssh.isoUnsupported" => "Le remote actuel utilise SSH, mais le moteur intégré ne peut pas effectuer de transport SSH. Installez git système ou passez l'URL du remote en HTTPS.", "git.ssh.emptyList" => "Aucune clé SSH pour le moment.", "git.ssh.generateAction" => "Générer une nouvelle", "git.ssh.importAction" => "Importer une existante", @@ -255,19 +280,30 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.ssh.importPathPlaceholder" => "/path/to/id_ed25519", "git.ssh.importBrowse" => "Parcourir…", "git.ssh.importSubmit" => "Importer", + "git.ssh.validationHost" => "L'hôte est obligatoire", "git.ssh.validationComment" => "Le commentaire est obligatoire", "git.ssh.validationImportPath" => "Choisissez un fichier de clé privée à importer", "git.ssh.providerLink" => "Ouvrir les paramètres de clés SSH {{host}}", + "git.ssh.genericGuidance" => "Copiez la clé publique et ajoutez-la aux paramètres de clés SSH de votre fournisseur Git.", "git.auth.formLabel" => "Identifiants Git", + "git.auth.heading" => "S'authentifier auprès de {{host}}", + "git.auth.headingUnknown" => "S'authentifier auprès de ce remote", + "git.auth.modeToggleLabel" => "Type d'identifiant", "git.auth.modeToken" => "Jeton", "git.auth.modeSsh" => "SSH", + "git.auth.usernameLabel" => "Nom d'utilisateur (optionnel)", + "git.auth.tokenLabel" => "Jeton d'accès", "git.auth.tokenPlaceholder" => "ghp_… ou PAT", "git.auth.sshKeyLabel" => "Clé SSH", + "git.auth.sshNoKeys" => "Aucune clé SSH disponible. Importez-en ou générez-en une d'abord dans les paramètres Git.", "git.auth.rememberLabel" => "Mémoriser ces identifiants pour cet hôte", "git.auth.rememberHint" => "Mémoriser ces identifiants pour cet hôte", "git.auth.cancel" => "Annuler", + "git.auth.validationToken" => "Le jeton d'accès est requis", "git.auth.validationSshKey" => "Sélectionnez une clé SSH", "git.auth.error.auth-required" => "Ce remote nécessite une authentification.", + "git.auth.error.auth-failed" => "Échec de l'authentification. Vérifiez vos identifiants et réessayez.", + "git.auth.error.auth-token-invalid" => "Le jeton d'accès a été rejeté. Générez-en un nouveau et réessayez.", "rightPanel.design" => "Design", "rightPanel.code" => "Code", "rightPanel.noSelection" => "Sélectionnez un élément", @@ -291,6 +327,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "updater.restartInstall" => "Redémarrer et installer", "updater.installing" => "Installation...", "updater.releaseDate" => "Date de publication : {{date}}", + "updater.restartHint" => "Redémarrez pour appliquer la mise à jour. Le redémarrage prend généralement 10 à 15 secondes.", "updater.unknownError" => "Erreur de mise à jour inconnue.", "updater.title.checking" => "Recherche de mises à jour", "updater.title.available" => "Mise à jour disponible", @@ -300,13 +337,13 @@ pub fn lookup(key: &str) -> Option<&'static str> { "updater.subtitle.checking" => "Recherche de la dernière version...", "updater.subtitle.available" => "La version {{version}} est disponible.", "updater.subtitle.availableGeneric" => "Une nouvelle version est disponible.", - "updater.subtitle.downloadingGeneric" => { - "Téléchargement du paquet de mise à jour en arrière-plan." - } + "updater.subtitle.downloading" => "La version {{version}} est en cours de téléchargement en arrière-plan.", + "updater.subtitle.downloadingGeneric" => "Téléchargement du paquet de mise à jour en arrière-plan.", "updater.subtitle.downloaded" => "La version {{version}} a été téléchargée.", "updater.subtitle.downloadedGeneric" => "La mise à jour a été téléchargée.", "updater.subtitle.error" => "Impossible de vérifier ou de télécharger la mise à jour.", "layers.title" => "Calques", + "layers.empty" => "Aucun calque pour le moment. Utilisez la barre d’outils pour dessiner des formes.", "layerMenu.groupSelection" => "Grouper la sélection", "layerMenu.createComponent" => "Créer un composant", "layerMenu.detachComponent" => "Détacher le composant", @@ -328,11 +365,13 @@ pub fn lookup(key: &str) -> Option<&'static str> { "fill.stops" => "Arrêts", "fill.angle" => "Angle", "image.title" => "Image", + "image.fit" => "Mode d'ajustement", "image.fill" => "Remplir", "image.fitMode" => "Ajuster", "image.crop" => "Recadrer", "image.tile" => "Mosaïque", "image.clickToUpload" => "Cliquez pour télécharger", + "image.changeImage" => "Changer l'image", "image.adjustments" => "Réglages", "image.exposure" => "Exposition", "image.contrast" => "Contraste", @@ -461,6 +500,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "ai.newChat" => "Nouvelle conversation", "ai.collapse" => "Réduire", "ai.tryExample" => "Essayez un exemple de design...", + "ai.tipSelectElements" => "Astuce : sélectionnez des éléments sur le canevas avant de discuter pour fournir du contexte.", "ai.generating" => "Génération...", "ai.designWithAgent" => "Concevoir avec un agent...", "ai.attachImage" => "Joindre une image", @@ -471,9 +511,13 @@ pub fn lookup(key: &str) -> Option<&'static str> { "ai.searchModels" => "Rechercher des modèles...", "ai.noModelsFound" => "Aucun modèle trouvé", "ai.quickAction.loginScreen" => "Concevoir un écran de connexion mobile", + "ai.quickAction.loginScreenPrompt" => "Concevez un écran de connexion mobile moderne avec un champ e-mail, un champ mot de passe, un bouton de connexion et des options de connexion sociale", + "ai.quickAction.foodApp" => "Page d'accueil appli cuisine", "ai.quickAction.foodAppPrompt" => "Generate a well-designed food mobile app homepage", "ai.quickAction.bottomNav" => "Concevoir une barre de navigation inférieure", + "ai.quickAction.bottomNavPrompt" => "Concevez une barre de navigation inférieure pour application mobile avec 5 onglets : Accueil, Recherche, Ajouter, Messages, Profil", "ai.quickAction.colorPalette" => "Suggérer une palette de couleurs pour mon application", + "ai.quickAction.colorPalettePrompt" => "Suggérez une palette de couleurs moderne pour une application de soins pour animaux", "ai.startDesigning" => "Start designing with AI", "ai.maximize" => "Maximize", "ai.restore" => "Restore", @@ -485,6 +529,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "fileMenu.openFile" => "Open file...", "fileMenu.save" => "Save", "fileMenu.saveAs" => "Save as...", + "fileMenu.exportImage" => "Exporter l'image...", "fileMenu.recentFiles" => "Recent files", "fileMenu.clearHistory" => "Clear history", "fileMenu.noRecentFiles" => "No recent files", @@ -496,6 +541,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "fileMenu.daysAgo" => "{{count}}d ago", "unsaved.title" => "Unsaved changes", "unsaved.message" => "Save changes to \"{{name}}\"?", + "unsaved.dontSave" => "Don't Save", "code.reactTailwind" => "React + Tailwind", "code.htmlCss" => "HTML + CSS", "code.cssVariables" => "CSS Variables", @@ -518,9 +564,8 @@ pub fn lookup(key: &str) -> Option<&'static str> { "agents.mcpIntegrations" => "Intégrations MCP dans le terminal", "agents.transport" => "Transport", "agents.port" => "Port", - "agents.mcpRestart" => { - "Les intégrations MCP prendront effet après le redémarrage du terminal." - } + "agents.mcpRestart" => "Les intégrations MCP prendront effet après le redémarrage du terminal.", + "agents.mcpReinstallHint" => "Après la mise à jour d'OpenPencil, veuillez réinstaller les intégrations MCP pour assurer la compatibilité.", "agents.modelCount" => "{{count}} modèle(s)", "agents.connectionFailed" => "Échec de la connexion", "agents.serverError" => "Erreur serveur {{status}}", @@ -552,6 +597,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "agents.notInstalled" => "Non installé", "agents.install" => "Installer", "agents.installing" => "Installation...", + "agents.installFailed" => "Échec de l'installation", "agents.viewDocs" => "Docs", "settings.title" => "Paramètres", "settings.agents" => "Agents", @@ -559,10 +605,13 @@ pub fn lookup(key: &str) -> Option<&'static str> { "settings.images" => "Images", "settings.system" => "Système", "settings.autoUpdateDesc" => "Vérifier automatiquement les nouvelles versions au démarrage", + "settings.systemDesktopOnly" => "Les paramètres système sont disponibles dans l'application de bureau.", + "settings.envHint" => "Vous pouvez définir des variables d'environnement supplémentaires dans {{path}}.", "builtin.title" => "Fournisseurs intégrés", "builtin.description" => "Configurez les clés API directement — aucun outil CLI requis.", "builtin.addProvider" => "Ajouter un fournisseur", "builtin.empty" => "Aucun fournisseur intégré configuré.", + "builtin.displayName" => "Nom d'affichage", "builtin.displayNamePlaceholder" => "ex. Ma clé Anthropic", "builtin.provider" => "Fournisseur", "builtin.region" => "Région", @@ -583,8 +632,11 @@ pub fn lookup(key: &str) -> Option<&'static str> { "builtin.custom" => "Personnalisé", "builtin.apiKeyBadge" => "API Key", "builtin.viaApiKey" => "via API Key {{name}}", + "builtin.errorProviderNotFound" => "Fournisseur intégré introuvable. Veuillez vérifier vos paramètres.", + "builtin.errorApiKeyEmpty" => "La clé API est vide. Veuillez ajouter votre clé API dans les paramètres.", "builtin.parallelAgents" => "Sous-agents parallèles : {{count}}x (cliquez pour changer)", "builtin.baseUrlPlaceholder" => "https://api.example.com/v1", + "builtin.teamDescription" => "Sélectionnez un modèle pour la génération de design. Une fois défini, les tâches de design sont automatiquement déléguées à un agent spécialisé utilisant ce modèle.", "builtin.teamDesignModel" => "Modèle de design", "builtin.teamSelectModel" => "Aucun (agent unique)", "acp.title" => "ACP Agent", @@ -600,6 +652,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "acp.commandPlaceholder" => "/usr/bin/myagent", "acp.args" => "Arguments", "acp.argsPlaceholder" => "--stdio", + "acp.env" => "Variables d'environnement", "acp.envPlaceholder" => "KEY=VALUE (une par ligne)", "acp.url" => "URL", "acp.urlPlaceholder" => "ws://localhost:8100", @@ -607,21 +660,18 @@ pub fn lookup(key: &str) -> Option<&'static str> { "acp.notConnected" => "Non connecté", "acp.connect" => "Connecter", "acp.disconnect" => "Déconnecter", + "acp.localDesktopOnly" => "Les Agent locaux sont disponibles uniquement dans l'application de bureau.", "figma.title" => "Importer depuis Figma", "figma.dropFile" => "Déposez un fichier .fig ici", "figma.orBrowse" => "ou cliquez pour parcourir", - "figma.exportTip" => { - "Exporter depuis Figma : Fichier → Enregistrer une copie locale (.fig)" - } + "figma.exportTip" => "Exporter depuis Figma : Fichier → Enregistrer une copie locale (.fig)", "figma.selectFigFile" => "Veuillez sélectionner un fichier .fig", "figma.noPages" => "Aucune page trouvée dans le fichier .fig", "figma.parseFailed" => "Échec de l’analyse du fichier .fig", "figma.convertFailed" => "Échec de la conversion du fichier Figma", "figma.parsing" => "Analyse du fichier .fig...", "figma.converting" => "Conversion des nœuds...", - "figma.selectPage" => { - "Ce fichier contient {{count}} pages. Sélectionnez celles à importer :" - } + "figma.selectPage" => "Ce fichier contient {{count}} pages. Sélectionnez celles à importer :", "figma.layers" => "{{count}} calques", "figma.importAll" => "Importer toutes les pages", "figma.importComplete" => "Importation terminée !", diff --git a/crates/openpencil-shell-core/src/i18n/hi.rs b/crates/openpencil-shell-core/src/i18n/hi.rs index 5787f2984..6004a25f6 100644 --- a/crates/openpencil-shell-core/src/i18n/hi.rs +++ b/crates/openpencil-shell-core/src/i18n/hi.rs @@ -65,6 +65,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.conflict.description" => "नीचे दिए कार्ड्स से प्रत्येक विरोध हल करें, फिर मर्ज लागू करें।", "git.conflict.abort" => "विलय रद्द करें", "git.conflict.nonOp.title" => ".op से भिन्न फ़ाइलों पर विलय रोका गया", + "git.conflict.nonOp.description" => ".op विलय पूरा हो गया है, लेकिन रेपो की अन्य फ़ाइलें अभी भी अनसुलझी हैं। उन्हें OpenPencil के बाहर हल करें, फिर जारी रखें।", "git.conflict.nonOp.unresolvedHeading_one" => "1 फ़ाइल को ध्यान चाहिए", "git.conflict.nonOp.unresolvedHeading_other" => "{{count}} फ़ाइलों को ध्यान चाहिए", "git.conflict.nonOp.continue" => "विलय जारी रखें", @@ -74,6 +75,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.conflict.banner.continue" => "जारी रखें", "git.conflict.banner.finalizeError" => "लागू नहीं हो सका: {{message}}", "git.conflict.banner.pollError" => "एक त्रुटि के कारण स्थिति जाँच रुकी हुई है: {{message}}", + "git.conflict.banner.reopenMessage" => "पैनल मर्ज के बीच में फिर से खोला गया — कृपया रद्द करें और फिर से pull करें।", "git.conflict.list.heading" => "सभी संघर्ष", "git.conflict.list.progress" => "{{resolved}} / {{total}} हल किए", "git.conflict.list.allResolved" => "सब हल हो गया", @@ -137,9 +139,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.commit.placeholder" => "इस बदलाव का वर्णन करें…", "git.commit.submitButton" => "माइलस्टोन सहेजें", "git.commit.saveRequiredTitle" => "पहले दस्तावेज़ सहेजें", - "git.commit.saveRequiredBody" => { - "आपके पास सहेजे न गए बदलाव हैं। जारी रखने के लिए दस्तावेज़ सहेजें: {{label}}" - } + "git.commit.saveRequiredBody" => "आपके पास सहेजे न गए बदलाव हैं। जारी रखने के लिए दस्तावेज़ सहेजें: {{label}}", "git.commit.saveRequiredSave" => "सहेजें", "git.commit.saveRequiredCancel" => "रद्द करें", "git.header.autosaveError" => "ऑटो-सेव त्रुटि", @@ -202,9 +202,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.wizard.clone.usernameLabel" => "उपयोगकर्ता नाम (वैकल्पिक)", "git.wizard.clone.tokenLabel" => "एक्सेस टोकन (वैकल्पिक)", "git.wizard.clone.tokenPlaceholder" => "ghp_… सार्वजनिक के लिए खाली छोड़ें", - "git.wizard.clone.anonymousHint" => { - "गुमनाम रूप से क्लोन करने के लिए खाली छोड़ें (केवल सार्वजनिक रिपॉज़िटरी)।" - } + "git.wizard.clone.anonymousHint" => "गुमनाम रूप से क्लोन करने के लिए खाली छोड़ें (केवल सार्वजनिक रिपॉज़िटरी)।", "git.wizard.clone.sshHint" => "इस URL के लिए SSH कुंजी प्रमाणीकरण आवश्यक है।", "git.wizard.clone.hostDetected" => "पहचाना गया: {{host}} · {{mode}}", "git.wizard.clone.authMode.token-or-anon" => "टोकन या गुमनाम", @@ -214,12 +212,13 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.wizard.clone.validationUrl" => "रिमोट URL आवश्यक है", "git.wizard.clone.validationDest" => "गंतव्य फ़ोल्डर आवश्यक है", "git.wizard.clone.validationTokenUsername" => "टोकन प्रदान करते समय उपयोगकर्ता नाम आवश्यक है", + "git.wizard.clone.error.clone-network" => "क्लोन करते समय नेटवर्क त्रुटि। अपना कनेक्शन जांचें और फिर से प्रयास करें।", "git.wizard.clone.error.network" => "नेटवर्क त्रुटि। अपना कनेक्शन जांचें और फिर से प्रयास करें।", + "git.wizard.clone.error.timeout" => "क्लोन का समय समाप्त हो गया। फिर से प्रयास करें या छोटी रिपॉज़िटरी का उपयोग करें।", "git.wizard.clone.error.auth-required" => "इस रिपॉज़िटरी के लिए प्रमाणीकरण आवश्यक है।", "git.wizard.clone.error.auth-failed" => "प्रमाणीकरण विफल। अपना उपयोगकर्ता नाम और टोकन जांचें।", - "git.wizard.clone.error.auth-token-invalid" => { - "एक्सेस टोकन अस्वीकृत। नया टोकन बनाएं और फिर से प्रयास करें।" - } + "git.wizard.clone.error.auth-token-invalid" => "एक्सेस टोकन अस्वीकृत। नया टोकन बनाएं और फिर से प्रयास करें।", + "git.wizard.clone.error.clone-failed" => "क्लोन विफल। सत्यापित करें कि URL किसी वास्तविक रिपॉज़िटरी की ओर इशारा करता है।", "git.wizard.clone.error.clone-target-exists" => "गंतव्य फ़ोल्डर पहले से मौजूद है या खाली नहीं है।", "git.pull.label" => "पुल", "git.pull.tooltip" => "origin से पुल", @@ -249,6 +248,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.remote.clearConfirmAction" => "पुष्टि करें", "git.remote.aheadBehind" => "{{ahead}} आगे · {{behind}} पीछे", "git.remote.fetchButton" => "फ़ेच", + "git.remote.sshIsoUnsupported" => "बिल्ट-इन इंजन SSH ट्रांसपोर्ट का समर्थन नहीं करता। सिस्टम git इंस्टॉल करें या HTTPS रिमोट URL पर स्विच करें।", "git.remote.storedAuthLabel" => "सहेजे गए क्रेडेंशियल", "git.remote.storedAuth.token" => "टोकन", "git.remote.storedAuth.ssh" => "SSH कुंजी", @@ -260,6 +260,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.ssh.heading" => "SSH कुंजियाँ", "git.ssh.back" => "वापस", "git.ssh.cancel" => "रद्द करें", + "git.ssh.isoUnsupported" => "वर्तमान रिमोट SSH का उपयोग कर रहा है, लेकिन बिल्ट-इन इंजन SSH ट्रांसपोर्ट नहीं कर सकता। सिस्टम git इंस्टॉल करें या रिमोट URL को HTTPS में बदलें।", "git.ssh.emptyList" => "अभी तक कोई SSH कुंजी नहीं।", "git.ssh.generateAction" => "नई बनाएँ", "git.ssh.importAction" => "मौजूदा आयात करें", @@ -283,9 +284,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.ssh.validationComment" => "टिप्पणी आवश्यक है", "git.ssh.validationImportPath" => "आयात करने के लिए निजी कुंजी फ़ाइल चुनें", "git.ssh.providerLink" => "{{host}} SSH कुंजी सेटिंग्स खोलें", - "git.ssh.genericGuidance" => { - "सार्वजनिक कुंजी कॉपी करें और अपने Git प्रदाता की SSH कुंजी सेटिंग्स में जोड़ें।" - } + "git.ssh.genericGuidance" => "सार्वजनिक कुंजी कॉपी करें और अपने Git प्रदाता की SSH कुंजी सेटिंग्स में जोड़ें।", "git.auth.formLabel" => "Git क्रेडेंशियल", "git.auth.heading" => "{{host}} के साथ प्रमाणीकरण", "git.auth.headingUnknown" => "इस रिमोट के साथ प्रमाणीकरण", @@ -304,9 +303,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.auth.validationSshKey" => "एक SSH कुंजी चुनें", "git.auth.error.auth-required" => "इस रिमोट के लिए प्रमाणीकरण आवश्यक है।", "git.auth.error.auth-failed" => "प्रमाणीकरण विफल। अपने क्रेडेंशियल जांचें और पुनः प्रयास करें।", - "git.auth.error.auth-token-invalid" => { - "एक्सेस टोकन अस्वीकृत किया गया। नया बनाएं और फिर से प्रयास करें।" - } + "git.auth.error.auth-token-invalid" => "एक्सेस टोकन अस्वीकृत किया गया। नया बनाएं और फिर से प्रयास करें।", "rightPanel.design" => "डिज़ाइन", "rightPanel.code" => "कोड", "rightPanel.noSelection" => "एक तत्व चुनें", @@ -330,9 +327,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "updater.restartInstall" => "पुनः आरंभ करें और इंस्टॉल करें", "updater.installing" => "इंस्टॉल हो रहा है...", "updater.releaseDate" => "रिलीज़ तिथि: {{date}}", - "updater.restartHint" => { - "अपडेट लागू करने के लिए पुनः आरंभ करें। पुनः लॉन्च में आमतौर पर 10-15 सेकंड लगते हैं।" - } + "updater.restartHint" => "अपडेट लागू करने के लिए पुनः आरंभ करें। पुनः लॉन्च में आमतौर पर 10-15 सेकंड लगते हैं।", "updater.unknownError" => "अज्ञात अपडेटर त्रुटि।", "updater.title.checking" => "अपडेट की जाँच हो रही है", "updater.title.available" => "अपडेट मिला", @@ -516,9 +511,11 @@ pub fn lookup(key: &str) -> Option<&'static str> { "ai.searchModels" => "मॉडल खोजें...", "ai.noModelsFound" => "कोई मॉडल नहीं मिला", "ai.quickAction.loginScreen" => "मोबाइल लॉगिन स्क्रीन डिज़ाइन करें", + "ai.quickAction.loginScreenPrompt" => "ईमेल इनपुट, पासवर्ड इनपुट, लॉगिन बटन और सोशल लॉगिन विकल्पों के साथ एक आधुनिक मोबाइल लॉगिन स्क्रीन डिज़ाइन करें", "ai.quickAction.foodApp" => "फ़ूड ऐप होमपेज", "ai.quickAction.foodAppPrompt" => "Generate a well-designed food mobile app homepage", "ai.quickAction.bottomNav" => "बॉटम नेविगेशन बार डिज़ाइन करें", + "ai.quickAction.bottomNavPrompt" => "5 टैब के साथ एक मोबाइल ऐप बॉटम नेविगेशन बार डिज़ाइन करें: होम, खोजें, जोड़ें, संदेश, प्रोफ़ाइल", "ai.quickAction.colorPalette" => "मेरे ऐप के लिए कलर पैलेट सुझाएँ", "ai.quickAction.colorPalettePrompt" => "एक पेट केयर ऐप के लिए आधुनिक कलर पैलेट सुझाएँ", "ai.startDesigning" => "Start designing with AI", @@ -544,6 +541,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "fileMenu.daysAgo" => "{{count}}d ago", "unsaved.title" => "Unsaved changes", "unsaved.message" => "Save changes to \"{{name}}\"?", + "unsaved.dontSave" => "Don't Save", "code.reactTailwind" => "React + Tailwind", "code.htmlCss" => "HTML + CSS", "code.cssVariables" => "CSS Variables", @@ -567,6 +565,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "agents.transport" => "ट्रांसपोर्ट", "agents.port" => "पोर्ट", "agents.mcpRestart" => "MCP इंटीग्रेशन टर्मिनल पुनः आरंभ करने के बाद प्रभावी होंगे।", + "agents.mcpReinstallHint" => "OpenPencil अपग्रेड करने के बाद, संगतता सुनिश्चित करने के लिए कृपया MCP इंटीग्रेशन पुनः इंस्टॉल करें।", "agents.modelCount" => "{{count}} मॉडल", "agents.connectionFailed" => "कनेक्शन विफल", "agents.serverError" => "सर्वर त्रुटि {{status}}", @@ -637,6 +636,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "builtin.errorApiKeyEmpty" => "API key खाली है। कृपया सेटिंग्स में अपनी API key जोड़ें।", "builtin.parallelAgents" => "समानांतर सब-एजेंट: {{count}}x (बदलने के लिए क्लिक करें)", "builtin.baseUrlPlaceholder" => "https://api.example.com/v1", + "builtin.teamDescription" => "डिज़ाइन जनरेशन के लिए एक मॉडल चुनें। सेट करने पर, डिज़ाइन कार्य स्वचालित रूप से इस मॉडल का उपयोग करने वाले विशेषज्ञ एजेंट को सौंपे जाते हैं।", "builtin.teamDesignModel" => "डिज़ाइन मॉडल", "builtin.teamSelectModel" => "कोई नहीं (एकल एजेंट)", "acp.title" => "ACP Agent", diff --git a/crates/openpencil-shell-core/src/i18n/id.rs b/crates/openpencil-shell-core/src/i18n/id.rs index 8df0873eb..45007a034 100644 --- a/crates/openpencil-shell-core/src/i18n/id.rs +++ b/crates/openpencil-shell-core/src/i18n/id.rs @@ -62,8 +62,10 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.close" => "Tutup", "git.initializing" => "Menginisialisasi repositori…", "git.conflict.title" => "Konflik merge", + "git.conflict.description" => "Selesaikan setiap konflik menggunakan kartu di bawah, lalu terapkan penggabungan.", "git.conflict.abort" => "Batalkan merge", "git.conflict.nonOp.title" => "Penggabungan dijeda pada file non-.op", + "git.conflict.nonOp.description" => "Penggabungan .op selesai, tetapi file lain di repo masih belum terselesaikan. Selesaikan di luar OpenPencil, lalu lanjutkan.", "git.conflict.nonOp.unresolvedHeading_one" => "1 file perlu perhatian", "git.conflict.nonOp.unresolvedHeading_other" => "{{count}} file perlu perhatian", "git.conflict.nonOp.continue" => "Lanjutkan penggabungan", @@ -73,6 +75,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.conflict.banner.continue" => "Lanjutkan", "git.conflict.banner.finalizeError" => "Tidak dapat diterapkan: {{message}}", "git.conflict.banner.pollError" => "Polling status dijeda karena kesalahan: {{message}}", + "git.conflict.banner.reopenMessage" => "Panel dibuka kembali saat penggabungan — silakan batalkan dan pull ulang.", "git.conflict.list.heading" => "Semua konflik", "git.conflict.list.progress" => "{{resolved}} / {{total}} diselesaikan", "git.conflict.list.allResolved" => "Semua selesai", @@ -98,9 +101,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.error.title" => "Terjadi kesalahan", "git.empty.heading" => "Belum ada riwayat versi", "git.empty.optional" => "Git opsional — boleh dilewati", - "git.empty.requireSavedFile" => { - "Simpan file .op terlebih dahulu untuk mengaktifkan riwayat" - } + "git.empty.requireSavedFile" => "Simpan file .op terlebih dahulu untuk mengaktifkan riwayat", "git.empty.newCard" => "Baru", "git.empty.newCardDescription" => "Buat riwayat lokal", "git.empty.openCard" => "Buka", @@ -138,6 +139,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.commit.placeholder" => "Jelaskan perubahan ini…", "git.commit.submitButton" => "Simpan milestone", "git.commit.saveRequiredTitle" => "Simpan dokumen dulu", + "git.commit.saveRequiredBody" => "Anda memiliki perubahan yang belum disimpan. Simpan dokumen untuk melanjutkan: {{label}}", "git.commit.saveRequiredSave" => "Simpan", "git.commit.saveRequiredCancel" => "Batal", "git.header.autosaveError" => "Error auto-save", @@ -209,19 +211,15 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.wizard.clone.submit" => "Klon", "git.wizard.clone.validationUrl" => "URL jarak jauh wajib diisi", "git.wizard.clone.validationDest" => "Folder tujuan wajib diisi", - "git.wizard.clone.validationTokenUsername" => { - "Nama pengguna wajib diisi saat token disediakan" - } - "git.wizard.clone.error.network" => { - "Kesalahan jaringan. Periksa koneksi Anda dan coba lagi." - } + "git.wizard.clone.validationTokenUsername" => "Nama pengguna wajib diisi saat token disediakan", + "git.wizard.clone.error.clone-network" => "Kesalahan jaringan saat klon. Periksa koneksi Anda dan coba lagi.", + "git.wizard.clone.error.network" => "Kesalahan jaringan. Periksa koneksi Anda dan coba lagi.", + "git.wizard.clone.error.timeout" => "Klon kehabisan waktu. Coba lagi atau gunakan repositori yang lebih kecil.", "git.wizard.clone.error.auth-required" => "Repositori ini memerlukan autentikasi.", - "git.wizard.clone.error.auth-failed" => { - "Autentikasi gagal. Periksa nama pengguna dan token Anda." - } - "git.wizard.clone.error.clone-target-exists" => { - "Folder tujuan sudah ada atau tidak kosong." - } + "git.wizard.clone.error.auth-failed" => "Autentikasi gagal. Periksa nama pengguna dan token Anda.", + "git.wizard.clone.error.auth-token-invalid" => "Token akses ditolak. Buat token baru dan coba lagi.", + "git.wizard.clone.error.clone-failed" => "Klon gagal. Pastikan URL menunjuk ke repositori yang sebenarnya.", + "git.wizard.clone.error.clone-target-exists" => "Folder tujuan sudah ada atau tidak kosong.", "git.pull.label" => "Pull", "git.pull.tooltip" => "Pull dari origin", "git.pull.noRemote" => "Tidak ada remote yang dikonfigurasi — tambahkan di pengaturan Git", @@ -232,6 +230,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.push.noRemote" => "Tidak ada remote yang dikonfigurasi — tambahkan di pengaturan Git", "git.push.upToDate" => "Tidak ada yang di-push — Anda sudah up-to-date", "git.push.retry" => "Coba push lagi", + "git.push.rejectedBody" => "Remote memiliki commit yang belum Anda miliki. Pull terlebih dahulu, lalu push lagi.", "git.push.rejectedDismiss" => "Tutup", "git.push.rejectedPull" => "Pull sekarang", "git.remote.dismissError" => "Tutup", @@ -249,6 +248,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.remote.clearConfirmAction" => "Konfirmasi", "git.remote.aheadBehind" => "{{ahead}} di depan · {{behind}} di belakang", "git.remote.fetchButton" => "Fetch", + "git.remote.sshIsoUnsupported" => "Transport SSH tidak didukung oleh mesin bawaan. Instal git sistem atau gunakan URL remote HTTPS.", "git.remote.storedAuthLabel" => "Kredensial tersimpan", "git.remote.storedAuth.token" => "Token", "git.remote.storedAuth.ssh" => "Kunci SSH", @@ -260,6 +260,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.ssh.heading" => "Kunci SSH", "git.ssh.back" => "Kembali", "git.ssh.cancel" => "Batal", + "git.ssh.isoUnsupported" => "Remote saat ini menggunakan SSH, tetapi mesin bawaan tidak dapat melakukan transport SSH. Instal git sistem atau ubah URL remote menjadi HTTPS.", "git.ssh.emptyList" => "Belum ada kunci SSH.", "git.ssh.generateAction" => "Buat baru", "git.ssh.importAction" => "Impor yang ada", @@ -283,6 +284,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.ssh.validationComment" => "Komentar wajib diisi", "git.ssh.validationImportPath" => "Pilih file kunci privat untuk diimpor", "git.ssh.providerLink" => "Buka pengaturan kunci SSH {{host}}", + "git.ssh.genericGuidance" => "Salin kunci publik dan tambahkan ke pengaturan kunci SSH penyedia Git Anda.", "git.auth.formLabel" => "Kredensial Git", "git.auth.heading" => "Autentikasi dengan {{host}}", "git.auth.headingUnknown" => "Autentikasi dengan remote ini", @@ -293,6 +295,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.auth.tokenLabel" => "Token akses", "git.auth.tokenPlaceholder" => "ghp_… atau PAT", "git.auth.sshKeyLabel" => "Kunci SSH", + "git.auth.sshNoKeys" => "Tidak ada kunci SSH yang tersedia. Impor atau buat satu di pengaturan Git terlebih dahulu.", "git.auth.rememberLabel" => "Ingat kredensial ini untuk host ini", "git.auth.rememberHint" => "Ingat kredensial ini untuk host ini", "git.auth.cancel" => "Batal", @@ -324,6 +327,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "updater.restartInstall" => "Mulai Ulang & Pasang", "updater.installing" => "Memasang...", "updater.releaseDate" => "Tanggal rilis: {{date}}", + "updater.restartHint" => "Mulai ulang untuk menerapkan pembaruan. Proses mulai ulang biasanya memakan waktu 10-15 detik.", "updater.unknownError" => "Kesalahan pembaruan tidak diketahui.", "updater.title.checking" => "Memeriksa pembaruan", "updater.title.available" => "Pembaruan ditemukan", @@ -334,9 +338,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "updater.subtitle.available" => "Versi {{version}} tersedia.", "updater.subtitle.availableGeneric" => "Versi baru tersedia.", "updater.subtitle.downloading" => "Versi {{version}} sedang diunduh di latar belakang.", - "updater.subtitle.downloadingGeneric" => { - "Paket pembaruan sedang diunduh di latar belakang." - } + "updater.subtitle.downloadingGeneric" => "Paket pembaruan sedang diunduh di latar belakang.", "updater.subtitle.downloaded" => "Versi {{version}} telah diunduh.", "updater.subtitle.downloadedGeneric" => "Pembaruan telah diunduh.", "updater.subtitle.error" => "Tidak dapat memeriksa atau mengunduh pembaruan.", @@ -432,9 +434,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "textLayout.autoWidth" => "Auto L", "textLayout.autoWidthDesc" => "Lebar Otomatis — teks meluas secara horizontal", "textLayout.autoHeight" => "Auto T", - "textLayout.autoHeightDesc" => { - "Tinggi Otomatis — lebar tetap, tinggi menyesuaikan otomatis" - } + "textLayout.autoHeightDesc" => "Tinggi Otomatis — lebar tetap, tinggi menyesuaikan otomatis", "textLayout.fixed" => "Tetap", "textLayout.fixedDesc" => "Ukuran Tetap — lebar dan tinggi tetap", "textLayout.fillWidth" => "Isi Lebar", @@ -500,9 +500,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "ai.newChat" => "Chat baru", "ai.collapse" => "Ciutkan", "ai.tryExample" => "Coba contoh untuk mendesain...", - "ai.tipSelectElements" => { - "Tips: Pilih elemen di canvas sebelum chat untuk memberikan konteks." - } + "ai.tipSelectElements" => "Tips: Pilih elemen di canvas sebelum chat untuk memberikan konteks.", "ai.generating" => "Membuat...", "ai.designWithAgent" => "Desain dengan Agent...", "ai.attachImage" => "Lampirkan gambar", @@ -513,10 +511,13 @@ pub fn lookup(key: &str) -> Option<&'static str> { "ai.searchModels" => "Cari model...", "ai.noModelsFound" => "Model tidak ditemukan", "ai.quickAction.loginScreen" => "Desain layar login mobile", + "ai.quickAction.loginScreenPrompt" => "Desain layar login mobile modern dengan input email, input kata sandi, tombol login, dan opsi login sosial", "ai.quickAction.foodApp" => "Beranda aplikasi makanan", "ai.quickAction.foodAppPrompt" => "Generate a well-designed food mobile app homepage", "ai.quickAction.bottomNav" => "Desain bilah navigasi bawah", + "ai.quickAction.bottomNavPrompt" => "Desain bilah navigasi bawah aplikasi mobile dengan 5 tab: Beranda, Cari, Tambah, Pesan, Profil", "ai.quickAction.colorPalette" => "Sarankan palet warna untuk aplikasi saya", + "ai.quickAction.colorPalettePrompt" => "Sarankan palet warna modern untuk aplikasi perawatan hewan peliharaan", "ai.startDesigning" => "Start designing with AI", "ai.maximize" => "Maximize", "ai.restore" => "Restore", @@ -540,6 +541,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "fileMenu.daysAgo" => "{{count}}d ago", "unsaved.title" => "Unsaved changes", "unsaved.message" => "Save changes to \"{{name}}\"?", + "unsaved.dontSave" => "Don't Save", "code.reactTailwind" => "React + Tailwind", "code.htmlCss" => "HTML + CSS", "code.cssVariables" => "CSS Variables", @@ -563,6 +565,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "agents.transport" => "Transport", "agents.port" => "Port", "agents.mcpRestart" => "Integrasi MCP akan berlaku setelah terminal dimulai ulang.", + "agents.mcpReinstallHint" => "Setelah memperbarui OpenPencil, silakan instal ulang integrasi MCP untuk memastikan kompatibilitas.", "agents.modelCount" => "{{count}} model", "agents.connectionFailed" => "Koneksi gagal", "agents.serverError" => "Kesalahan server {{status}}", @@ -629,9 +632,11 @@ pub fn lookup(key: &str) -> Option<&'static str> { "builtin.custom" => "Kustom", "builtin.apiKeyBadge" => "API Key", "builtin.viaApiKey" => "melalui API Key {{name}}", + "builtin.errorProviderNotFound" => "Penyedia bawaan tidak ditemukan. Silakan periksa pengaturan Anda.", "builtin.errorApiKeyEmpty" => "API Key kosong. Silakan tambahkan API Key di pengaturan.", "builtin.parallelAgents" => "Sub-agen paralel: {{count}}x (klik untuk berganti)", "builtin.baseUrlPlaceholder" => "https://api.example.com/v1", + "builtin.teamDescription" => "Pilih model untuk pembuatan desain. Jika diatur, tugas desain akan otomatis didelegasikan ke agen spesialis yang menggunakan model ini.", "builtin.teamDesignModel" => "Model Desain", "builtin.teamSelectModel" => "Tidak ada (agen tunggal)", "acp.title" => "ACP Agent", diff --git a/crates/openpencil-shell-core/src/i18n/ja.rs b/crates/openpencil-shell-core/src/i18n/ja.rs index 857bf41e9..04cf9ce19 100644 --- a/crates/openpencil-shell-core/src/i18n/ja.rs +++ b/crates/openpencil-shell-core/src/i18n/ja.rs @@ -62,8 +62,10 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.close" => "閉じる", "git.initializing" => "リポジトリを初期化中…", "git.conflict.title" => "マージコンフリクト", + "git.conflict.description" => "以下のカードで各コンフリクトを解決してから、マージを適用してください。", "git.conflict.abort" => "マージを中止", "git.conflict.nonOp.title" => ".op 以外のファイルによりマージが一時停止しました", + "git.conflict.nonOp.description" => ".op ファイルのマージは完了しましたが、このリポジトリ内の他のファイルがまだ未解決です。OpenPencil の外で解決してから続行してください。", "git.conflict.nonOp.unresolvedHeading_one" => "1 個のファイルに対応が必要", "git.conflict.nonOp.unresolvedHeading_other" => "{{count}} 個のファイルに対応が必要", "git.conflict.nonOp.continue" => "マージを続行", @@ -72,9 +74,8 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.conflict.banner.apply" => "マージを適用", "git.conflict.banner.continue" => "続行", "git.conflict.banner.finalizeError" => "適用できませんでした: {{message}}", - "git.conflict.banner.pollError" => { - "エラーのためステータスポーリングを一時停止中: {{message}}" - } + "git.conflict.banner.pollError" => "エラーのためステータスポーリングを一時停止中: {{message}}", + "git.conflict.banner.reopenMessage" => "マージ中にパネルが再開されました — 中止して再度プルしてください。", "git.conflict.list.heading" => "すべての競合", "git.conflict.list.progress" => "{{resolved}} / {{total}} 解決済み", "git.conflict.list.allResolved" => "すべて解決済み", @@ -138,6 +139,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.commit.placeholder" => "この変更を説明…", "git.commit.submitButton" => "マイルストーンとして保存", "git.commit.saveRequiredTitle" => "まず文書を保存してください", + "git.commit.saveRequiredBody" => "未保存の変更があります。続行するには文書を保存してください: {{label}}", "git.commit.saveRequiredSave" => "保存", "git.commit.saveRequiredCancel" => "キャンセル", "git.header.autosaveError" => "自動保存エラー", @@ -200,9 +202,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.wizard.clone.usernameLabel" => "ユーザー名(任意)", "git.wizard.clone.tokenLabel" => "アクセストークン(任意)", "git.wizard.clone.tokenPlaceholder" => "ghp_… 公開リポジトリは空欄可", - "git.wizard.clone.anonymousHint" => { - "空欄のままにすると匿名でクローンします(公開リポジトリのみ)。" - } + "git.wizard.clone.anonymousHint" => "空欄のままにすると匿名でクローンします(公開リポジトリのみ)。", "git.wizard.clone.sshHint" => "この URL には SSH 鍵認証が必要です。", "git.wizard.clone.hostDetected" => "検出: {{host}} · {{mode}}", "git.wizard.clone.authMode.token-or-anon" => "トークンまたは匿名", @@ -211,13 +211,15 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.wizard.clone.submit" => "クローン", "git.wizard.clone.validationUrl" => "リモート URL を入力してください", "git.wizard.clone.validationDest" => "コピー先フォルダを選択してください", - "git.wizard.clone.validationTokenUsername" => { - "トークンを指定する場合はユーザー名が必要です" - } - "git.wizard.clone.error.network" => { - "ネットワークエラー。接続を確認して再試行してください。" - } + "git.wizard.clone.validationTokenUsername" => "トークンを指定する場合はユーザー名が必要です", + "git.wizard.clone.error.clone-network" => "クローン中にネットワークエラーが発生しました。接続を確認して再試行してください。", + "git.wizard.clone.error.network" => "ネットワークエラー。接続を確認して再試行してください。", + "git.wizard.clone.error.timeout" => "クローンがタイムアウトしました。再試行するか、より小さなリポジトリを使用してください。", "git.wizard.clone.error.auth-required" => "このリポジトリは認証が必要です。", + "git.wizard.clone.error.auth-failed" => "認証に失敗しました。ユーザー名とトークンを確認してください。", + "git.wizard.clone.error.auth-token-invalid" => "アクセストークンが拒否されました。新しいトークンを生成して再試行してください。", + "git.wizard.clone.error.clone-failed" => "クローンに失敗しました。URL が実在するリポジトリを指していることを確認してください。", + "git.wizard.clone.error.clone-target-exists" => "コピー先フォルダが既に存在するか、空ではありません。", "git.pull.label" => "プル", "git.pull.tooltip" => "origin からプル", "git.pull.noRemote" => "リモートが設定されていません — Git 設定で追加してください", @@ -228,6 +230,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.push.noRemote" => "リモートが設定されていません — Git 設定で追加してください", "git.push.upToDate" => "プッシュする内容はありません — 最新の状態です", "git.push.retry" => "プッシュを再試行", + "git.push.rejectedBody" => "リモートに未取得のコミットがあります。先にプルしてから再度プッシュしてください。", "git.push.rejectedDismiss" => "閉じる", "git.push.rejectedPull" => "今すぐプル", "git.remote.dismissError" => "閉じる", @@ -245,6 +248,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.remote.clearConfirmAction" => "確認", "git.remote.aheadBehind" => "{{ahead}} 先行 · {{behind}} 遅延", "git.remote.fetchButton" => "Fetch", + "git.remote.sshIsoUnsupported" => "内蔵エンジンは SSH トランスポートをサポートしていません。システム git をインストールするか、HTTPS リモート URL に切り替えてください。", "git.remote.storedAuthLabel" => "保存済み認証情報", "git.remote.storedAuth.token" => "トークン", "git.remote.storedAuth.ssh" => "SSH 鍵", @@ -256,14 +260,13 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.ssh.heading" => "SSH 鍵", "git.ssh.back" => "戻る", "git.ssh.cancel" => "キャンセル", + "git.ssh.isoUnsupported" => "現在のリモートは SSH を使用していますが、内蔵エンジンは SSH トランスポートを実行できません。システム git をインストールするか、リモート URL を HTTPS に変更してください。", "git.ssh.emptyList" => "SSH 鍵はまだありません。", "git.ssh.generateAction" => "新しく生成", "git.ssh.importAction" => "既存のものをインポート", "git.ssh.copyPublicKey" => "公開鍵をコピー", "git.ssh.copiedHint" => "コピーしました", - "git.ssh.copyUnsupported" => { - "クリップボードを利用できません。この鍵を手動でコピーしてください。" - } + "git.ssh.copyUnsupported" => "クリップボードを利用できません。この鍵を手動でコピーしてください。", "git.ssh.deleteKey" => "{{name}} を削除", "git.ssh.deletePrompt" => "SSH 鍵 {{name}} を削除しますか?", "git.ssh.deleteConfirm" => "削除", @@ -281,9 +284,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.ssh.validationComment" => "コメントを入力してください", "git.ssh.validationImportPath" => "インポートする秘密鍵ファイルを選択してください", "git.ssh.providerLink" => "{{host}} の SSH 鍵設定を開く", - "git.ssh.genericGuidance" => { - "公開鍵をコピーして、Git プロバイダの SSH 鍵設定に追加してください。" - } + "git.ssh.genericGuidance" => "公開鍵をコピーして、Git プロバイダの SSH 鍵設定に追加してください。", "git.auth.formLabel" => "Git 認証情報", "git.auth.heading" => "{{host}} に対して認証", "git.auth.headingUnknown" => "このリモートに対して認証", @@ -294,15 +295,15 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.auth.tokenLabel" => "アクセストークン", "git.auth.tokenPlaceholder" => "ghp_… または PAT", "git.auth.sshKeyLabel" => "SSH キー", + "git.auth.sshNoKeys" => "利用可能な SSH キーがありません。先に Git 設定でインポートまたは生成してください。", "git.auth.rememberLabel" => "このホストの認証情報を記憶する", "git.auth.rememberHint" => "このホストの認証情報を記憶する", "git.auth.cancel" => "キャンセル", "git.auth.validationToken" => "アクセストークンは必須です", "git.auth.validationSshKey" => "SSH キーを選択してください", "git.auth.error.auth-required" => "このリモートには認証が必要です。", - "git.auth.error.auth-failed" => { - "認証に失敗しました。認証情報を確認して再度お試しください。" - } + "git.auth.error.auth-failed" => "認証に失敗しました。認証情報を確認して再度お試しください。", + "git.auth.error.auth-token-invalid" => "アクセストークンが拒否されました。新しいトークンを生成してから再試行してください。", "rightPanel.design" => "デザイン", "rightPanel.code" => "コード", "rightPanel.noSelection" => "要素を選択してください", @@ -326,9 +327,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "updater.restartInstall" => "再起動してインストール", "updater.installing" => "インストール中...", "updater.releaseDate" => "リリース日:{{date}}", - "updater.restartHint" => { - "再起動してアップデートを適用します。再起動には通常 10〜15 秒かかります。" - } + "updater.restartHint" => "再起動してアップデートを適用します。再起動には通常 10〜15 秒かかります。", "updater.unknownError" => "不明なアップデートエラーです。", "updater.title.checking" => "アップデートを確認中", "updater.title.available" => "アップデートが見つかりました", @@ -338,9 +337,8 @@ pub fn lookup(key: &str) -> Option<&'static str> { "updater.subtitle.checking" => "最新リリースを確認中...", "updater.subtitle.available" => "バージョン {{version}} が利用可能です。", "updater.subtitle.availableGeneric" => "新しいバージョンが利用可能です。", - "updater.subtitle.downloading" => { - "バージョン {{version}} をバックグラウンドでダウンロード中。" - } + "updater.subtitle.downloading" => "バージョン {{version}} をバックグラウンドでダウンロード中。", + "updater.subtitle.downloadingGeneric" => "アップデートパッケージをバックグラウンドでダウンロード中。", "updater.subtitle.downloaded" => "バージョン {{version}} のダウンロードが完了しました。", "updater.subtitle.downloadedGeneric" => "アップデートのダウンロードが完了しました。", "updater.subtitle.error" => "アップデートの確認またはダウンロードができませんでした。", @@ -502,6 +500,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "ai.newChat" => "新しいチャット", "ai.collapse" => "折りたたむ", "ai.tryExample" => "サンプルを試してデザイン...", + "ai.tipSelectElements" => "ヒント:チャットの前にキャンバス上の要素を選択するとコンテキストが提供されます。", "ai.generating" => "生成中...", "ai.designWithAgent" => "Agent でデザイン...", "ai.attachImage" => "画像を添付", @@ -512,10 +511,13 @@ pub fn lookup(key: &str) -> Option<&'static str> { "ai.searchModels" => "モデルを検索...", "ai.noModelsFound" => "モデルが見つかりません", "ai.quickAction.loginScreen" => "モバイルログイン画面をデザイン", + "ai.quickAction.loginScreenPrompt" => "メール入力、パスワード入力、ログインボタン、ソーシャルログインオプションを含む、モダンなモバイルログイン画面をデザインしてください", "ai.quickAction.foodApp" => "フードアプリのホームページ", "ai.quickAction.foodAppPrompt" => "Generate a well-designed food mobile app homepage", "ai.quickAction.bottomNav" => "ボトムナビゲーションバーをデザイン", + "ai.quickAction.bottomNavPrompt" => "ホーム、検索、追加、メッセージ、プロフィールの 5 つのタブを含むモバイルアプリのボトムナビゲーションバーをデザインしてください", "ai.quickAction.colorPalette" => "アプリのカラーパレットを提案", + "ai.quickAction.colorPalettePrompt" => "ペットケアアプリ向けのモダンなカラーパレットを提案してください", "ai.startDesigning" => "Start designing with AI", "ai.maximize" => "Maximize", "ai.restore" => "Restore", @@ -539,6 +541,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "fileMenu.daysAgo" => "{{count}}d ago", "unsaved.title" => "Unsaved changes", "unsaved.message" => "Save changes to \"{{name}}\"?", + "unsaved.dontSave" => "Don't Save", "code.reactTailwind" => "React + Tailwind", "code.htmlCss" => "HTML + CSS", "code.cssVariables" => "CSS Variables", @@ -562,6 +565,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "agents.transport" => "トランスポート", "agents.port" => "ポート", "agents.mcpRestart" => "MCP 連携はターミナルの再起動後に有効になります。", + "agents.mcpReinstallHint" => "OpenPencil のバージョンアップ後、互換性を確保するため MCP 統合を再インストールしてください。", "agents.modelCount" => "{{count}} 個のモデル", "agents.connectionFailed" => "接続に失敗しました", "agents.serverError" => "サーバーエラー {{status}}", @@ -628,12 +632,11 @@ pub fn lookup(key: &str) -> Option<&'static str> { "builtin.custom" => "カスタム", "builtin.apiKeyBadge" => "API Key", "builtin.viaApiKey" => "{{name}} API Key 経由", - "builtin.errorProviderNotFound" => { - "組み込みプロバイダーが見つかりません。設定を確認してください。" - } + "builtin.errorProviderNotFound" => "組み込みプロバイダーが見つかりません。設定を確認してください。", "builtin.errorApiKeyEmpty" => "API キーが空です。設定で API キーを追加してください。", "builtin.parallelAgents" => "並列サブエージェント:{{count}}x(クリックで切替)", "builtin.baseUrlPlaceholder" => "https://api.example.com/v1", + "builtin.teamDescription" => "デザイン生成用のモデルを選択します。設定すると、デザインタスクはこのモデルを使用する専門エージェントに自動的に委任されます。", "builtin.teamDesignModel" => "デザインモデル", "builtin.teamSelectModel" => "なし(シングルエージェント)", "acp.title" => "ACP Agent", @@ -668,6 +671,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "figma.convertFailed" => "Figma ファイルの変換に失敗しました", "figma.parsing" => ".fig ファイルを解析中...", "figma.converting" => "ノードを変換中...", + "figma.selectPage" => "このファイルには {{count}} ページあります。インポートするページを選択してください:", "figma.layers" => "{{count}} レイヤー", "figma.importAll" => "すべてのページをインポート", "figma.importComplete" => "インポート完了!", diff --git a/crates/openpencil-shell-core/src/i18n/ko.rs b/crates/openpencil-shell-core/src/i18n/ko.rs index 55ff73997..3d1e2767e 100644 --- a/crates/openpencil-shell-core/src/i18n/ko.rs +++ b/crates/openpencil-shell-core/src/i18n/ko.rs @@ -65,6 +65,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.conflict.description" => "아래 카드로 각 충돌을 해결한 다음 병합을 적용하세요.", "git.conflict.abort" => "병합 중단", "git.conflict.nonOp.title" => ".op 이외 파일로 병합이 일시 중지됨", + "git.conflict.nonOp.description" => ".op 파일 병합은 완료되었지만 저장소의 다른 파일이 아직 해결되지 않았습니다. OpenPencil 외부에서 해결한 후 계속하세요.", "git.conflict.nonOp.unresolvedHeading_one" => "1개 파일에 조치가 필요함", "git.conflict.nonOp.unresolvedHeading_other" => "{{count}}개 파일에 조치가 필요함", "git.conflict.nonOp.continue" => "병합 계속", @@ -74,6 +75,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.conflict.banner.continue" => "계속", "git.conflict.banner.finalizeError" => "적용 실패: {{message}}", "git.conflict.banner.pollError" => "오류로 인해 상태 폴링이 일시 중지됨: {{message}}", + "git.conflict.banner.reopenMessage" => "패널이 병합 중 다시 열렸습니다 — 중단하고 다시 pull 하세요.", "git.conflict.list.heading" => "모든 충돌", "git.conflict.list.progress" => "{{resolved}} / {{total}} 해결됨", "git.conflict.list.allResolved" => "모두 해결됨", @@ -137,6 +139,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.commit.placeholder" => "이 변경 설명…", "git.commit.submitButton" => "마일스톤으로 저장", "git.commit.saveRequiredTitle" => "문서를 먼저 저장하세요", + "git.commit.saveRequiredBody" => "저장되지 않은 변경 사항이 있습니다. 계속하려면 문서를 저장하세요: {{label}}", "git.commit.saveRequiredSave" => "저장", "git.commit.saveRequiredCancel" => "취소", "git.header.autosaveError" => "자동 저장 오류", @@ -209,14 +212,14 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.wizard.clone.validationUrl" => "원격 URL을 입력하세요", "git.wizard.clone.validationDest" => "대상 폴더를 선택하세요", "git.wizard.clone.validationTokenUsername" => "토큰을 제공할 때 사용자 이름이 필요합니다", + "git.wizard.clone.error.clone-network" => "복제 중 네트워크 오류가 발생했습니다. 연결을 확인하고 다시 시도하세요.", "git.wizard.clone.error.network" => "네트워크 오류. 연결을 확인하고 다시 시도하세요.", + "git.wizard.clone.error.timeout" => "복제 시간이 초과되었습니다. 다시 시도하거나 더 작은 저장소를 사용하세요.", "git.wizard.clone.error.auth-required" => "이 저장소는 인증이 필요합니다.", - "git.wizard.clone.error.auth-failed" => { - "인증에 실패했습니다. 사용자 이름과 토큰을 확인하세요." - } - "git.wizard.clone.error.clone-target-exists" => { - "대상 폴더가 이미 존재하거나 비어 있지 않습니다." - } + "git.wizard.clone.error.auth-failed" => "인증에 실패했습니다. 사용자 이름과 토큰을 확인하세요.", + "git.wizard.clone.error.auth-token-invalid" => "액세스 토큰이 거부되었습니다. 새 토큰을 생성하고 다시 시도하세요.", + "git.wizard.clone.error.clone-failed" => "복제에 실패했습니다. URL이 실제 저장소를 가리키는지 확인하세요.", + "git.wizard.clone.error.clone-target-exists" => "대상 폴더가 이미 존재하거나 비어 있지 않습니다.", "git.pull.label" => "풀", "git.pull.tooltip" => "origin에서 풀", "git.pull.noRemote" => "원격이 구성되지 않음 — Git 설정에서 추가하세요", @@ -227,9 +230,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.push.noRemote" => "원격이 구성되지 않음 — Git 설정에서 추가하세요", "git.push.upToDate" => "푸시할 내용이 없음 — 최신 상태입니다", "git.push.retry" => "푸시 다시 시도", - "git.push.rejectedBody" => { - "원격에 아직 받지 않은 커밋이 있습니다. 먼저 풀한 뒤 다시 푸시하세요." - } + "git.push.rejectedBody" => "원격에 아직 받지 않은 커밋이 있습니다. 먼저 풀한 뒤 다시 푸시하세요.", "git.push.rejectedDismiss" => "닫기", "git.push.rejectedPull" => "지금 풀", "git.remote.dismissError" => "닫기", @@ -247,6 +248,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.remote.clearConfirmAction" => "확인", "git.remote.aheadBehind" => "{{ahead}} 앞서고 · {{behind}} 뒤처짐", "git.remote.fetchButton" => "Fetch", + "git.remote.sshIsoUnsupported" => "내장 엔진은 SSH 전송을 지원하지 않습니다. 시스템 git을 설치하거나 HTTPS 원격 URL로 전환하세요.", "git.remote.storedAuthLabel" => "저장된 자격 증명", "git.remote.storedAuth.token" => "토큰", "git.remote.storedAuth.ssh" => "SSH 키", @@ -258,6 +260,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.ssh.heading" => "SSH 키", "git.ssh.back" => "뒤로", "git.ssh.cancel" => "취소", + "git.ssh.isoUnsupported" => "현재 원격은 SSH를 사용하지만 내장 엔진은 SSH 전송을 수행할 수 없습니다. 시스템 git을 설치하거나 원격 URL을 HTTPS로 변경하세요.", "git.ssh.emptyList" => "아직 SSH 키가 없습니다.", "git.ssh.generateAction" => "새로 생성", "git.ssh.importAction" => "기존 항목 가져오기", @@ -292,9 +295,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.auth.tokenLabel" => "액세스 토큰", "git.auth.tokenPlaceholder" => "ghp_… 또는 PAT", "git.auth.sshKeyLabel" => "SSH 키", - "git.auth.sshNoKeys" => { - "사용 가능한 SSH 키가 없습니다. 먼저 Git 설정에서 가져오거나 생성하세요." - } + "git.auth.sshNoKeys" => "사용 가능한 SSH 키가 없습니다. 먼저 Git 설정에서 가져오거나 생성하세요.", "git.auth.rememberLabel" => "이 호스트의 자격 증명 기억", "git.auth.rememberHint" => "이 호스트의 자격 증명 기억", "git.auth.cancel" => "취소", @@ -302,6 +303,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.auth.validationSshKey" => "SSH 키를 선택하세요", "git.auth.error.auth-required" => "이 원격에는 인증이 필요합니다.", "git.auth.error.auth-failed" => "인증 실패. 자격 증명을 확인하고 다시 시도하세요.", + "git.auth.error.auth-token-invalid" => "액세스 토큰이 거부되었습니다. 새 토큰을 생성한 후 다시 시도하세요.", "rightPanel.design" => "디자인", "rightPanel.code" => "코드", "rightPanel.noSelection" => "요소를 선택하세요", @@ -325,9 +327,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "updater.restartInstall" => "재시작 및 설치", "updater.installing" => "설치 중...", "updater.releaseDate" => "출시일: {{date}}", - "updater.restartHint" => { - "업데이트를 적용하려면 재시작하세요. 재실행은 보통 10~15초 소요됩니다." - } + "updater.restartHint" => "업데이트를 적용하려면 재시작하세요. 재실행은 보통 10~15초 소요됩니다.", "updater.unknownError" => "알 수 없는 업데이트 오류입니다.", "updater.title.checking" => "업데이트 확인 중", "updater.title.available" => "업데이트 발견", @@ -338,9 +338,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "updater.subtitle.available" => "버전 {{version}}을 사용할 수 있습니다.", "updater.subtitle.availableGeneric" => "새 버전을 사용할 수 있습니다.", "updater.subtitle.downloading" => "버전 {{version}}을 백그라운드에서 다운로드 중입니다.", - "updater.subtitle.downloadingGeneric" => { - "업데이트 패키지를 백그라운드에서 다운로드 중입니다." - } + "updater.subtitle.downloadingGeneric" => "업데이트 패키지를 백그라운드에서 다운로드 중입니다.", "updater.subtitle.downloaded" => "버전 {{version}}이 다운로드되었습니다.", "updater.subtitle.downloadedGeneric" => "업데이트가 다운로드되었습니다.", "updater.subtitle.error" => "업데이트를 확인하거나 다운로드할 수 없습니다.", @@ -502,9 +500,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "ai.newChat" => "새 대화", "ai.collapse" => "접기", "ai.tryExample" => "예시로 디자인 해보세요...", - "ai.tipSelectElements" => { - "팁: 대화 전에 캔버스에서 요소를 선택하면 컨텍스트를 제공할 수 있습니다." - } + "ai.tipSelectElements" => "팁: 대화 전에 캔버스에서 요소를 선택하면 컨텍스트를 제공할 수 있습니다.", "ai.generating" => "생성 중...", "ai.designWithAgent" => "에이전트로 디자인...", "ai.attachImage" => "이미지 첨부", @@ -515,10 +511,13 @@ pub fn lookup(key: &str) -> Option<&'static str> { "ai.searchModels" => "모델 검색...", "ai.noModelsFound" => "일치하는 모델이 없습니다", "ai.quickAction.loginScreen" => "모바일 로그인 화면 디자인", + "ai.quickAction.loginScreenPrompt" => "이메일 입력, 비밀번호 입력, 로그인 버튼, 소셜 로그인 옵션이 있는 모던 모바일 로그인 화면을 디자인해 주세요", "ai.quickAction.foodApp" => "음식 앱 홈페이지", "ai.quickAction.foodAppPrompt" => "Generate a well-designed food mobile app homepage", "ai.quickAction.bottomNav" => "하단 네비게이션 바 디자인", + "ai.quickAction.bottomNavPrompt" => "홈, 검색, 추가, 메시지, 프로필 5개 탭이 있는 모바일 앱 하단 네비게이션 바를 디자인해 주세요", "ai.quickAction.colorPalette" => "앱에 맞는 색상 팔레트 추천", + "ai.quickAction.colorPalettePrompt" => "반려동물 관리 앱에 어울리는 모던한 색상 팔레트를 추천해 주세요", "ai.startDesigning" => "Start designing with AI", "ai.maximize" => "Maximize", "ai.restore" => "Restore", @@ -542,6 +541,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "fileMenu.daysAgo" => "{{count}}d ago", "unsaved.title" => "Unsaved changes", "unsaved.message" => "Save changes to \"{{name}}\"?", + "unsaved.dontSave" => "Don't Save", "code.reactTailwind" => "React + Tailwind", "code.htmlCss" => "HTML + CSS", "code.cssVariables" => "CSS Variables", @@ -565,6 +565,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "agents.transport" => "전송 방식", "agents.port" => "포트", "agents.mcpRestart" => "MCP 연동은 터미널을 재시작한 후 적용됩니다.", + "agents.mcpReinstallHint" => "OpenPencil 버전 업그레이드 후 호환성을 위해 MCP 통합을 다시 설치해 주세요.", "agents.modelCount" => "모델 {{count}}개", "agents.connectionFailed" => "연결 실패", "agents.serverError" => "서버 오류 {{status}}", @@ -635,6 +636,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "builtin.errorApiKeyEmpty" => "API 키가 비어 있습니다. 설정에서 API 키를 추가해 주세요.", "builtin.parallelAgents" => "병렬 하위 에이전트: {{count}}x (클릭하여 전환)", "builtin.baseUrlPlaceholder" => "https://api.example.com/v1", + "builtin.teamDescription" => "디자인 생성용 모델을 선택하세요. 설정하면 디자인 작업이 이 모델을 사용하는 전문 에이전트에 자동으로 위임됩니다.", "builtin.teamDesignModel" => "디자인 모델", "builtin.teamSelectModel" => "없음 (단일 에이전트)", "acp.title" => "ACP Agent", @@ -669,9 +671,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "figma.convertFailed" => "Figma 파일 변환에 실패했습니다", "figma.parsing" => ".fig 파일 파싱 중...", "figma.converting" => "노드 변환 중...", - "figma.selectPage" => { - "이 파일에는 {{count}}개의 페이지가 있습니다. 가져올 페이지를 선택하세요:" - } + "figma.selectPage" => "이 파일에는 {{count}}개의 페이지가 있습니다. 가져올 페이지를 선택하세요:", "figma.layers" => "{{count}}개 레이어", "figma.importAll" => "모든 페이지 가져오기", "figma.importComplete" => "가져오기 완료!", diff --git a/crates/openpencil-shell-core/src/i18n/pt.rs b/crates/openpencil-shell-core/src/i18n/pt.rs index 26c14f741..84689454e 100644 --- a/crates/openpencil-shell-core/src/i18n/pt.rs +++ b/crates/openpencil-shell-core/src/i18n/pt.rs @@ -62,8 +62,10 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.close" => "Fechar", "git.initializing" => "Inicializando repositório…", "git.conflict.title" => "Conflito de mesclagem", + "git.conflict.description" => "Resolva cada conflito usando os cartões abaixo, depois aplique a mesclagem.", "git.conflict.abort" => "Abortar mesclagem", "git.conflict.nonOp.title" => "Mesclagem pausada em arquivos não .op", + "git.conflict.nonOp.description" => "A mesclagem dos arquivos .op foi concluída, mas outros arquivos do repositório ainda não foram resolvidos. Resolva-os fora do OpenPencil e continue.", "git.conflict.nonOp.unresolvedHeading_one" => "1 arquivo precisa de atenção", "git.conflict.nonOp.unresolvedHeading_other" => "{{count}} arquivos precisam de atenção", "git.conflict.nonOp.continue" => "Continuar mesclagem", @@ -72,9 +74,8 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.conflict.banner.apply" => "Aplicar mesclagem", "git.conflict.banner.continue" => "Continuar", "git.conflict.banner.finalizeError" => "Não foi possível aplicar: {{message}}", - "git.conflict.banner.pollError" => { - "Sondagem de status pausada devido a um erro: {{message}}" - } + "git.conflict.banner.pollError" => "Sondagem de status pausada devido a um erro: {{message}}", + "git.conflict.banner.reopenMessage" => "Painel reaberto durante a mesclagem — por favor, cancele e faça pull novamente.", "git.conflict.list.heading" => "Todos os conflitos", "git.conflict.list.progress" => "{{resolved}} / {{total}} resolvidos", "git.conflict.list.allResolved" => "Tudo resolvido", @@ -126,9 +127,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.picker.back" => "Voltar", "git.picker.backClose" => "Cancelar", "git.picker.empty.heading" => "Nenhum arquivo .op neste repositório", - "git.picker.empty.body" => { - "O painel Git precisa de pelo menos um arquivo .op para funcionar." - } + "git.picker.empty.body" => "O painel Git precisa de pelo menos um arquivo .op para funcionar.", "git.picker.empty.close" => "Fechar painel", "git.autoBind.confirmHeading" => "{{fileName}} encontrado — abrir?", "git.autoBind.openButton" => "Abrir", @@ -140,6 +139,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.commit.placeholder" => "Descreva esta alteração…", "git.commit.submitButton" => "Salvar marco", "git.commit.saveRequiredTitle" => "Salve o documento primeiro", + "git.commit.saveRequiredBody" => "Você tem alterações não salvas. Salve o documento para continuar: {{label}}", "git.commit.saveRequiredSave" => "Salvar", "git.commit.saveRequiredCancel" => "Cancelar", "git.header.autosaveError" => "Erro de auto-salvamento", @@ -202,6 +202,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.wizard.clone.usernameLabel" => "Usuário (opcional)", "git.wizard.clone.tokenLabel" => "Token de acesso (opcional)", "git.wizard.clone.tokenPlaceholder" => "ghp_… deixe em branco para repos públicos", + "git.wizard.clone.anonymousHint" => "Deixe em branco para clonar anonimamente (apenas repos públicos).", "git.wizard.clone.sshHint" => "Esta URL exige autenticação por chave SSH.", "git.wizard.clone.hostDetected" => "Detectado: {{host}} · {{mode}}", "git.wizard.clone.authMode.token-or-anon" => "token ou anônimo", @@ -210,19 +211,15 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.wizard.clone.submit" => "Clonar", "git.wizard.clone.validationUrl" => "A URL remota é obrigatória", "git.wizard.clone.validationDest" => "A pasta de destino é obrigatória", - "git.wizard.clone.validationTokenUsername" => { - "O usuário é obrigatório quando um token é fornecido" - } - "git.wizard.clone.error.network" => { - "Erro de rede. Verifique sua conexão e tente novamente." - } + "git.wizard.clone.validationTokenUsername" => "O usuário é obrigatório quando um token é fornecido", + "git.wizard.clone.error.clone-network" => "Erro de rede ao clonar. Verifique sua conexão e tente novamente.", + "git.wizard.clone.error.network" => "Erro de rede. Verifique sua conexão e tente novamente.", + "git.wizard.clone.error.timeout" => "Tempo limite ao clonar. Tente novamente ou use um repositório menor.", "git.wizard.clone.error.auth-required" => "Este repositório exige autenticação.", - "git.wizard.clone.error.auth-failed" => { - "Falha na autenticação. Verifique seu usuário e token." - } - "git.wizard.clone.error.clone-target-exists" => { - "A pasta de destino já existe ou não está vazia." - } + "git.wizard.clone.error.auth-failed" => "Falha na autenticação. Verifique seu usuário e token.", + "git.wizard.clone.error.auth-token-invalid" => "O token de acesso foi rejeitado. Gere um novo e tente novamente.", + "git.wizard.clone.error.clone-failed" => "Falha ao clonar. Verifique se a URL aponta para um repositório real.", + "git.wizard.clone.error.clone-target-exists" => "A pasta de destino já existe ou não está vazia.", "git.pull.label" => "Pull", "git.pull.tooltip" => "Pull do origin", "git.pull.noRemote" => "Nenhum remoto configurado — adicione um nas configurações do Git", @@ -233,6 +230,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.push.noRemote" => "Nenhum remoto configurado — adicione um nas configurações do Git", "git.push.upToDate" => "Nada para enviar — você está em dia", "git.push.retry" => "Tentar push novamente", + "git.push.rejectedBody" => "O remoto tem commits que você ainda não possui. Faça pull primeiro e depois push novamente.", "git.push.rejectedDismiss" => "Fechar", "git.push.rejectedPull" => "Fazer pull agora", "git.remote.dismissError" => "Fechar", @@ -250,6 +248,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.remote.clearConfirmAction" => "Confirmar", "git.remote.aheadBehind" => "{{ahead}} à frente · {{behind}} atrás", "git.remote.fetchButton" => "Buscar", + "git.remote.sshIsoUnsupported" => "Transporte SSH não é suportado pelo motor integrado. Instale o git do sistema ou use uma URL remota HTTPS.", "git.remote.storedAuthLabel" => "Credenciais salvas", "git.remote.storedAuth.token" => "Token", "git.remote.storedAuth.ssh" => "Chave SSH", @@ -261,14 +260,13 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.ssh.heading" => "Chaves SSH", "git.ssh.back" => "Voltar", "git.ssh.cancel" => "Cancelar", + "git.ssh.isoUnsupported" => "O remoto atual usa SSH, mas o motor integrado não pode executar transporte SSH. Instale o git do sistema ou mude a URL remota para HTTPS.", "git.ssh.emptyList" => "Ainda não há chaves SSH.", "git.ssh.generateAction" => "Gerar nova", "git.ssh.importAction" => "Importar existente", "git.ssh.copyPublicKey" => "Copiar chave pública", "git.ssh.copiedHint" => "Copiada", - "git.ssh.copyUnsupported" => { - "Área de transferência indisponível — copie esta chave manualmente." - } + "git.ssh.copyUnsupported" => "Área de transferência indisponível — copie esta chave manualmente.", "git.ssh.deleteKey" => "Excluir {{name}}", "git.ssh.deletePrompt" => "Excluir a chave SSH {{name}}?", "git.ssh.deleteConfirm" => "Excluir", @@ -286,6 +284,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.ssh.validationComment" => "O comentário é obrigatório", "git.ssh.validationImportPath" => "Escolha um arquivo de chave privada para importar", "git.ssh.providerLink" => "Abrir configurações de chaves SSH de {{host}}", + "git.ssh.genericGuidance" => "Copie a chave pública e adicione-a às configurações de chaves SSH do seu provedor Git.", "git.auth.formLabel" => "Credenciais do Git", "git.auth.heading" => "Autenticar em {{host}}", "git.auth.headingUnknown" => "Autenticar neste remoto", @@ -296,12 +295,15 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.auth.tokenLabel" => "Token de acesso", "git.auth.tokenPlaceholder" => "ghp_… ou PAT", "git.auth.sshKeyLabel" => "Chave SSH", + "git.auth.sshNoKeys" => "Nenhuma chave SSH disponível. Importe ou gere uma primeiro nas configurações do Git.", "git.auth.rememberLabel" => "Lembrar esta credencial para este host", "git.auth.rememberHint" => "Lembrar esta credencial para este host", "git.auth.cancel" => "Cancelar", "git.auth.validationToken" => "O token de acesso é obrigatório", "git.auth.validationSshKey" => "Selecione uma chave SSH", "git.auth.error.auth-required" => "Este remoto requer autenticação.", + "git.auth.error.auth-failed" => "Falha na autenticação. Verifique suas credenciais e tente novamente.", + "git.auth.error.auth-token-invalid" => "O token de acesso foi rejeitado. Gere um novo e tente novamente.", "rightPanel.design" => "Design", "rightPanel.code" => "Código", "rightPanel.noSelection" => "Selecione um elemento", @@ -325,6 +327,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "updater.restartInstall" => "Reiniciar e instalar", "updater.installing" => "Instalando...", "updater.releaseDate" => "Data de lançamento: {{date}}", + "updater.restartHint" => "Reinicie para aplicar a atualização. A reinicialização geralmente leva de 10 a 15 segundos.", "updater.unknownError" => "Erro desconhecido do atualizador.", "updater.title.checking" => "Verificando atualizações", "updater.title.available" => "Atualização encontrada", @@ -334,9 +337,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "updater.subtitle.checking" => "Procurando a versão mais recente...", "updater.subtitle.available" => "A versão {{version}} está disponível.", "updater.subtitle.availableGeneric" => "Uma nova versão está disponível.", - "updater.subtitle.downloading" => { - "A versão {{version}} está sendo baixada em segundo plano." - } + "updater.subtitle.downloading" => "A versão {{version}} está sendo baixada em segundo plano.", "updater.subtitle.downloadingGeneric" => "Baixando pacote de atualização em segundo plano.", "updater.subtitle.downloaded" => "A versão {{version}} foi baixada.", "updater.subtitle.downloadedGeneric" => "A atualização foi baixada.", @@ -499,6 +500,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "ai.newChat" => "Novo chat", "ai.collapse" => "Recolher", "ai.tryExample" => "Experimente um exemplo para criar...", + "ai.tipSelectElements" => "Dica: Selecione elementos no canvas antes de conversar para dar contexto.", "ai.generating" => "Gerando...", "ai.designWithAgent" => "Criar com Agente...", "ai.attachImage" => "Anexar imagem", @@ -509,9 +511,11 @@ pub fn lookup(key: &str) -> Option<&'static str> { "ai.searchModels" => "Pesquisar modelos...", "ai.noModelsFound" => "Nenhum modelo encontrado", "ai.quickAction.loginScreen" => "Criar uma tela de login mobile", + "ai.quickAction.loginScreenPrompt" => "Design a modern mobile login screen with email input, password input, login button, and social login options", "ai.quickAction.foodApp" => "Página inicial de app de comida", "ai.quickAction.foodAppPrompt" => "Generate a well-designed food mobile app homepage", "ai.quickAction.bottomNav" => "Criar uma barra de navegação inferior", + "ai.quickAction.bottomNavPrompt" => "Design a mobile app bottom navigation bar with 5 tabs: Home, Search, Add, Messages, Profile", "ai.quickAction.colorPalette" => "Sugerir uma paleta de cores para meu app", "ai.quickAction.colorPalettePrompt" => "Suggest a modern color palette for a pet care app", "ai.startDesigning" => "Start designing with AI", @@ -537,6 +541,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "fileMenu.daysAgo" => "{{count}}d ago", "unsaved.title" => "Unsaved changes", "unsaved.message" => "Save changes to \"{{name}}\"?", + "unsaved.dontSave" => "Don't Save", "code.reactTailwind" => "React + Tailwind", "code.htmlCss" => "HTML + CSS", "code.cssVariables" => "CSS Variables", @@ -560,6 +565,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "agents.transport" => "Transporte", "agents.port" => "Porta", "agents.mcpRestart" => "As integrações MCP entrarão em vigor após reiniciar o terminal.", + "agents.mcpReinstallHint" => "Após atualizar o OpenPencil, reinstale as integrações MCP para garantir a compatibilidade.", "agents.modelCount" => "{{count}} modelo(s)", "agents.connectionFailed" => "Falha na conexão", "agents.serverError" => "Erro do servidor {{status}}", @@ -599,8 +605,10 @@ pub fn lookup(key: &str) -> Option<&'static str> { "settings.images" => "Images", "settings.system" => "Sistema", "settings.autoUpdateDesc" => "Verificar automaticamente novas versões ao iniciar", + "settings.systemDesktopOnly" => "As configurações do sistema estão disponíveis no aplicativo de desktop.", "settings.envHint" => "Você pode definir variáveis de ambiente adicionais em {{path}}.", "builtin.title" => "Provedores integrados", + "builtin.description" => "Configure as chaves de API diretamente — sem ferramentas CLI necessárias.", "builtin.addProvider" => "Adicionar provedor", "builtin.empty" => "Nenhum provedor integrado configurado ainda.", "builtin.displayName" => "Nome de exibição", @@ -624,8 +632,11 @@ pub fn lookup(key: &str) -> Option<&'static str> { "builtin.custom" => "Personalizado", "builtin.apiKeyBadge" => "API Key", "builtin.viaApiKey" => "via API Key de {{name}}", + "builtin.errorProviderNotFound" => "Provedor integrado não encontrado. Por favor, verifique suas configurações.", + "builtin.errorApiKeyEmpty" => "A API key está vazia. Por favor, adicione sua API key nas configurações.", "builtin.parallelAgents" => "Sub-agentes paralelos: {{count}}x (clique para alternar)", "builtin.baseUrlPlaceholder" => "https://api.example.com/v1", + "builtin.teamDescription" => "Selecione um modelo para geração de design. Quando definido, tarefas de design são automaticamente delegadas a um agente especializado usando este modelo.", "builtin.teamDesignModel" => "Modelo de design", "builtin.teamSelectModel" => "Nenhum (agente único)", "acp.title" => "ACP Agent", diff --git a/crates/openpencil-shell-core/src/i18n/ru.rs b/crates/openpencil-shell-core/src/i18n/ru.rs index 607a83931..7582d20c7 100644 --- a/crates/openpencil-shell-core/src/i18n/ru.rs +++ b/crates/openpencil-shell-core/src/i18n/ru.rs @@ -62,8 +62,10 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.close" => "Закрыть", "git.initializing" => "Инициализация репозитория…", "git.conflict.title" => "Конфликт слияния", + "git.conflict.description" => "Разрешите каждый конфликт с помощью карточек ниже, затем примените слияние.", "git.conflict.abort" => "Отменить слияние", "git.conflict.nonOp.title" => "Слияние приостановлено из-за не-.op файлов", + "git.conflict.nonOp.description" => "Слияние .op файлов завершено, но другие файлы в репозитории ещё не разрешены. Разрешите их вне OpenPencil и продолжите.", "git.conflict.nonOp.unresolvedHeading_one" => "1 файл требует внимания", "git.conflict.nonOp.unresolvedHeading_other" => "{{count}} файлов требуют внимания", "git.conflict.nonOp.continue" => "Продолжить слияние", @@ -73,6 +75,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.conflict.banner.continue" => "Продолжить", "git.conflict.banner.finalizeError" => "Не удалось применить: {{message}}", "git.conflict.banner.pollError" => "Опрос статуса приостановлен из-за ошибки: {{message}}", + "git.conflict.banner.reopenMessage" => "Панель была открыта повторно в процессе слияния — пожалуйста, прервите и повторите pull.", "git.conflict.list.heading" => "Все конфликты", "git.conflict.list.progress" => "{{resolved}} / {{total}} разрешено", "git.conflict.list.allResolved" => "Всё разрешено", @@ -136,6 +139,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.commit.placeholder" => "Опишите это изменение…", "git.commit.submitButton" => "Сохранить веху", "git.commit.saveRequiredTitle" => "Сначала сохраните документ", + "git.commit.saveRequiredBody" => "У вас есть несохранённые изменения. Сохраните документ, чтобы продолжить: {{label}}", "git.commit.saveRequiredSave" => "Сохранить", "git.commit.saveRequiredCancel" => "Отмена", "git.header.autosaveError" => "Ошибка автосохранения", @@ -198,6 +202,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.wizard.clone.usernameLabel" => "Имя пользователя (необязательно)", "git.wizard.clone.tokenLabel" => "Токен доступа (необязательно)", "git.wizard.clone.tokenPlaceholder" => "ghp_… для публичных можно оставить пустым", + "git.wizard.clone.anonymousHint" => "Оставьте пустым для анонимного клонирования (только публичные репозитории).", "git.wizard.clone.sshHint" => "Этот URL требует аутентификации по SSH-ключу.", "git.wizard.clone.hostDetected" => "Обнаружено: {{host}} · {{mode}}", "git.wizard.clone.authMode.token-or-anon" => "токен или анонимно", @@ -206,16 +211,15 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.wizard.clone.submit" => "Клонировать", "git.wizard.clone.validationUrl" => "Требуется URL удалённого репозитория", "git.wizard.clone.validationDest" => "Требуется папка назначения", - "git.wizard.clone.validationTokenUsername" => { - "Имя пользователя обязательно при указании токена" - } - "git.wizard.clone.error.network" => { - "Сетевая ошибка. Проверьте подключение и повторите попытку." - } + "git.wizard.clone.validationTokenUsername" => "Имя пользователя обязательно при указании токена", + "git.wizard.clone.error.clone-network" => "Сетевая ошибка при клонировании. Проверьте подключение и повторите попытку.", + "git.wizard.clone.error.network" => "Сетевая ошибка. Проверьте подключение и повторите попытку.", + "git.wizard.clone.error.timeout" => "Истекло время ожидания клонирования. Повторите попытку или используйте репозиторий поменьше.", "git.wizard.clone.error.auth-required" => "Этот репозиторий требует аутентификации.", - "git.wizard.clone.error.clone-target-exists" => { - "Папка назначения уже существует или не пуста." - } + "git.wizard.clone.error.auth-failed" => "Аутентификация не удалась. Проверьте имя пользователя и токен.", + "git.wizard.clone.error.auth-token-invalid" => "Токен доступа отклонён. Создайте новый и повторите попытку.", + "git.wizard.clone.error.clone-failed" => "Клонирование не удалось. Убедитесь, что URL указывает на существующий репозиторий.", + "git.wizard.clone.error.clone-target-exists" => "Папка назначения уже существует или не пуста.", "git.pull.label" => "Pull", "git.pull.tooltip" => "Pull из origin", "git.pull.noRemote" => "Удалённый репозиторий не настроен — добавьте его в настройках Git", @@ -226,6 +230,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.push.noRemote" => "Удалённый репозиторий не настроен — добавьте его в настройках Git", "git.push.upToDate" => "Нечего отправлять — вы в курсе", "git.push.retry" => "Повторить push", + "git.push.rejectedBody" => "В удалённом репозитории есть коммиты, которых у вас ещё нет. Сначала выполните pull, затем повторите push.", "git.push.rejectedDismiss" => "Закрыть", "git.push.rejectedPull" => "Выполнить pull", "git.remote.dismissError" => "Закрыть", @@ -243,6 +248,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.remote.clearConfirmAction" => "Подтвердить", "git.remote.aheadBehind" => "Впереди {{ahead}} · Позади {{behind}}", "git.remote.fetchButton" => "Fetch", + "git.remote.sshIsoUnsupported" => "Встроенный движок не поддерживает SSH. Установите системный git или используйте HTTPS URL.", "git.remote.storedAuthLabel" => "Сохранённые учётные данные", "git.remote.storedAuth.token" => "Токен", "git.remote.storedAuth.ssh" => "SSH-ключ", @@ -254,6 +260,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.ssh.heading" => "SSH-ключи", "git.ssh.back" => "Назад", "git.ssh.cancel" => "Отмена", + "git.ssh.isoUnsupported" => "Текущий удалённый использует SSH, но встроенный движок не может выполнить SSH-транспорт. Установите системный git или смените URL на HTTPS.", "git.ssh.emptyList" => "SSH-ключей пока нет.", "git.ssh.generateAction" => "Создать новый", "git.ssh.importAction" => "Импортировать существующий", @@ -277,6 +284,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.ssh.validationComment" => "Комментарий обязателен", "git.ssh.validationImportPath" => "Выберите файл приватного ключа для импорта", "git.ssh.providerLink" => "Открыть настройки SSH-ключей {{host}}", + "git.ssh.genericGuidance" => "Скопируйте публичный ключ и добавьте его в настройки SSH-ключей вашего Git-провайдера.", "git.auth.formLabel" => "Учётные данные Git", "git.auth.heading" => "Аутентификация на {{host}}", "git.auth.headingUnknown" => "Аутентификация с этим удалённым", @@ -287,12 +295,15 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.auth.tokenLabel" => "Токен доступа", "git.auth.tokenPlaceholder" => "ghp_… или PAT", "git.auth.sshKeyLabel" => "SSH-ключ", + "git.auth.sshNoKeys" => "Нет доступных SSH-ключей. Сначала импортируйте или сгенерируйте один в настройках Git.", "git.auth.rememberLabel" => "Запомнить эти учётные данные для этого хоста", "git.auth.rememberHint" => "Запомнить эти учётные данные для этого хоста", "git.auth.cancel" => "Отмена", "git.auth.validationToken" => "Токен доступа обязателен", "git.auth.validationSshKey" => "Выберите SSH-ключ", "git.auth.error.auth-required" => "Этот удалённый репозиторий требует аутентификации.", + "git.auth.error.auth-failed" => "Ошибка аутентификации. Проверьте свои учётные данные и повторите попытку.", + "git.auth.error.auth-token-invalid" => "Токен доступа был отклонён. Сгенерируйте новый и повторите попытку.", "rightPanel.design" => "Дизайн", "rightPanel.code" => "Код", "rightPanel.noSelection" => "Выберите элемент", @@ -316,6 +327,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "updater.restartInstall" => "Перезапуск и установка", "updater.installing" => "Установка...", "updater.releaseDate" => "Дата выпуска: {{date}}", + "updater.restartHint" => "Перезапустите приложение для применения обновления. Перезапуск обычно занимает 10–15 секунд.", "updater.unknownError" => "Неизвестная ошибка обновления.", "updater.title.checking" => "Проверка обновлений", "updater.title.available" => "Обновление найдено", @@ -499,9 +511,11 @@ pub fn lookup(key: &str) -> Option<&'static str> { "ai.searchModels" => "Поиск моделей...", "ai.noModelsFound" => "Модели не найдены", "ai.quickAction.loginScreen" => "Создать экран входа для мобильного", + "ai.quickAction.loginScreenPrompt" => "Design a modern mobile login screen with email input, password input, login button, and social login options", "ai.quickAction.foodApp" => "Главная страница приложения еды", "ai.quickAction.foodAppPrompt" => "Generate a well-designed food mobile app homepage", "ai.quickAction.bottomNav" => "Создать нижнюю панель навигации", + "ai.quickAction.bottomNavPrompt" => "Design a mobile app bottom navigation bar with 5 tabs: Home, Search, Add, Messages, Profile", "ai.quickAction.colorPalette" => "Предложить цветовую палитру для приложения", "ai.quickAction.colorPalettePrompt" => "Suggest a modern color palette for a pet care app", "ai.startDesigning" => "Start designing with AI", @@ -527,6 +541,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "fileMenu.daysAgo" => "{{count}}d ago", "unsaved.title" => "Unsaved changes", "unsaved.message" => "Save changes to \"{{name}}\"?", + "unsaved.dontSave" => "Don't Save", "code.reactTailwind" => "React + Tailwind", "code.htmlCss" => "HTML + CSS", "code.cssVariables" => "CSS Variables", @@ -550,6 +565,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "agents.transport" => "Транспорт", "agents.port" => "Порт", "agents.mcpRestart" => "Интеграции MCP вступят в силу после перезапуска терминала.", + "agents.mcpReinstallHint" => "После обновления OpenPencil переустановите интеграции MCP для обеспечения совместимости.", "agents.modelCount" => "{{count}} модель(ей)", "agents.connectionFailed" => "Ошибка подключения", "agents.serverError" => "Ошибка сервера {{status}}", @@ -616,11 +632,11 @@ pub fn lookup(key: &str) -> Option<&'static str> { "builtin.custom" => "Пользовательский", "builtin.apiKeyBadge" => "API Key", "builtin.viaApiKey" => "через API Key {{name}}", + "builtin.errorProviderNotFound" => "Встроенный провайдер не найден. Пожалуйста, проверьте настройки.", "builtin.errorApiKeyEmpty" => "API key пуст. Пожалуйста, добавьте API key в настройках.", - "builtin.parallelAgents" => { - "Параллельные суб-агенты: {{count}}x (нажмите для переключения)" - } + "builtin.parallelAgents" => "Параллельные суб-агенты: {{count}}x (нажмите для переключения)", "builtin.baseUrlPlaceholder" => "https://api.example.com/v1", + "builtin.teamDescription" => "Выберите модель для генерации дизайна. При установке задачи дизайна автоматически делегируются специализированному агенту, использующему эту модель.", "builtin.teamDesignModel" => "Модель дизайна", "builtin.teamSelectModel" => "Нет (один агент)", "acp.title" => "ACP Agent", @@ -667,9 +683,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "figma.comingSoon" => "Скоро", "landing.open" => "Open", "landing.pencil" => "Pencil", - "landing.tagline" => { - "Векторный дизайн-инструмент с открытым исходным кодом. Design as Code." - } + "landing.tagline" => "Векторный дизайн-инструмент с открытым исходным кодом. Design as Code.", "landing.newDesign" => "Новый дизайн", "landing.shortcutHint" => "Нажмите {{key1}} + {{key2}} для создания нового дизайна", "notFound.message" => "Страница не найдена", diff --git a/crates/openpencil-shell-core/src/i18n/th.rs b/crates/openpencil-shell-core/src/i18n/th.rs index 6529bfac6..7504e6ca4 100644 --- a/crates/openpencil-shell-core/src/i18n/th.rs +++ b/crates/openpencil-shell-core/src/i18n/th.rs @@ -65,6 +65,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.conflict.description" => "แก้ไขแต่ละความขัดแย้งโดยใช้การ์ดด้านล่าง จากนั้นใช้การรวม", "git.conflict.abort" => "ยกเลิกการรวม", "git.conflict.nonOp.title" => "การรวมหยุดชั่วคราวที่ไฟล์ที่ไม่ใช่ .op", + "git.conflict.nonOp.description" => "การรวมไฟล์ .op เสร็จแล้ว แต่ไฟล์อื่นในที่เก็บยังไม่ได้แก้ไข แก้ไขนอก OpenPencil แล้วดำเนินการต่อ", "git.conflict.nonOp.unresolvedHeading_one" => "ต้องการการแก้ไข 1 ไฟล์", "git.conflict.nonOp.unresolvedHeading_other" => "ต้องการการแก้ไข {{count}} ไฟล์", "git.conflict.nonOp.continue" => "ดำเนินการรวมต่อ", @@ -138,9 +139,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.commit.placeholder" => "อธิบายการเปลี่ยนแปลงนี้…", "git.commit.submitButton" => "บันทึก milestone", "git.commit.saveRequiredTitle" => "บันทึกเอกสารก่อน", - "git.commit.saveRequiredBody" => { - "คุณมีการเปลี่ยนแปลงที่ยังไม่ได้บันทึก บันทึกเอกสารเพื่อดำเนินการต่อ: {{label}}" - } + "git.commit.saveRequiredBody" => "คุณมีการเปลี่ยนแปลงที่ยังไม่ได้บันทึก บันทึกเอกสารเพื่อดำเนินการต่อ: {{label}}", "git.commit.saveRequiredSave" => "บันทึก", "git.commit.saveRequiredCancel" => "ยกเลิก", "git.header.autosaveError" => "ข้อผิดพลาดการบันทึกอัตโนมัติ", @@ -213,17 +212,13 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.wizard.clone.validationUrl" => "จำเป็นต้องระบุ URL ระยะไกล", "git.wizard.clone.validationDest" => "จำเป็นต้องระบุโฟลเดอร์ปลายทาง", "git.wizard.clone.validationTokenUsername" => "ต้องระบุชื่อผู้ใช้เมื่อใช้โทเคน", - "git.wizard.clone.error.clone-network" => { - "เกิดข้อผิดพลาดเครือข่ายขณะโคลน ตรวจสอบการเชื่อมต่อแล้วลองใหม่" - } + "git.wizard.clone.error.clone-network" => "เกิดข้อผิดพลาดเครือข่ายขณะโคลน ตรวจสอบการเชื่อมต่อแล้วลองใหม่", "git.wizard.clone.error.network" => "ข้อผิดพลาดเครือข่าย ตรวจสอบการเชื่อมต่อแล้วลองใหม่", "git.wizard.clone.error.timeout" => "การโคลนหมดเวลา ลองใหม่หรือใช้ repository ที่เล็กกว่า", "git.wizard.clone.error.auth-required" => "repository นี้ต้องการการยืนยันตัวตน", "git.wizard.clone.error.auth-failed" => "การยืนยันตัวตนล้มเหลว ตรวจสอบชื่อผู้ใช้และโทเคน", "git.wizard.clone.error.auth-token-invalid" => "โทเคนเข้าถึงถูกปฏิเสธ สร้างโทเคนใหม่แล้วลองอีกครั้ง", - "git.wizard.clone.error.clone-failed" => { - "การโคลนล้มเหลว ตรวจสอบว่า URL ชี้ไปยัง repository ที่มีอยู่จริง" - } + "git.wizard.clone.error.clone-failed" => "การโคลนล้มเหลว ตรวจสอบว่า URL ชี้ไปยัง repository ที่มีอยู่จริง", "git.wizard.clone.error.clone-target-exists" => "โฟลเดอร์ปลายทางมีอยู่แล้วหรือไม่ว่างเปล่า", "git.pull.label" => "ดึง", "git.pull.tooltip" => "ดึงจาก origin", @@ -253,6 +248,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.remote.clearConfirmAction" => "ยืนยัน", "git.remote.aheadBehind" => "นำหน้า {{ahead}} · ตามหลัง {{behind}}", "git.remote.fetchButton" => "Fetch", + "git.remote.sshIsoUnsupported" => "เอนจินในตัวไม่รองรับการส่งผ่าน SSH ติดตั้ง git ระบบหรือเปลี่ยนเป็น URL รีโมต HTTPS", "git.remote.storedAuthLabel" => "ข้อมูลรับรองที่บันทึกไว้", "git.remote.storedAuth.token" => "โทเคน", "git.remote.storedAuth.ssh" => "คีย์ SSH", @@ -264,6 +260,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.ssh.heading" => "คีย์ SSH", "git.ssh.back" => "กลับ", "git.ssh.cancel" => "ยกเลิก", + "git.ssh.isoUnsupported" => "รีโมตปัจจุบันใช้ SSH แต่เอนจินในตัวไม่สามารถส่งผ่าน SSH ได้ ติดตั้ง git ระบบหรือเปลี่ยน URL รีโมตเป็น HTTPS", "git.ssh.emptyList" => "ยังไม่มีคีย์ SSH", "git.ssh.generateAction" => "สร้างใหม่", "git.ssh.importAction" => "นำเข้าที่มีอยู่", @@ -514,9 +511,11 @@ pub fn lookup(key: &str) -> Option<&'static str> { "ai.searchModels" => "ค้นหาโมเดล...", "ai.noModelsFound" => "ไม่พบโมเดล", "ai.quickAction.loginScreen" => "ออกแบบหน้าจอเข้าสู่ระบบมือถือ", + "ai.quickAction.loginScreenPrompt" => "ออกแบบหน้าจอเข้าสู่ระบบมือถือที่ทันสมัย พร้อมช่องกรอกอีเมล รหัสผ่าน ปุ่มเข้าสู่ระบบ และตัวเลือกเข้าสู่ระบบผ่านโซเชียล", "ai.quickAction.foodApp" => "หน้าแรกแอปอาหาร", "ai.quickAction.foodAppPrompt" => "Generate a well-designed food mobile app homepage", "ai.quickAction.bottomNav" => "ออกแบบแถบนำทางด้านล่าง", + "ai.quickAction.bottomNavPrompt" => "ออกแบบแถบนำทางด้านล่างของแอปมือถือ 5 แท็บ: หน้าแรก, ค้นหา, เพิ่ม, ข้อความ, โปรไฟล์", "ai.quickAction.colorPalette" => "แนะนำจานสีสำหรับแอปของฉัน", "ai.quickAction.colorPalettePrompt" => "แนะนำจานสีที่ทันสมัยสำหรับแอปดูแลสัตว์เลี้ยง", "ai.startDesigning" => "Start designing with AI", @@ -542,6 +541,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "fileMenu.daysAgo" => "{{count}}d ago", "unsaved.title" => "Unsaved changes", "unsaved.message" => "Save changes to \"{{name}}\"?", + "unsaved.dontSave" => "Don't Save", "code.reactTailwind" => "React + Tailwind", "code.htmlCss" => "HTML + CSS", "code.cssVariables" => "CSS Variables", @@ -565,6 +565,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "agents.transport" => "การส่งข้อมูล", "agents.port" => "พอร์ต", "agents.mcpRestart" => "การผสานรวม MCP จะมีผลหลังจากรีสตาร์ทเทอร์มินัล", + "agents.mcpReinstallHint" => "หลังจากอัปเกรด OpenPencil กรุณาติดตั้ง MCP Integration ใหม่เพื่อให้แน่ใจว่าเข้ากันได้", "agents.modelCount" => "{{count}} โมเดล", "agents.connectionFailed" => "การเชื่อมต่อล้มเหลว", "agents.serverError" => "ข้อผิดพลาดของเซิร์ฟเวอร์ {{status}}", @@ -635,6 +636,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "builtin.errorApiKeyEmpty" => "API Key ว่างเปล่า กรุณาเพิ่ม API Key ในการตั้งค่า", "builtin.parallelAgents" => "ตัวแทนย่อยแบบขนาน: {{count}}x (คลิกเพื่อสลับ)", "builtin.baseUrlPlaceholder" => "https://api.example.com/v1", + "builtin.teamDescription" => "เลือกโมเดลสำหรับสร้างงานออกแบบ เมื่อตั้งค่าแล้ว งานออกแบบจะถูกมอบหมายให้เอเจนต์ผู้เชี่ยวชาญที่ใช้โมเดลนี้โดยอัตโนมัติ", "builtin.teamDesignModel" => "โมเดลออกแบบ", "builtin.teamSelectModel" => "ไม่มี (เอเจนต์เดี่ยว)", "acp.title" => "ACP Agent", diff --git a/crates/openpencil-shell-core/src/i18n/tr.rs b/crates/openpencil-shell-core/src/i18n/tr.rs index 86b8a94b4..b694515a2 100644 --- a/crates/openpencil-shell-core/src/i18n/tr.rs +++ b/crates/openpencil-shell-core/src/i18n/tr.rs @@ -62,8 +62,10 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.close" => "Kapat", "git.initializing" => "Depo başlatılıyor…", "git.conflict.title" => "Birleştirme çakışması", + "git.conflict.description" => "Aşağıdaki kartları kullanarak her çakışmayı çözün, ardından birleştirmeyi uygulayın.", "git.conflict.abort" => "Birleştirmeyi iptal et", "git.conflict.nonOp.title" => ".op olmayan dosyalar nedeniyle birleştirme duraklatıldı", + "git.conflict.nonOp.description" => ".op birleştirmesi tamamlandı, ancak depodaki diğer dosyalar hâlâ çözülmedi. OpenPencil dışında çözün, ardından devam edin.", "git.conflict.nonOp.unresolvedHeading_one" => "1 dosya ilgilenmeyi bekliyor", "git.conflict.nonOp.unresolvedHeading_other" => "{{count}} dosya ilgilenmeyi bekliyor", "git.conflict.nonOp.continue" => "Birleştirmeye devam et", @@ -72,9 +74,8 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.conflict.banner.apply" => "Birleştirmeyi uygula", "git.conflict.banner.continue" => "Devam et", "git.conflict.banner.finalizeError" => "Uygulanamadı: {{message}}", - "git.conflict.banner.pollError" => { - "Bir hata nedeniyle durum kontrolü duraklatıldı: {{message}}" - } + "git.conflict.banner.pollError" => "Bir hata nedeniyle durum kontrolü duraklatıldı: {{message}}", + "git.conflict.banner.reopenMessage" => "Panel birleştirme sırasında yeniden açıldı — lütfen iptal edip tekrar pull yapın.", "git.conflict.list.heading" => "Tüm çakışmalar", "git.conflict.list.progress" => "{{resolved}} / {{total}} çözüldü", "git.conflict.list.allResolved" => "Hepsi çözüldü", @@ -126,9 +127,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.picker.back" => "Geri", "git.picker.backClose" => "İptal", "git.picker.empty.heading" => "Bu depoda .op dosyası yok", - "git.picker.empty.body" => { - "Git paneli çalışmak için en az bir .op dosyasına ihtiyaç duyar." - } + "git.picker.empty.body" => "Git paneli çalışmak için en az bir .op dosyasına ihtiyaç duyar.", "git.picker.empty.close" => "Paneli kapat", "git.autoBind.confirmHeading" => "{{fileName}} bulundu — açılsın mı?", "git.autoBind.openButton" => "Aç", @@ -140,6 +139,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.commit.placeholder" => "Bu değişikliği açıklayın…", "git.commit.submitButton" => "Kilometre taşı olarak kaydet", "git.commit.saveRequiredTitle" => "Önce belgeyi kaydedin", + "git.commit.saveRequiredBody" => "Kaydedilmemiş değişiklikleriniz var. Devam etmek için belgeyi kaydedin: {{label}}", "git.commit.saveRequiredSave" => "Kaydet", "git.commit.saveRequiredCancel" => "İptal", "git.header.autosaveError" => "Otomatik kaydetme hatası", @@ -157,6 +157,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.history.autosaveLabel" => "auto {{time}}", "git.history.milestoneDetailTitle" => "Kilometre taşı detayları", "git.history.restoreButton" => "Geri yükle", + "git.history.copyHashButton" => "Hash'i kopyala", "git.history.copiedToast" => "Kopyalandı", "git.history.diff.loading" => "Diff yükleniyor…", "git.history.diff.initialCommit" => "İlk commit — karşılaştırılacak üst yok", @@ -201,9 +202,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.wizard.clone.usernameLabel" => "Kullanıcı adı (isteğe bağlı)", "git.wizard.clone.tokenLabel" => "Erişim belirteci (isteğe bağlı)", "git.wizard.clone.tokenPlaceholder" => "ghp_… veya genel depolar için boş bırakın", - "git.wizard.clone.anonymousHint" => { - "Anonim klonlamak için boş bırakın (yalnızca genel depolar)." - } + "git.wizard.clone.anonymousHint" => "Anonim klonlamak için boş bırakın (yalnızca genel depolar).", "git.wizard.clone.sshHint" => "Bu URL için SSH anahtar kimlik doğrulaması gerekir.", "git.wizard.clone.hostDetected" => "Algılandı: {{host}} · {{mode}}", "git.wizard.clone.authMode.token-or-anon" => "belirteç veya anonim", @@ -212,17 +211,26 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.wizard.clone.submit" => "Klonla", "git.wizard.clone.validationUrl" => "Uzak URL gerekli", "git.wizard.clone.validationDest" => "Hedef klasör gerekli", - "git.wizard.clone.validationTokenUsername" => { - "Belirteç sağlandığında kullanıcı adı gerekli" - } + "git.wizard.clone.validationTokenUsername" => "Belirteç sağlandığında kullanıcı adı gerekli", + "git.wizard.clone.error.clone-network" => "Klonlama sırasında ağ hatası. Bağlantınızı kontrol edip tekrar deneyin.", "git.wizard.clone.error.network" => "Ağ hatası. Bağlantınızı kontrol edip tekrar deneyin.", + "git.wizard.clone.error.timeout" => "Klonlama zaman aşımına uğradı. Tekrar deneyin veya daha küçük bir depo kullanın.", "git.wizard.clone.error.auth-required" => "Bu depo kimlik doğrulama gerektiriyor.", + "git.wizard.clone.error.auth-failed" => "Kimlik doğrulama başarısız. Kullanıcı adınızı ve belirtecinizi kontrol edin.", + "git.wizard.clone.error.auth-token-invalid" => "Erişim belirteci reddedildi. Yenisini oluşturup tekrar deneyin.", + "git.wizard.clone.error.clone-failed" => "Klonlama başarısız. URL'nin gerçek bir depoya işaret ettiğini doğrulayın.", "git.wizard.clone.error.clone-target-exists" => "Hedef klasör zaten var veya boş değil.", "git.pull.label" => "Pull", + "git.pull.tooltip" => "origin'den pull", "git.pull.noRemote" => "Remote yapılandırılmamış — Git ayarlarından ekleyin", + "git.pull.retry" => "Pull'u yeniden dene", "git.push.label" => "Push", + "git.push.tooltip_one" => "origin'e 1 commit push", + "git.push.tooltip_other" => "origin'e {{count}} commit push", "git.push.noRemote" => "Remote yapılandırılmamış — Git ayarlarından ekleyin", "git.push.upToDate" => "Push edilecek bir şey yok — güncelsiniz", + "git.push.retry" => "Push'u yeniden dene", + "git.push.rejectedBody" => "Remote'da henüz sizde olmayan commit'ler var. Önce pull yapın, sonra tekrar push yapın.", "git.push.rejectedDismiss" => "Kapat", "git.push.rejectedPull" => "Şimdi pull", "git.remote.dismissError" => "Kapat", @@ -235,10 +243,12 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.remote.urlPlaceholder" => "https://github.com/owner/repo.git", "git.remote.saveButton" => "Kaydet", "git.remote.clearButton" => "Temizle", + "git.remote.clearConfirmHeading" => "origin'i temizle?", "git.remote.clearConfirmBody" => "Bu, origin uzağını bu depodan kaldıracak.", "git.remote.clearConfirmAction" => "Onayla", "git.remote.aheadBehind" => "{{ahead}} ilerde · {{behind}} geride", "git.remote.fetchButton" => "Fetch", + "git.remote.sshIsoUnsupported" => "SSH aktarımı yerleşik motor tarafından desteklenmiyor. Sistem git kurun veya HTTPS uzak URL kullanın.", "git.remote.storedAuthLabel" => "Kayıtlı kimlik bilgileri", "git.remote.storedAuth.token" => "Token", "git.remote.storedAuth.ssh" => "SSH anahtarı", @@ -250,6 +260,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.ssh.heading" => "SSH anahtarları", "git.ssh.back" => "Geri", "git.ssh.cancel" => "İptal", + "git.ssh.isoUnsupported" => "Mevcut uzak SSH kullanıyor, ancak yerleşik motor SSH aktarımı yapamıyor. Sistem git kurun veya uzak URL’yi HTTPS olarak değiştirin.", "git.ssh.emptyList" => "Henüz SSH anahtarı yok.", "git.ssh.generateAction" => "Yeni oluştur", "git.ssh.importAction" => "Mevcut olanı içe aktar", @@ -273,6 +284,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.ssh.validationComment" => "Yorum gerekli", "git.ssh.validationImportPath" => "İçe aktarmak için bir özel anahtar dosyası seçin", "git.ssh.providerLink" => "{{host}} SSH anahtar ayarlarını aç", + "git.ssh.genericGuidance" => "Genel anahtarı kopyalayın ve Git sağlayıcınızın SSH anahtar ayarlarına ekleyin.", "git.auth.formLabel" => "Git kimlik bilgileri", "git.auth.heading" => "{{host}} ile kimlik doğrula", "git.auth.headingUnknown" => "Bu remote ile kimlik doğrula", @@ -280,13 +292,18 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.auth.modeToken" => "Token", "git.auth.modeSsh" => "SSH", "git.auth.usernameLabel" => "Kullanıcı adı (isteğe bağlı)", + "git.auth.tokenLabel" => "Erişim token'ı", "git.auth.tokenPlaceholder" => "ghp_… veya PAT", "git.auth.sshKeyLabel" => "SSH anahtarı", + "git.auth.sshNoKeys" => "Kullanılabilir SSH anahtarı yok. Önce Git ayarlarından içe aktarın veya oluşturun.", "git.auth.rememberLabel" => "Bu host için kimlik bilgilerini hatırla", "git.auth.rememberHint" => "Bu host için kimlik bilgilerini hatırla", "git.auth.cancel" => "İptal", + "git.auth.validationToken" => "Erişim token'ı gereklidir", "git.auth.validationSshKey" => "Bir SSH anahtarı seçin", "git.auth.error.auth-required" => "Bu remote kimlik doğrulaması gerektiriyor.", + "git.auth.error.auth-failed" => "Kimlik doğrulama başarısız. Kimlik bilgilerinizi kontrol edin ve tekrar deneyin.", + "git.auth.error.auth-token-invalid" => "Erişim token'ı reddedildi. Yeni bir tane oluşturun ve tekrar deneyin.", "rightPanel.design" => "Tasarım", "rightPanel.code" => "Kod", "rightPanel.noSelection" => "Bir öğe seçin", @@ -310,6 +327,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "updater.restartInstall" => "Yeniden Başlat ve Kur", "updater.installing" => "Kuruluyor...", "updater.releaseDate" => "Yayın tarihi: {{date}}", + "updater.restartHint" => "Güncellemeyi uygulamak için yeniden başlatın. Yeniden başlatma genellikle 10-15 saniye sürer.", "updater.unknownError" => "Bilinmeyen güncelleme hatası.", "updater.title.checking" => "Güncellemeler kontrol ediliyor", "updater.title.available" => "Güncelleme bulundu", @@ -416,6 +434,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "textLayout.autoWidth" => "Oto G", "textLayout.autoWidthDesc" => "Otomatik Genişlik — metin yatay olarak genişler", "textLayout.autoHeight" => "Oto Y", + "textLayout.autoHeightDesc" => "Otomatik Yükseklik — sabit genişlik, yükseklik otomatik ayarlanır", "textLayout.fixed" => "Sabit", "textLayout.fixedDesc" => "Sabit Boyut — hem genişlik hem yükseklik sabit", "textLayout.fillWidth" => "Genişliği Doldur", @@ -492,10 +511,13 @@ pub fn lookup(key: &str) -> Option<&'static str> { "ai.searchModels" => "Model ara...", "ai.noModelsFound" => "Model bulunamadı", "ai.quickAction.loginScreen" => "Mobil giriş ekranı tasarla", + "ai.quickAction.loginScreenPrompt" => "E-posta girişi, şifre girişi, giriş butonu ve sosyal giriş seçenekleri ile modern bir mobil giriş ekranı tasarla", "ai.quickAction.foodApp" => "Yemek uygulaması ana sayfası", "ai.quickAction.foodAppPrompt" => "Generate a well-designed food mobile app homepage", "ai.quickAction.bottomNav" => "Alt gezinme çubuğu tasarla", + "ai.quickAction.bottomNavPrompt" => "5 sekmeli bir mobil uygulama alt gezinme çubuğu tasarla: Ana Sayfa, Ara, Ekle, Mesajlar, Profil", "ai.quickAction.colorPalette" => "Uygulamam için renk paleti öner", + "ai.quickAction.colorPalettePrompt" => "Evcil hayvan bakım uygulaması için modern bir renk paleti öner", "ai.startDesigning" => "Start designing with AI", "ai.maximize" => "Maximize", "ai.restore" => "Restore", @@ -519,6 +541,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "fileMenu.daysAgo" => "{{count}}d ago", "unsaved.title" => "Unsaved changes", "unsaved.message" => "Save changes to \"{{name}}\"?", + "unsaved.dontSave" => "Don't Save", "code.reactTailwind" => "React + Tailwind", "code.htmlCss" => "HTML + CSS", "code.cssVariables" => "CSS Variables", @@ -541,9 +564,8 @@ pub fn lookup(key: &str) -> Option<&'static str> { "agents.mcpIntegrations" => "Terminalde MCP Entegrasyonları", "agents.transport" => "Aktarım", "agents.port" => "Port", - "agents.mcpRestart" => { - "MCP entegrasyonları terminal yeniden başlatıldıktan sonra etkin olacaktır." - } + "agents.mcpRestart" => "MCP entegrasyonları terminal yeniden başlatıldıktan sonra etkin olacaktır.", + "agents.mcpReinstallHint" => "OpenPencil'i yükselttikten sonra uyumluluğu sağlamak için MCP entegrasyonlarını yeniden yükleyin.", "agents.modelCount" => "{{count}} model", "agents.connectionFailed" => "Bağlantı başarısız", "agents.serverError" => "Sunucu hatası {{status}}", @@ -586,9 +608,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "settings.systemDesktopOnly" => "Sistem ayarları masaüstü uygulamasında kullanılabilir.", "settings.envHint" => "{{path}} dosyasında ek ortam değişkenleri ayarlayabilirsiniz.", "builtin.title" => "Yerleşik Sağlayıcılar", - "builtin.description" => { - "API anahtarlarını doğrudan yapılandırın — CLI araçlarına gerek yok." - } + "builtin.description" => "API anahtarlarını doğrudan yapılandırın — CLI araçlarına gerek yok.", "builtin.addProvider" => "Sağlayıcı Ekle", "builtin.empty" => "Henüz yerleşik sağlayıcı yapılandırılmadı.", "builtin.displayName" => "Görünen Ad", @@ -612,9 +632,11 @@ pub fn lookup(key: &str) -> Option<&'static str> { "builtin.custom" => "Özel", "builtin.apiKeyBadge" => "API Key", "builtin.viaApiKey" => "{{name}} API Key ile", + "builtin.errorProviderNotFound" => "Yerleşik sağlayıcı bulunamadı. Lütfen ayarlarınızı kontrol edin.", "builtin.errorApiKeyEmpty" => "API Key boş. Lütfen ayarlardan API Key ekleyin.", "builtin.parallelAgents" => "Paralel alt ajanlar: {{count}}x (döngü için tıklayın)", "builtin.baseUrlPlaceholder" => "https://api.example.com/v1", + "builtin.teamDescription" => "Tasarım oluşturma için bir model seçin. Ayarlandığında, tasarım görevleri otomatik olarak bu modeli kullanan uzman bir ajana devredilir.", "builtin.teamDesignModel" => "Tasarım Modeli", "builtin.teamSelectModel" => "Yok (tek ajan)", "acp.title" => "ACP Agent", @@ -622,6 +644,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "acp.addAgent" => "Agent Ekle", "acp.empty" => "Yapılandırılmış ACP Agent yok.", "acp.displayName" => "Görünen Ad", + "acp.displayNamePlaceholder" => "örn. Tasarım Agent'ım", "acp.connectionType" => "Bağlantı Türü", "acp.local" => "Yerel", "acp.remote" => "Uzak", @@ -638,8 +661,10 @@ pub fn lookup(key: &str) -> Option<&'static str> { "acp.connect" => "Bağlan", "acp.disconnect" => "Bağlantıyı Kes", "acp.localDesktopOnly" => "Yerel Agent yalnızca masaüstü uygulamasında kullanılabilir.", + "figma.title" => "Figma'dan İçe Aktar", "figma.dropFile" => "Bir .fig dosyasını buraya bırakın", "figma.orBrowse" => "veya göz atmak için tıklayın", + "figma.exportTip" => "Figma'dan dışa aktar: File → Save local copy (.fig)", "figma.selectFigFile" => "Lütfen bir .fig dosyası seçin", "figma.noPages" => ".fig dosyasında sayfa bulunamadı", "figma.parseFailed" => ".fig dosyası ayrıştırılamadı", @@ -660,9 +685,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "landing.pencil" => "Pencil", "landing.tagline" => "Açık kaynaklı vektör tasarım aracı. Kod olarak Tasarım.", "landing.newDesign" => "Yeni Tasarım", - "landing.shortcutHint" => { - "Yeni tasarım oluşturmak için {{key1}} + {{key2}} tuşlarına basın" - } + "landing.shortcutHint" => "Yeni tasarım oluşturmak için {{key1}} + {{key2}} tuşlarına basın", "notFound.message" => "Sayfa bulunamadı", "componentBrowser.title" => "UIKit Tarayıcısı", "componentBrowser.exportKit" => "Kiti dışa aktar", diff --git a/crates/openpencil-shell-core/src/i18n/vi.rs b/crates/openpencil-shell-core/src/i18n/vi.rs index 9ba44ea74..f778a728e 100644 --- a/crates/openpencil-shell-core/src/i18n/vi.rs +++ b/crates/openpencil-shell-core/src/i18n/vi.rs @@ -62,11 +62,10 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.close" => "Đóng", "git.initializing" => "Đang khởi tạo kho…", "git.conflict.title" => "Xung đột hợp nhất", - "git.conflict.description" => { - "Giải quyết từng xung đột bằng các thẻ bên dưới, sau đó áp dụng gộp." - } + "git.conflict.description" => "Giải quyết từng xung đột bằng các thẻ bên dưới, sau đó áp dụng gộp.", "git.conflict.abort" => "Hủy hợp nhất", "git.conflict.nonOp.title" => "Gộp tạm dừng ở các tệp không phải .op", + "git.conflict.nonOp.description" => "Gộp .op đã hoàn tất, nhưng các tệp khác trong kho vẫn chưa được giải quyết. Giải quyết chúng bên ngoài OpenPencil, sau đó tiếp tục.", "git.conflict.nonOp.unresolvedHeading_one" => "1 tệp cần xử lý", "git.conflict.nonOp.unresolvedHeading_other" => "{{count}} tệp cần xử lý", "git.conflict.nonOp.continue" => "Tiếp tục gộp", @@ -76,6 +75,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.conflict.banner.continue" => "Tiếp tục", "git.conflict.banner.finalizeError" => "Không thể áp dụng: {{message}}", "git.conflict.banner.pollError" => "Kiểm tra trạng thái tạm dừng do lỗi: {{message}}", + "git.conflict.banner.reopenMessage" => "Bảng điều khiển được mở lại trong khi hợp nhất — vui lòng hủy và pull lại.", "git.conflict.list.heading" => "Tất cả xung đột", "git.conflict.list.progress" => "{{resolved}} / {{total}} đã giải quyết", "git.conflict.list.allResolved" => "Đã giải quyết tất cả", @@ -139,9 +139,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.commit.placeholder" => "Mô tả thay đổi này…", "git.commit.submitButton" => "Lưu mốc", "git.commit.saveRequiredTitle" => "Hãy lưu tài liệu trước", - "git.commit.saveRequiredBody" => { - "Bạn có thay đổi chưa lưu. Lưu tài liệu để tiếp tục: {{label}}" - } + "git.commit.saveRequiredBody" => "Bạn có thay đổi chưa lưu. Lưu tài liệu để tiếp tục: {{label}}", "git.commit.saveRequiredSave" => "Lưu", "git.commit.saveRequiredCancel" => "Hủy", "git.header.autosaveError" => "Lỗi tự động lưu", @@ -213,14 +211,14 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.wizard.clone.submit" => "Sao chép", "git.wizard.clone.validationUrl" => "Cần URL từ xa", "git.wizard.clone.validationDest" => "Cần thư mục đích", - "git.wizard.clone.validationTokenUsername" => { - "Cần tên người dùng khi cung cấp mã thông báo" - } - "git.wizard.clone.error.clone-network" => { - "Lỗi mạng khi sao chép. Kiểm tra kết nối và thử lại." - } + "git.wizard.clone.validationTokenUsername" => "Cần tên người dùng khi cung cấp mã thông báo", + "git.wizard.clone.error.clone-network" => "Lỗi mạng khi sao chép. Kiểm tra kết nối và thử lại.", "git.wizard.clone.error.network" => "Lỗi mạng. Kiểm tra kết nối và thử lại.", + "git.wizard.clone.error.timeout" => "Sao chép hết thời gian. Thử lại hoặc dùng kho lưu trữ nhỏ hơn.", "git.wizard.clone.error.auth-required" => "Kho lưu trữ này cần xác thực.", + "git.wizard.clone.error.auth-failed" => "Xác thực thất bại. Kiểm tra tên người dùng và mã thông báo.", + "git.wizard.clone.error.auth-token-invalid" => "Mã thông báo truy cập bị từ chối. Tạo mã mới và thử lại.", + "git.wizard.clone.error.clone-failed" => "Sao chép thất bại. Hãy xác minh URL trỏ đến một kho lưu trữ thực sự.", "git.wizard.clone.error.clone-target-exists" => "Thư mục đích đã tồn tại hoặc không trống.", "git.pull.label" => "Pull", "git.pull.tooltip" => "Pull từ origin", @@ -250,6 +248,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.remote.clearConfirmAction" => "Xác nhận", "git.remote.aheadBehind" => "Trước {{ahead}} · Sau {{behind}}", "git.remote.fetchButton" => "Fetch", + "git.remote.sshIsoUnsupported" => "Engine tích hợp không hỗ trợ truyền tải SSH. Cài đặt git hệ thống hoặc chuyển sang URL remote HTTPS.", "git.remote.storedAuthLabel" => "Thông tin xác thực đã lưu", "git.remote.storedAuth.token" => "Token", "git.remote.storedAuth.ssh" => "Khóa SSH", @@ -261,14 +260,13 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.ssh.heading" => "Khóa SSH", "git.ssh.back" => "Quay lại", "git.ssh.cancel" => "Hủy", + "git.ssh.isoUnsupported" => "Remote hiện tại dùng SSH, nhưng engine tích hợp không thể thực hiện truyền tải SSH. Cài đặt git hệ thống hoặc đổi URL remote sang HTTPS.", "git.ssh.emptyList" => "Chưa có khóa SSH nào.", "git.ssh.generateAction" => "Tạo mới", "git.ssh.importAction" => "Nhập khóa có sẵn", "git.ssh.copyPublicKey" => "Sao chép khóa công khai", "git.ssh.copiedHint" => "Đã sao chép", - "git.ssh.copyUnsupported" => { - "Không có clipboard — vui lòng sao chép khóa này theo cách thủ công." - } + "git.ssh.copyUnsupported" => "Không có clipboard — vui lòng sao chép khóa này theo cách thủ công.", "git.ssh.deleteKey" => "Xóa {{name}}", "git.ssh.deletePrompt" => "Xóa khóa SSH {{name}}?", "git.ssh.deleteConfirm" => "Xóa", @@ -286,6 +284,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.ssh.validationComment" => "Ghi chú là bắt buộc", "git.ssh.validationImportPath" => "Chọn tệp khóa riêng để nhập", "git.ssh.providerLink" => "Mở cài đặt khóa SSH {{host}}", + "git.ssh.genericGuidance" => "Sao chép khóa công khai và thêm vào cài đặt khóa SSH của nhà cung cấp Git của bạn.", "git.auth.formLabel" => "Thông tin xác thực Git", "git.auth.heading" => "Xác thực với {{host}}", "git.auth.headingUnknown" => "Xác thực với remote này", @@ -296,9 +295,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.auth.tokenLabel" => "Access token", "git.auth.tokenPlaceholder" => "ghp_… hoặc PAT", "git.auth.sshKeyLabel" => "Khóa SSH", - "git.auth.sshNoKeys" => { - "Không có khóa SSH khả dụng. Nhập hoặc tạo mới trong cài đặt Git trước." - } + "git.auth.sshNoKeys" => "Không có khóa SSH khả dụng. Nhập hoặc tạo mới trong cài đặt Git trước.", "git.auth.rememberLabel" => "Ghi nhớ thông tin xác thực cho máy chủ này", "git.auth.rememberHint" => "Ghi nhớ thông tin xác thực cho máy chủ này", "git.auth.cancel" => "Hủy", @@ -330,6 +327,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "updater.restartInstall" => "Khởi động lại & Cài đặt", "updater.installing" => "Đang cài đặt...", "updater.releaseDate" => "Ngày phát hành: {{date}}", + "updater.restartHint" => "Khởi động lại để áp dụng bản cập nhật. Quá trình khởi động lại thường mất 10-15 giây.", "updater.unknownError" => "Lỗi cập nhật không xác định.", "updater.title.checking" => "Đang kiểm tra bản cập nhật", "updater.title.available" => "Đã tìm thấy bản cập nhật", @@ -436,6 +434,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "textLayout.autoWidth" => "Tự động R", "textLayout.autoWidthDesc" => "Tự động chiều rộng — văn bản mở rộng theo chiều ngang", "textLayout.autoHeight" => "Tự động C", + "textLayout.autoHeightDesc" => "Tự động chiều cao — chiều rộng cố định, chiều cao tự điều chỉnh", "textLayout.fixed" => "Cố định", "textLayout.fixedDesc" => "Kích thước cố định — cả chiều rộng và chiều cao đều cố định", "textLayout.fillWidth" => "Lấp đầy chiều rộng", @@ -501,6 +500,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "ai.newChat" => "Cuộc trò chuyện mới", "ai.collapse" => "Thu gọn", "ai.tryExample" => "Thử một ví dụ để thiết kế...", + "ai.tipSelectElements" => "Mẹo: Chọn các phần tử trên canvas trước khi trò chuyện để cung cấp ngữ cảnh.", "ai.generating" => "Đang tạo...", "ai.designWithAgent" => "Thiết kế với Agent...", "ai.attachImage" => "Đính kèm hình ảnh", @@ -511,13 +511,13 @@ pub fn lookup(key: &str) -> Option<&'static str> { "ai.searchModels" => "Tìm kiếm mô hình...", "ai.noModelsFound" => "Không tìm thấy mô hình", "ai.quickAction.loginScreen" => "Thiết kế màn hình đăng nhập di động", + "ai.quickAction.loginScreenPrompt" => "Thiết kế màn hình đăng nhập di động hiện đại với ô nhập email, ô nhập mật khẩu, nút đăng nhập và các tuỳ chọn đăng nhập bằng mạng xã hội", "ai.quickAction.foodApp" => "Trang chủ ứng dụng ẩm thực", "ai.quickAction.foodAppPrompt" => "Generate a well-designed food mobile app homepage", "ai.quickAction.bottomNav" => "Thiết kế thanh điều hướng dưới cùng", + "ai.quickAction.bottomNavPrompt" => "Thiết kế thanh điều hướng dưới cùng cho ứng dụng di động với 5 tab: Trang chủ, Tìm kiếm, Thêm, Tin nhắn, Hồ sơ", "ai.quickAction.colorPalette" => "Gợi ý bảng màu cho ứng dụng", - "ai.quickAction.colorPalettePrompt" => { - "Gợi ý bảng màu hiện đại cho ứng dụng chăm sóc thú cưng" - } + "ai.quickAction.colorPalettePrompt" => "Gợi ý bảng màu hiện đại cho ứng dụng chăm sóc thú cưng", "ai.startDesigning" => "Start designing with AI", "ai.maximize" => "Maximize", "ai.restore" => "Restore", @@ -541,6 +541,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "fileMenu.daysAgo" => "{{count}}d ago", "unsaved.title" => "Unsaved changes", "unsaved.message" => "Save changes to \"{{name}}\"?", + "unsaved.dontSave" => "Don't Save", "code.reactTailwind" => "React + Tailwind", "code.htmlCss" => "HTML + CSS", "code.cssVariables" => "CSS Variables", @@ -564,6 +565,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "agents.transport" => "Giao thức", "agents.port" => "Cổng", "agents.mcpRestart" => "Các tích hợp MCP sẽ có hiệu lực sau khi khởi động lại terminal.", + "agents.mcpReinstallHint" => "Sau khi nâng cấp OpenPencil, vui lòng cài đặt lại tích hợp MCP để đảm bảo tương thích.", "agents.modelCount" => "{{count}} mô hình", "agents.connectionFailed" => "Kết nối thất bại", "agents.serverError" => "Lỗi máy chủ {{status}}", @@ -630,9 +632,11 @@ pub fn lookup(key: &str) -> Option<&'static str> { "builtin.custom" => "Tùy chỉnh", "builtin.apiKeyBadge" => "API Key", "builtin.viaApiKey" => "qua API Key của {{name}}", + "builtin.errorProviderNotFound" => "Không tìm thấy nhà cung cấp tích hợp. Vui lòng kiểm tra cài đặt của bạn.", "builtin.errorApiKeyEmpty" => "API Key đang trống. Vui lòng thêm API Key trong cài đặt.", "builtin.parallelAgents" => "Tác nhân phụ song song: {{count}}x (nhấn để chuyển đổi)", "builtin.baseUrlPlaceholder" => "https://api.example.com/v1", + "builtin.teamDescription" => "Chọn mô hình để tạo thiết kế. Khi được đặt, các tác vụ thiết kế sẽ tự động được giao cho agent chuyên dụng sử dụng mô hình này.", "builtin.teamDesignModel" => "Mô hình thiết kế", "builtin.teamSelectModel" => "Không (agent đơn)", "acp.title" => "ACP Agent", diff --git a/crates/openpencil-shell-core/src/i18n/zh_cn.rs b/crates/openpencil-shell-core/src/i18n/zh_cn.rs index 2672d70b9..5e41a6475 100644 --- a/crates/openpencil-shell-core/src/i18n/zh_cn.rs +++ b/crates/openpencil-shell-core/src/i18n/zh_cn.rs @@ -65,6 +65,9 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.conflict.description" => "使用下方卡片逐一解决每个冲突,然后应用合并。", "git.conflict.abort" => "中止合并", "git.conflict.nonOp.title" => "合并因非 .op 文件暂停", + "git.conflict.nonOp.description" => { + ".op 文件合并已完成,但仓库中仍有其他文件未解决。请在 OpenPencil 之外解决它们,然后继续。" + } "git.conflict.nonOp.unresolvedHeading_one" => "1 个文件需要处理", "git.conflict.nonOp.unresolvedHeading_other" => "{{count}} 个文件需要处理", "git.conflict.nonOp.continue" => "继续合并", @@ -261,6 +264,9 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.ssh.heading" => "SSH 密钥", "git.ssh.back" => "返回", "git.ssh.cancel" => "取消", + "git.ssh.isoUnsupported" => { + "当前远端使用 SSH,但内置引擎无法执行 SSH 传输。请安装系统 git,或将远端地址改为 HTTPS。" + } "git.ssh.emptyList" => "暂无 SSH 密钥。", "git.ssh.generateAction" => "生成新密钥", "git.ssh.importAction" => "导入现有密钥", @@ -511,9 +517,15 @@ pub fn lookup(key: &str) -> Option<&'static str> { "ai.searchModels" => "搜索模型...", "ai.noModelsFound" => "未找到匹配的模型", "ai.quickAction.loginScreen" => "设计一个移动端登录页面", + "ai.quickAction.loginScreenPrompt" => { + "设计一个现代的移动端登录页面,包含邮箱输入框、密码输入框、登录按钮和社交登录选项" + } "ai.quickAction.foodApp" => "美食App首页", "ai.quickAction.foodAppPrompt" => "Generate a well-designed food mobile app homepage", "ai.quickAction.bottomNav" => "设计一个底部导航栏", + "ai.quickAction.bottomNavPrompt" => { + "设计一个包含 5 个标签的移动应用底部导航栏:首页、搜索、添加、消息、个人" + } "ai.quickAction.colorPalette" => "为我的应用推荐配色方案", "ai.quickAction.colorPalettePrompt" => "为一个宠物护理应用推荐一套现代配色方案", "ai.startDesigning" => "用 AI 开始设计", @@ -634,6 +646,9 @@ pub fn lookup(key: &str) -> Option<&'static str> { "builtin.errorApiKeyEmpty" => "API 密钥为空,请在设置中添加您的 API 密钥。", "builtin.parallelAgents" => "并行子代理:{{count}}x(点击切换)", "builtin.baseUrlPlaceholder" => "https://api.example.com/v1", + "builtin.teamDescription" => { + "选择用于设计生成的模型。设置后,设计任务将自动委派给使用此模型的专业 Agent。" + } "builtin.teamDesignModel" => "设计模型", "builtin.teamSelectModel" => "无(单 Agent)", "acp.title" => "ACP Agent", diff --git a/crates/openpencil-shell-core/src/i18n/zh_tw.rs b/crates/openpencil-shell-core/src/i18n/zh_tw.rs index 2b8673dc2..60213cb6f 100644 --- a/crates/openpencil-shell-core/src/i18n/zh_tw.rs +++ b/crates/openpencil-shell-core/src/i18n/zh_tw.rs @@ -65,6 +65,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.conflict.description" => "使用下方卡片逐一解決每個衝突,然後套用合併。", "git.conflict.abort" => "中止合併", "git.conflict.nonOp.title" => "合併因非 .op 檔案暫停", + "git.conflict.nonOp.description" => ".op 檔案合併已完成,但儲存庫中仍有其他檔案未解決。請在 OpenPencil 之外解決它們,然後繼續。", "git.conflict.nonOp.unresolvedHeading_one" => "1 個檔案需要處理", "git.conflict.nonOp.unresolvedHeading_other" => "{{count}} 個檔案需要處理", "git.conflict.nonOp.continue" => "繼續合併", @@ -247,9 +248,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.remote.clearConfirmAction" => "確認", "git.remote.aheadBehind" => "領先 {{ahead}} · 落後 {{behind}}", "git.remote.fetchButton" => "取得", - "git.remote.sshIsoUnsupported" => { - "內建引擎不支援 SSH 傳輸。請安裝系統 git,或改用 HTTPS 遠端網址。" - } + "git.remote.sshIsoUnsupported" => "內建引擎不支援 SSH 傳輸。請安裝系統 git,或改用 HTTPS 遠端網址。", "git.remote.storedAuthLabel" => "已儲存的憑證", "git.remote.storedAuth.token" => "權杖", "git.remote.storedAuth.ssh" => "SSH 金鑰", @@ -261,6 +260,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "git.ssh.heading" => "SSH 金鑰", "git.ssh.back" => "返回", "git.ssh.cancel" => "取消", + "git.ssh.isoUnsupported" => "目前的遠端使用 SSH,但內建引擎無法執行 SSH 傳輸。請安裝系統 git,或將遠端網址改為 HTTPS。", "git.ssh.emptyList" => "尚無 SSH 金鑰。", "git.ssh.generateAction" => "產生新金鑰", "git.ssh.importAction" => "匯入現有金鑰", @@ -511,9 +511,11 @@ pub fn lookup(key: &str) -> Option<&'static str> { "ai.searchModels" => "搜尋模型...", "ai.noModelsFound" => "未找到匹配的模型", "ai.quickAction.loginScreen" => "設計行動裝置登入頁面", + "ai.quickAction.loginScreenPrompt" => "設計一個現代的行動裝置登入頁面,包含電子郵件輸入框、密碼輸入框、登入按鈕和社群登入選項", "ai.quickAction.foodApp" => "美食App首頁", "ai.quickAction.foodAppPrompt" => "Generate a well-designed food mobile app homepage", "ai.quickAction.bottomNav" => "設計底部導覽列", + "ai.quickAction.bottomNavPrompt" => "設計一個包含 5 個標籤的行動應用程式底部導覽列:首頁、搜尋、新增、訊息、個人", "ai.quickAction.colorPalette" => "為我的應用程式推薦配色方案", "ai.quickAction.colorPalettePrompt" => "為一個寵物照護應用程式推薦一套現代配色方案", "ai.startDesigning" => "用 AI 開始設計", @@ -634,6 +636,7 @@ pub fn lookup(key: &str) -> Option<&'static str> { "builtin.errorApiKeyEmpty" => "API 金鑰為空,請在設定中新增您的 API 金鑰。", "builtin.parallelAgents" => "並行子代理:{{count}}x(點擊切換)", "builtin.baseUrlPlaceholder" => "https://api.example.com/v1", + "builtin.teamDescription" => "選擇用於設計生成的模型。設定後,設計任務將自動委派給使用此模型的專業 Agent。", "builtin.teamDesignModel" => "設計模型", "builtin.teamSelectModel" => "無(單 Agent)", "acp.title" => "ACP Agent", diff --git a/tools/__pycache__/convert-locales.cpython-314.pyc b/tools/__pycache__/convert-locales.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1fd038624879c749ba29101ac6163c3efdc7706f GIT binary patch literal 6413 zcmbVQYit|G5#Bo<$>W=PS+*=oC)qJYSrq+H;%A)3wjA4%E#)LrNkfUI$dg2g;<0;2 z%ckpqDcVM=jfzPPSV7!IDBQw912ipyqD2cd=%1!QQOKbm%tb}gw0{Ehhg8=HkYAnM z6G=suXJA)Xy~_(a;8UNm7mUoh!bZL?b*V(JbUTDvwk1Jfmi4ecTj}2`q&|nG zI4UR3OIQ`;q?CYPBo_CFlS#!tAr1N!9P!6??MwLMawHs=6n}H8st7|dAca^$m91h* zQHAla8X570@wlLd2Z<<^h)P(9;IIl!O8xqj5h)(`MPw|MdOoCgeYh1XtyXJ$I5Hyi z_RvoV(uJgq;d^00i6w^Pk{}O`N)c6v$5aW2b2#-si z1A^y#IG&O`EhWK3OdV;Jlt?&9<>6pr@DXt;5sS!CD*r6=QxIGGBtaUFsW6Ch$<&}Q zln~;wJeEo}!M6?w+Z7di1>a$zE2+lh#G&mTMGdR5hyeV<=U{kY)ruuGg%b)LD;*RW zu`rg9ClUg50`p5mg)?#j<_FWk6EQ`Cl{lS>t1(|Z25j00s$nVNQH7KuMPc!2cd$~5 zoWcoV4NDiSF-1^PLqoAhOiHM&)-zs4b4!#*V}^Rt3H~qOs?Jjz!Zi z3 zClWH8Oeqw?wb1oG_$waBGUy9b!?+hocCBrJ6gQ6Dth%YZb9DB?PwMa1?xLaxP!-YT zBm_xhDd=(z!CW$^6(yMf>Mkrct)gclfX&_|em7~cA{7A2joO*x7KD;)X~Db6rmaW; zwg6>GL%=}hK+-VX#*VEB1q|KL%gQvs6kBm?)F}2V0aVwn)lae3Y4;la6b($$7%+C* zR*nRLK>{PRbi7uTbE0uwIhd$*#I`r7vtSGXQdL_ zaum$MmuxVoF(}OjJsRVIw?>U=gd(9aRwz`Bu|R<}#_^ToOAb~A{2!cxEQ5l@gBvU! zQ8>=V!mvtZ=^zahCsR0DFhqu!R8V`(5E;Rm0gR+(9L91g3A)XUQ?=fXH$xST4W+co zWEd+_NL5;OGpHPH4W&+lR3S>5LGu+Gt|>FS-rD=d-q~Gm9+<_s>gHU-IucN2yI%$8=PW(n^BhC)_z zI{|A!&?mO{gJ&g?{rNMPYq|oS4Jld`MUbIhTj;T4Zk`1VO?96xo&>VJi}bG z{<`7!p5J)hZ}@HVq;bKD9Oa)lDyRCgftf(gu}!DX&K%7-gaW@e=V&bOkL4T!(D#e^tx%T+II`*-1{eud3V)y$7_z6q1kB8y#wBP`?PJ!mhH)Q-sc+@ z{iy8l!cJs&XFBL+eZ?4Yuo&c^J=jTC<*~*HYUxQgD!3BfG)BQ2p!70$lU@)*q+1TU z3l!;Tc9sZ;l)!x%vvHAR*Y+%s;>I5ORvIHzqls)P9pfM1NEZ;^jgJ43V03^L5p_Ue zB!HF7s>ol&+k(~SXH~4LwG(X)B-(c`pZ%|3RI9FQ$pXTB|D@xi=vWP`0>vEw zXma8wVMj3x4dLx1dxB(5B=eB0nPgs)wUBHFWNAY%bxAYqY`dT_moA(g{%kwfer#T4ADVI_qZ`ZHF^wx0R-TH)t))}vBNpZ z?wUR|bt-%Qp1m&baAvn%eQ_OD>Yjbeidt*1<{j>A*_A*xdbNM4znQ8V3ZUuv*~m=% zRwL;1J$vh?OJD!S_fIcwK~C2~9kM&8_fGB2?zwVkj;k(dN5N3=Fb%3589JZ!HF#BL zl7ogct?fdB8(OR-8kW&qiS~1_w?>Kx_%QSb(65BXSZ_g;h+f3Bd#o#%ULO?}ad zN&@{5$BZu8B!v`lRfn;3yhVn%N+Q>4Od3i`Q*aoQTmS(aoj_;;oGBdW>)j9C>;8O) z1C)nbRV9{z1vqd7L!(&eo1MT-W2+v7i;vq_i3PV^P7tXC2C;Bg4 zhMRzM!e^Ol>3yVSR2I&3^$H^p%lf2fOl=iJ$%j)3;oMqL$+=bxTZhuS|JSfuxRkCW zo<@&6E;Ugn=A;Qx`FdA>Sq)kM0*^8fpflws$ znlLew;08&mW(Y^46!0i`Vd5!*OGI=Gcaf}{)HLdj6{kp20)LILpM^~Kh_+LoNC!g; zxkU&OM8pB8KvnBKATsDv{>Xj)_j9Jl#VGz10I6?+?<()wuVXW-DWI$|w3FvJZ4KW0q_=4Fs8#9t>! zWMdqQB)b}+g+3aP6_XVx3Ntq;%#_0V)#6WxPf3JIW&o*vS-8KNdKSP3fM<3Ic$gru z1vCW^zyZ6PZCMue5npLF6)f~bY%fW}4a8>%0&wX`Gz3^X+RX-w@z!dWiy~JVc}EBM zBxI3jD#0j#XMqVG1&q+RVuTz(CGqrEq#&^rH1+KYph9#a4 z3r!`U0lsy25jFuRf2;%L0D{wC>-Dml8G;75sZt=gy8t&MA$crq0F+5v#$yV(0X!f; z5XF((N8n=x*TWaE09lH}X~JjUeO*YiLKA2;xmNRf9hyn(2^~8rLbx*)jbY8)*>&{U z&h{S72seo15DoR}ViWzIq8XEz1Z)Q7BFGdKE-^8UUo`6kh88rOqS~t&;!?tE)Xb_9 zBKM6DLlp?%kh>n;6caXiQ|JH**yv!ujfZ0i3~nc)2m6;mK(NPAt(>X6#br7{G3RTy zzIFPI(?9CE&2OAE&zEnU8J>9&oR(+qmN!qD^R5lkFHgOE-&OyitA5^ImOV+tbLF0Q zB0nE}d-Se-KOn@st9r(qa|sYxt!&P_?(;Rb`I;O1XM5j$F1Pv6`xA3~%^kjLo_A!c zvzD2vnTeU$EPiL}t?19Zw>H0fe9n3B9)D=D3~gyyEJt<+)jN$3g~((=A#a&x4uzs} z1g@A4!h~=HGP0-YNIW)3Z@ln1!Y79j4^Ux59#6t{YUV(@c%-YR9TP)Dmt2Qjf|PWb z$Y;nxhe8?$o29;u=-2htWOci SnCiU}xW`p48W2}Q=ldT(>JDlE literal 0 HcmV?d00001 diff --git a/tools/convert-locales.py b/tools/convert-locales.py index 1e9bd4b7e..c854273e5 100644 --- a/tools/convert-locales.py +++ b/tools/convert-locales.py @@ -40,16 +40,32 @@ LOCALES = { "id": "id", } -KEY_RE = re.compile(r"^\s*'([^']+)':\s*'((?:[^'\\]|\\.)*)',?\s*$") +# Match `'key': 'value'` / `'key': "value"` on one logical line. +# Spans newline because some entries split key + value across lines: +# 'long.key.name': +# 'value here', +KEY_RE = re.compile( + r"""^\s*'([^']+)':\s*(?: + '((?:[^'\\]|\\.)*)' + | "((?:[^"\\]|\\.)*)" + ),?\s*$""", + re.VERBOSE | re.MULTILINE, +) +KEY_AND_VALUE_RE = re.compile( + r"""'([^']+)':\s*(?: + '((?:[^'\\]|\\.)*)' + | "((?:[^"\\]|\\.)*)" + )\s*,?""", + re.VERBOSE, +) def parse_ts(path: Path) -> list[tuple[str, str]]: - rows = [] - for line in path.read_text(encoding="utf-8").splitlines(): - m = KEY_RE.match(line) - if not m: - continue - key, value = m.group(1), m.group(2) + text = path.read_text(encoding="utf-8") + rows: list[tuple[str, str]] = [] + for m in KEY_AND_VALUE_RE.finditer(text): + key = m.group(1) + value = m.group(2) if m.group(2) is not None else m.group(3) # TS uses \u escapes + \n / \t — Python read_text already # decoded the file as UTF-8, but the JS-style \uXXXX # escapes are still literal. Decode them.