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

+186
View File
@@ -0,0 +1,186 @@
{
"panel": {
"local": "로컬",
"remote": "원격",
"notConnectedTitle": "원격 서버에 연결되지 않음",
"notConnectedDesc": "SFTP를 사용하려면 먼저 SSH 세션을 연결하세요",
"ariaLabel": "{{title}} 파일 패널"
},
"connection": {
"selectServer": "서버 선택",
"noSessions": "저장된 세션 없음",
"createSessionHint": "먼저 사이드바에서 세션을 생성하세요",
"reconnect": "재연결",
"notConnected": "연결되지 않음",
"connecting": "연결 중..."
},
"errors": {
"notConnected": "SFTP가 연결되지 않았습니다",
"noUploadFiles": "업로드할 파일이 없습니다",
"localStatFailed": "로컬 파일 정보를 읽을 수 없습니다",
"loadRemoteFailed": "원격 디렉터리 로드 실패: {{message}}",
"noFolderDownload": "폴더 다운로드 실패",
"selectDownloadFiles": "먼저 다운로드할 파일을 선택하세요",
"uploadFailed": "업로드 실패",
"downloadFailed": "다운로드 실패",
"fileError": "{{fileName}}: {{message}}"
},
"toolbar": {
"upload": "업로드",
"uploadAria": "업로드",
"download": "다운로드",
"downloadAria": "다운로드",
"downloadNeedSelection": "먼저 원격 파일을 선택하세요",
"downloadHint": "선택한 원격 파일 다운로드",
"refresh": "새로고침",
"refreshAria": "새로고침",
"newFolder": "새 폴더",
"newFolderAria": "새 폴더"
},
"sort": {
"name": "이름",
"modified": "수정일",
"size": "크기",
"type": "유형"
},
"nav": {
"home": "홈",
"back": "뒤로",
"forward": "앞으로",
"up": "위로",
"searchPlaceholder": "파일 이름 검색",
"clearSearch": "검색 지우기",
"clearSearchAria": "검색 지우기",
"showHidden": "숨김 파일 표시",
"hideHidden": "도트파일 숨기기 (.xxx)",
"showHiddenAria": "숨김 파일 표시",
"hideHiddenAria": "도트파일 숨기기",
"searchAria": "{{title}}에서 검색"
},
"status": {
"loading": "불러오는 중...",
"selected": "{{count}}개 선택됨",
"filtered": "{{shown}} / {{total}} 표시 중",
"hiddenCount": "전체 {{total}}개 항목 ({{hidden}}개 숨김)",
"total": "{{count}}개 항목",
"filterHint": "필터: {{query}}"
},
"empty": {
"dirTitle": "빈 디렉터리",
"dirDescLocal": "이 디렉터리에 파일이 없습니다",
"dirDescRemote": "위로 이동하거나 새로고침해 보세요",
"goUp": "위로 이동",
"hiddenOnlyTitle": "숨김 파일만",
"hiddenOnlyDesc": "헤더의 눈 아이콘을 클릭하여 도트파일 표시",
"showHiddenAction": "숨김 파일 표시",
"noMatchTitle": "일치하는 파일 없음",
"noMatchDesc": "\"{{query}}\"와 일치하는 파일이 없습니다"
},
"fileType": {
"folder": "폴더",
"symlink": "링크",
"symlinkLong": "심볼릭 링크",
"file": "파일",
"text": "텍스트",
"log": "로그",
"database": "데이터베이스",
"imageIso": "디스크 이미지",
"executable": "실행 파일",
"library": "라이브러리"
},
"relativeDate": {
"today": "오늘",
"yesterday": "어제",
"daysAgo": "{{count}}일 전"
},
"contextMenu": {
"open": "열기",
"upload": "업로드",
"download": "다운로드",
"edit": "편집",
"rename": "이름 변경",
"copyPath": "경로 복사",
"properties": "속성",
"permissions": "권한",
"delete": "삭제"
},
"dialog": {
"renameTitle": "이름 변경",
"renameMessage": "새 이름 입력:",
"renamePlaceholder": "새 이름",
"newFolderTitle": "새 폴더",
"newFolderMessage": "폴더 이름 입력:",
"newFolderPlaceholder": "폴더 이름",
"propertiesTitle": "파일 속성",
"propertiesClose": "닫기",
"chmodTitle": "권한 편집",
"chmodApply": "적용",
"pickUploadTitle": "업로드할 파일 또는 폴더 선택",
"pickUploadRzTitle": "업로드할 파일 선택 (rz)"
},
"properties": {
"name": "이름",
"path": "경로",
"size": "크기",
"permissions": "권한",
"modified": "수정일",
"accessed": "액세스일",
"symlink": "심볼릭 링크",
"loadingDetails": "세부 정보 로드 중..."
},
"chmod": {
"read": "읽기",
"write": "쓰기",
"execute": "실행",
"owner": "소유자",
"group": "그룹",
"other": "기타",
"current": "현재 모드:",
"readR": "읽기 (r)",
"writeW": "쓰기 (w)",
"executeX": "실행 (x)"
},
"transfer": {
"queue": "전송 대기열",
"active": "{{count}}개 활성",
"completed": "{{count}}개 완료",
"taskCount": "{{count}}개 작업",
"empty": "전송 작업 없음",
"cancel": "취소",
"remove": "제거",
"statusWaiting": "대기 중",
"statusDone": "완료",
"statusFailed": "실패",
"statusCancelled": "취소됨",
"dropUpload": "{{path}}에 업로드",
"dropDownload": "{{path}}에 다운로드"
},
"editor": {
"readFailed": "읽기 실패",
"saveFailed": "저장 실패",
"unsavedClose": "저장되지 않은 변경 사항이 있습니다. 그래도 닫으시겠습니까?",
"saving": "저장 중...",
"save": "저장",
"saved": "파일 저장됨",
"loadingEditor": "에디터 로드 중...",
"footer": "UTF-8 · Monaco · ⌘/Ctrl+S 저장 · 최대 ~2MB",
"charCount": "{{count}}자",
"unsavedMark": " · 저장 안 됨",
"savedMark": " · 저장됨"
},
"toast": {
"renamed": "{{name}}(으)로 이름 변경됨",
"renameFailed": "이름 변경 실패",
"pathCopied": "경로가 클립보드에 복사됨",
"pathCopyFailed": "경로 복사 실패",
"chmodUpdated": "권한이 {{mode}}(으)로 업데이트됨",
"chmodFailed": "권한 업데이트 실패",
"uploadPartial": "{{action}} 완료 {{completed}}, 실패 {{failed}}: {{detail}}",
"uploadSuccess": "{{completed}}개 항목에 대해 {{action}} 완료",
"uploadAction": "업로드",
"downloadAction": "다운로드",
"noFolderUpload": "폴더 업로드 실패",
"noDragPath": "드래그 앤 드롭 경로를 사용할 수 없습니다; 업로드를 사용하세요",
"noFolderRecursive": "재귀 폴더 전송 실패; 재시도하거나 업로드를 사용하세요"
}
}