feat(i18n): add multi-language support (ja/ko/vi/ru/zh-TW) with system auto-detection

- Extend AppLanguage to 7 locales: zh-CN, zh-TW, en, ja, ko, vi, ru
- Auto-detect system language via navigator.languages; fallback to English
- Add BCP47 locale mapping for date formatting and sorting
- Create 50 translation JSON files (5 languages × 10 namespaces, 1137 keys each)
- Update language selector with native language names
- Extend locale key parity test to cover all 7 languages (70 assertions)
- Add VNC/RDP desktop, serial terminal, AI agent, port forwarding, and SFTP features
- Add credential encryption, host metrics, session backup crypto, and zmodem bridge
- Update Rust backend: desktop services, host metrics, SSH/SFTP enhancements
This commit is contained in:
Logan.Li committed 2026-08-12 00:07:48 +08:00
1 parent fea6d8db04
commit b0d0e3a5f3
301 files changed
+28002 -2705

No files matched your search

+119
View File
@@ -0,0 +1,119 @@
{
"toolbar": {
"splitHorizontal": "Разделить влево/вправо",
"splitVertical": "Разделить сверху/снизу",
"addPane": "Добавить панель",
"closePane": "Закрыть текущую панель",
"maximizePane": "Развернуть текущую панель",
"restoreLayout": "Восстановить разделённый макет",
"broadcast": "Широковещательная рассылка",
"broadcastAria": "Широковещательный ввод",
"broadcastOn": "Рассылка включена: ввод синхронизируется в {{count}} терминалах в области",
"broadcastOffPro": "Широковещательный ввод (Pro) · {{count}} терминалов в области",
"broadcastNeedPanesTab": "Для рассылки этой вкладке нужно минимум 2 готовые панели (сначала разделите)",
"broadcastNeedPanesAll": "Для рассылки во всех вкладках терминала нужно минимум 2 готовых терминала",
"broadcastScopeAria": "Область рассылки",
"broadcastScopeTab": "Панели текущей вкладки",
"broadcastScopeAll": "Все вкладки терминала",
"broadcastActive": "Рассылка · {{count}}",
"aiAssistant": "AI-ассистент",
"aiOpen": "Открыть терминального AI-ассистента",
"aiClose": "Закрыть терминального AI-ассистента",
"aiTitle": "Терминальный AI-ассистент (Pro)",
"paneCount": "{{current}}/{{max}}",
"labelLocal": "Локальный терминал",
"labelSsh": "SSH-терминал",
"closePaneLabel": "Закрыть текущую панель",
"closeTabLabel": "Закрыть текущую вкладку терминала",
"targetSshSession": "Текущий SSH-сеанс"
},
"overlay": {
"shellClosedIdle": "Тайм-аут простоя; оболочка завершилась",
"shellClosed": "Оболочка завершилась",
"shellClosedHint": "SSH-подключение сохранено; остальные панели, SFTP и туннели не затронуты",
"reopenShell": "Открыть оболочку снова",
"reopening": "Открытие…",
"disconnected": "Отключено",
"disconnectedHint": "SSH-сеанс завершился или сеть упала. Нажмите ниже, чтобы переподключиться.",
"reconnect": "Переподключиться",
"suspended": "Подключение приостановлено",
"suspendedHint": "Долгое отсутствие активности; подключение приостановлено для экономии ресурсов",
"resume": "Возобновить подключение",
"connectFailed": "Сбой подключения",
"connectFailedHint": "Проверьте хост, порт, имя пользователя и аутентификацию",
"retryConnect": "Повторить подключение",
"connecting": "Подключение…",
"reconnecting": "Автопереподключение{{attempt}}…",
"reconnectingAttempt": " ({{count}})",
"localShellExited": "Локальная оболочка завершилась"
},
"hostKey": {
"titleNew": "Проверка ключа хоста",
"titleChanged": "Ключ хоста изменился",
"descNew": "Первое подключение к этому хосту. Проверьте отпечаток перед доверием.",
"descChanged": "SSH-ключ этого хоста больше не совпадает с локальной записью. Возможен риск MITM.",
"host": "Хост",
"type": "Тип",
"fingerprint": "SHA256-отпечаток",
"previousFingerprint": "Предыдущий отпечаток",
"reject": "Отклонить",
"acceptOnce": "Доверять один раз",
"acceptAlways": "Всегда доверять",
"acceptAlwaysChanged": "Доверять и обновить в любом случае"
},
"contextMenu": {
"aria": "Действия терминала",
"copy": "Копировать",
"paste": "Вставить",
"selectAll": "Выделить всё",
"clear": "Очистить экран",
"splitRight": "Разделить справа",
"splitDown": "Разделить вниз",
"maximizePane": "Развернуть текущую панель",
"restoreLayout": "Восстановить разделённый макет"
},
"search": {
"placeholder": "Поиск...",
"previous": "Предыдущее (Shift+Enter)",
"next": "Следующее (Enter)",
"close": "Закрыть (Escape)"
},
"zmodem": {
"uploadTransferring": "rz загрузка: {{detail}}",
"downloadTransferring": "sz скачивание: {{detail}}",
"selectLocalFile": "Выберите локальный файл",
"pickUploadTitle": "Выберите файл для загрузки (rz)",
"uploadedCount": "Загружено файлов: {{count}}",
"downloadedSingle": "{{path}}",
"downloadedCount": "Скачано файлов: {{count}} → {{dir}}",
"transferDone": "Передача завершена",
"transferFailed": "Сбой передачи {{message}}",
"uploadSuccessTerminal": "✓ Загружено файлов: {{count}} в удалённый рабочий каталог",
"downloadSuccessTerminal": "✓ Скачано {{path}}",
"savedDownloadsSingle": "✓ Сохранено в Downloads",
"savedDownloadsMultiple": "✓ Сохранено файлов: {{count}} в Downloads",
"nativeApiUnavailable": "Нативный API недоступен",
"readFailed": "Сбой чтения: {{name}}",
"writeFailed": "Сбой записи: {{name}}",
"createLocalShellFailed": "Не удалось создать локальную оболочку",
"createRemoteShellFailed": "Не удалось создать удалённую оболочку",
"createShellFailed": "Не удалось создать оболочку: {{error}}"
},
"clipboard": {
"readFailed": "Не удалось прочитать буфер обмена",
"writeFailed": "Не удалось записать в буфер обмена"
},
"input": {
"failed": "Сбой ввода в терминал"
},
"connection": {
"errorPrefix": "Ошибка: {{message}}",
"autoReconnecting": "Автопереподключение ({{attempt}})...",
"autoReconnectLimit": "Достигнут предел автопереподключений ({{max}}){{reasonSuffix}}",
"autoReconnectLimitReason": " — {{reason}}",
"disconnectedRetry": "Отключено, повтор {{attempt}}/{{max}} через {{seconds}} с...",
"autoReconnectBanner": "[Автопереподключение] Повтор {{attempt}}/{{max}} через {{seconds}} с",
"disconnectedBanner": "[Отключено] {{reason}}",
"noConfig": "Данные для подключения отсутствуют"
}
}