feat: harden local shell, SFTP, and desktop session reliability

Finder-launched terminals now inherit a login PATH so tools like ollama resolve, destructive SFTP/editor actions require confirmation, and terminal search plus window dragging work again. SSH forwards and RDP sessions keep listeners and survive reconnect without FastPath crashes.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Logan.LiandCursor committed 2026-08-16 16:08:11 +08:00
1 parent 188f3556ed
commit 08696896f9
223 files changed
+13493 -3423

No files matched your search

+120 -36
View File
@@ -90,6 +90,8 @@
"terminal": "Terminal",
"batch": "Batch exec",
"newTerminal": "New terminal",
"closeAria": "Close {{title}}",
"listAria": "Open tabs",
"kind": {
"terminal": "Terminal",
"sftp": "SFTP",
@@ -105,7 +107,8 @@
"closeRight": "Close tabs to the right",
"closeLeft": "Close tabs to the left",
"closeAll": "Close all",
"clone": "Duplicate tab"
"clone": "Duplicate tab",
"openSftp": "Open SFTP"
}
},
"sidebar": {
@@ -149,37 +152,42 @@
"disconnect": "Disconnect"
},
"pro": {
"upgrade": "Upgrade Pro",
"upgrade": "Upgrade to Pro",
"feature": "Pro features",
"unlock": "Unlock {{feature}}",
"unlock": "Unlock Pro advanced features",
"comingSoon": "Coming soon",
"activateSuccess": "Activated",
"activateFailed": "Activation failed",
"licenseActivated": "Pro license activated",
"paymentPending": "After payment, paste your license here or try activating again later",
"invalidLicense": "Activation failed: invalid license",
"goUpgrade": "Upgrade",
"goUpgrade": "Upgrade to Pro",
"haveLicense": "Have a license? Activate",
"title": "OpsXShell Pro · Unlock pro ops features",
"subtitleComingSoon": "{{feature}} coming soon · upgrade Pro for early access",
"subtitleUnlock": "Unlocking: {{feature}}",
"subtitleDefault": "Forwarding, proxy, serial, AI, batch, and broadcast",
"title": "OpsXShell · Unlock Pro",
"subtitleComingSoon": "Advanced features coming soon · upgrade to Pro for early access",
"subtitleUnlock": "Unlocking advanced Pro features",
"subtitleDefault": "Port forwarding, terminal AI, batch ops, host lists, and remote desktop in Pro",
"activated": "Pro activated",
"expiresAt": " · valid until {{date}}",
"lifetime": " · lifetime license",
"oneTimeFee": "One-time purchase · lifetime on this device · no subscription",
"oneTimeFee": "Free / Pro Yearly / Pro Perpetual",
"pasteLicense": "Paste license",
"activateButton": "Activate",
"clearLicense": "Clear local license",
"paymentNote": "Checkout is handled by Waffo; this app does not collect card details.",
"testDeviceId": "Test environment · device ID: {{deviceId}}",
"later": "Maybe later",
"viewPro": "View Pro",
"wallComingSoonSuffix": " · coming soon",
"wallUnlock": "Unlock {{feature}}",
"wallMessageComingSoon": "This Pro capability is still in development. Upgrade for early access.",
"wallMessageDefault": "This feature requires OpsXShell Pro. Upgrade to use it on this device.",
"viewPro": "View Pro plans",
"wallComingSoonSuffix": "coming soon",
"wallUnlock": "Unlock Pro advanced features",
"wallMessageComingSoon": "This capability is part of OpsXShell Pro and is still being finished. Upgrade to Pro Yearly or Perpetual for early access.",
"wallMessageDefault": "Port forwarding, terminal AI, batch execution, host lists, and remote desktop are included in Pro. Upgrade to Pro Yearly or Perpetual to use them on this device.",
"checkoutUnavailable": "Checkout unavailable ({{status}})",
"emailLabel": "Email",
"emailRequired": "Enter your email before checkout",
"claimPending": "Claiming your license…",
"invalidKeyFormat": "Invalid key format — paste a LIC- license key",
"accountEmail": "Account: {{email}}",
"freeTier": "Free",
"proTier": "Pro",
"freeItems": {
@@ -192,21 +200,59 @@
"proItems": {
"forward": "Port forwarding",
"proxy": "Session proxy / SOCKS",
"serial": "Serial terminal",
"serial": "Serial console",
"ai": "Terminal AI assistant",
"batch": "Batch exec / broadcast sync",
"broadcast": "Broadcast input sync",
"importExport": "Bulk import/export hosts",
"desktop": "RDP / VNC remote desktop"
}
"batch": "Batch execute / broadcast sync",
"broadcast": "Broadcast synchronized input",
"importExport": "Batch import/export host list",
"desktop": "Remote desktop (RDP / VNC)"
},
"planYearly": "Pro Yearly",
"planYearlyDesc": "¥99 / year · 2 devices",
"planPerpetual": "Pro Perpetual",
"planPerpetualDesc": "¥199 · 5 devices · lifetime",
"planTrial": "Pro Trial",
"devices": "Up to {{count}} devices",
"goUpgradeYearly": "Buy Pro Yearly",
"goUpgradePerpetual": "Buy Pro Perpetual",
"activatedYearly": "Pro Yearly activated",
"activatedPerpetual": "Pro Perpetual activated",
"activatedTrial": "Pro Trial activated",
"choosePlan": "Choose: Free / Pro Yearly / Pro Perpetual",
"planFreePrice": "¥0",
"planFreeDesc": "SSH · SFTP · local terminal",
"planFreeCta": "Current plan",
"planIncludesPro": "Includes all Pro features",
"planFree": "Free",
"subtitleUnlockDetail": "Related capability: {{feature}}",
"wallUnlockComingSoon": "Pro advanced features coming soon",
"wallMessageComingSoonFeature": "“{{feature}}” is a Pro advanced capability still being finished. Upgrade to Pro Yearly or Perpetual for early access.",
"wallMessageFeature": "“{{feature}}” is a Pro advanced capability. Upgrade to Pro Yearly or Perpetual to use it on this device."
},
"launcher": {
"title": "Quick launch",
"description": "Sessions, local shells, and device consoles",
"description": "Start here: sessions, local shells, desktop, and serial",
"cards": {
"quickConnect": { "title": "Quick connect", "desc": "user@host:port" },
"saveSession": { "title": "Save session", "desc": "Credentials, groups, proxy" },
"serial": { "title": "Serial terminal", "desc": "Baud rate and port settings" }
"quickConnect": {
"title": "Quick connect",
"desc": "user@host:port"
},
"saveSession": {
"title": "Save session",
"desc": "Credentials, groups, proxy"
},
"serial": {
"title": "Serial terminal",
"desc": "Baud rate and port settings"
},
"rdp": {
"title": "RDP desktop",
"desc": "Remote Windows desktop"
},
"vnc": {
"title": "VNC desktop",
"desc": "Remote graphical desktop"
}
},
"sectionLocalShell": "Local shell",
"sectionSavedSessions": "Saved sessions",
@@ -220,6 +266,7 @@
"forwardOpenRunning": "SOCKS5 running (:{{port}}) · click to manage · right-click to copy",
"forwardStarted": "Forward started",
"forwardStartedDynamic": "SOCKS5 started: socks5://127.0.0.1:{{port}}",
"forwardResumed": "Restored {{count}} port forward(s)",
"socksStartFailed": "Start failed: {{message}}",
"socksStopFailed": "Stop failed: {{message}}",
"socksCopied": "Copied socks5://127.0.0.1:{{port}}"
@@ -240,7 +287,7 @@
"typeDynamic": "Dynamic",
"running": "Running",
"socksProxy": "SOCKS5: 127.0.0.1:{{port}}",
"remoteToLocal": "Remote {{remote}} → local {{local}}",
"remoteToLocal": "remote {{bind}}:{{remote}} → {{host}}:{{local}}",
"stats": "{{connections}} conn · ↑{{up}} · ↓{{down}}",
"copyProxy": "Copy proxy",
"copyRule": "Duplicate rule",
@@ -250,15 +297,15 @@
"delete": "Delete",
"editTitle": "Edit forward",
"addTitle": "Add forward",
"typeLocalDesc": "Local → remote",
"typeRemoteDesc": "Remote → local",
"typeLocalDesc": "Reach a remote service",
"typeRemoteDesc": "Expose a local service",
"typeDynamicDesc": "SOCKS5",
"selectType": "Type",
"drawerSubtitle": "Tunnel via the current SSH session",
"ruleFields": "Details",
"dynamicHint": "Local SOCKS5, default 127.0.0.1:1080 (editable). Traffic exits via this SSH server's public IP.",
"dynamicSingleHint": "One Dynamic rule per SSH host; change the listen port while stopped.",
"dynamicPortHint": "If the port is busy, pick another local port (e.g. 1081).",
"dynamicHint": "Local SOCKS5 (default :1080). Traffic exits via this SSH server.",
"dynamicSingleHint": "One Dynamic rule per SSH host; change the port while stopped.",
"dynamicPortHint": "If busy, try another port (e.g. 1081).",
"ruleList": "Rules",
"ruleListEmpty": "No Local / Remote rules yet",
"addSection": "Add new",
@@ -292,17 +339,30 @@
"internet": "Internet",
"localCaption": "Local: reach a remote port as if it were local.",
"remoteCaption": "Remote: remote access is forwarded to a local service.",
"dynamicCaption": "Dynamic: this machine becomes a SOCKS5 proxy that exits via the current SSH server's public IP."
"dynamicCaption": "Dynamic: local SOCKS5 that exits via this SSH server."
},
"ruleName": "Name",
"ruleNamePlaceholder": "e.g. MySQL",
"localListenPort": "Local listen port",
"localListenPortHint": "Defaults to localhost — same as ssh -L port:…. Usually just enter the port.",
"localBindAdvanced": "Advanced: change local bind",
"localTargetPort": "Local target port",
"remoteTargetPort": "Remote target port",
"remoteTargetPort": "Target port",
"remoteListenPort": "Remote listen port",
"remoteListenPortHint": "Defaults to remote localhost — same as ssh -R port:…. Usually just enter the port.",
"remoteListenAddress": "Remote listen",
"remoteListenAddressPlaceholder": "127.0.0.1:18080",
"remoteListenAddressHint": "127.0.0.1 = remote host only; 0.0.0.0 = remote LAN (needs GatewayPorts).",
"errorRemoteListenAddress": "Enter a valid remote listen address, e.g. 127.0.0.1:18080",
"localTargetAddress": "Local / LAN target",
"localTargetAddressPlaceholder": "127.0.0.1:8080",
"localTargetAddressHint": "Forwards to a local or LAN service, e.g. 127.0.0.1:8080. Do not use 0.0.0.0.",
"viaSessionRemote": "Listen on {{target}} (localhost by default)",
"errorRemoteListenPort": "Enter a valid remote listen port (1–65535)",
"errorLocalTargetAddress": "Enter a valid local/LAN target, e.g. 127.0.0.1:8080",
"portPlaceholder": "e.g. 3306",
"remoteHost": "Remote host",
"remoteHostPlaceholder": "localhost or IP",
"remoteHost": "Target host",
"remoteHostPlaceholder": "127.0.0.1",
"socksRuleName": "SOCKS5 proxy",
"defaultLocalName": "Local forward",
"defaultRemoteName": "Remote forward",
@@ -316,11 +376,35 @@
"deleteConfirm": "Delete this rule?",
"errorNamePort": "Enter a name and a valid port (1–65535)",
"errorTargetPort": "Enter a valid target port (1–65535)",
"errorRemoteHost": "Enter a remote host",
"errorRemoteHost": "Enter a target host (relative to the SSH server)",
"errorNotConnected": "Not connected",
"errorStartFailed": "Start failed",
"errorStopFailed": "Stop failed",
"errorSocksRunning": "SOCKS5 already running",
"copySuffix": "Copy"
"copySuffix": "Copy",
"remoteBindHint": "0.0.0.0 needs GatewayPorts; without it sshd often still binds 127.0.0.1. Target must not be 0.0.0.0.",
"localToRemote": "local {{bind}}:{{local}} → remote {{host}}:{{remote}}",
"localToRemotePort": "local :{{local}} → remote {{host}}:{{remote}}",
"remoteHostHint": "Relative to the SSH server. Use 127.0.0.1 for that host, or a reachable LAN IP. Not 0.0.0.0.",
"localBindHost": "Local bind",
"localBindHostPlaceholder": "127.0.0.1",
"localBindHostHint": "This machine only by default. Use 0.0.0.0 or a LAN IP for network access.",
"errorTargetHostInvalid": "Target cannot be 0.0.0.0 — use 127.0.0.1 or a reachable internal IP",
"listenAddress": "Local listen",
"listenAddressPlaceholder": "127.0.0.1:8080",
"listenAddressHint": "This machine only by default; 0.0.0.0 allows LAN access.",
"targetAddress": "Remote target",
"targetAddressPlaceholder": "127.0.0.1:80",
"targetAddressHint": "As seen from the SSH server. Use 127.0.0.1:port for a service on that host.",
"errorListenAddress": "Enter a valid listen address, e.g. 127.0.0.1:8080",
"errorTargetAddress": "Enter a valid target, e.g. 127.0.0.1:80",
"targetAddressHintVia": "Via {{target}}. Use 127.0.0.1:port for a service on that host (does not open a new remote port).",
"viaSession": "Tunnel via {{target}}",
"remoteToLocalPort": "remote :{{remote}} → {{host}}:{{local}}",
"remoteBindAdvanced": "Advanced: change remote bind",
"remoteBindHost": "Remote bind",
"remoteBindHostPlaceholder": "127.0.0.1",
"remoteBindHostHint": "Remote host only by default. 0.0.0.0 needs GatewayPorts; without it most sshd still bind 127.0.0.1 only.",
"remoteGatewayPortsWarning": "Requested remote 0.0.0.0 listen. Without GatewayPorts, sshd often silently binds 127.0.0.1 only."
}
}
+11 -4
View File
@@ -15,10 +15,12 @@
"passwordOptional": "Password (optional)",
"width": "Width",
"height": "Height",
"rdpFootnote": "Native IronRDP: TCP → X.224 → TLS → CredSSP/NLA → MCS; 45s handshake timeout. Certificate verification is relaxed during development.",
"vncFootnote": "Native vnc-rs RFB with Tight JPEG decoding; clipboard is sent as UTF-8 (very old servers may garble text).",
"rdpFootnote": "Fullscreen or maximize dynamically requests remote resolution to match the window. You can also pick an initial size before connecting. Certificate verification is relaxed during development.",
"vncFootnote": "Most VNC servers keep a fixed remote resolution; fullscreen only scales locally. Preferred size at connect is advisory. Clipboard is sent as UTF-8.",
"errorHostRequired": "Enter a host address",
"errorUsernameRequired": "Enter a username"
"errorUsernameRequired": "Enter a username",
"resolution": "Resolution",
"resolutionCustom": "Custom"
},
"toolbar": {
"pasteClipboard": "Paste local clipboard to remote",
@@ -28,7 +30,12 @@
"openShareDir": "Open shared folder locally (Downloads)",
"openShareDirAria": "Open shared folder",
"disconnect": "Disconnect",
"disconnectAria": "Disconnect"
"disconnectAria": "Disconnect",
"fullscreen": "Fullscreen",
"fullscreenAria": "Enter fullscreen",
"exitFullscreen": "Exit fullscreen",
"exitFullscreenAria": "Exit fullscreen",
"exitFullscreenHint": "Esc / F11 to exit"
},
"status": {
"connecting": "Connecting…",
+16 -3
View File
@@ -39,7 +39,9 @@
"closed": "Connection closed",
"dnsFailed": "Could not resolve host",
"refused": "Connection refused",
"disconnected": "Disconnected"
"disconnected": "Disconnected",
"keepaliveFailed": "SSH keep-alive failed repeatedly; connection closed",
"idleKicked": "Remote shell logged out due to idle timeout (TMOUT)"
},
"auth": {
"failed": "Authentication failed. Check the username and password.",
@@ -68,7 +70,10 @@
"forward": {
"failed": "Port forward setup failed",
"bindFailed": "Failed to bind port",
"alreadyInUse": "Port already in use"
"alreadyInUse": "Local port is already in use. Stop the running forward (or the other process on that port), then start again.",
"remoteDenied": "Remote port forward refused by the server (AllowTcpForwarding / PermitListen, port in use, or bind limits). OpsXShell listens on remote 127.0.0.1 only.",
"remoteDeniedPrivileged": "Remote refused a privileged listen port (<1024). Use a port ≥1024, or root on the server, and check AllowTcpForwarding / PermitListen.",
"invalidTargetHost": "Target cannot be 0.0.0.0 — use 127.0.0.1 or a reachable internal IP"
},
"sftp": {
"connectFailed": "SFTP connection failed",
@@ -80,7 +85,15 @@
"writeFailed": "Save failed",
"renameFailed": "Rename failed",
"chmodFailed": "Failed to update permissions",
"apiUnavailable": "SFTP API unavailable"
"apiUnavailable": "SFTP API unavailable",
"channelFailed": "Could not open SFTP channel (server limit or busy session). Reconnect and try again",
"sessionGone": "SFTP session ended; reconnect to continue",
"busy": "A file transfer is in progress. Try again when it finishes.",
"editTooLarge": "File is too large for the text editor (max ~2MB). Download it and open locally.",
"editBinary": "This file looks binary and cannot be opened in the text editor",
"editNotUtf8": "Remote file is not valid UTF-8 text",
"transferCancelled": "Transfer cancelled",
"diskFull": "Not enough disk space on the remote or local side"
},
"session": {
"notFound": "Session not found",
+6 -4
View File
@@ -69,17 +69,17 @@
"confirm": "Delete"
},
"welcome": {
"tagline": "Remote terminal · SFTP · Port forwarding",
"tagline": "Simple & practical · terminal · files · desktop",
"sectionStart": "Get started",
"sectionDesktop": "Remote desktop",
"sectionRecent": "Recent sessions",
"quickConnect": {
"title": "Quick connect",
"desc": "One-off SSH; not saved to the library"
"desc": "One-shot SSH — not saved to the session library"
},
"newSession": {
"title": "New session",
"desc": "Save hosts; double-click in the sidebar to connect"
"desc": "Save a host — double-click in the sidebar to connect"
},
"localShell": {
"title": "Local shell",
@@ -167,7 +167,9 @@
"jumpHost": "Jump host (optional)",
"jumpNone": "No jump host",
"jumpNoneAlt": "No jump host",
"jumpHint": "One saved session can be used as a jump host"
"jumpHint": "One saved session can be used as a jump host",
"resolution": "Resolution",
"resolutionCustom": "Custom"
},
"batch": {
"title": "Batch exec",
+50 -18
View File
@@ -1,9 +1,7 @@
{
"nav": {
"general": "Workspace",
"generalDesc": "Layout and resources",
"appearance": "Appearance",
"appearanceDesc": "Theme and language",
"general": "General",
"generalDesc": "Theme, language, and layout",
"terminal": "Terminal",
"terminalDesc": "Font and colors",
"shortcuts": "Shortcuts",
@@ -15,11 +13,13 @@
"ai": "AI models",
"aiDesc": "AI providers",
"about": "About",
"aboutDesc": "Version and data"
"aboutDesc": "Version and data",
"account": "Account",
"accountDesc": "Email, license, and device"
},
"title": "Settings",
"search": {
"placeholder": "Search settings..."
"placeholder": "Search settings…"
},
"language": {
"label": "Language",
@@ -89,7 +89,7 @@
"ssh": {
"connection": "Connection",
"keepAlive": "Keep-alive",
"keepAliveDesc": "Send keep-alive when idle to reduce disconnects",
"keepAliveDesc": "Send SSH keep-alive while idle; disconnect only after several missed replies",
"autoReconnect": "Auto reconnect",
"autoReconnectDesc": "Automatically retry after unexpected disconnects",
"timeout": "Connection timeout",
@@ -102,7 +102,9 @@
"maxBackground": "Background connection limit",
"maxBackgroundDesc": "Evict least recently used connections when over limit",
"suspend": "Background suspend",
"suspendDesc": "Minutes before releasing active channels when a tab is in background"
"suspendDesc": "Minutes before idle background tabs suspend (active Shell/SFTP stay connected)",
"keepAliveInterval": "Keep-alive interval (sec)",
"keepAliveIntervalDesc": "How often to ping the server (like ClientAliveInterval). Use 15s or less on flaky Wi‑Fi / NAT"
},
"security": {
"credentials": "Credential protection",
@@ -119,7 +121,7 @@
"clearConfirm": "Clear all known host keys? You will be prompted again on next connect."
},
"about": {
"tagline": "A lightweight native SSH / SFTP ops terminal",
"tagline": "Simple, practical native ops terminal",
"appVersion": "App v{{version}}",
"copyVersion": "Copy version info",
"runtime": "Runtime",
@@ -127,8 +129,9 @@
"localData": "Local data",
"sessionsSettings": "Sessions and settings",
"masterKeyPath": "Master key",
"privacyNote": "Passwords and key passphrases are encrypted with AES-256-GCM in Rust. OpsXShell does not save terminal command history.",
"license": "MIT License · Rust · XTerm.js"
"privacyNote": "Passwords and key passphrases are AES-256-GCM encrypted in Rust. No terminal history, no bastion audit trail.",
"license": "MIT License · Rust · XTerm.js",
"logPath": "Application log"
},
"ai": {
"presets": "Provider presets",
@@ -162,13 +165,42 @@
"apiKeySaveFailed": "Failed to save API key",
"providerNotFound": "Provider not found",
"modelCatalogReadFailed": "Failed to read model catalog",
"catalogUnavailable": "models.dev is unavailable"
"catalogUnavailable": "models.dev is unavailable",
"family": {
"openai_compatible": "OpenAI compatible",
"standalone": "Native APIs",
"plan": "Subscription plans",
"local": "Self-hosted",
"custom": "Custom"
}
},
"family": {
"openai_compatible": "OpenAI compatible",
"standalone": "────────",
"plan": "Plan",
"local": "Self-hosted",
"custom": "Custom"
"account": {
"title": "Account",
"email": "Email",
"emailDesc": "Used for checkout and license claims",
"plan": "Current plan",
"planFree": "Free",
"planYearly": "Pro Yearly",
"planPerpetual": "Pro Perpetual",
"planTrial": "Pro Trial",
"expires": "Expires {{date}}",
"lifetime": "Lifetime",
"devices": "Seats: up to {{count}} devices",
"deviceId": "This device ID",
"saveEmail": "Save email",
"activate": "Activate license",
"pasteLicense": "Paste LIC- license key",
"clear": "Clear local license",
"deactivate": "Deactivate this device",
"upgrade": "Upgrade",
"saved": "Saved",
"activateOk": "Activated",
"deviceList": "Bound devices",
"loadingDevices": "Loading devices…",
"noDevices": "No bound devices",
"thisDevice": "This device",
"removeDevice": "Unbind",
"deviceRemoved": "Device unbound",
"seatFull": "All seats are in use. Unbind another device before activating on a new machine."
}
}
+54 -24
View File
@@ -3,8 +3,9 @@
"local": "Local",
"remote": "Remote",
"notConnectedTitle": "Not connected to remote server",
"notConnectedDesc": "Connect an SSH session first to use SFTP",
"ariaLabel": "{{title}} file panel"
"notConnectedDesc": "Connect SSH first, then transfer files or edit configs",
"ariaLabel": "{{title}} file panel",
"reconnectResumeDesc": "Disconnected. One-click reconnect resumes at {{path}}"
},
"connection": {
"selectServer": "Select server",
@@ -12,7 +13,9 @@
"createSessionHint": "Create a session in the sidebar first",
"reconnect": "Reconnect",
"notConnected": "Not connected",
"connecting": "Connecting..."
"connecting": "Connecting...",
"resumeHint": "Reconnect will resume at {{path}}",
"reconnectingResume": "Reconnecting and resuming {{path}}…"
},
"errors": {
"notConnected": "SFTP is not connected",
@@ -23,19 +26,14 @@
"selectDownloadFiles": "Select files to download first",
"uploadFailed": "Upload failed",
"downloadFailed": "Download failed",
"fileError": "{{fileName}}: {{message}}"
"fileError": "{{fileName}}: {{message}}",
"mkdirFailed": "Failed to create folder"
},
"toolbar": {
"upload": "Upload",
"uploadAria": "Upload",
"download": "Download",
"downloadAria": "Download",
"downloadNeedSelection": "Select remote files first",
"downloadHint": "Download selected remote files",
"refresh": "Refresh",
"refreshAria": "Refresh",
"refreshAria": "Refresh this pane",
"newFolder": "New folder",
"newFolderAria": "New folder"
"newFolderAria": "New folder in this pane"
},
"sort": {
"name": "Name",
@@ -55,7 +53,8 @@
"hideHidden": "Hide dotfiles (.xxx)",
"showHiddenAria": "Show hidden files",
"hideHiddenAria": "Hide dotfiles",
"searchAria": "Search in {{title}}"
"searchAria": "Search in {{title}}",
"upAtRoot": "Already at root"
},
"status": {
"loading": "Loading...",
@@ -63,7 +62,8 @@
"filtered": "Showing {{shown}} / {{total}}",
"hiddenCount": "{{total}} items ({{hidden}} hidden)",
"total": "{{count}} items",
"filterHint": "Filter: {{query}}"
"filterHint": "Filter: {{query}}",
"refreshing": "Refreshing..."
},
"empty": {
"dirTitle": "Empty directory",
@@ -99,7 +99,6 @@
"download": "Download",
"edit": "Edit",
"rename": "Rename",
"copyPath": "Copy path",
"properties": "Properties",
"permissions": "Permissions",
"delete": "Delete"
@@ -116,7 +115,18 @@
"chmodTitle": "Edit permissions",
"chmodApply": "Apply",
"pickUploadTitle": "Choose files or folders to upload",
"pickUploadRzTitle": "Choose file to upload (rz)"
"pickUploadRzTitle": "Choose file to upload (rz)",
"overwriteTitle": "Overwrite existing files?",
"overwriteConfirm": "Overwrite",
"overwriteSkip": "Skip",
"overwriteOneRemote": "「{{name}}」 already exists remotely. Overwrite?",
"overwriteOneLocal": "「{{name}}」 already exists locally. Overwrite?",
"overwriteManyRemote": "{{count}} items already exist remotely. Overwrite all?",
"overwriteManyLocal": "{{count}} items already exist locally. Overwrite all?",
"overwriteMore": "…and {{count}} more",
"deleteTitle": "Delete",
"deleteMessage": "Delete {{count}} item(s): {{names}}",
"deleteRecursiveWarn": "This includes folders. Deletion is recursive and cannot be undone."
},
"properties": {
"name": "Name",
@@ -152,27 +162,41 @@
"statusDone": "Done",
"statusFailed": "Failed",
"statusCancelled": "Cancelled",
"dropUpload": "Upload to {{path}}",
"dropDownload": "Download to {{path}}"
"dropUpload": "Drop to upload to {{path}}",
"dropDownload": "Drop to download to {{path}}",
"railAria": "Transfer between local and remote",
"railUpload": "Upload selected local files (or choose files if none selected)",
"railDownload": "Download selected remote files to local",
"railUploadAria": "Upload to remote",
"railDownloadAria": "Download to local",
"railDownloadNeedSelection": "Select remote files first",
"retry": "Retry"
},
"editor": {
"readFailed": "Read failed",
"saveFailed": "Save failed",
"unsavedClose": "Unsaved changes. Close anyway?",
"unsavedTitle": "Unsaved changes",
"discardAndClose": "Discard and close",
"reloadTitle": "Reload",
"discardAndReload": "Discard and reload",
"saving": "Saving...",
"save": "Save",
"saved": "File saved",
"loadingEditor": "Loading editor...",
"footer": "UTF-8 · Monaco · ⌘/Ctrl+S save · ~2MB max",
"loadBlocked": "Could not load file content",
"footer": "UTF-8 · ⌘/Ctrl+S save · Esc close · max ~2MB",
"charCount": "{{count}} characters",
"unsavedMark": " · unsaved",
"savedMark": " · saved"
"savedMark": " · saved",
"title": "Edit {{name}}",
"dirtyBadge": "Unsaved",
"reload": "Reload",
"unsavedReload": "Discard unsaved changes and reload?"
},
"toast": {
"renamed": "Renamed to {{name}}",
"renameFailed": "Rename failed",
"pathCopied": "Path copied to clipboard",
"pathCopyFailed": "Failed to copy path",
"chmodUpdated": "Permissions updated to {{mode}}",
"chmodFailed": "Failed to update permissions",
"uploadPartial": "{{action}} finished {{completed}}, failed {{failed}}: {{detail}}",
@@ -180,7 +204,13 @@
"uploadAction": "Upload",
"downloadAction": "Download",
"noFolderUpload": "Folder upload failed",
"noDragPath": "Drag-and-drop paths are unavailable; use Upload",
"noFolderRecursive": "Recursive folder transfer failed; retry or use Upload"
"noDragPath": "This system did not provide a drag path. Use the → arrow or choose files to upload.",
"noFolderRecursive": "Folder transfer failed. Retry or use the → arrow / file picker.",
"dropFailed": "Drop failed: could not read the file info. Try again or use the transfer arrows.",
"folderCreated": "Created folder {{name}}",
"allSkippedExisting": "Skipped all files that already exist",
"skippedExisting": "Skipped {{count}} existing file(s)",
"deleteFailed": "Delete failed",
"deleted": "Deleted"
}
}
+3 -2
View File
@@ -34,7 +34,7 @@
"reopenShell": "Reopen shell",
"reopening": "Opening…",
"disconnected": "Disconnected",
"disconnectedHint": "The SSH session ended or the network dropped. Click below to reconnect.",
"disconnectedHint": "The SSH session ended or the network dropped. One click below reconnects so you can keep working.",
"reconnect": "Reconnect",
"suspended": "Connection suspended",
"suspendedHint": "Inactive for a while; connection was suspended to save resources",
@@ -70,7 +70,8 @@
"splitRight": "Split right",
"splitDown": "Split down",
"maximizePane": "Maximize current pane",
"restoreLayout": "Restore split layout"
"restoreLayout": "Restore split layout",
"openSftp": "Open SFTP"
},
"search": {
"placeholder": "Search...",
+106 -31
View File
@@ -90,6 +90,8 @@
"terminal": "ターミナル",
"batch": "一括実行",
"newTerminal": "新規ターミナル",
"closeAria": "{{title}} を閉じる",
"listAria": "開いているタブ",
"kind": {
"terminal": "ターミナル",
"sftp": "SFTP",
@@ -105,7 +107,8 @@
"closeRight": "右側のタブを閉じる",
"closeLeft": "左側のタブを閉じる",
"closeAll": "すべて閉じる",
"clone": "タブを複製"
"clone": "タブを複製",
"openSftp": "SFTP を開く"
}
},
"sidebar": {
@@ -151,7 +154,7 @@
"pro": {
"upgrade": "Pro にアップグレード",
"feature": "Pro 機能",
"unlock": "{{feature}} のロック解除",
"unlock": "Pro の高度な機能を解除",
"comingSoon": "近日公開",
"activateSuccess": "アクティベート済み",
"activateFailed": "アクティベートに失敗",
@@ -160,28 +163,33 @@
"invalidLicense": "アクティベート失敗: 無効なライセンス",
"goUpgrade": "アップグレード",
"haveLicense": "ライセンスをお持ちですか? アクティベート",
"title": "OpsXShell Pro · プロ向け運用機能をアンロック",
"subtitleComingSoon": "{{feature}} は近日公開 · Pro にアップグレードで早期アクセス",
"subtitleUnlock": "アンロック中: {{feature}}",
"subtitleDefault": "転送、プロキシ、シリアル、AI、一括実行、ブロードキャスト",
"title": "OpsXShell · Pro を解除",
"subtitleComingSoon": "高度な機能は近日公開 · Pro で先行体験",
"subtitleUnlock": "高度な機能を解除しています",
"subtitleDefault": "ポート転送、ターミナル AI、一括運用、ホスト一覧、リモートデスクトップなどの Pro 機能",
"activated": "Pro アクティベート済み",
"expiresAt": " · 有効期限 {{date}}",
"lifetime": " · 永久ライセンス",
"oneTimeFee": "1 回限りの購入 · このデバイスで永久利用 · サブスクなし",
"oneTimeFee": "無料 / Pro 年額 / Pro 永久",
"pasteLicense": "ライセンスを貼り付け",
"activateButton": "アクティベート",
"clearLicense": "ローカルライセンスを削除",
"paymentNote": "決済は Waffo が処理します。本アプリはカード情報を収集しません。",
"testDeviceId": "テスト環境 · デバイス ID: {{deviceId}}",
"later": "後で",
"viewPro": "Pro を見る",
"wallComingSoonSuffix": " · 近日公開",
"wallUnlock": "{{feature}} のロックを解除",
"wallMessageComingSoon": "この Pro 機能はまだ開発中です。アップグレードで早期アクセス。",
"wallMessageDefault": "この機能には OpsXShell Pro が必要です。このデバイスで利用するにはアップグレードしてください。",
"viewPro": "Pro プランを見る",
"wallComingSoonSuffix": "近日公開",
"wallUnlock": "Pro の高度な機能を解除",
"wallMessageComingSoon": "この能力は OpsXShell Pro に含まれ、実装整備中です。Pro 年額または永久で先行体験できます。",
"wallMessageDefault": "ポート転送、ターミナル AI、一括実行、ホスト一覧、リモートデスクトップは Pro に含まれます。Pro 年額または永久でこの端末で利用できます。",
"checkoutUnavailable": "チェックアウト不可 ({{status}})",
"emailLabel": "メールアドレス",
"emailRequired": "チェックアウト前にメールアドレスを入力してください",
"claimPending": "ライセンスを取得しています…",
"invalidKeyFormat": "キー形式が無効です。LIC- で始まるライセンスキーを貼り付けてください",
"accountEmail": "アカウント: {{email}}",
"freeTier": "無料",
"proTier": "Pro",
"proTier": "プロフェッショナル",
"freeItems": {
"ssh": "SSH ターミナル",
"sftp": "SFTP ファイルマネージャー",
@@ -192,17 +200,38 @@
"proItems": {
"forward": "ポート転送",
"proxy": "セッションプロキシ / SOCKS",
"serial": "シリアルターミナル",
"serial": "シリアル端末",
"ai": "ターミナル AI アシスタント",
"batch": "一括実行 / ブロードキャスト同期",
"broadcast": "ブロードキャスト入力同期",
"importExport": "ホストの一括インポート/エクスポート",
"desktop": "RDP / VNC リモートデスクトップ"
}
"broadcast": "ブロードキャスト同期入力",
"importExport": "ホスト一覧の一括インポート/エクスポート",
"desktop": "リモートデスクトップ(RDP / VNC)"
},
"planYearly": "Pro 年額",
"planYearlyDesc": "¥99 / 年 · 2 台",
"planPerpetual": "Pro 永久",
"planPerpetualDesc": "¥199 · 5 台 · 生涯",
"planTrial": "Pro 体験",
"devices": "最大 {{count}} 台",
"goUpgradeYearly": "Pro 年額を購入",
"goUpgradePerpetual": "Pro 永久を購入",
"activatedYearly": "Pro 年額が有効",
"activatedPerpetual": "Pro 永久が有効",
"activatedTrial": "Pro 体験が有効",
"choosePlan": "選択:無料 / Pro 年額 / Pro 永久",
"planFreePrice": "¥0",
"planFreeDesc": "SSH · SFTP · ローカル端末",
"planFreeCta": "現在のプラン",
"planIncludesPro": "全 Pro 機能を含む",
"planFree": "無料",
"subtitleUnlockDetail": "関連機能:{{feature}}",
"wallUnlockComingSoon": "Pro の高度な機能は近日公開",
"wallMessageComingSoonFeature": "「{{feature}}」は Pro の高度な機能で、実装整備中です。Pro 年額または永久で先行体験できます。",
"wallMessageFeature": "「{{feature}}」は Pro の高度な機能です。Pro 年額または永久でこの端末で利用できます。"
},
"launcher": {
"title": "クイック起動",
"description": "セッション、ローカルシェル、デバイスコンソール",
"description": "セッション・ローカル Shell・デスクトップ・シリアル",
"cards": {
"quickConnect": {
"title": "クイック接続",
@@ -215,6 +244,14 @@
"serial": {
"title": "シリアルターミナル",
"desc": "ボーレートとポート設定"
},
"rdp": {
"title": "RDP デスクトップ",
"desc": "リモート Windows"
},
"vnc": {
"title": "VNC デスクトップ",
"desc": "リモート画面"
}
},
"sectionLocalShell": "ローカルシェル",
@@ -229,6 +266,7 @@
"forwardOpenRunning": "SOCKS5 実行中 (:{{port}}) · クリックで管理 · 右クリックでコピー",
"forwardStarted": "転送を開始しました",
"forwardStartedDynamic": "SOCKS5 を開始: socks5://127.0.0.1:{{port}}",
"forwardResumed": "{{count}} 件のポート転送を復旧しました",
"socksStartFailed": "開始失敗: {{message}}",
"socksStopFailed": "停止失敗: {{message}}",
"socksCopied": "socks5://127.0.0.1:{{port}} をコピーしました"
@@ -249,7 +287,7 @@
"typeDynamic": "Dynamic",
"running": "実行中",
"socksProxy": "SOCKS5: 127.0.0.1:{{port}}",
"remoteToLocal": "リモート {{remote}} → ローカル {{local}}",
"remoteToLocal": "リモート {{bind}}:{{remote}} → {{host}}:{{local}}",
"stats": "{{connections}} 接続 · ↑{{up}} · ↓{{down}}",
"copyProxy": "プロキシをコピー",
"copyRule": "ルールを複製",
@@ -259,15 +297,15 @@
"delete": "削除",
"editTitle": "転送を編集",
"addTitle": "転送を追加",
"typeLocalDesc": "Local → リモート",
"typeRemoteDesc": "リモート → Local",
"typeLocalDesc": "リモートサービスへアクセス",
"typeRemoteDesc": "ローカルサービスを公開",
"typeDynamicDesc": "SOCKS5",
"selectType": "タイプ",
"drawerSubtitle": "現在の SSH セッション経由でトンネル",
"ruleFields": "詳細",
"dynamicHint": "127.0.0.1:1080 のローカル SOCKS5。トラフィックはこの SSH サーバーのパブリック IP から出ていきます。",
"dynamicSingleHint": "SSH ホストごとに 1 つの Dynamic ルール、固定ポート 1080。",
"dynamicPortHint": "If the port is busy, pick another local port (e.g. 1081).",
"dynamicHint": "ローカル SOCKS5(既定 :1080)。トラフィックはこの SSH 出口経由。",
"dynamicSingleHint": "SSH ホストごとに動的は1つ。停止中にポート変更可。",
"dynamicPortHint": "使用中なら別ポート(例 1081)。",
"ruleList": "ルール",
"ruleListEmpty": "Local / Remote ルールはまだありません",
"addSection": "新規追加",
@@ -301,17 +339,30 @@
"internet": "インターネット",
"localCaption": "Local: リモートポートをローカルにあるかのように利用できます。",
"remoteCaption": "Remote: リモートからのアクセスをローカルサービスに転送します。",
"dynamicCaption": "Dynamic: このマシンが SOCKS5 プロキシとなり、現在の SSH サーバーのパブリック IP から出ていきます。"
"dynamicCaption": "動的: ローカル SOCKS5。この SSH 出口経由で外へ。"
},
"ruleName": "名前",
"ruleNamePlaceholder": "例: MySQL",
"localListenPort": "ローカルリッスンポート",
"localListenPortHint": "既定は localhost。ssh -L ポート:… と同じ。通常はポートだけ。",
"localBindAdvanced": "詳細: ローカルバインド変更",
"localTargetPort": "ローカルターゲットポート",
"remoteTargetPort": "リモートターゲットポート",
"remoteTargetPort": "転送先ポート",
"remoteListenPort": "リモートリッスンポート",
"remoteListenPortHint": "既定はリモート localhost(ssh -R ポート:… と同じ)。通常はポートだけ入力。",
"remoteListenAddress": "リモート待ち受け",
"remoteListenAddressPlaceholder": "127.0.0.1:18080",
"remoteListenAddressHint": "127.0.0.1 = リモート本体のみ / 0.0.0.0 = リモート LAN(GatewayPorts 必要)。",
"errorRemoteListenAddress": "有効なリモート待ち受けを入力(例: 127.0.0.1:18080)",
"localTargetAddress": "ローカル / LAN ターゲット",
"localTargetAddressPlaceholder": "127.0.0.1:8080",
"localTargetAddressHint": "本機または LAN のサービスへ転送(例: 127.0.0.1:8080)。0.0.0.0 は不可。",
"viaSessionRemote": "{{target}} で待ち受け(既定は localhost)",
"errorRemoteListenPort": "有効なリモートリッスンポート(1–65535)を入力してください",
"errorLocalTargetAddress": "有効なローカル/LAN ターゲットを入力(例: 127.0.0.1:8080)",
"portPlaceholder": "例: 3306",
"remoteHost": "リモートホスト",
"remoteHostPlaceholder": "localhost または IP",
"remoteHost": "転送先ホスト",
"remoteHostPlaceholder": "127.0.0.1",
"socksRuleName": "SOCKS5 プロキシ",
"defaultLocalName": "Local 転送",
"defaultRemoteName": "Remote 転送",
@@ -325,11 +376,35 @@
"deleteConfirm": "このルールを削除しますか?",
"errorNamePort": "名前と有効なポート (1–65535) を入力してください",
"errorTargetPort": "有効なターゲットポート (1–65535) を入力してください",
"errorRemoteHost": "リモートホストを入力してください",
"errorRemoteHost": "転送先ホストを入力してください(SSH サーバ基準)",
"errorNotConnected": "未接続",
"errorStartFailed": "開始失敗",
"errorStopFailed": "停止失敗",
"errorSocksRunning": "SOCKS5 は既に実行中",
"copySuffix": "コピー"
"copySuffix": "コピー",
"remoteBindHint": "0.0.0.0 は GatewayPorts が必要。未設定だと 127.0.0.1 のみになることが多い。転送先に 0.0.0.0 は不可。",
"localToRemote": "ローカル {{bind}}:{{local}} → リモート {{host}}:{{remote}}",
"localToRemotePort": "ローカル :{{local}} → リモート {{host}}:{{remote}}",
"remoteHostHint": "SSH サーバー基準。その本体は 127.0.0.1、LAN は到達可能な IP。0.0.0.0 不可。",
"localBindHost": "ローカルバインド",
"localBindHostPlaceholder": "127.0.0.1",
"localBindHostHint": "既定はこの端末のみ。0.0.0.0 や LAN IP で他端末から接続可。",
"errorTargetHostInvalid": "ターゲットに 0.0.0.0 は不可。127.0.0.1 か到達可能な IP を指定",
"listenAddress": "ローカル待ち受け",
"listenAddressPlaceholder": "127.0.0.1:8080",
"listenAddressHint": "既定はこの端末のみ。0.0.0.0 で LAN 許可。",
"targetAddress": "リモート転送先",
"targetAddressPlaceholder": "127.0.0.1:80",
"targetAddressHint": "SSH サーバーから見た宛先。その本体のサービスは 127.0.0.1:ポート。",
"errorListenAddress": "有効な待ち受けを入力(例: 127.0.0.1:8080)",
"errorTargetAddress": "有効なターゲットを入力(例: 127.0.0.1:80)",
"targetAddressHintVia": "{{target}} 経由。その本体のサービスは 127.0.0.1:ポート(新しい待ち受けは作らない)。",
"viaSession": "セッション経由 {{target}}",
"remoteToLocalPort": "リモート :{{remote}} → {{host}}:{{local}}",
"remoteBindAdvanced": "詳細: リモートバインドを変更",
"remoteBindHost": "リモートバインド",
"remoteBindHostPlaceholder": "127.0.0.1",
"remoteBindHostHint": "既定はリモート本機のみ。0.0.0.0 は GatewayPorts が必要。未設定だと多くの sshd は 127.0.0.1 のみにバインドします。",
"remoteGatewayPortsWarning": "リモート 0.0.0.0 待ち受けを要求しました。GatewayPorts が無いと、sshd はしばしば黙って 127.0.0.1 のみにバインドします。"
}
}
+11 -4
View File
@@ -15,10 +15,12 @@
"passwordOptional": "パスワード (任意)",
"width": "幅",
"height": "高さ",
"rdpFootnote": "ネイティブ IronRDP: TCP → X.224 → TLS → CredSSP/NLA → MCS · ハンドシェイクタイムアウト 45 秒。開発中は証明書の検証が緩和されています。",
"vncFootnote": "ネイティブ vnc-rs RFB · Tight JPEG デコード · クリップボードは UTF-8 で送信 (非常に古いサーバーでは文字化けする場合があります)。",
"rdpFootnote": "フルスクリーンまたは最大化時は、現在のウィンドウ領域に合わせてリモート解像度を動的に要求します。接続前に初期解像度を選ぶこともできます。証明書の検証は開発中は緩和されています。",
"vncFootnote": "多くの VNC サーバーではリモート解像度が固定です。フルスクリーンはローカルでの拡大のみで、接続時の希望サイズは参考値です。クリップボードは UTF-8 で送信します。",
"errorHostRequired": "ホストアドレスを入力してください",
"errorUsernameRequired": "ユーザー名を入力してください"
"errorUsernameRequired": "ユーザー名を入力してください",
"resolution": "解像度",
"resolutionCustom": "カスタム"
},
"toolbar": {
"pasteClipboard": "ローカルのクリップボードをリモートに貼り付け",
@@ -28,7 +30,12 @@
"openShareDir": "共有フォルダーをローカルで開く (Downloads)",
"openShareDirAria": "共有フォルダーを開く",
"disconnect": "切断",
"disconnectAria": "切断"
"disconnectAria": "切断",
"fullscreen": "全画面",
"fullscreenAria": "全画面表示にする",
"exitFullscreen": "全画面を終了",
"exitFullscreenAria": "全画面を終了",
"exitFullscreenHint": "Esc / F11 で終了"
},
"status": {
"connecting": "接続中…",
+16 -3
View File
@@ -39,7 +39,9 @@
"closed": "接続が閉じられました",
"dnsFailed": "ホストを解決できませんでした",
"refused": "接続が拒否されました",
"disconnected": "切断されました"
"disconnected": "切断されました",
"keepaliveFailed": "SSH キープアライブが連続失敗し、切断されました",
"idleKicked": "リモート Shell がアイドルタイムアウトで終了しました(TMOUT)"
},
"auth": {
"failed": "認証に失敗しました。ユーザー名とパスワードを確認してください。",
@@ -68,7 +70,10 @@
"forward": {
"failed": "ポート転送の設定に失敗しました",
"bindFailed": "ポートのバインドに失敗しました",
"alreadyInUse": "ポートは既に使用中です"
"alreadyInUse": "ローカルポートは使用中です。実行中の転送や他プロセスを停止してから再起動してください。",
"remoteDenied": "リモート転送をサーバーが拒否しました(AllowTcpForwarding / PermitListen、ポート使用中、またはバインド制限)。リモートは 127.0.0.1 のみで待ち受けます。",
"remoteDeniedPrivileged": "特権ポート(<1024)の待ち受けを拒否されました。≥1024 を使うか root で実行し、AllowTcpForwarding / PermitListen を確認してください。",
"invalidTargetHost": "転送先に 0.0.0.0 は指定できません。127.0.0.1 か到達可能な内網 IP を使ってください"
},
"sftp": {
"connectFailed": "SFTP 接続に失敗しました",
@@ -80,7 +85,15 @@
"writeFailed": "保存に失敗しました",
"renameFailed": "名前の変更に失敗しました",
"chmodFailed": "権限の更新に失敗しました",
"apiUnavailable": "SFTP API は利用できません"
"apiUnavailable": "SFTP API は利用できません",
"channelFailed": "SFTP チャネルを開けません(上限またはビジー)。再接続して再試行してください",
"sessionGone": "SFTP セッションが終了しました。再接続してください",
"busy": "ファイル転送中です。完了してから再試行してください。",
"editTooLarge": "ファイルが大きすぎます(テキスト編集の上限は約 2MB)。ダウンロードしてローカルで開いてください。",
"editBinary": "バイナリの可能性があるため、テキストエディタでは開けません",
"editNotUtf8": "リモートファイルは有効な UTF-8 テキストではありません",
"transferCancelled": "転送をキャンセルしました",
"diskFull": "ディスク容量不足(ローカルまたはリモート)"
},
"session": {
"notFound": "セッションが見つかりません",
+6 -4
View File
@@ -69,17 +69,17 @@
"confirm": "削除"
},
"welcome": {
"tagline": "リモートターミナル · SFTP · ポート転送",
"tagline": "シンプル実用 · ターミナル · ファイル · デスクトップ",
"sectionStart": "はじめる",
"sectionDesktop": "リモートデスクトップ",
"sectionRecent": "最近のセッション",
"quickConnect": {
"title": "クイック接続",
"desc": "単発の SSH · ライブラリに保存しない"
"desc": "一時 SSH。セッション一覧には保存しません"
},
"newSession": {
"title": "新規セッション",
"desc": "ホストを保存 · サイドバーでダブルクリックして接続"
"desc": "ホストを保存。サイドバーをダブルクリックで接続"
},
"localShell": {
"title": "ローカルシェル",
@@ -167,7 +167,9 @@
"jumpHost": "ジャンプホスト (任意)",
"jumpNone": "ジャンプホストなし",
"jumpNoneAlt": "ジャンプホストなし",
"jumpHint": "保存済みセッションをジャンプホストとして使用可能"
"jumpHint": "保存済みセッションをジャンプホストとして使用可能",
"resolution": "解像度",
"resolutionCustom": "カスタム"
},
"batch": {
"title": "一括実行",
+51 -19
View File
@@ -1,9 +1,7 @@
{
"nav": {
"general": "ワークスペース",
"generalDesc": "レイアウトとリソース",
"appearance": "外観",
"appearanceDesc": "テーマと言語",
"general": "一般",
"generalDesc": "テーマ、言語、レイアウト",
"terminal": "ターミナル",
"terminalDesc": "フォントと配色",
"shortcuts": "ショートカット",
@@ -15,11 +13,13 @@
"ai": "AI モデル",
"aiDesc": "AI プロバイダー",
"about": "情報",
"aboutDesc": "バージョンとデータ"
"aboutDesc": "バージョンとデータ",
"account": "アカウント",
"accountDesc": "メール、ライセンス、デバイス"
},
"title": "設定",
"search": {
"placeholder": "設定を検索..."
"placeholder": "設定を検索…"
},
"language": {
"label": "言語",
@@ -89,7 +89,7 @@
"ssh": {
"connection": "接続",
"keepAlive": "キープアライブ",
"keepAliveDesc": "アイドル時にキープアライブを送り、切断を減らします",
"keepAliveDesc": "アイドル時に SSH キープアライブを送信。数回連続失敗してから切断",
"autoReconnect": "自動再接続",
"autoReconnectDesc": "予期しない切断後に自動で再試行します",
"timeout": "接続タイムアウト",
@@ -101,8 +101,10 @@
"maxConnectionsDesc": "SSH・SFTP・一括接続で共有する上限",
"maxBackground": "バックグラウンド接続上限",
"maxBackgroundDesc": "上限超過時は最も長く未使用の接続から回収します",
"suspend": "バックグラウンド一時停止",
"suspendDesc": "タブがバックグラウンドになってからアクティブチャネルを解放するまでの分数"
"suspend": "バックグラウンド休止",
"suspendDesc": "アイドルのバックグラウンドタブを何分後に休止するか(稼働中の Shell/SFTP は維持)",
"keepAliveInterval": "キープアライブ間隔(秒)",
"keepAliveIntervalDesc": "サーバーへの ping 間隔(ClientAliveInterval 相当)。不安定な回線では 15 秒以下を推奨"
},
"security": {
"credentials": "資格情報の保護",
@@ -119,7 +121,7 @@
"clearConfirm": "既知のホスト鍵をすべて消去しますか?次回接続時に再度確認されます。"
},
"about": {
"tagline": "軽量ネイティブの SSH / SFTP 運用ターミナル",
"tagline": "シンプルで使いやすいネイティブ運用端末",
"appVersion": "アプリ v{{version}}",
"copyVersion": "バージョン情報をコピー",
"runtime": "ランタイム",
@@ -127,8 +129,9 @@
"localData": "ローカルデータ",
"sessionsSettings": "セッションと設定",
"masterKeyPath": "マスターキー",
"privacyNote": "パスワードと鍵パスフレーズは Rust が AES-256-GCM で暗号化します。OpsXShell はターミナルのコマンド履歴を保存しません。",
"license": "MIT License · Rust · XTerm.js"
"privacyNote": "パスワードと鍵パスフレーズは Rust 側で AES-256-GCM 暗号化。コマンド履歴も監査ログも保存しません。",
"license": "MIT License · Rust · XTerm.js",
"logPath": "アプリログ"
},
"ai": {
"presets": "プロバイダープリセット",
@@ -162,13 +165,42 @@
"apiKeySaveFailed": "API Key の保存に失敗しました",
"providerNotFound": "プロバイダーが見つかりません",
"modelCatalogReadFailed": "モデルカタログの読み取りに失敗しました",
"catalogUnavailable": "models.dev を利用できません"
"catalogUnavailable": "models.dev を利用できません",
"family": {
"openai_compatible": "OpenAI 互換",
"standalone": "独自プロトコル",
"plan": "プラン",
"local": "セルフホスト",
"custom": "カスタム"
}
},
"family": {
"openai_compatible": "OpenAI 互換",
"standalone": "────────",
"plan": "Plan",
"local": "セルフホスト",
"custom": "カスタム"
"account": {
"title": "Account",
"email": "Email",
"emailDesc": "Used for checkout and license claims",
"plan": "Current plan",
"planFree": "Free",
"planYearly": "Pro 年額",
"planPerpetual": "Pro 永久",
"planTrial": "Pro 体験",
"expires": "Expires {{date}}",
"lifetime": "Lifetime",
"devices": "Seats: up to {{count}} devices",
"deviceId": "This device ID",
"saveEmail": "Save email",
"activate": "Activate license",
"pasteLicense": "Paste LIC- license key",
"clear": "Clear local license",
"deactivate": "Deactivate this device",
"upgrade": "Upgrade",
"saved": "Saved",
"activateOk": "Activated",
"deviceList": "紐付けデバイス",
"loadingDevices": "デバイスを読み込み中…",
"noDevices": "紐付けデバイスはありません",
"thisDevice": "このデバイス",
"removeDevice": "解除",
"deviceRemoved": "デバイスの紐付けを解除しました",
"seatFull": "デバイス枠がいっぱいです。新しい端末で有効化する前に、別のデバイスを解除してください。"
}
}
+55 -25
View File
@@ -3,8 +3,9 @@
"local": "ローカル",
"remote": "リモート",
"notConnectedTitle": "リモートサーバーに接続されていません",
"notConnectedDesc": "SFTP を使用するにはまず SSH セッションを接続してください",
"ariaLabel": "{{title}} ファイルパネル"
"notConnectedDesc": "まず SSH 接続してから転送・編集",
"ariaLabel": "{{title}} ファイルパネル",
"reconnectResumeDesc": "切断されました。再接続で {{path}} に戻ります"
},
"connection": {
"selectServer": "サーバーを選択",
@@ -12,7 +13,9 @@
"createSessionHint": "まずサイドバーでセッションを作成してください",
"reconnect": "再接続",
"notConnected": "未接続",
"connecting": "接続中..."
"connecting": "接続中...",
"resumeHint": "再接続後は {{path}} に戻ります",
"reconnectingResume": "{{path}} を復元して再接続中…"
},
"errors": {
"notConnected": "SFTP に接続されていません",
@@ -23,19 +26,14 @@
"selectDownloadFiles": "ダウンロードするファイルを先に選択してください",
"uploadFailed": "アップロード失敗",
"downloadFailed": "ダウンロード失敗",
"fileError": "{{fileName}}: {{message}}"
"fileError": "{{fileName}}: {{message}}",
"mkdirFailed": "フォルダの作成に失敗しました"
},
"toolbar": {
"upload": "アップロード",
"uploadAria": "アップロード",
"download": "ダウンロード",
"downloadAria": "ダウンロード",
"downloadNeedSelection": "リモートファイルを先に選択してください",
"downloadHint": "選択したリモートファイルをダウンロード",
"refresh": "更新",
"refreshAria": "更新",
"newFolder": "新規フォルダー",
"newFolderAria": "新規フォルダー"
"refreshAria": "このパネルを更新",
"newFolder": "新規フォルダ",
"newFolderAria": "このパネルにフォルダを作成"
},
"sort": {
"name": "名前",
@@ -55,7 +53,8 @@
"hideHidden": "ドットファイルを非表示 (.xxx)",
"showHiddenAria": "隠しファイルを表示",
"hideHiddenAria": "ドットファイルを非表示",
"searchAria": "{{title}} 内を検索"
"searchAria": "{{title}} 内を検索",
"upAtRoot": "すでにルートです"
},
"status": {
"loading": "読み込み中...",
@@ -63,7 +62,8 @@
"filtered": "{{shown}} / {{total}} 件を表示",
"hiddenCount": "{{total}} 件 ({{hidden}} 件非表示)",
"total": "{{count}} 件",
"filterHint": "絞り込み: {{query}}"
"filterHint": "絞り込み: {{query}}",
"refreshing": "更新中..."
},
"empty": {
"dirTitle": "空のディレクトリ",
@@ -99,7 +99,6 @@
"download": "ダウンロード",
"edit": "編集",
"rename": "名前を変更",
"copyPath": "パスをコピー",
"properties": "プロパティ",
"permissions": "権限",
"delete": "削除"
@@ -116,7 +115,18 @@
"chmodTitle": "権限を編集",
"chmodApply": "適用",
"pickUploadTitle": "アップロードするファイルまたはフォルダーを選択",
"pickUploadRzTitle": "アップロードするファイルを選択 (rz)"
"pickUploadRzTitle": "アップロードするファイルを選択 (rz)",
"overwriteTitle": "既存ファイルを上書きしますか?",
"overwriteConfirm": "上書き",
"overwriteSkip": "スキップ",
"overwriteOneRemote": "リモートに「{{name}}」があります。上書きしますか?",
"overwriteOneLocal": "ローカルに「{{name}}」があります。上書きしますか?",
"overwriteManyRemote": "リモートに同名が {{count}} 件あります。すべて上書きしますか?",
"overwriteManyLocal": "ローカルに同名が {{count}} 件あります。すべて上書きしますか?",
"overwriteMore": "…ほか {{count}} 件",
"deleteTitle": "削除の確認",
"deleteMessage": "{{count}} 件を削除します:{{names}}",
"deleteRecursiveWarn": "フォルダが含まれます。再帰的に削除され、元に戻せません。"
},
"properties": {
"name": "名前",
@@ -152,27 +162,41 @@
"statusDone": "完了",
"statusFailed": "失敗",
"statusCancelled": "キャンセル済み",
"dropUpload": "{{path}} へアップロード",
"dropDownload": "{{path}} へダウンロード"
"dropUpload": "{{path}} にドロップしてアップロード",
"dropDownload": "{{path}} にドロップしてダウンロード",
"railAria": "ローカルとリモート間の転送",
"railUpload": "選択したローカルファイルをアップロード(未選択時はファイル選択)",
"railDownload": "選択したリモートファイルをダウンロード",
"railUploadAria": "リモートへアップロード",
"railDownloadAria": "ローカルへダウンロード",
"railDownloadNeedSelection": "先にリモートファイルを選択してください",
"retry": "再試行"
},
"editor": {
"readFailed": "読み取り失敗",
"saveFailed": "保存失敗",
"unsavedClose": "未保存の変更があります。それでも閉じますか?",
"unsavedTitle": "未保存の変更",
"discardAndClose": "破棄して閉じる",
"reloadTitle": "再読み込み",
"discardAndReload": "破棄して再読み込み",
"saving": "保存中...",
"save": "保存",
"saved": "ファイルを保存しました",
"loadingEditor": "エディターを読み込み中...",
"footer": "UTF-8 · Monaco · ⌘/Ctrl+S で保存 · 最大約 2MB",
"loadBlocked": "ファイル内容を読み込めませんでした",
"footer": "UTF-8 · ⌘/Ctrl+S 保存 · Esc 閉じる · 最大約 2MB",
"charCount": "{{count}} 文字",
"unsavedMark": " · 未保存",
"savedMark": " · 保存済み"
"savedMark": " · 保存済み",
"title": "{{name}} を編集",
"dirtyBadge": "未保存",
"reload": "再読み込み",
"unsavedReload": "未保存の変更を破棄して再読み込みしますか?"
},
"toast": {
"renamed": "{{name}} に名前を変更しました",
"renameFailed": "名前の変更に失敗",
"pathCopied": "パスをクリップボードにコピー",
"pathCopyFailed": "パスのコピーに失敗",
"chmodUpdated": "権限を {{mode}} に更新しました",
"chmodFailed": "権限の更新に失敗",
"uploadPartial": "{{action}} 完了 {{completed}} · 失敗 {{failed}}: {{detail}}",
@@ -180,7 +204,13 @@
"uploadAction": "アップロード",
"downloadAction": "ダウンロード",
"noFolderUpload": "フォルダーのアップロードに失敗",
"noDragPath": "ドラッグ&ドロップのパスは利用できません · アップロードを使用してください",
"noFolderRecursive": "フォルダーの再帰転送に失敗 · 再試行するかアップロードを使用してください"
"noDragPath": "この環境ではドラッグパスを取得できません。中央の → かファイル選択を使ってください。",
"noFolderRecursive": "フォルダ転送に失敗しました。再試行するか、中央の → / ファイル選択を使ってください。",
"dropFailed": "ドロップに失敗しました。再試行するか、中央の矢印で転送してください。",
"folderCreated": "フォルダ {{name}} を作成しました",
"allSkippedExisting": "既存ファイルはすべてスキップしました",
"skippedExisting": "既存 {{count}} 件をスキップしました",
"deleteFailed": "削除に失敗しました",
"deleted": "削除しました"
}
}
+3 -2
View File
@@ -34,7 +34,7 @@
"reopenShell": "シェルを再開",
"reopening": "開いています…",
"disconnected": "切断されました",
"disconnectedHint": "SSH セッションが終了したか、ネットワークが切断されました。下のボタンで再接続できます。",
"disconnectedHint": "SSH セッション終了またはネットワーク切断。下のボタンで再接続して作業を続けられます。",
"reconnect": "再接続",
"suspended": "接続が一時停止",
"suspendedHint": "しばらく操作がなかったため、リソース節約のため接続を一時停止しました",
@@ -70,7 +70,8 @@
"splitRight": "右に分割",
"splitDown": "下に分割",
"maximizePane": "現在のペインを最大化",
"restoreLayout": "分割レイアウトを復元"
"restoreLayout": "分割レイアウトを復元",
"openSftp": "SFTP を開く"
},
"search": {
"placeholder": "検索...",
+107 -32
View File
@@ -78,7 +78,7 @@
"closeTab": "현재 탭 닫기",
"closeAllTabs": "모든 탭 닫기",
"portForward": "새 포트 포워딩",
"upgradePro": "OpsXShell Pro 업그레이드",
"upgradePro": "OpsXShell 프로로 업그레이드",
"editSession": "세션 편집: {{name}}"
}
},
@@ -90,6 +90,8 @@
"terminal": "터미널",
"batch": "일괄 실행",
"newTerminal": "새 터미널",
"closeAria": "{{title}} 닫기",
"listAria": "열린 탭",
"kind": {
"terminal": "터미널",
"sftp": "SFTP",
@@ -105,7 +107,8 @@
"closeRight": "오른쪽 탭 닫기",
"closeLeft": "왼쪽 탭 닫기",
"closeAll": "모두 닫기",
"clone": "탭 복제"
"clone": "탭 복제",
"openSftp": "SFTP 열기"
}
},
"sidebar": {
@@ -149,9 +152,9 @@
"disconnect": "연결 끊기"
},
"pro": {
"upgrade": "Pro 업그레이드",
"upgrade": "프로로 업그레이드",
"feature": "Pro 기능",
"unlock": "{{feature}} 잠금 해제",
"unlock": "프로 고급 기능 잠금 해제",
"comingSoon": "출시 예정",
"activateSuccess": "활성화됨",
"activateFailed": "활성화 실패",
@@ -160,28 +163,33 @@
"invalidLicense": "활성화 실패: 잘못된 라이선스",
"goUpgrade": "업그레이드",
"haveLicense": "라이선스가 있나요? 활성화",
"title": "OpsXShell Pro · Pro 운영 기능 잠금 해제",
"subtitleComingSoon": "{{feature}} 출시 예정 · 조기 액세스는 Pro 업그레이드",
"subtitleUnlock": "잠금 해제 중: {{feature}}",
"subtitleDefault": "포워딩, 프록시, 시리얼, AI, 일괄 실행, 브로드캐스트",
"title": "OpsXShell · 프로 잠금 해제",
"subtitleComingSoon": "고급 기능 곧 제공 · 프로로 먼저 체험",
"subtitleUnlock": "고급 기능을 잠금 해제하는 중",
"subtitleDefault": "포트 포워딩, 터미널 AI, 일괄 운영, 호스트 목록, 원격 데스크톱 등 프로 기능",
"activated": "Pro 활성화됨",
"expiresAt": " · {{date}}까지 유효",
"lifetime": " · 평생 라이선스",
"oneTimeFee": "1회 구매 · 이 기기에서 평생 사용 · 구독 없음",
"oneTimeFee": "무료 / 프로 연간 / 프로 영구",
"pasteLicense": "라이선스 붙여넣기",
"activateButton": "활성화",
"clearLicense": "로컬 라이선스 삭제",
"paymentNote": "결제는 Waffo가 처리합니다. 이 앱은 카드 정보를 수집하지 않습니다.",
"testDeviceId": "테스트 환경 · 기기 ID: {{deviceId}}",
"later": "나중에 하기",
"viewPro": "Pro 보기",
"wallComingSoonSuffix": " · 출시 예정",
"wallUnlock": "{{feature}} 잠금 해제",
"wallMessageComingSoon": "이 Pro 기능은 아직 개발 중입니다. 조기 액세스를 위해 업그레이드하세요.",
"wallMessageDefault": "이 기능은 OpsXShell Pro가 필요합니다. 이 기기에서 사용하려면 업그레이드하세요.",
"viewPro": "프로 요금제 보기",
"wallComingSoonSuffix": "곧 제공",
"wallUnlock": "프로 고급 기능 잠금 해제",
"wallMessageComingSoon": "이 기능은 OpsXShell 프로에 포함되며 아직 준비 중입니다. 프로 연간 또는 영구로 먼저 체험하세요.",
"wallMessageDefault": "포트 포워딩, 터미널 AI, 일괄 실행, 호스트 목록, 원격 데스크톱은 프로에 포함됩니다. 프로 연간 또는 영구로 이 기기에서 사용하세요.",
"checkoutUnavailable": "결제를 사용할 수 없습니다 ({{status}})",
"emailLabel": "이메일",
"emailRequired": "결제 전에 이메일을 입력하세요",
"claimPending": "라이선스를 받는 중…",
"invalidKeyFormat": "키 형식이 올바르지 않습니다. LIC- 라이선스 키를 붙여넣으세요",
"accountEmail": "계정: {{email}}",
"freeTier": "무료",
"proTier": "Pro",
"proTier": "프로",
"freeItems": {
"ssh": "SSH 터미널",
"sftp": "SFTP 파일 관리자",
@@ -195,14 +203,35 @@
"serial": "시리얼 터미널",
"ai": "터미널 AI 어시스턴트",
"batch": "일괄 실행 / 브로드캐스트 동기화",
"broadcast": "브로드캐스트 입력 동기화",
"importExport": "호스트 일괄 가져오기/내보내기",
"desktop": "RDP / VNC 원격 데스크톱"
}
"broadcast": "브로드캐스트 동기 입력",
"importExport": "호스트 목록 일괄 가져오기/내보내기",
"desktop": "원격 데스크톱 (RDP / VNC)"
},
"planYearly": "프로 연간",
"planYearlyDesc": "¥99 / 년 · 기기 2대",
"planPerpetual": "프로 영구",
"planPerpetualDesc": "¥199 · 기기 5대 · 평생",
"planTrial": "프로 체험",
"devices": "최대 {{count}}대",
"goUpgradeYearly": "프로 연간 구매",
"goUpgradePerpetual": "프로 영구 구매",
"activatedYearly": "프로 연간 활성화됨",
"activatedPerpetual": "프로 영구 활성화됨",
"activatedTrial": "프로 체험 활성화됨",
"choosePlan": "선택: 무료 / 프로 연간 / 프로 영구",
"planFreePrice": "¥0",
"planFreeDesc": "SSH · SFTP · 로컬 터미널",
"planFreeCta": "현재 요금제",
"planIncludesPro": "모든 프로 기능 포함",
"planFree": "무료",
"subtitleUnlockDetail": "관련 기능: {{feature}}",
"wallUnlockComingSoon": "프로 고급 기능 곧 제공",
"wallMessageComingSoonFeature": "「{{feature}}」는 프로 고급 기능이며 아직 준비 중입니다. 프로 연간 또는 영구로 먼저 체험하세요.",
"wallMessageFeature": "「{{feature}}」는 프로 고급 기능입니다. 프로 연간 또는 영구로 이 기기에서 사용하세요."
},
"launcher": {
"title": "빠른 실행",
"description": "세션, 로컬 셸 및 기기 콘솔",
"description": "세션, 로컬 Shell, 데스크톱, 시리얼",
"cards": {
"quickConnect": {
"title": "빠른 연결",
@@ -215,6 +244,14 @@
"serial": {
"title": "시리얼 터미널",
"desc": "보레이트 및 포트 설정"
},
"rdp": {
"title": "RDP 데스크톱",
"desc": "원격 Windows"
},
"vnc": {
"title": "VNC 데스크톱",
"desc": "원격 그래픽"
}
},
"sectionLocalShell": "로컬 셸",
@@ -229,6 +266,7 @@
"forwardOpenRunning": "SOCKS5 실행 중 (:{{port}}) · 클릭하여 관리 · 우클릭으로 복사",
"forwardStarted": "포워딩 시작됨",
"forwardStartedDynamic": "SOCKS5 시작됨: socks5://127.0.0.1:{{port}}",
"forwardResumed": "포트 포워딩 {{count}}개를 복구했습니다",
"socksStartFailed": "시작 실패: {{message}}",
"socksStopFailed": "중지 실패: {{message}}",
"socksCopied": "socks5://127.0.0.1:{{port}} 복사됨"
@@ -249,7 +287,7 @@
"typeDynamic": "동적",
"running": "실행 중",
"socksProxy": "SOCKS5: 127.0.0.1:{{port}}",
"remoteToLocal": "원격 {{remote}} → 로컬 {{local}}",
"remoteToLocal": "원격 {{bind}}:{{remote}} → {{host}}:{{local}}",
"stats": "{{connections}}개 연결 · ↑{{up}} · ↓{{down}}",
"copyProxy": "프록시 복사",
"copyRule": "규칙 복제",
@@ -259,15 +297,15 @@
"delete": "삭제",
"editTitle": "포워딩 편집",
"addTitle": "포워딩 추가",
"typeLocalDesc": "로컬 → 원격",
"typeRemoteDesc": "원격 → 로컬",
"typeLocalDesc": "원격 서비스 접근",
"typeRemoteDesc": "로컬 서비스 노출",
"typeDynamicDesc": "SOCKS5",
"selectType": "유형",
"drawerSubtitle": "현재 SSH 세션을 통한 터널",
"ruleFields": "세부 정보",
"dynamicHint": "127.0.0.1:1080의 로컬 SOCKS5. 트래픽은 이 SSH 서버의 공인 IP를 통해 나갑니다.",
"dynamicSingleHint": "SSH 호스트당 하나의 동적 규칙, 고정 포트 1080.",
"dynamicPortHint": "If the port is busy, pick another local port (e.g. 1081).",
"dynamicHint": "로컬 SOCKS5(기본 :1080). 트래픽은 현재 SSH 출구를 통해 나갑니다.",
"dynamicSingleHint": "SSH 호스트당 동적 규칙 1개. 중지 후 포트 변경.",
"dynamicPortHint": "사용 중이면 다른 포트(예: 1081).",
"ruleList": "규칙",
"ruleListEmpty": "아직 로컬/원격 규칙이 없습니다",
"addSection": "새로 추가",
@@ -301,17 +339,30 @@
"internet": "인터넷",
"localCaption": "로컬: 원격 포트를 로컬 포트인 것처럼 접근합니다.",
"remoteCaption": "원격: 원격 접근을 로컬 서비스로 포워딩합니다.",
"dynamicCaption": "동적: 이 컴퓨터가 현재 SSH 서버의 공인 IP를 통해 나가는 SOCKS5 프록시가 됩니다."
"dynamicCaption": "동적: 로컬 SOCKS5, 현재 SSH 출구로 외부 접속."
},
"ruleName": "이름",
"ruleNamePlaceholder": "예: MySQL",
"localListenPort": "로컬 수신 포트",
"localListenPortHint": "기본 localhost — ssh -L 포트:… 와 같음. 보통 포트만 입력.",
"localBindAdvanced": "고급: 로컬 바인드 변경",
"localTargetPort": "로컬 대상 포트",
"remoteTargetPort": "원격 대상 포트",
"remoteTargetPort": "대상 포트",
"remoteListenPort": "원격 수신 포트",
"remoteListenPortHint": "기본은 원격 localhost — ssh -R 포트:… 와 같습니다. 보통 포트만 입력하세요.",
"remoteListenAddress": "원격 수신",
"remoteListenAddressPlaceholder": "127.0.0.1:18080",
"remoteListenAddressHint": "127.0.0.1 = 원격 본기만 / 0.0.0.0 = 원격 LAN(GatewayPorts 필요).",
"errorRemoteListenAddress": "유효한 원격 수신 주소 입력(예: 127.0.0.1:18080)",
"localTargetAddress": "로컬 / LAN 대상",
"localTargetAddressPlaceholder": "127.0.0.1:8080",
"localTargetAddressHint": "로컬/LAN 서비스로 전달 (예: 127.0.0.1:8080). 0.0.0.0 금지.",
"viaSessionRemote": "{{target}} 에서 수신 (기본 localhost)",
"errorRemoteListenPort": "유효한 원격 수신 포트(1–65535)를 입력하세요",
"errorLocalTargetAddress": "유효한 로컬/LAN 대상 입력(예: 127.0.0.1:8080)",
"portPlaceholder": "예: 3306",
"remoteHost": "원격 호스트",
"remoteHostPlaceholder": "localhost 또는 IP",
"remoteHost": "대상 호스트",
"remoteHostPlaceholder": "127.0.0.1",
"socksRuleName": "SOCKS5 프록시",
"defaultLocalName": "로컬 포워딩",
"defaultRemoteName": "원격 포워딩",
@@ -325,11 +376,35 @@
"deleteConfirm": "이 규칙을 삭제하시겠습니까?",
"errorNamePort": "이름과 유효한 포트(1–65535)를 입력하세요",
"errorTargetPort": "유효한 대상 포트(1–65535)를 입력하세요",
"errorRemoteHost": "원격 호스트를 입력하세요",
"errorRemoteHost": "대상 호스트를 입력하세요(SSH 서버 기준)",
"errorNotConnected": "연결되지 않음",
"errorStartFailed": "시작 실패",
"errorStopFailed": "중지 실패",
"errorSocksRunning": "SOCKS5가 이미 실행 중입니다",
"copySuffix": "복사"
"copySuffix": "복사",
"remoteBindHint": "0.0.0.0 은 GatewayPorts 필요. 없으면 종종 127.0.0.1 만 바인드. 대상에 0.0.0.0 금지.",
"localToRemote": "로컬 {{bind}}:{{local}} → 원격 {{host}}:{{remote}}",
"localToRemotePort": "로컬 :{{local}} → 원격 {{host}}:{{remote}}",
"remoteHostHint": "SSH 서버 기준. 본기는 127.0.0.1, LAN은 도달 가능한 IP. 0.0.0.0 불가.",
"localBindHost": "로컬 바인드",
"localBindHostPlaceholder": "127.0.0.1",
"localBindHostHint": "기본은 이 기기만. 0.0.0.0 또는 LAN IP로 네트워크 접근 허용.",
"errorTargetHostInvalid": "대상은 0.0.0.0 불가 — 127.0.0.1 또는 도달 가능한 IP",
"listenAddress": "로컬 수신",
"listenAddressPlaceholder": "127.0.0.1:8080",
"listenAddressHint": "기본은 이 기기만. 0.0.0.0이면 LAN 접근 가능.",
"targetAddress": "원격 대상",
"targetAddressPlaceholder": "127.0.0.1:80",
"targetAddressHint": "SSH 서버에서 본 주소. 본기 서비스는 127.0.0.1:포트.",
"errorListenAddress": "유효한 수신 주소 입력(예: 127.0.0.1:8080)",
"errorTargetAddress": "유효한 대상 입력(예: 127.0.0.1:80)",
"targetAddressHintVia": "{{target}} 경유. 본기 서비스는 127.0.0.1:포트(새 원격 포트 생성 안 함).",
"viaSession": "세션 경유 {{target}}",
"remoteToLocalPort": "원격 :{{remote}} → {{host}}:{{local}}",
"remoteBindAdvanced": "고급: 원격 바인드 변경",
"remoteBindHost": "원격 바인드",
"remoteBindHostPlaceholder": "127.0.0.1",
"remoteBindHostHint": "기본은 원격 호스트만. 0.0.0.0 은 GatewayPorts 필요. 없으면 대부분 sshd 가 여전히 127.0.0.1 만 바인드합니다.",
"remoteGatewayPortsWarning": "원격 0.0.0.0 수신을 요청했습니다. GatewayPorts 가 없으면 sshd 가 조용히 127.0.0.1 만 바인드하는 경우가 많습니다."
}
}
+11 -4
View File
@@ -15,10 +15,12 @@
"passwordOptional": "비밀번호 (선택 사항)",
"width": "너비",
"height": "높이",
"rdpFootnote": "네이티브 IronRDP: TCP → X.224 → TLS → CredSSP/NLA → MCS; 45초 핸드셰이크 시간 초과. 개발 중 인증서 확인은 완화됩니다.",
"vncFootnote": "네이티브 vnc-rs RFB(Tight JPEG 디코딩); 클립보드는 UTF-8로 전송됩니다(매우 오래된 서버는 텍스트가 깨질 수 있음).",
"rdpFootnote": "전체 화면 또는 최대화 시 현재 창 영역에 맞춰 원격 해상도를 동적으로 요청합니다. 연결 전에 초기 해상도를 선택할 수도 있습니다. 인증서 검증은 개발 중에는 완화되어 있습니다.",
"vncFootnote": "대부분 VNC 서버는 원격 해상도가 고정됩니다. 전체 화면은 로컬 확대만 하며, 연결 시 선호 크기는 참고용입니다. 클립보드는 UTF-8로 전송됩니다.",
"errorHostRequired": "호스트 주소를 입력하세요",
"errorUsernameRequired": "사용자 이름을 입력하세요"
"errorUsernameRequired": "사용자 이름을 입력하세요",
"resolution": "해상도",
"resolutionCustom": "사용자 지정"
},
"toolbar": {
"pasteClipboard": "로컬 클립보드를 원격에 붙여넣기",
@@ -28,7 +30,12 @@
"openShareDir": "공유 폴더를 로컬에서 열기 (다운로드)",
"openShareDirAria": "공유 폴더 열기",
"disconnect": "연결 끊기",
"disconnectAria": "연결 끊기"
"disconnectAria": "연결 끊기",
"fullscreen": "전체 화면",
"fullscreenAria": "전체 화면으로 전환",
"exitFullscreen": "전체 화면 종료",
"exitFullscreenAria": "전체 화면 종료",
"exitFullscreenHint": "Esc / F11로 종료"
},
"status": {
"connecting": "연결 중…",
+16 -3
View File
@@ -39,7 +39,9 @@
"closed": "연결이 닫혔습니다",
"dnsFailed": "호스트를 확인할 수 없습니다",
"refused": "연결이 거부되었습니다",
"disconnected": "연결 끊김"
"disconnected": "연결 끊김",
"keepaliveFailed": "SSH keep-alive가 연속 실패하여 연결이 닫혔습니다",
"idleKicked": "원격 Shell이 유휴 시간 초과로 종료되었습니다(TMOUT)"
},
"auth": {
"failed": "인증 실패. 사용자 이름과 비밀번호를 확인하세요.",
@@ -68,7 +70,10 @@
"forward": {
"failed": "포트 포워딩 설정 실패",
"bindFailed": "포트 바인딩 실패",
"alreadyInUse": "포트가 이미 사용 중입니다"
"alreadyInUse": "로컬 포트가 이미 사용 중입니다. 실행 중인 포워딩이나 다른 프로세스를 중지한 뒤 다시 시작하세요.",
"remoteDenied": "서버가 원격 포트 포워딩을 거부했습니다(AllowTcpForwarding / PermitListen, 포트 사용 중 또는 바인드 제한). 원격은 127.0.0.1에서만 수신합니다.",
"remoteDeniedPrivileged": "특권 수신 포트(<1024)가 거부되었습니다. ≥1024를 사용하거나 root로 실행하고 AllowTcpForwarding / PermitListen을 확인하세요.",
"invalidTargetHost": "대상은 0.0.0.0일 수 없습니다. 127.0.0.1 또는 도달 가능한 내부 IP를 사용하세요"
},
"sftp": {
"connectFailed": "SFTP 연결 실패",
@@ -80,7 +85,15 @@
"writeFailed": "저장 실패",
"renameFailed": "이름 변경 실패",
"chmodFailed": "권한 업데이트 실패",
"apiUnavailable": "SFTP API를 사용할 수 없음"
"apiUnavailable": "SFTP API를 사용할 수 없음",
"channelFailed": "SFTP 채널을 열 수 없습니다(서버 제한 또는 세션 바쁨). 다시 연결하세요",
"sessionGone": "SFTP 세션이 종료되었습니다. 다시 연결하세요",
"busy": "파일 전송 중입니다. 완료 후 다시 시도하세요.",
"editTooLarge": "파일이 너무 큽니다(텍스트 편집 한도 약 2MB). 다운로드 후 로컬에서 여세요.",
"editBinary": "이진 파일로 보이며 텍스트 편집기로 열 수 없습니다",
"editNotUtf8": "원격 파일이 유효한 UTF-8 텍스트가 아닙니다",
"transferCancelled": "전송이 취소되었습니다",
"diskFull": "디스크 공간 부족(로컬 또는 원격)"
},
"session": {
"notFound": "세션을 찾을 수 없음",
+6 -4
View File
@@ -69,17 +69,17 @@
"confirm": "삭제"
},
"welcome": {
"tagline": "원격 터미널 · SFTP · 포트 포워딩",
"tagline": "간단 실용 · 터미널 · 파일 · 데스크톱",
"sectionStart": "시작하기",
"sectionDesktop": "원격 데스크톱",
"sectionRecent": "최근 세션",
"quickConnect": {
"title": "빠른 연결",
"desc": "1회성 SSH; 라이브러리에 저장되지 않음"
"desc": "임시 SSH — 세션 목록에 저장하지 않음"
},
"newSession": {
"title": "새 세션",
"desc": "호스트 저장; 사이드바에서 더블클릭하여 연결"
"desc": "호스트 저장 — 사이드바에서 더블클릭으로 연결"
},
"localShell": {
"title": "로컬 셸",
@@ -167,7 +167,9 @@
"jumpHost": "점프 호스트 (선택 사항)",
"jumpNone": "점프 호스트 없음",
"jumpNoneAlt": "점프 호스트 없음",
"jumpHint": "저장된 세션 하나를 점프 호스트로 사용할 수 있습니다"
"jumpHint": "저장된 세션 하나를 점프 호스트로 사용할 수 있습니다",
"resolution": "해상도",
"resolutionCustom": "사용자 지정"
},
"batch": {
"title": "일괄 실행",
+51 -19
View File
@@ -1,9 +1,7 @@
{
"nav": {
"general": "워크스페이스",
"generalDesc": "레이아웃 및 리소스",
"appearance": "외관",
"appearanceDesc": "테마 및 언어",
"general": "일반",
"generalDesc": "테마, 언어, 레이아웃",
"terminal": "터미널",
"terminalDesc": "글꼴 및 색상",
"shortcuts": "단축키",
@@ -15,11 +13,13 @@
"ai": "AI 모델",
"aiDesc": "AI 제공자",
"about": "정보",
"aboutDesc": "버전 및 데이터"
"aboutDesc": "버전 및 데이터",
"account": "계정",
"accountDesc": "이메일, 라이선스, 기기"
},
"title": "설정",
"search": {
"placeholder": "설정 검색..."
"placeholder": "설정 검색…"
},
"language": {
"label": "언어",
@@ -89,7 +89,7 @@
"ssh": {
"connection": "연결",
"keepAlive": "연결 유지",
"keepAliveDesc": "연결 끊김을 줄이기 위해 유휴 시 keep-alive 전송",
"keepAliveDesc": "유휴 시 SSH keep-alive를 보냅니다. 연속 실패 후에만 연결을 끊습니다",
"autoReconnect": "자동 재연결",
"autoReconnectDesc": "예기치 않은 연결 끊김 후 자동으로 재시도",
"timeout": "연결 시간 초과",
@@ -101,8 +101,10 @@
"maxConnectionsDesc": "SSH, SFTP 및 일괄 연결에 공유되는 상한",
"maxBackground": "백그라운드 연결 제한",
"maxBackgroundDesc": "제한 초과 시 가장 오래전 사용한 연결 제거",
"suspend": "백그라운드 일시 중단",
"suspendDesc": "탭이 백그라운드에 있을 때 활성 채널을 해제하기까지의 시간(분)"
"suspend": "백그라운드 일시 중지",
"suspendDesc": "유휴 백그라운드 탭을 몇 분 후 일시 중지할지(활성 Shell/SFTP는 유지)",
"keepAliveInterval": "유지 간격(초)",
"keepAliveIntervalDesc": "서버 ping 주기(ClientAliveInterval과 유사). 불안정한 네트워크에서는 15초 이하 권장"
},
"security": {
"credentials": "자격 증명 보호",
@@ -119,7 +121,7 @@
"clearConfirm": "모든 알려진 호스트 키를 지우시겠습니까? 다음 연결 시 다시 확인 메시지가 표시됩니다."
},
"about": {
"tagline": "가벼운 네이티브 SSH / SFTP 운영 터미널",
"tagline": "간단하고 실용적인 네이티브 운영 터미널",
"appVersion": "앱 v{{version}}",
"copyVersion": "버전 정보 복사",
"runtime": "런타임",
@@ -127,8 +129,9 @@
"localData": "로컬 데이터",
"sessionsSettings": "세션 및 설정",
"masterKeyPath": "마스터 키",
"privacyNote": "비밀번호와 키 암호는 Rust에서 AES-256-GCM으로 암호화됩니다. OpsXShell은 터미널 명령 히스토리를 저장하지 않습니다.",
"license": "MIT 라이선스 · Rust · XTerm.js"
"privacyNote": "비밀번호·키 암호는 Rust에서 AES-256-GCM으로 암호화합니다. 명령 기록·감사 로그는 저장하지 않습니다.",
"license": "MIT 라이선스 · Rust · XTerm.js",
"logPath": "앱 로그"
},
"ai": {
"presets": "제공자 프리셋",
@@ -162,13 +165,42 @@
"apiKeySaveFailed": "API 키 저장 실패",
"providerNotFound": "제공자를 찾을 수 없음",
"modelCatalogReadFailed": "모델 카탈로그 읽기 실패",
"catalogUnavailable": "models.dev를 사용할 수 없습니다"
"catalogUnavailable": "models.dev를 사용할 수 없습니다",
"family": {
"openai_compatible": "OpenAI 호환",
"standalone": "독립 프로토콜",
"plan": "구독 플랜",
"local": "자체 호스팅",
"custom": "사용자 지정"
}
},
"family": {
"openai_compatible": "OpenAI 호환",
"standalone": "────────",
"plan": "플랜",
"local": "셀프 호스팅",
"custom": "사용자 지정"
"account": {
"title": "Account",
"email": "Email",
"emailDesc": "Used for checkout and license claims",
"plan": "Current plan",
"planFree": "Free",
"planYearly": "프로 연간",
"planPerpetual": "프로 영구",
"planTrial": "프로 체험",
"expires": "Expires {{date}}",
"lifetime": "Lifetime",
"devices": "Seats: up to {{count}} devices",
"deviceId": "This device ID",
"saveEmail": "Save email",
"activate": "Activate license",
"pasteLicense": "Paste LIC- license key",
"clear": "Clear local license",
"deactivate": "Deactivate this device",
"upgrade": "Upgrade",
"saved": "Saved",
"activateOk": "Activated",
"deviceList": "바인딩된 기기",
"loadingDevices": "기기 목록 불러오는 중…",
"noDevices": "바인딩된 기기 없음",
"thisDevice": "이 기기",
"removeDevice": "해제",
"deviceRemoved": "기기 바인딩이 해제됨",
"seatFull": "기기 좌석이 가득 찼습니다. 새 기기에서 활성화하기 전에 다른 기기를 해제하세요."
}
}
+54 -24
View File
@@ -3,8 +3,9 @@
"local": "로컬",
"remote": "원격",
"notConnectedTitle": "원격 서버에 연결되지 않음",
"notConnectedDesc": "SFTP를 사용하려면 먼저 SSH 세션을 연결하세요",
"ariaLabel": "{{title}} 파일 패널"
"notConnectedDesc": "먼저 SSH에 연결한 뒤 전송·편집",
"ariaLabel": "{{title}} 파일 패널",
"reconnectResumeDesc": "연결이 끊겼습니다. 다시 연결하면 {{path}}(으)로 복귀합니다"
},
"connection": {
"selectServer": "서버 선택",
@@ -12,7 +13,9 @@
"createSessionHint": "먼저 사이드바에서 세션을 생성하세요",
"reconnect": "재연결",
"notConnected": "연결되지 않음",
"connecting": "연결 중..."
"connecting": "연결 중...",
"resumeHint": "다시 연결하면 {{path}}(으)로 복귀합니다",
"reconnectingResume": "{{path}} 복원하며 다시 연결 중…"
},
"errors": {
"notConnected": "SFTP가 연결되지 않았습니다",
@@ -23,19 +26,14 @@
"selectDownloadFiles": "먼저 다운로드할 파일을 선택하세요",
"uploadFailed": "업로드 실패",
"downloadFailed": "다운로드 실패",
"fileError": "{{fileName}}: {{message}}"
"fileError": "{{fileName}}: {{message}}",
"mkdirFailed": "폴더 만들기 실패"
},
"toolbar": {
"upload": "업로드",
"uploadAria": "업로드",
"download": "다운로드",
"downloadAria": "다운로드",
"downloadNeedSelection": "먼저 원격 파일을 선택하세요",
"downloadHint": "선택한 원격 파일 다운로드",
"refresh": "새로고침",
"refreshAria": "새로고침",
"refreshAria": "이 패널 새로고침",
"newFolder": "새 폴더",
"newFolderAria": "새 폴더"
"newFolderAria": "이 패널에 새 폴더 만들기"
},
"sort": {
"name": "이름",
@@ -55,7 +53,8 @@
"hideHidden": "도트파일 숨기기 (.xxx)",
"showHiddenAria": "숨김 파일 표시",
"hideHiddenAria": "도트파일 숨기기",
"searchAria": "{{title}}에서 검색"
"searchAria": "{{title}}에서 검색",
"upAtRoot": "이미 루트입니다"
},
"status": {
"loading": "불러오는 중...",
@@ -63,7 +62,8 @@
"filtered": "{{shown}} / {{total}} 표시 중",
"hiddenCount": "전체 {{total}}개 항목 ({{hidden}}개 숨김)",
"total": "{{count}}개 항목",
"filterHint": "필터: {{query}}"
"filterHint": "필터: {{query}}",
"refreshing": "새로 고치는 중..."
},
"empty": {
"dirTitle": "빈 디렉터리",
@@ -99,7 +99,6 @@
"download": "다운로드",
"edit": "편집",
"rename": "이름 변경",
"copyPath": "경로 복사",
"properties": "속성",
"permissions": "권한",
"delete": "삭제"
@@ -116,7 +115,18 @@
"chmodTitle": "권한 편집",
"chmodApply": "적용",
"pickUploadTitle": "업로드할 파일 또는 폴더 선택",
"pickUploadRzTitle": "업로드할 파일 선택 (rz)"
"pickUploadRzTitle": "업로드할 파일 선택 (rz)",
"overwriteTitle": "기존 파일을 덮어쓸까요?",
"overwriteConfirm": "덮어쓰기",
"overwriteSkip": "건너뛰기",
"overwriteOneRemote": "원격에 「{{name}}」이(가) 있습니다. 덮어쓸까요?",
"overwriteOneLocal": "로컬에 「{{name}}」이(가) 있습니다. 덮어쓸까요?",
"overwriteManyRemote": "원격에 같은 이름 {{count}}개가 있습니다. 모두 덮어쓸까요?",
"overwriteManyLocal": "로컬에 같은 이름 {{count}}개가 있습니다. 모두 덮어쓸까요?",
"overwriteMore": "…외 {{count}}개",
"deleteTitle": "삭제 확인",
"deleteMessage": "{{count}}개 항목을 삭제합니다: {{names}}",
"deleteRecursiveWarn": "폴더가 포함되어 있습니다. 재귀 삭제되며 되돌릴 수 없습니다."
},
"properties": {
"name": "이름",
@@ -152,27 +162,41 @@
"statusDone": "완료",
"statusFailed": "실패",
"statusCancelled": "취소됨",
"dropUpload": "{{path}}에 업로드",
"dropDownload": "{{path}}에 다운로드"
"dropUpload": "{{path}}(으)로 업로드하려면 여기에 놓으세요",
"dropDownload": "{{path}}(으)로 다운로드하려면 여기에 놓으세요",
"railAria": "로컬과 원격 간 전송",
"railUpload": "선택한 로컬 파일 업로드(선택 없으면 파일 선택)",
"railDownload": "선택한 원격 파일을 로컬로 다운로드",
"railUploadAria": "원격으로 업로드",
"railDownloadAria": "로컬로 다운로드",
"railDownloadNeedSelection": "먼저 원격 파일을 선택하세요",
"retry": "다시 시도"
},
"editor": {
"readFailed": "읽기 실패",
"saveFailed": "저장 실패",
"unsavedClose": "저장되지 않은 변경 사항이 있습니다. 그래도 닫으시겠습니까?",
"unsavedTitle": "저장되지 않은 변경 사항",
"discardAndClose": "버리고 닫기",
"reloadTitle": "다시 로드",
"discardAndReload": "버리고 다시 로드",
"saving": "저장 중...",
"save": "저장",
"saved": "파일 저장됨",
"loadingEditor": "에디터 로드 중...",
"footer": "UTF-8 · Monaco · ⌘/Ctrl+S 저장 · 최대 ~2MB",
"loadBlocked": "파일 내용을 불러오지 못했습니다",
"footer": "UTF-8 · ⌘/Ctrl+S 저장 · Esc 닫기 · 최대 약 2MB",
"charCount": "{{count}}자",
"unsavedMark": " · 저장 안 됨",
"savedMark": " · 저장됨"
"savedMark": " · 저장됨",
"title": "{{name}} 편집",
"dirtyBadge": "저장 안 됨",
"reload": "다시 불러오기",
"unsavedReload": "저장되지 않은 변경을 버리고 다시 불러올까요?"
},
"toast": {
"renamed": "{{name}}(으)로 이름 변경됨",
"renameFailed": "이름 변경 실패",
"pathCopied": "경로가 클립보드에 복사됨",
"pathCopyFailed": "경로 복사 실패",
"chmodUpdated": "권한이 {{mode}}(으)로 업데이트됨",
"chmodFailed": "권한 업데이트 실패",
"uploadPartial": "{{action}} 완료 {{completed}}, 실패 {{failed}}: {{detail}}",
@@ -180,7 +204,13 @@
"uploadAction": "업로드",
"downloadAction": "다운로드",
"noFolderUpload": "폴더 업로드 실패",
"noDragPath": "드래그 앤 드롭 경로를 사용할 수 없습니다; 업로드를 사용하세요",
"noFolderRecursive": "재귀 폴더 전송 실패; 재시도하거나 업로드를 사용하세요"
"noDragPath": "이 환경에서는 드래그 경로를 제공하지 않습니다. 가운데 → 또는 파일 선택을 사용하세요.",
"noFolderRecursive": "폴더 전송에 실패했습니다. 다시 시도하거나 가운데 → / 파일 선택을 사용하세요.",
"dropFailed": "끌어다 놓기 실패: 파일 정보를 읽지 못했습니다. 다시 시도하거나 가운데 화살표를 사용하세요.",
"folderCreated": "폴더 {{name}} 생성됨",
"allSkippedExisting": "이미 있는 파일을 모두 건너뛰었습니다",
"skippedExisting": "기존 파일 {{count}}개를 건너뛰었습니다",
"deleteFailed": "삭제 실패",
"deleted": "삭제됨"
}
}
+3 -2
View File
@@ -34,7 +34,7 @@
"reopenShell": "셸 다시 열기",
"reopening": "여는 중…",
"disconnected": "연결 끊김",
"disconnectedHint": "SSH 세션이 종료되었거나 네트워크가 끊겼습니다. 아래를 클릭하여 재연결하세요.",
"disconnectedHint": "SSH 세션이 종료되었거나 네트워크가 끊겼습니다. 아래를 누르면 다시 연결해 작업을 이어갑니다.",
"reconnect": "재연결",
"suspended": "연결 일시 중단됨",
"suspendedHint": "오랫동안 활동이 없어 리소스 절약을 위해 연결이 일시 중단되었습니다",
@@ -70,7 +70,8 @@
"splitRight": "오른쪽으로 분할",
"splitDown": "아래로 분할",
"maximizePane": "현재 창 최대화",
"restoreLayout": "분할 레이아웃 복원"
"restoreLayout": "분할 레이아웃 복원",
"openSftp": "SFTP 열기"
},
"search": {
"placeholder": "검색...",
+122 -38
View File
@@ -90,6 +90,8 @@
"terminal": "Терминал",
"batch": "Пакетное выполнение",
"newTerminal": "Новый терминал",
"closeAria": "Закрыть {{title}}",
"listAria": "Открытые вкладки",
"kind": {
"terminal": "Терминал",
"sftp": "SFTP",
@@ -105,7 +107,8 @@
"closeRight": "Закрыть вкладки справа",
"closeLeft": "Закрыть вкладки слева",
"closeAll": "Закрыть все",
"clone": "Дублировать вкладку"
"clone": "Дублировать вкладку",
"openSftp": "Открыть SFTP"
}
},
"sidebar": {
@@ -149,9 +152,9 @@
"disconnect": "Отключиться"
},
"pro": {
"upgrade": "Обновить Pro",
"upgrade": "Обновить до Pro",
"feature": "Возможности Pro",
"unlock": "Разблокировать {{feature}}",
"unlock": "Разблокировать расширенные функции Pro",
"comingSoon": "Скоро",
"activateSuccess": "Активировано",
"activateFailed": "Сбой активации",
@@ -160,28 +163,33 @@
"invalidLicense": "Сбой активации: недействительная лицензия",
"goUpgrade": "Обновить",
"haveLicense": "Есть лицензия? Активировать",
"title": "OpsXShell Pro · Оперативные возможности Pro",
"subtitleComingSoon": "{{feature}} скоро · обновите Pro для раннего доступа",
"subtitleUnlock": "Разблокировка: {{feature}}",
"subtitleDefault": "Проброс портов, прокси, serial, AI, пакетное выполнение и рассылка",
"title": "OpsXShell · Разблокировать Pro",
"subtitleComingSoon": "Расширенные функции скоро · обновите до Pro для раннего доступа",
"subtitleUnlock": "Разблокируются расширенные функции",
"subtitleDefault": "Проброс портов, AI в терминале, пакетные операции, списки хостов и удалённый рабочий стол в Pro",
"activated": "Pro активирован",
"expiresAt": " · действует до {{date}}",
"lifetime": " · бессрочная лицензия",
"oneTimeFee": "Разовая покупка · бессрочно на этом устройстве · без подписки",
"oneTimeFee": "Бесплатно / Pro год / Pro бессрочно",
"pasteLicense": "Вставить лицензию",
"activateButton": "Активировать",
"clearLicense": "Очистить локальную лицензию",
"paymentNote": "Оплата обрабатывается Waffo; это приложение не собирает данные карт.",
"testDeviceId": "Тестовая среда · ID устройства: {{deviceId}}",
"later": "Может быть позже",
"viewPro": "Посмотреть Pro",
"wallComingSoonSuffix": " · скоро",
"wallUnlock": "Разблокировать {{feature}}",
"wallMessageComingSoon": "Эта возможность Pro ещё в разработке. Обновите для раннего доступа.",
"wallMessageDefault": "Эта функция требует OpsXShell Pro. Обновите, чтобы использовать её на этом устройстве.",
"later": "Позже",
"viewPro": "Смотреть тарифы Pro",
"wallComingSoonSuffix": "скоро",
"wallUnlock": "Разблокировать расширенные функции Pro",
"wallMessageComingSoon": "Эта возможность входит в OpsXShell Pro и ещё дорабатывается. Обновите до Pro на год или бессрочно для раннего доступа.",
"wallMessageDefault": "Проброс портов, AI в терминале, пакетный запуск, списки хостов и удалённый рабочий стол входят в Pro. Обновите до Pro на год или бессрочно, чтобы использовать на этом устройстве.",
"checkoutUnavailable": "Оформление недоступно ({{status}})",
"emailLabel": "Email",
"emailRequired": "Введите email перед оформлением заказа",
"claimPending": "Получение лицензии…",
"invalidKeyFormat": "Неверный формат ключа — вставьте лицензию LIC-",
"accountEmail": "Аккаунт: {{email}}",
"freeTier": "Бесплатно",
"proTier": "Pro",
"proTier": "Профессиональная",
"freeItems": {
"ssh": "SSH-терминал",
"sftp": "Менеджер файлов SFTP",
@@ -191,22 +199,60 @@
},
"proItems": {
"forward": "Проброс портов",
"proxy": "Прокси сеанса / SOCKS",
"proxy": "Прокси сессии / SOCKS",
"serial": "Последовательный терминал",
"ai": "Терминальный AI-ассистент",
"batch": "Пакетное выполнение / синхронизация рассылки",
"broadcast": "Синхронизация ввода рассылки",
"importExport": "Массовый импорт/экспорт хостов",
"desktop": "Удалённый рабочий стол RDP / VNC"
}
"ai": "AI-помощник в терминале",
"batch": "Пакетный запуск / синхронный broadcast",
"broadcast": "Синхронный ввод broadcast",
"importExport": "Пакетный импорт/экспорт списка хостов",
"desktop": "Удалённый рабочий стол (RDP / VNC)"
},
"planYearly": "Pro на год",
"planYearlyDesc": "¥99 / год · 2 устройства",
"planPerpetual": "Pro бессрочно",
"planPerpetualDesc": "¥199 · 5 устройств · навсегда",
"planTrial": "Pro пробный",
"devices": "До {{count}} устройств",
"goUpgradeYearly": "Купить Pro на год",
"goUpgradePerpetual": "Купить Pro бессрочно",
"activatedYearly": "Активирован Pro на год",
"activatedPerpetual": "Активирован Pro бессрочно",
"activatedTrial": "Активирован Pro пробный",
"choosePlan": "Выбор: бесплатно / Pro год / Pro бессрочно",
"planFreePrice": "¥0",
"planFreeDesc": "SSH · SFTP · локальный терминал",
"planFreeCta": "Текущий план",
"planIncludesPro": "Все функции Pro",
"planFree": "Бесплатно",
"subtitleUnlockDetail": "Связанная возможность: {{feature}}",
"wallUnlockComingSoon": "Расширенные функции Pro скоро",
"wallMessageComingSoonFeature": "«{{feature}}» — расширенная функция Pro, ещё дорабатывается. Обновите до Pro на год или бессрочно для раннего доступа.",
"wallMessageFeature": "«{{feature}}» — расширенная функция Pro. Обновите до Pro на год или бессрочно, чтобы использовать на этом устройстве."
},
"launcher": {
"title": "Быстрый запуск",
"description": "Сеансы, локальные оболочки и консоли устройств",
"description": "Сессии, локальный Shell, рабочий стол, serial",
"cards": {
"quickConnect": { "title": "Быстрое подключение", "desc": "user@host:port" },
"saveSession": { "title": "Сохранить сеанс", "desc": "Учётные данные, группы, прокси" },
"serial": { "title": "Последовательный терминал", "desc": "Скорость (baud) и настройки порта" }
"quickConnect": {
"title": "Быстрое подключение",
"desc": "user@host:port"
},
"saveSession": {
"title": "Сохранить сеанс",
"desc": "Учётные данные, группы, прокси"
},
"serial": {
"title": "Последовательный терминал",
"desc": "Скорость (baud) и настройки порта"
},
"rdp": {
"title": "RDP рабочий стол",
"desc": "Удалённый Windows"
},
"vnc": {
"title": "VNC рабочий стол",
"desc": "Удалённый графический"
}
},
"sectionLocalShell": "Локальная оболочка",
"sectionSavedSessions": "Сохранённые сеансы",
@@ -220,6 +266,7 @@
"forwardOpenRunning": "SOCKS5 работает (:{{port}}) · клик для управления · правый клик для копирования",
"forwardStarted": "Проброс запущен",
"forwardStartedDynamic": "SOCKS5 запущен: socks5://127.0.0.1:{{port}}",
"forwardResumed": "Восстановлено перенаправлений: {{count}}",
"socksStartFailed": "Сбой запуска: {{message}}",
"socksStopFailed": "Сбой остановки: {{message}}",
"socksCopied": "Скопировано socks5://127.0.0.1:{{port}}"
@@ -240,7 +287,7 @@
"typeDynamic": "Dynamic",
"running": "Выполняется",
"socksProxy": "SOCKS5: 127.0.0.1:{{port}}",
"remoteToLocal": "Удалённый {{remote}} → локальный {{local}}",
"remoteToLocal": "удалённо {{bind}}:{{remote}} → {{host}}:{{local}}",
"stats": "{{connections}} подкл. · ↑{{up}} · ↓{{down}}",
"copyProxy": "Копировать прокси",
"copyRule": "Дублировать правило",
@@ -250,15 +297,15 @@
"delete": "Удалить",
"editTitle": "Изменить проброс",
"addTitle": "Добавить проброс",
"typeLocalDesc": "Локальный → удалённый",
"typeRemoteDesc": "Удалённый → локальный",
"typeLocalDesc": "Доступ к удалённому сервису",
"typeRemoteDesc": "Открыть локальный сервис",
"typeDynamicDesc": "SOCKS5",
"selectType": "Тип",
"drawerSubtitle": "Туннель через текущий SSH-сеанс",
"ruleFields": "Подробности",
"dynamicHint": "Локальный SOCKS5, по умолчанию 127.0.0.1:1080 (можно менять). Трафик выходит через публичный IP этого SSH-сервера.",
"dynamicSingleHint": "Одно правило Dynamic на SSH-хост; измените порт прослушивания при остановке.",
"dynamicPortHint": "Если порт занят, выберите другой локальный порт (напр. 1081).",
"dynamicHint": "Локальный SOCKS5 (по умолчанию :1080). Трафик выходит через этот SSH.",
"dynamicSingleHint": "Одно динамическое правило на SSH-хост; порт меняйте, когда остановлено.",
"dynamicPortHint": "Если занят — другой порт (напр. 1081).",
"ruleList": "Правила",
"ruleListEmpty": "Правил Local / Remote пока нет",
"addSection": "Добавить новое",
@@ -292,17 +339,30 @@
"internet": "Интернет",
"localCaption": "Local: обращение к удалённому порту как к локальному.",
"remoteCaption": "Remote: удалённый доступ пробрасывается к локальному сервису.",
"dynamicCaption": "Dynamic: эта машина становится прокси SOCKS5, выходящим через публичный IP текущего SSH-сервера."
"dynamicCaption": "Динамический: локальный SOCKS5 через выход этого SSH."
},
"ruleName": "Название",
"ruleNamePlaceholder": "напр. MySQL",
"localListenPort": "Локальный порт прослушивания",
"localListenPortHint": "По умолчанию localhost — как ssh -L порт:…. Обычно достаточно порта.",
"localBindAdvanced": "Дополнительно: сменить локальный bind",
"localTargetPort": "Локальный целевой порт",
"remoteTargetPort": "Удалённый целевой порт",
"remoteTargetPort": "Целевой порт",
"remoteListenPort": "Удалённый порт прослушивания",
"remoteListenPortHint": "По умолчанию localhost на SSH-сервере — как ssh -R порт:…. Обычно достаточно порта.",
"remoteListenAddress": "Удалённый listen",
"remoteListenAddressPlaceholder": "127.0.0.1:18080",
"remoteListenAddressHint": "127.0.0.1 — только удалённый хост; 0.0.0.0 — удалённая LAN (нужен GatewayPorts).",
"errorRemoteListenAddress": "Укажите корректный удалённый listen, напр. 127.0.0.1:18080",
"localTargetAddress": "Локальная / LAN цель",
"localTargetAddressPlaceholder": "127.0.0.1:8080",
"localTargetAddressHint": "На локальный/LAN сервис, напр. 127.0.0.1:8080. Не используйте 0.0.0.0.",
"viaSessionRemote": "Слушать на {{target}} (по умолчанию localhost)",
"errorRemoteListenPort": "Укажите корректный удалённый порт прослушивания (1–65535)",
"errorLocalTargetAddress": "Укажите корректную локальную/LAN цель, напр. 127.0.0.1:8080",
"portPlaceholder": "напр. 3306",
"remoteHost": "Удалённый хост",
"remoteHostPlaceholder": "localhost или IP",
"remoteHost": "Целевой хост",
"remoteHostPlaceholder": "127.0.0.1",
"socksRuleName": "Прокси SOCKS5",
"defaultLocalName": "Локальный проброс",
"defaultRemoteName": "Удалённый проброс",
@@ -316,11 +376,35 @@
"deleteConfirm": "Удалить это правило?",
"errorNamePort": "Введите имя и корректный порт (1–65535)",
"errorTargetPort": "Введите корректный целевой порт (1–65535)",
"errorRemoteHost": "Введите удалённый хост",
"errorRemoteHost": "Укажите целевой хост (относительно SSH-сервера)",
"errorNotConnected": "Нет подключения",
"errorStartFailed": "Сбой запуска",
"errorStopFailed": "Сбой остановки",
"errorSocksRunning": "SOCKS5 уже работает",
"copySuffix": "Копировать"
"copySuffix": "Копировать",
"remoteBindHint": "0.0.0.0 нужен GatewayPorts; иначе часто только 127.0.0.1. Цель не должна быть 0.0.0.0.",
"localToRemote": "локально {{bind}}:{{local}} → удалённо {{host}}:{{remote}}",
"localToRemotePort": "локально :{{local}} → удалённо {{host}}:{{remote}}",
"remoteHostHint": "Относительно SSH-сервера. Сам хост — 127.0.0.1, LAN — достижимый IP. Не 0.0.0.0.",
"localBindHost": "Локальный bind",
"localBindHostPlaceholder": "127.0.0.1",
"localBindHostHint": "По умолчанию только этот ПК. 0.0.0.0 или LAN IP — доступ из сети.",
"errorTargetHostInvalid": "Цель не может быть 0.0.0.0 — укажите 127.0.0.1 или достижимый IP",
"listenAddress": "Локальный listen",
"listenAddressPlaceholder": "127.0.0.1:8080",
"listenAddressHint": "По умолчанию только этот ПК; 0.0.0.0 разрешает LAN.",
"targetAddress": "Удалённая цель",
"targetAddressPlaceholder": "127.0.0.1:80",
"targetAddressHint": "С точки зрения SSH-сервера. Сервис на нём — 127.0.0.1:порт.",
"errorListenAddress": "Укажите корректный listen, напр. 127.0.0.1:8080",
"errorTargetAddress": "Укажите корректную цель, напр. 127.0.0.1:80",
"targetAddressHintVia": "Через {{target}}. Сервис на том хосте — 127.0.0.1:порт (новый порт не открывается).",
"viaSession": "Через сессию {{target}}",
"remoteToLocalPort": "удал. :{{remote}} → {{host}}:{{local}}",
"remoteBindAdvanced": "Дополнительно: сменить remote bind",
"remoteBindHost": "Remote bind",
"remoteBindHostPlaceholder": "127.0.0.1",
"remoteBindHostHint": "По умолчанию только на SSH-сервере. 0.0.0.0 требует GatewayPorts; без него sshd часто тихо слушает только 127.0.0.1.",
"remoteGatewayPortsWarning": "Запрошен remote-listen 0.0.0.0. Без GatewayPorts sshd часто молча слушает только 127.0.0.1."
}
}
+11 -4
View File
@@ -15,10 +15,12 @@
"passwordOptional": "Пароль (необязательно)",
"width": "Ширина",
"height": "Высота",
"rdpFootnote": "Нативный IronRDP: TCP → X.224 → TLS → CredSSP/NLA → MCS; тайм-аут рукопожатия 45 с. Проверка сертификата во время разработки ослаблена.",
"vncFootnote": "Нативный vnc-rs RFB с декодированием Tight JPEG; буфер обмена передаётся в UTF-8 (очень старые серверы могут искажать текст).",
"rdpFootnote": "В полноэкранном или развёрнутом режиме удалённое разрешение запрашивается под текущую область окна. Начальный размер можно выбрать и до подключения. Проверка сертификата сейчас ослаблена для разработки.",
"vncFootnote": "У большинства VNC-серверов удалённое разрешение фиксировано; полноэкранный режим только масштабирует изображение локально. Предпочтительный размер при подключении носит справочный характер. Буфер обмена отправляется в UTF-8.",
"errorHostRequired": "Введите адрес хоста",
"errorUsernameRequired": "Введите имя пользователя"
"errorUsernameRequired": "Введите имя пользователя",
"resolution": "Разрешение",
"resolutionCustom": "Свой размер"
},
"toolbar": {
"pasteClipboard": "Вставить локальный буфер обмена на удалённый сервер",
@@ -28,7 +30,12 @@
"openShareDir": "Открыть общую папку локально (Downloads)",
"openShareDirAria": "Открыть общую папку",
"disconnect": "Отключиться",
"disconnectAria": "Отключиться"
"disconnectAria": "Отключиться",
"fullscreen": "Полный экран",
"fullscreenAria": "Развернуть на весь экран",
"exitFullscreen": "Выйти из полного экрана",
"exitFullscreenAria": "Выйти из полного экрана",
"exitFullscreenHint": "Esc / F11 — выход"
},
"status": {
"connecting": "Подключение…",
+16 -3
View File
@@ -39,7 +39,9 @@
"closed": "Подключение закрыто",
"dnsFailed": "Не удалось разрешить имя хоста",
"refused": "В подключении отказано",
"disconnected": "Отключено"
"disconnected": "Отключено",
"keepaliveFailed": "SSH keep-alive несколько раз не удался; соединение закрыто",
"idleKicked": "Удалённая оболочка завершилась по таймауту простоя (TMOUT)"
},
"auth": {
"failed": "Сбой аутентификации. Проверьте имя пользователя и пароль.",
@@ -68,7 +70,10 @@
"forward": {
"failed": "Сбой настройки проброса портов",
"bindFailed": "Не удалось привязать порт",
"alreadyInUse": "Порт уже занят"
"alreadyInUse": "Локальный порт уже занят. Остановите этот проброс или другой процесс на порту, затем запустите снова.",
"remoteDenied": "Сервер отклонил удалённый проброс (AllowTcpForwarding / PermitListen, порт занят или ограничение bind). Слушаем только 127.0.0.1 на удалённой стороне.",
"remoteDeniedPrivileged": "Отклонён привилегированный порт (<1024). Используйте ≥1024 или root и проверьте AllowTcpForwarding / PermitListen.",
"invalidTargetHost": "Цель не может быть 0.0.0.0 — укажите 127.0.0.1 или доступный внутренний IP"
},
"sftp": {
"connectFailed": "Сбой SFTP-подключения",
@@ -80,7 +85,15 @@
"writeFailed": "Сбой сохранения",
"renameFailed": "Сбой переименования",
"chmodFailed": "Не удалось обновить права доступа",
"apiUnavailable": "SFTP API недоступен"
"apiUnavailable": "SFTP API недоступен",
"channelFailed": "Не удалось открыть канал SFTP (лимит сервера или занятая сессия). Переподключитесь",
"sessionGone": "Сессия SFTP завершена; переподключитесь",
"busy": "Идёт передача файла. Повторите позже.",
"editTooLarge": "Файл слишком большой для текстового редактора (макс. ~2 МБ). Скачайте и откройте локально.",
"editBinary": "Файл похож на двоичный и не открывается в текстовом редакторе",
"editNotUtf8": "Удалённый файл не является допустимым текстом UTF-8",
"transferCancelled": "Передача отменена",
"diskFull": "Недостаточно места на диске (локально или удалённо)"
},
"session": {
"notFound": "Сеанс не найден",
+6 -4
View File
@@ -69,17 +69,17 @@
"confirm": "Удалить"
},
"welcome": {
"tagline": "Удалённый терминал · SFTP · Проброс портов",
"tagline": "Просто и по делу · терминал · файлы · рабочий стол",
"sectionStart": "Начало работы",
"sectionDesktop": "Удалённый рабочий стол",
"sectionRecent": "Недавние сеансы",
"quickConnect": {
"title": "Быстрое подключение",
"desc": "Разовое SSH; не сохраняется в библиотеке"
"desc": "Разовый SSH — не сохраняется в библиотеке"
},
"newSession": {
"title": "Новый сеанс",
"desc": "Сохраняйте хосты; двойной клик в боковой панели для подключения"
"desc": "Сохраните хост — двойной клик в сайдбаре для подключения"
},
"localShell": {
"title": "Локальная оболочка",
@@ -167,7 +167,9 @@
"jumpHost": "Jump-хост (необязательно)",
"jumpNone": "Без jump-хоста",
"jumpNoneAlt": "Без jump-хоста",
"jumpHint": "Сохранённый сеанс можно использовать как jump-хост"
"jumpHint": "Сохранённый сеанс можно использовать как jump-хост",
"resolution": "Разрешение",
"resolutionCustom": "Свой размер"
},
"batch": {
"title": "Пакетное выполнение",
+50 -18
View File
@@ -1,9 +1,7 @@
{
"nav": {
"general": "Рабочее пространство",
"generalDesc": "Макет и ресурсы",
"appearance": "Внешний вид",
"appearanceDesc": "Тема и язык",
"general": "Основные",
"generalDesc": "Тема, язык и макет",
"terminal": "Терминал",
"terminalDesc": "Шрифт и цвета",
"shortcuts": "Горячие клавиши",
@@ -15,11 +13,13 @@
"ai": "AI-модели",
"aiDesc": "AI-провайдеры",
"about": "О приложении",
"aboutDesc": "Версия и данные"
"aboutDesc": "Версия и данные",
"account": "Аккаунт",
"accountDesc": "Email, лицензия и устройство"
},
"title": "Настройки",
"search": {
"placeholder": "Поиск по настройкам..."
"placeholder": "Поиск настроек…"
},
"language": {
"label": "Язык",
@@ -89,7 +89,7 @@
"ssh": {
"connection": "Подключение",
"keepAlive": "Keep-alive",
"keepAliveDesc": "Отправлять keep-alive при простое для уменьшения разрывов",
"keepAliveDesc": "Отправлять SSH keep-alive в простое; отключать только после нескольких сбоев",
"autoReconnect": "Авто-переподключение",
"autoReconnectDesc": "Автоматически повторять после неожиданного разрыва",
"timeout": "Тайм-аут подключения",
@@ -102,7 +102,9 @@
"maxBackground": "Лимит фоновых подключений",
"maxBackgroundDesc": "Вытеснять давно не использованные подключения при превышении лимита",
"suspend": "Фоновая приостановка",
"suspendDesc": "Минуты до освобождения активных каналов, когда вкладка в фоне"
"suspendDesc": "Через сколько минут приостанавливать простаивающие фоновые вкладки (активные Shell/SFTP остаются)",
"keepAliveInterval": "Интервал keep-alive (сек)",
"keepAliveIntervalDesc": "Как часто опрашивать сервер (как ClientAliveInterval). При нестабильной сети — ≤15 с"
},
"security": {
"credentials": "Защита учётных данных",
@@ -119,7 +121,7 @@
"clearConfirm": "Очистить все известные ключи хостов? При следующем подключении запрос появится снова."
},
"about": {
"tagline": "Лёгкий нативный терминал эксплуатации SSH / SFTP",
"tagline": "Простой и удобный нативный терминал для эксплуатации",
"appVersion": "Приложение v{{version}}",
"copyVersion": "Копировать сведения о версии",
"runtime": "Среда выполнения",
@@ -127,8 +129,9 @@
"localData": "Локальные данные",
"sessionsSettings": "Сеансы и настройки",
"masterKeyPath": "Мастер-ключ",
"privacyNote": "Пароли и парольные фразы ключей шифруются AES-256-GCM в Rust. OpsXShell не сохраняет историю команд терминала.",
"license": "Лицензия MIT · Rust · XTerm.js"
"privacyNote": "Пароли и passphrase шифруются в Rust (AES-256-GCM). Без истории команд и без аудита-бастиона.",
"license": "Лицензия MIT · Rust · XTerm.js",
"logPath": "Журнал приложения"
},
"ai": {
"presets": "Пресеты провайдеров",
@@ -162,13 +165,42 @@
"apiKeySaveFailed": "Не удалось сохранить API-ключ",
"providerNotFound": "Провайдер не найден",
"modelCatalogReadFailed": "Не удалось прочитать каталог моделей",
"catalogUnavailable": "models.dev недоступен"
"catalogUnavailable": "models.dev недоступен",
"family": {
"openai_compatible": "Совместимые с OpenAI",
"standalone": "Нативные API",
"plan": "Подписки",
"local": "Локальные",
"custom": "Свой"
}
},
"family": {
"openai_compatible": "Совместимый с OpenAI",
"standalone": "────────",
"plan": "План",
"local": "Self-hosted",
"custom": "Своё"
"account": {
"title": "Account",
"email": "Email",
"emailDesc": "Used for checkout and license claims",
"plan": "Current plan",
"planFree": "Free",
"planYearly": "Pro на год",
"planPerpetual": "Pro бессрочно",
"planTrial": "Pro пробный",
"expires": "Expires {{date}}",
"lifetime": "Lifetime",
"devices": "Seats: up to {{count}} devices",
"deviceId": "This device ID",
"saveEmail": "Save email",
"activate": "Activate license",
"pasteLicense": "Paste LIC- license key",
"clear": "Clear local license",
"deactivate": "Deactivate this device",
"upgrade": "Upgrade",
"saved": "Saved",
"activateOk": "Activated",
"deviceList": "Привязанные устройства",
"loadingDevices": "Загрузка устройств…",
"noDevices": "Нет привязанных устройств",
"thisDevice": "Это устройство",
"removeDevice": "Отвязать",
"deviceRemoved": "Устройство отвязано",
"seatFull": "Все места заняты. Отвяжите другое устройство перед активацией на новой машине."
}
}
+54 -24
View File
@@ -3,8 +3,9 @@
"local": "Локально",
"remote": "Удалённо",
"notConnectedTitle": "Нет подключения к удалённому серверу",
"notConnectedDesc": "Сначала подключите SSH-сеанс, чтобы использовать SFTP",
"ariaLabel": "Панель файлов: {{title}}"
"notConnectedDesc": "Сначала подключите SSH — потом файлы и правки",
"ariaLabel": "Панель файлов: {{title}}",
"reconnectResumeDesc": "Соединение потеряно. Переподключение вернёт в {{path}}"
},
"connection": {
"selectServer": "Выберите сервер",
@@ -12,7 +13,9 @@
"createSessionHint": "Сначала создайте сеанс на боковой панели",
"reconnect": "Переподключиться",
"notConnected": "Нет подключения",
"connecting": "Подключение..."
"connecting": "Подключение...",
"resumeHint": "После переподключения вернёмся в {{path}}",
"reconnectingResume": "Переподключение и восстановление {{path}}…"
},
"errors": {
"notConnected": "SFTP не подключён",
@@ -23,19 +26,14 @@
"selectDownloadFiles": "Сначала выберите файлы для скачивания",
"uploadFailed": "Сбой загрузки",
"downloadFailed": "Сбой скачивания",
"fileError": "{{fileName}}: {{message}}"
"fileError": "{{fileName}}: {{message}}",
"mkdirFailed": "Не удалось создать папку"
},
"toolbar": {
"upload": "Загрузить",
"uploadAria": "Загрузить",
"download": "Скачать",
"downloadAria": "Скачать",
"downloadNeedSelection": "Сначала выберите удалённые файлы",
"downloadHint": "Скачать выбранные удалённые файлы",
"refresh": "Обновить",
"refreshAria": "Обновить",
"refreshAria": "Обновить эту панель",
"newFolder": "Новая папка",
"newFolderAria": "Новая папка"
"newFolderAria": "Создать папку на этой панели"
},
"sort": {
"name": "Имя",
@@ -55,7 +53,8 @@
"hideHidden": "Скрыть dot-файлы (.xxx)",
"showHiddenAria": "Показать скрытые файлы",
"hideHiddenAria": "Скрыть dot-файлы",
"searchAria": "Поиск в {{title}}"
"searchAria": "Поиск в {{title}}",
"upAtRoot": "Уже в корне"
},
"status": {
"loading": "Загрузка...",
@@ -63,7 +62,8 @@
"filtered": "Показано {{shown}} / {{total}}",
"hiddenCount": "{{total}} объектов ({{hidden}} скрыто)",
"total": "Объектов: {{count}}",
"filterHint": "Фильтр: {{query}}"
"filterHint": "Фильтр: {{query}}",
"refreshing": "Обновление..."
},
"empty": {
"dirTitle": "Пустой каталог",
@@ -99,7 +99,6 @@
"download": "Скачать",
"edit": "Изменить",
"rename": "Переименовать",
"copyPath": "Копировать путь",
"properties": "Свойства",
"permissions": "Права доступа",
"delete": "Удалить"
@@ -116,7 +115,18 @@
"chmodTitle": "Изменить права доступа",
"chmodApply": "Применить",
"pickUploadTitle": "Выберите файлы или папки для загрузки",
"pickUploadRzTitle": "Выберите файл для загрузки (rz)"
"pickUploadRzTitle": "Выберите файл для загрузки (rz)",
"overwriteTitle": "Перезаписать существующие файлы?",
"overwriteConfirm": "Перезаписать",
"overwriteSkip": "Пропустить",
"overwriteOneRemote": "«{{name}}» уже есть на удалённой стороне. Перезаписать?",
"overwriteOneLocal": "«{{name}}» уже есть локально. Перезаписать?",
"overwriteManyRemote": "На удалённой стороне уже есть {{count}} одноимённых. Перезаписать все?",
"overwriteManyLocal": "Локально уже есть {{count}} одноимённых. Перезаписать все?",
"overwriteMore": "…и ещё {{count}}",
"deleteTitle": "Подтвердите удаление",
"deleteMessage": "Удалить {{count}} элемент(ов): {{names}}",
"deleteRecursiveWarn": "Есть каталоги. Удаление рекурсивное и необратимо."
},
"properties": {
"name": "Имя",
@@ -152,27 +162,41 @@
"statusDone": "Готово",
"statusFailed": "Сбой",
"statusCancelled": "Отменено",
"dropUpload": "Загрузить в {{path}}",
"dropDownload": "Скачать в {{path}}"
"dropUpload": "Отпустите здесь, чтобы загрузить в {{path}}",
"dropDownload": "Отпустите здесь, чтобы скачать в {{path}}",
"railAria": "Передача между локальным и удалённым",
"railUpload": "Загрузить выбранные локальные файлы (или выбрать файлы, если ничего не выбрано)",
"railDownload": "Скачать выбранные удалённые файлы локально",
"railUploadAria": "Загрузить на удалённый",
"railDownloadAria": "Скачать локально",
"railDownloadNeedSelection": "Сначала выберите удалённые файлы",
"retry": "Повторить"
},
"editor": {
"readFailed": "Сбой чтения",
"saveFailed": "Сбой сохранения",
"unsavedClose": "Есть несохранённые изменения. Всё равно закрыть?",
"unsavedTitle": "Несохранённые изменения",
"discardAndClose": "Отменить и закрыть",
"reloadTitle": "Перезагрузить",
"discardAndReload": "Отменить и перезагрузить",
"saving": "Сохранение...",
"save": "Сохранить",
"saved": "Файл сохранён",
"loadingEditor": "Загрузка редактора...",
"footer": "UTF-8 · Monaco · ⌘/Ctrl+S сохранить · максимум ~2 МБ",
"loadBlocked": "Не удалось загрузить содержимое файла",
"footer": "UTF-8 · ⌘/Ctrl+S сохранить · Esc закрыть · макс. ~2 МБ",
"charCount": "Символов: {{count}}",
"unsavedMark": " · не сохранено",
"savedMark": " · сохранено"
"savedMark": " · сохранено",
"title": "Редактирование {{name}}",
"dirtyBadge": "Не сохранено",
"reload": "Перезагрузить",
"unsavedReload": "Отменить несохранённые изменения и перезагрузить?"
},
"toast": {
"renamed": "Переименовано в {{name}}",
"renameFailed": "Сбой переименования",
"pathCopied": "Путь скопирован в буфер обмена",
"pathCopyFailed": "Не удалось скопировать путь",
"chmodUpdated": "Права доступа изменены на {{mode}}",
"chmodFailed": "Не удалось обновить права доступа",
"uploadPartial": "{{action}} завершено для {{completed}}, сбой {{failed}}: {{detail}}",
@@ -180,7 +204,13 @@
"uploadAction": "Загрузка",
"downloadAction": "Скачивание",
"noFolderUpload": "Сбой загрузки папки",
"noDragPath": "Пути перетаскивания недоступны; используйте «Загрузить»",
"noFolderRecursive": "Сбой рекурсивной передачи папки; повторите или используйте «Загрузить»"
"noDragPath": "Система не предоставила путь при перетаскивании. Используйте стрелку → или выбор файлов.",
"noFolderRecursive": "Передача папки не удалась. Повторите или используйте → / выбор файлов.",
"dropFailed": "Перетаскивание не удалось: не удалось прочитать файл. Повторите или используйте стрелки.",
"folderCreated": "Создана папка {{name}}",
"allSkippedExisting": "Все уже существующие файлы пропущены",
"skippedExisting": "Пропущено существующих: {{count}}",
"deleteFailed": "Не удалось удалить",
"deleted": "Удалено"
}
}
+3 -2
View File
@@ -34,7 +34,7 @@
"reopenShell": "Открыть оболочку снова",
"reopening": "Открытие…",
"disconnected": "Отключено",
"disconnectedHint": "SSH-сеанс завершился или сеть упала. Нажмите ниже, чтобы переподключиться.",
"disconnectedHint": "SSH-сеанс завершился или сеть упала. Один клик ниже — и можно продолжать работу.",
"reconnect": "Переподключиться",
"suspended": "Подключение приостановлено",
"suspendedHint": "Долгое отсутствие активности; подключение приостановлено для экономии ресурсов",
@@ -70,7 +70,8 @@
"splitRight": "Разделить справа",
"splitDown": "Разделить вниз",
"maximizePane": "Развернуть текущую панель",
"restoreLayout": "Восстановить разделённый макет"
"restoreLayout": "Восстановить разделённый макет",
"openSftp": "Открыть SFTP"
},
"search": {
"placeholder": "Поиск...",
+107 -32
View File
@@ -90,6 +90,8 @@
"terminal": "Terminal",
"batch": "Thực thi hàng loạt",
"newTerminal": "Terminal mới",
"closeAria": "Đóng {{title}}",
"listAria": "Các tab đang mở",
"kind": {
"terminal": "Terminal",
"sftp": "SFTP",
@@ -105,7 +107,8 @@
"closeRight": "Đóng các tab bên phải",
"closeLeft": "Đóng các tab bên trái",
"closeAll": "Đóng tất cả",
"clone": "Nhân đôi tab"
"clone": "Nhân đôi tab",
"openSftp": "Mở SFTP"
}
},
"sidebar": {
@@ -151,7 +154,7 @@
"pro": {
"upgrade": "Nâng cấp Pro",
"feature": "Tính năng Pro",
"unlock": "Mở khóa {{feature}}",
"unlock": "Mở khóa tính năng nâng cao Pro",
"comingSoon": "Sắp ra mắt",
"activateSuccess": "Đã kích hoạt",
"activateFailed": "Kích hoạt thất bại",
@@ -160,28 +163,33 @@
"invalidLicense": "Kích hoạt thất bại: giấy phép không hợp lệ",
"goUpgrade": "Nâng cấp",
"haveLicense": "Có giấy phép? Kích hoạt",
"title": "OpsXShell Pro · Mở khóa các tính năng vận hành chuyên nghiệp",
"subtitleComingSoon": "{{feature}} sắp ra mắt · nâng cấp Pro để truy cập sớm",
"subtitleUnlock": "Đang mở khóa: {{feature}}",
"subtitleDefault": "Chuyển tiếp cổng, proxy, serial, AI, hàng loạt và phát sóng",
"title": "OpsXShell · Mở khóa Pro",
"subtitleComingSoon": "Tính năng nâng cao sắp có · nâng cấp Pro để dùng sớm",
"subtitleUnlock": "Đang mở khóa tính năng nâng cao",
"subtitleDefault": "Chuyển tiếp cổng, AI terminal, vận hành hàng loạt, danh sách host và máy tính từ xa trong Pro",
"activated": "Đã kích hoạt Pro",
"expiresAt": " · hợp lệ đến {{date}}",
"lifetime": " · giấy phép trọn đời",
"oneTimeFee": "Mua một lần · trọn đời trên thiết bị này · không cần đăng ký",
"oneTimeFee": "Miễn phí / Pro năm / Pro vĩnh viễn",
"pasteLicense": "Dán giấy phép",
"activateButton": "Kích hoạt",
"clearLicense": "Xóa giấy phép cục bộ",
"paymentNote": "Thanh toán được xử lý bởi Waffo; ứng dụng này không thu thập thông tin thẻ.",
"testDeviceId": "Môi trường thử nghiệm · ID thiết bị: {{deviceId}}",
"later": "Để sau",
"viewPro": "Xem Pro",
"wallComingSoonSuffix": " · sắp ra mắt",
"wallUnlock": "Mở khóa {{feature}}",
"wallMessageComingSoon": "Tính năng Pro này vẫn đang được phát triển. Nâng cấp để truy cập sớm.",
"wallMessageDefault": "Tính năng này yêu cầu OpsXShell Pro. Nâng cấp để sử dụng trên thiết bị này.",
"viewPro": "Xem gói Pro",
"wallComingSoonSuffix": "sắp có",
"wallUnlock": "Mở khóa tính năng nâng cao Pro",
"wallMessageComingSoon": "Khả năng này thuộc OpsXShell Pro và đang hoàn thiện. Nâng cấp Pro năm hoặc vĩnh viễn để dùng sớm.",
"wallMessageDefault": "Chuyển tiếp cổng, AI terminal, chạy hàng loạt, danh sách host và máy tính từ xa nằm trong Pro. Nâng cấp Pro năm hoặc vĩnh viễn để dùng trên máy này.",
"checkoutUnavailable": "Không thể thanh toán ({{status}})",
"emailLabel": "Email",
"emailRequired": "Nhập email trước khi thanh toán",
"claimPending": "Đang nhận giấy phép…",
"invalidKeyFormat": "Định dạng khóa không hợp lệ — dán khóa giấy phép LIC-",
"accountEmail": "Tài khoản: {{email}}",
"freeTier": "Miễn phí",
"proTier": "Pro",
"proTier": "Chuyên nghiệp",
"freeItems": {
"ssh": "Terminal SSH",
"sftp": "Quản lý tệp SFTP",
@@ -192,17 +200,38 @@
"proItems": {
"forward": "Chuyển tiếp cổng",
"proxy": "Proxy phiên / SOCKS",
"serial": "Terminal Serial",
"serial": "Terminal serial",
"ai": "Trợ lý AI terminal",
"batch": "Thực thi hàng loạt / đồng bộ phát sóng",
"broadcast": "Đồng bộ đầu vào phát sóng",
"importExport": "Nhập/xuất máy chủ hàng loạt",
"desktop": "Màn hình từ xa RDP / VNC"
}
"batch": "Chạy hàng loạt / đồng bộ phát sóng",
"broadcast": "Đồng bộ nhập phát sóng",
"importExport": "Nhập/xuất hàng loạt danh sách host",
"desktop": "Máy tính từ xa (RDP / VNC)"
},
"planYearly": "Pro theo năm",
"planYearlyDesc": "¥99 / năm · 2 thiết bị",
"planPerpetual": "Pro vĩnh viễn",
"planPerpetualDesc": "¥199 · 5 thiết bị · trọn đời",
"planTrial": "Pro dùng thử",
"devices": "Tối đa {{count}} thiết bị",
"goUpgradeYearly": "Mua Pro theo năm",
"goUpgradePerpetual": "Mua Pro vĩnh viễn",
"activatedYearly": "Đã kích hoạt Pro năm",
"activatedPerpetual": "Đã kích hoạt Pro vĩnh viễn",
"activatedTrial": "Đã kích hoạt Pro dùng thử",
"choosePlan": "Chọn: Miễn phí / Pro năm / Pro vĩnh viễn",
"planFreePrice": "¥0",
"planFreeDesc": "SSH · SFTP · terminal local",
"planFreeCta": "Gói hiện tại",
"planIncludesPro": "Đầy đủ tính năng Pro",
"planFree": "Miễn phí",
"subtitleUnlockDetail": "Khả năng liên quan: {{feature}}",
"wallUnlockComingSoon": "Tính năng nâng cao Pro sắp có",
"wallMessageComingSoonFeature": "「{{feature}}」 thuộc tính năng nâng cao Pro và đang hoàn thiện. Nâng cấp Pro năm hoặc vĩnh viễn để dùng sớm.",
"wallMessageFeature": "「{{feature}}」 thuộc tính năng nâng cao Pro. Nâng cấp Pro năm hoặc vĩnh viễn để dùng trên máy này."
},
"launcher": {
"title": "Khởi động nhanh",
"description": "Phiên, shell cục bộ và bảng điều khiển thiết bị",
"description": "Phiên, shell cục bộ, desktop, serial",
"cards": {
"quickConnect": {
"title": "Kết nối nhanh",
@@ -215,6 +244,14 @@
"serial": {
"title": "Terminal Serial",
"desc": "Tốc độ baud và cài đặt cổng"
},
"rdp": {
"title": "Máy tính RDP",
"desc": "Desktop Windows từ xa"
},
"vnc": {
"title": "Máy tính VNC",
"desc": "Desktop đồ họa từ xa"
}
},
"sectionLocalShell": "Shell cục bộ",
@@ -229,6 +266,7 @@
"forwardOpenRunning": "SOCKS5 đang chạy (:{{port}}) · nhấp để quản lý · nhấp chuột phải để sao chép",
"forwardStarted": "Đã bắt đầu chuyển tiếp",
"forwardStartedDynamic": "Đã khởi động SOCKS5: socks5://127.0.0.1:{{port}}",
"forwardResumed": "Đã khôi phục {{count}} chuyển tiếp cổng",
"socksStartFailed": "Khởi động thất bại: {{message}}",
"socksStopFailed": "Dừng thất bại: {{message}}",
"socksCopied": "Đã sao chép socks5://127.0.0.1:{{port}}"
@@ -249,7 +287,7 @@
"typeDynamic": "Động",
"running": "Đang chạy",
"socksProxy": "SOCKS5: 127.0.0.1:{{port}}",
"remoteToLocal": "Từ xa {{remote}} → cục bộ {{local}}",
"remoteToLocal": "từ xa {{bind}}:{{remote}} → {{host}}:{{local}}",
"stats": "{{connections}} kết nối · ↑{{up}} · ↓{{down}}",
"copyProxy": "Sao chép proxy",
"copyRule": "Nhân đôi quy tắc",
@@ -259,15 +297,15 @@
"delete": "Xóa",
"editTitle": "Sửa chuyển tiếp",
"addTitle": "Thêm chuyển tiếp",
"typeLocalDesc": "Cục bộ → từ xa",
"typeRemoteDesc": "Từ xa → cục bộ",
"typeLocalDesc": "Truy cập dịch vụ từ xa",
"typeRemoteDesc": "Công khai dịch vụ cục bộ",
"typeDynamicDesc": "SOCKS5",
"selectType": "Loại",
"drawerSubtitle": "Đường hầm qua phiên SSH hiện tại",
"ruleFields": "Chi tiết",
"dynamicHint": "SOCKS5 cục bộ tại 127.0.0.1:1080. Lưu lượng thoát qua địa chỉ IP công cộng của máy chủ SSH này.",
"dynamicSingleHint": "Một quy tắc Động cho mỗi máy chủ SSH, cổng cố định 1080.",
"dynamicPortHint": "If the port is busy, pick another local port (e.g. 1081).",
"dynamicHint": "SOCKS5 cục bộ (mặc định :1080). Lưu lượng ra qua SSH hiện tại.",
"dynamicSingleHint": "Mỗi SSH một quy tắc động; đổi cổng khi đã dừng.",
"dynamicPortHint": "Nếu bận, chọn cổng khác (vd. 1081).",
"ruleList": "Quy tắc",
"ruleListEmpty": "Chưa có quy tắc Cục bộ / Từ xa nào",
"addSection": "Thêm mới",
@@ -301,17 +339,30 @@
"internet": "Internet",
"localCaption": "Cục bộ: truy cập một cổng từ xa như thể nó là cổng cục bộ.",
"remoteCaption": "Từ xa: quyền truy cập từ xa được chuyển tiếp tới dịch vụ cục bộ.",
"dynamicCaption": "Động: máy này trở thành proxy SOCKS5 thoát qua IP công cộng của máy chủ SSH hiện tại."
"dynamicCaption": "Động: SOCKS5 cục bộ, ra ngoài qua SSH hiện tại."
},
"ruleName": "Tên",
"ruleNamePlaceholder": "vd. MySQL",
"localListenPort": "Cổng lắng nghe cục bộ",
"localListenPortHint": "Mặc định localhost — giống ssh -L cổng:…. Thường chỉ cần cổng.",
"localBindAdvanced": "Nâng cao: đổi bind cục bộ",
"localTargetPort": "Cổng đích cục bộ",
"remoteTargetPort": "Cổng đích từ xa",
"remoteTargetPort": "Cổng đích",
"remoteListenPort": "Cổng lắng nghe từ xa",
"remoteListenPortHint": "Mặc định localhost phía remote — giống ssh -R cổng:…. Thường chỉ cần nhập cổng.",
"remoteListenAddress": "Lắng nghe từ xa",
"remoteListenAddressPlaceholder": "127.0.0.1:18080",
"remoteListenAddressHint": "127.0.0.1 = chỉ máy remote; 0.0.0.0 = LAN remote (cần GatewayPorts).",
"errorRemoteListenAddress": "Nhập địa chỉ lắng nghe remote hợp lệ, vd. 127.0.0.1:18080",
"localTargetAddress": "Đích cục bộ / LAN",
"localTargetAddressPlaceholder": "127.0.0.1:8080",
"localTargetAddressHint": "Chuyển tới dịch vụ local/LAN, vd. 127.0.0.1:8080. Không dùng 0.0.0.0.",
"viaSessionRemote": "Lắng nghe trên {{target}} (mặc định localhost)",
"errorRemoteListenPort": "Nhập cổng lắng nghe từ xa hợp lệ (1–65535)",
"errorLocalTargetAddress": "Nhập đích local/LAN hợp lệ, vd. 127.0.0.1:8080",
"portPlaceholder": "vd. 3306",
"remoteHost": "Máy chủ từ xa",
"remoteHostPlaceholder": "localhost hoặc IP",
"remoteHost": "Máy đích",
"remoteHostPlaceholder": "127.0.0.1",
"socksRuleName": "Proxy SOCKS5",
"defaultLocalName": "Chuyển tiếp cục bộ",
"defaultRemoteName": "Chuyển tiếp từ xa",
@@ -325,11 +376,35 @@
"deleteConfirm": "Xóa quy tắc này?",
"errorNamePort": "Nhập tên và cổng hợp lệ (1–65535)",
"errorTargetPort": "Nhập cổng đích hợp lệ (1–65535)",
"errorRemoteHost": "Nhập máy chủ từ xa",
"errorRemoteHost": "Nhập máy đích (tính theo máy SSH)",
"errorNotConnected": "Chưa kết nối",
"errorStartFailed": "Khởi động thất bại",
"errorStopFailed": "Dừng thất bại",
"errorSocksRunning": "SOCKS5 đã đang chạy",
"copySuffix": "Sao chép"
"copySuffix": "Sao chép",
"remoteBindHint": "0.0.0.0 cần GatewayPorts; không có thì thường chỉ bind 127.0.0.1. Đích không được là 0.0.0.0.",
"localToRemote": "cục bộ {{bind}}:{{local}} → remote {{host}}:{{remote}}",
"localToRemotePort": "cục bộ :{{local}} → remote {{host}}:{{remote}}",
"remoteHostHint": "Theo máy SSH. Máy đó dùng 127.0.0.1, LAN dùng IP tới được. Không 0.0.0.0.",
"localBindHost": "Bind cục bộ",
"localBindHostPlaceholder": "127.0.0.1",
"localBindHostHint": "Mặc định chỉ máy này. 0.0.0.0 hoặc IP LAN để mạng truy cập.",
"errorTargetHostInvalid": "Đích không được 0.0.0.0 — dùng 127.0.0.1 hoặc IP nội bộ",
"listenAddress": "Lắng nghe cục bộ",
"listenAddressPlaceholder": "127.0.0.1:8080",
"listenAddressHint": "Mặc định chỉ máy này; 0.0.0.0 cho phép LAN.",
"targetAddress": "Đích từ xa",
"targetAddressPlaceholder": "127.0.0.1:80",
"targetAddressHint": "Theo góc nhìn máy SSH. Dịch vụ trên máy đó: 127.0.0.1:cổng.",
"errorListenAddress": "Nhập địa chỉ lắng nghe hợp lệ, vd. 127.0.0.1:8080",
"errorTargetAddress": "Nhập đích hợp lệ, vd. 127.0.0.1:80",
"targetAddressHintVia": "Qua {{target}}. Dịch vụ trên máy đó: 127.0.0.1:cổng (không mở cổng remote mới).",
"viaSession": "Qua phiên {{target}}",
"remoteToLocalPort": "remote :{{remote}} → {{host}}:{{local}}",
"remoteBindAdvanced": "Nâng cao: đổi bind phía remote",
"remoteBindHost": "Bind phía remote",
"remoteBindHostPlaceholder": "127.0.0.1",
"remoteBindHostHint": "Mặc định chỉ máy remote. 0.0.0.0 cần GatewayPorts; nếu không, hầu hết sshd vẫn chỉ bind 127.0.0.1.",
"remoteGatewayPortsWarning": "Đã yêu cầu lắng nghe 0.0.0.0 phía remote. Không có GatewayPorts, sshd thường vẫn chỉ bind 127.0.0.1."
}
}
+11 -4
View File
@@ -15,10 +15,12 @@
"passwordOptional": "Mật khẩu (tùy chọn)",
"width": "Chiều rộng",
"height": "Chiều cao",
"rdpFootnote": "IronRDP gốc: TCP → X.224 → TLS → CredSSP/NLA → MCS; thời gian chờ bắt tay 45 giây. Việc xác minh chứng chỉ được nới lỏng trong quá trình phát triển.",
"vncFootnote": "RFB vnc-rs gốc với giải mã Tight JPEG; clipboard được gửi dưới dạng UTF-8 (các máy chủ rất cũ có thể làm hỏng văn bản).",
"rdpFootnote": "Khi toàn màn hình hoặc phóng to, ứng dụng sẽ yêu cầu độ phân giải từ xa theo vùng cửa sổ hiện tại. Bạn cũng có thể chọn kích thước ban đầu trước khi kết nối. Xác minh chứng chỉ đang được nới lỏng trong giai đoạn phát triển.",
"vncFootnote": "Hầu hết máy chủ VNC giữ độ phân giải từ xa cố định; toàn màn hình chỉ phóng to cục bộ. Kích thước ưu tiên khi kết nối mang tính tham khảo. Nội dung bảng tạm được gửi dạng UTF-8.",
"errorHostRequired": "Nhập địa chỉ máy chủ",
"errorUsernameRequired": "Nhập tên người dùng"
"errorUsernameRequired": "Nhập tên người dùng",
"resolution": "Độ phân giải",
"resolutionCustom": "Tùy chỉnh"
},
"toolbar": {
"pasteClipboard": "Dán clipboard cục bộ sang máy từ xa",
@@ -28,7 +30,12 @@
"openShareDir": "Mở thư mục dùng chung cục bộ (Downloads)",
"openShareDirAria": "Mở thư mục dùng chung",
"disconnect": "Ngắt kết nối",
"disconnectAria": "Ngắt kết nối"
"disconnectAria": "Ngắt kết nối",
"fullscreen": "Toàn màn hình",
"fullscreenAria": "Vào toàn màn hình",
"exitFullscreen": "Thoát toàn màn hình",
"exitFullscreenAria": "Thoát toàn màn hình",
"exitFullscreenHint": "Esc / F11 để thoát"
},
"status": {
"connecting": "Đang kết nối…",
+16 -3
View File
@@ -39,7 +39,9 @@
"closed": "Kết nối đã đóng",
"dnsFailed": "Không thể phân giải máy chủ",
"refused": "Kết nối bị từ chối",
"disconnected": "Đã ngắt kết nối"
"disconnected": "Đã ngắt kết nối",
"keepaliveFailed": "Keep-alive SSH thất bại liên tiếp; đã đóng kết nối",
"idleKicked": "Shell từ xa đã thoát do hết thời gian chờ (TMOUT)"
},
"auth": {
"failed": "Xác thực thất bại. Kiểm tra tên người dùng và mật khẩu.",
@@ -68,7 +70,10 @@
"forward": {
"failed": "Thiết lập chuyển tiếp cổng thất bại",
"bindFailed": "Không thể ràng buộc cổng",
"alreadyInUse": "Cổng đã được sử dụng"
"alreadyInUse": "Cổng local đã bị chiếm. Hãy dừng chuyển tiếp đang chạy (hoặc tiến trình khác) rồi khởi động lại.",
"remoteDenied": "Máy chủ từ chối chuyển tiếp cổng từ xa (AllowTcpForwarding / PermitListen, cổng đang dùng hoặc hạn chế bind). Chỉ lắng nghe trên 127.0.0.1 phía remote.",
"remoteDeniedPrivileged": "Máy chủ từ chối cổng đặc quyền (<1024). Dùng cổng ≥1024 hoặc root, và kiểm tra AllowTcpForwarding / PermitListen.",
"invalidTargetHost": "Đích không thể là 0.0.0.0 — dùng 127.0.0.1 hoặc IP nội bộ tới được"
},
"sftp": {
"connectFailed": "Kết nối SFTP thất bại",
@@ -80,7 +85,15 @@
"writeFailed": "Lưu thất bại",
"renameFailed": "Đổi tên thất bại",
"chmodFailed": "Không thể cập nhật quyền",
"apiUnavailable": "API SFTP không khả dụng"
"apiUnavailable": "API SFTP không khả dụng",
"channelFailed": "Không mở được kênh SFTP (giới hạn máy chủ hoặc phiên bận). Hãy kết nối lại",
"sessionGone": "Phiên SFTP đã kết thúc; hãy kết nối lại",
"busy": "Đang truyền tệp. Vui lòng thử lại sau.",
"editTooLarge": "Tệp quá lớn cho trình soạn thảo văn bản (tối đa ~2MB). Hãy tải về và mở cục bộ.",
"editBinary": "Tệp có vẻ là nhị phân, không mở được trong trình soạn thảo văn bản",
"editNotUtf8": "Tệp từ xa không phải văn bản UTF-8 hợp lệ",
"transferCancelled": "Đã hủy truyền tệp",
"diskFull": "Không đủ dung lượng đĩa (cục bộ hoặc từ xa)"
},
"session": {
"notFound": "Không tìm thấy phiên",
+6 -4
View File
@@ -69,17 +69,17 @@
"confirm": "Xóa"
},
"welcome": {
"tagline": "Terminal từ xa · SFTP · Chuyển tiếp cổng",
"tagline": "Đơn giản · terminal · tệp · desktop",
"sectionStart": "Bắt đầu",
"sectionDesktop": "Màn hình từ xa",
"sectionRecent": "Phiên gần đây",
"quickConnect": {
"title": "Kết nối nhanh",
"desc": "SSH dùng một lần; không lưu vào thư viện"
"desc": "SSH tạm thời — không ghi vào thư viện phiên"
},
"newSession": {
"title": "Phiên mới",
"desc": "Lưu máy chủ; nhấp đúp trong thanh bên để kết nối"
"desc": "Lưu máy chủ — double-click ở thanh bên để kết nối"
},
"localShell": {
"title": "Shell cục bộ",
@@ -167,7 +167,9 @@
"jumpHost": "Jump host (tùy chọn)",
"jumpNone": "Không có jump host",
"jumpNoneAlt": "Không có jump host",
"jumpHint": "Một phiên đã lưu có thể được dùng làm jump host"
"jumpHint": "Một phiên đã lưu có thể được dùng làm jump host",
"resolution": "Độ phân giải",
"resolutionCustom": "Tùy chỉnh"
},
"batch": {
"title": "Thực thi hàng loạt",
+51 -19
View File
@@ -1,9 +1,7 @@
{
"nav": {
"general": "Không gian làm việc",
"generalDesc": "Bố cục và tài nguyên",
"appearance": "Giao diện",
"appearanceDesc": "Chủ đề và ngôn ngữ",
"general": "Chung",
"generalDesc": "Giao diện, ngôn ngữ và bố cục",
"terminal": "Terminal",
"terminalDesc": "Phông chữ và màu sắc",
"shortcuts": "Phím tắt",
@@ -15,11 +13,13 @@
"ai": "Mô hình AI",
"aiDesc": "Nhà cung cấp AI",
"about": "Giới thiệu",
"aboutDesc": "Phiên bản và dữ liệu"
"aboutDesc": "Phiên bản và dữ liệu",
"account": "Tài khoản",
"accountDesc": "Email, giấy phép và thiết bị"
},
"title": "Cài đặt",
"search": {
"placeholder": "Tìm cài đặt..."
"placeholder": "Tìm cài đặt…"
},
"language": {
"label": "Ngôn ngữ",
@@ -89,7 +89,7 @@
"ssh": {
"connection": "Kết nối",
"keepAlive": "Keep-alive",
"keepAliveDesc": "Gửi keep-alive khi nhàn rỗi để giảm ngắt kết nối",
"keepAliveDesc": "Gửi keep-alive SSH khi nhàn rỗi; chỉ ngắt sau vài lần không phản hồi",
"autoReconnect": "Tự động kết nối lại",
"autoReconnectDesc": "Tự động thử lại sau khi ngắt kết nối bất ngờ",
"timeout": "Thời gian chờ kết nối",
@@ -101,8 +101,10 @@
"maxConnectionsDesc": "Giới hạn dùng chung cho kết nối SSH, SFTP và hàng loạt",
"maxBackground": "Giới hạn kết nối chạy nền",
"maxBackgroundDesc": "Loại bỏ các kết nối ít dùng gần nhất khi vượt quá giới hạn",
"suspend": "Tạm dừng ở nền",
"suspendDesc": "Số phút trước khi giải phóng các kênh đang hoạt động khi một tab chạy nền"
"suspend": "Tạm dừng nền",
"suspendDesc": "Số phút trước khi tạm dừng tab nền nhàn rỗi (Shell/SFTP đang chạy vẫn giữ kết nối)",
"keepAliveInterval": "Khoảng keep-alive (giây)",
"keepAliveIntervalDesc": "Tần suất ping máy chủ (giống ClientAliveInterval). Mạng yếu nên ≤15 giây"
},
"security": {
"credentials": "Bảo vệ thông tin xác thực",
@@ -119,7 +121,7 @@
"clearConfirm": "Xóa tất cả khóa máy chủ đã biết? Bạn sẽ được nhắc lại vào lần kết nối sau."
},
"about": {
"tagline": "Terminal vận hành SSH / SFTP gốc, nhẹ",
"tagline": "Terminal vận hành gốc — đơn giản, tiện, dễ dùng",
"appVersion": "Ứng dụng v{{version}}",
"copyVersion": "Sao chép thông tin phiên bản",
"runtime": "Runtime",
@@ -127,8 +129,9 @@
"localData": "Dữ liệu cục bộ",
"sessionsSettings": "Phiên và cài đặt",
"masterKeyPath": "Khóa chính",
"privacyNote": "Mật khẩu và cụm mật khẩu khóa được mã hóa bằng AES-256-GCM trong Rust. OpsXShell không lưu lịch sử lệnh terminal.",
"license": "Giấy phép MIT · Rust · XTerm.js"
"privacyNote": "Mật khẩu và passphrase được Rust mã hóa AES-256-GCM. Không lưu lịch sử lệnh, không audit kiểu bastion.",
"license": "Giấy phép MIT · Rust · XTerm.js",
"logPath": "Nhật ký ứng dụng"
},
"ai": {
"presets": "Cài sẵn nhà cung cấp",
@@ -162,13 +165,42 @@
"apiKeySaveFailed": "Không thể lưu API key",
"providerNotFound": "Không tìm thấy nhà cung cấp",
"modelCatalogReadFailed": "Không thể đọc danh mục mô hình",
"catalogUnavailable": "models.dev không khả dụng"
"catalogUnavailable": "models.dev không khả dụng",
"family": {
"openai_compatible": "Tương thích OpenAI",
"standalone": "API gốc",
"plan": "Gói đăng ký",
"local": "Tự lưu trữ",
"custom": "Tùy chỉnh"
}
},
"family": {
"openai_compatible": "Tương thích OpenAI",
"standalone": "────────",
"plan": "Gói",
"local": "Tự lưu trú",
"custom": "Tùy chỉnh"
"account": {
"title": "Account",
"email": "Email",
"emailDesc": "Used for checkout and license claims",
"plan": "Current plan",
"planFree": "Free",
"planYearly": "Pro theo năm",
"planPerpetual": "Pro vĩnh viễn",
"planTrial": "Pro dùng thử",
"expires": "Expires {{date}}",
"lifetime": "Lifetime",
"devices": "Seats: up to {{count}} devices",
"deviceId": "This device ID",
"saveEmail": "Save email",
"activate": "Activate license",
"pasteLicense": "Paste LIC- license key",
"clear": "Clear local license",
"deactivate": "Deactivate this device",
"upgrade": "Upgrade",
"saved": "Saved",
"activateOk": "Activated",
"deviceList": "Thiết bị đã gắn",
"loadingDevices": "Đang tải danh sách thiết bị…",
"noDevices": "Chưa có thiết bị",
"thisDevice": "Thiết bị này",
"removeDevice": "Gỡ gắn",
"deviceRemoved": "Đã gỡ gắn thiết bị",
"seatFull": "Đã hết chỗ thiết bị. Hãy gỡ thiết bị khác trước khi kích hoạt máy mới."
}
}
+54 -24
View File
@@ -3,8 +3,9 @@
"local": "Cục bộ",
"remote": "Từ xa",
"notConnectedTitle": "Chưa kết nối tới máy chủ từ xa",
"notConnectedDesc": "Kết nối một phiên SSH trước để dùng SFTP",
"ariaLabel": "Bảng tệp {{title}}"
"notConnectedDesc": "Kết nối SSH trước, rồi truyền tệp hoặc sửa cấu hình",
"ariaLabel": "Bảng tệp {{title}}",
"reconnectResumeDesc": "Đã ngắt. Kết nối lại một chạm sẽ về {{path}}"
},
"connection": {
"selectServer": "Chọn máy chủ",
@@ -12,7 +13,9 @@
"createSessionHint": "Tạo phiên trong thanh bên trước tiên",
"reconnect": "Kết nối lại",
"notConnected": "Chưa kết nối",
"connecting": "Đang kết nối..."
"connecting": "Đang kết nối...",
"resumeHint": "Kết nối lại sẽ quay về {{path}}",
"reconnectingResume": "Đang kết nối lại và khôi phục {{path}}…"
},
"errors": {
"notConnected": "SFTP chưa được kết nối",
@@ -23,19 +26,14 @@
"selectDownloadFiles": "Chọn tệp để tải xuống trước",
"uploadFailed": "Tải lên thất bại",
"downloadFailed": "Tải xuống thất bại",
"fileError": "{{fileName}}: {{message}}"
"fileError": "{{fileName}}: {{message}}",
"mkdirFailed": "Không tạo được thư mục"
},
"toolbar": {
"upload": "Tải lên",
"uploadAria": "Tải lên",
"download": "Tải xuống",
"downloadAria": "Tải xuống",
"downloadNeedSelection": "Chọn tệp từ xa trước",
"downloadHint": "Tải xuống các tệp từ xa đã chọn",
"refresh": "Làm mới",
"refreshAria": "Làm mới",
"refreshAria": "Làm mới bảng này",
"newFolder": "Thư mục mới",
"newFolderAria": "Thư mục mới"
"newFolderAria": "Tạo thư mục trên bảng này"
},
"sort": {
"name": "Tên",
@@ -55,7 +53,8 @@
"hideHidden": "Ẩn tệp chấm (.xxx)",
"showHiddenAria": "Hiển thị tệp ẩn",
"hideHiddenAria": "Ẩn tệp chấm",
"searchAria": "Tìm trong {{title}}"
"searchAria": "Tìm trong {{title}}",
"upAtRoot": "Đã ở thư mục gốc"
},
"status": {
"loading": "Đang tải...",
@@ -63,7 +62,8 @@
"filtered": "Hiển thị {{shown}} / {{total}}",
"hiddenCount": "{{total}} mục ({{hidden}} ẩn)",
"total": "{{count}} mục",
"filterHint": "Lọc: {{query}}"
"filterHint": "Lọc: {{query}}",
"refreshing": "Đang làm mới..."
},
"empty": {
"dirTitle": "Thư mục rỗng",
@@ -99,7 +99,6 @@
"download": "Tải xuống",
"edit": "Sửa",
"rename": "Đổi tên",
"copyPath": "Sao chép đường dẫn",
"properties": "Thuộc tính",
"permissions": "Quyền",
"delete": "Xóa"
@@ -116,7 +115,18 @@
"chmodTitle": "Sửa quyền",
"chmodApply": "Áp dụng",
"pickUploadTitle": "Chọn tệp hoặc thư mục để tải lên",
"pickUploadRzTitle": "Chọn tệp để tải lên (rz)"
"pickUploadRzTitle": "Chọn tệp để tải lên (rz)",
"overwriteTitle": "Ghi đè tệp đã có?",
"overwriteConfirm": "Ghi đè",
"overwriteSkip": "Bỏ qua",
"overwriteOneRemote": "Từ xa đã có「{{name}}」. Ghi đè?",
"overwriteOneLocal": "Cục bộ đã có「{{name}}」. Ghi đè?",
"overwriteManyRemote": "Từ xa đã có {{count}} mục trùng tên. Ghi đè tất cả?",
"overwriteManyLocal": "Cục bộ đã có {{count}} mục trùng tên. Ghi đè tất cả?",
"overwriteMore": "…và {{count}} mục nữa",
"deleteTitle": "Xác nhận xóa",
"deleteMessage": "Xóa {{count}} mục: {{names}}",
"deleteRecursiveWarn": "Có thư mục. Việc xóa là đệ quy và không hoàn tác được."
},
"properties": {
"name": "Tên",
@@ -152,27 +162,41 @@
"statusDone": "Xong",
"statusFailed": "Thất bại",
"statusCancelled": "Đã hủy",
"dropUpload": "Tải lên {{path}}",
"dropDownload": "Tải xuống vào {{path}}"
"dropUpload": "Thả vào đây để tải lên {{path}}",
"dropDownload": "Thả vào đây để tải xuống {{path}}",
"railAria": "Truyền giữa cục bộ và từ xa",
"railUpload": "Tải lên tệp cục bộ đã chọn (hoặc chọn tệp nếu chưa chọn)",
"railDownload": "Tải xuống tệp từ xa đã chọn về máy cục bộ",
"railUploadAria": "Tải lên máy từ xa",
"railDownloadAria": "Tải về máy cục bộ",
"railDownloadNeedSelection": "Hãy chọn tệp từ xa trước",
"retry": "Thử lại"
},
"editor": {
"readFailed": "Đọc thất bại",
"saveFailed": "Lưu thất bại",
"unsavedClose": "Có thay đổi chưa lưu. Vẫn đóng?",
"unsavedTitle": "Thay đổi chưa lưu",
"discardAndClose": "Bỏ và đóng",
"reloadTitle": "Tải lại",
"discardAndReload": "Bỏ và tải lại",
"saving": "Đang lưu...",
"save": "Lưu",
"saved": "Đã lưu tệp",
"loadingEditor": "Đang tải trình soạn thảo...",
"footer": "UTF-8 · Monaco · ⌘/Ctrl+S lưu · tối đa ~2MB",
"loadBlocked": "Không tải được nội dung tệp",
"footer": "UTF-8 · ⌘/Ctrl+S lưu · Esc đóng · tối đa ~2MB",
"charCount": "{{count}} ký tự",
"unsavedMark": " · chưa lưu",
"savedMark": " · đã lưu"
"savedMark": " · đã lưu",
"title": "Sửa {{name}}",
"dirtyBadge": "Chưa lưu",
"reload": "Tải lại",
"unsavedReload": "Hủy thay đổi chưa lưu và tải lại?"
},
"toast": {
"renamed": "Đã đổi tên thành {{name}}",
"renameFailed": "Đổi tên thất bại",
"pathCopied": "Đường dẫn đã được sao chép vào clipboard",
"pathCopyFailed": "Không thể sao chép đường dẫn",
"chmodUpdated": "Đã cập nhật quyền thành {{mode}}",
"chmodFailed": "Không thể cập nhật quyền",
"uploadPartial": "{{action}} đã hoàn tất {{completed}}, thất bại {{failed}}: {{detail}}",
@@ -180,7 +204,13 @@
"uploadAction": "Tải lên",
"downloadAction": "Tải xuống",
"noFolderUpload": "Tải lên thư mục thất bại",
"noDragPath": "Đường dẫn kéo-thả không khả dụng; hãy dùng Tải lên",
"noFolderRecursive": "Truyền thư mục đệ quy thất bại; thử lại hoặc dùng Tải lên"
"noDragPath": "Hệ thống không cung cấp đường dẫn kéo thả. Dùng mũi tên → giữa hoặc chọn tệp để tải lên.",
"noFolderRecursive": "Truyền thư mục thất bại. Thử lại hoặc dùng → / hộp thoại chọn tệp.",
"dropFailed": "Kéo thả thất bại: không đọc được thông tin tệp. Thử lại hoặc dùng mũi tên giữa.",
"folderCreated": "Đã tạo thư mục {{name}}",
"allSkippedExisting": "Đã bỏ qua mọi tệp trùng tên",
"skippedExisting": "Đã bỏ qua {{count}} tệp trùng tên",
"deleteFailed": "Xóa thất bại",
"deleted": "Đã xóa"
}
}
+3 -2
View File
@@ -34,7 +34,7 @@
"reopenShell": "Mở lại shell",
"reopening": "Đang mở…",
"disconnected": "Đã ngắt kết nối",
"disconnectedHint": "Phiên SSH đã kết thúc hoặc mạng bị ngắt. Nhấn bên dưới để kết nối lại.",
"disconnectedHint": "Phiên SSH đã kết thúc hoặc mạng bị ngắt. Một chạm bên dưới để kết nối lại và tiếp tục.",
"reconnect": "Kết nối lại",
"suspended": "Kết nối đã bị tạm dừng",
"suspendedHint": "Không hoạt động một thời gian; kết nối đã bị tạm dừng để tiết kiệm tài nguyên",
@@ -70,7 +70,8 @@
"splitRight": "Chia bên phải",
"splitDown": "Chia xuống dưới",
"maximizePane": "Phóng to pane hiện tại",
"restoreLayout": "Khôi phục bố cục chia"
"restoreLayout": "Khôi phục bố cục chia",
"openSftp": "Mở SFTP"
},
"search": {
"placeholder": "Tìm kiếm...",
+122 -38
View File
@@ -78,7 +78,7 @@
"closeTab": "关闭当前标签",
"closeAllTabs": "关闭所有标签",
"portForward": "新建端口转发",
"upgradePro": "升级 OpsXShell Pro",
"upgradePro": "升级 OpsXShell 专业版",
"editSession": "编辑会话: {{name}}"
}
},
@@ -90,6 +90,8 @@
"terminal": "终端",
"batch": "批量执行",
"newTerminal": "新终端",
"closeAria": "关闭 {{title}}",
"listAria": "打开的标签",
"kind": {
"terminal": "终端",
"sftp": "SFTP",
@@ -105,7 +107,8 @@
"closeRight": "关闭右侧标签",
"closeLeft": "关闭左侧标签",
"closeAll": "关闭全部",
"clone": "克隆标签"
"clone": "克隆标签",
"openSftp": "打开 SFTP"
}
},
"sidebar": {
@@ -149,39 +152,44 @@
"disconnect": "断开"
},
"pro": {
"upgrade": "升级 Pro",
"feature": "专业功能",
"unlock": "解锁 {{feature}}",
"upgrade": "升级专业版",
"feature": "专业版功能",
"unlock": "解锁专业版高级功能",
"comingSoon": "即将推出",
"activateSuccess": "激活成功",
"activateFailed": "激活失败",
"licenseActivated": "Pro 许可证已激活",
"licenseActivated": "专业版许可证已激活",
"paymentPending": "支付完成后请粘贴许可证,或稍后再试激活",
"invalidLicense": "激活失败:许可证无效",
"goUpgrade": "去付费升级",
"goUpgrade": "去升级专业版",
"haveLicense": "已有许可证?激活",
"title": "OpsXShell Pro · 解锁专业运维能力",
"subtitleComingSoon": "{{feature}} 即将推出 · 升级 Pro 可优先体验",
"subtitleUnlock": "正在解锁:{{feature}}",
"subtitleDefault": "转发、代理、串口、AI、批量与广播",
"activated": "已激活 Pro",
"title": "OpsXShell · 解锁专业版",
"subtitleComingSoon": "高级功能即将推出 · 升级专业版可优先体验",
"subtitleUnlock": "目前正在解锁高级功能",
"subtitleDefault": "端口转发、终端 AI、批量运维、主机清单与远程桌面等专业版能力",
"activated": "已激活专业版",
"expiresAt": " · 有效期至 {{date}}",
"lifetime": " · 终身授权",
"oneTimeFee": "一次性费用 · 本机终身授权 · 无需订阅",
"oneTimeFee": "免费 / 专业版包年 / 专业版永久",
"pasteLicense": "粘贴许可证",
"activateButton": "激活",
"clearLicense": "清除本机许可证",
"paymentNote": "支付由 Waffo 托管收银台处理;本应用不收集或保存银行卡信息。",
"testDeviceId": "测试环境 · 设备 ID:{{deviceId}}",
"later": "稍后再说",
"viewPro": "查看 Pro",
"wallComingSoonSuffix": " · 即将推出",
"wallUnlock": "解锁 {{feature}}",
"wallMessageComingSoon": "该能力属于 OpsXShell Pro,协议实现尚在开发中。升级后可优先体验。",
"wallMessageDefault": "此功能属于 OpsXShell Pro。升级后即可在本机使用。",
"viewPro": "查看专业版方案",
"wallComingSoonSuffix": "即将推出",
"wallUnlock": "解锁专业版高级功能",
"wallMessageComingSoon": "该能力属于 OpsXShell 专业版,相关实现尚在完善。升级专业版包年或永久后,可优先体验。",
"wallMessageDefault": "端口转发、终端 AI、批量执行、主机清单与远程桌面等均包含在专业版中。升级专业版包年或永久后,即可在本机使用。",
"checkoutUnavailable": "结账服务不可用 ({{status}})",
"freeTier": "Free",
"proTier": "Pro",
"emailLabel": "邮箱",
"emailRequired": "结账前请先填写邮箱",
"claimPending": "正在领取许可证…",
"invalidKeyFormat": "密钥格式无效,请粘贴 LIC- 开头的许可证",
"accountEmail": "账户:{{email}}",
"freeTier": "免费",
"proTier": "专业版",
"freeItems": {
"ssh": "SSH 终端",
"sftp": "SFTP 文件管理",
@@ -197,16 +205,54 @@
"batch": "批量执行 / 广播同步",
"broadcast": "广播同步输入",
"importExport": "批量导入导出主机清单",
"desktop": "RDP / VNC 远程桌面"
}
"desktop": "远程桌面(RDP / VNC)"
},
"planYearly": "专业版包年",
"planYearlyDesc": "¥99 / 年 · 2 台设备",
"planPerpetual": "专业版永久",
"planPerpetualDesc": "¥199 · 5 台设备 · 终身",
"planTrial": "专业版体验",
"devices": "最多 {{count}} 台设备",
"goUpgradeYearly": "购买专业版包年",
"goUpgradePerpetual": "购买专业版永久",
"activatedYearly": "已激活专业版包年",
"activatedPerpetual": "已激活专业版永久",
"activatedTrial": "已激活专业版体验",
"choosePlan": "选择方案:免费 / 专业版包年 / 专业版永久",
"planFreePrice": "¥0",
"planFreeDesc": "SSH · SFTP · 本地终端",
"planFreeCta": "当前方案",
"planIncludesPro": "含全部专业版功能",
"planFree": "免费",
"subtitleUnlockDetail": "相关能力:{{feature}}",
"wallUnlockComingSoon": "专业版高级功能即将推出",
"wallMessageComingSoonFeature": "「{{feature}}」属于专业版高级功能,相关实现尚在完善。升级专业版包年或永久后,可优先体验。",
"wallMessageFeature": "「{{feature}}」属于专业版高级功能。升级专业版包年或永久后,即可在本机使用。"
},
"launcher": {
"title": "快速启动",
"description": "会话、本地 Shell 与设备控制台统一入口",
"description": "常用入口集中:会话、本机 Shell、桌面、串口",
"cards": {
"quickConnect": { "title": "快速连接", "desc": "user@host:port" },
"saveSession": { "title": "保存会话", "desc": "凭据、分组、代理" },
"serial": { "title": "串口终端", "desc": "波特率与串口参数" }
"quickConnect": {
"title": "快速连接",
"desc": "user@host:port"
},
"saveSession": {
"title": "保存会话",
"desc": "凭据、分组、代理"
},
"serial": {
"title": "串口终端",
"desc": "波特率与串口参数"
},
"rdp": {
"title": "RDP 桌面",
"desc": "远程 Windows 桌面"
},
"vnc": {
"title": "VNC 桌面",
"desc": "远程图形桌面"
}
},
"sectionLocalShell": "本地 Shell",
"sectionSavedSessions": "保存会话",
@@ -220,6 +266,7 @@
"forwardOpenRunning": "SOCKS5 已开(:{{port}})· 点击管理 · 右键复制",
"forwardStarted": "转发已启动",
"forwardStartedDynamic": "SOCKS5 已启动:socks5://127.0.0.1:{{port}}",
"forwardResumed": "已恢复 {{count}} 条端口转发",
"socksStartFailed": "启动失败:{{message}}",
"socksStopFailed": "停止失败:{{message}}",
"socksCopied": "已复制 socks5://127.0.0.1:{{port}}"
@@ -240,7 +287,7 @@
"typeDynamic": "动态",
"running": "运行中",
"socksProxy": "SOCKS5:127.0.0.1:{{port}}",
"remoteToLocal": "远端 {{remote}} → 本机 {{local}}",
"remoteToLocal": "远端 {{bind}}:{{remote}} → {{host}}:{{local}}",
"stats": "{{connections}} 连接 · ↑{{up}} · ↓{{down}}",
"copyProxy": "复制代理",
"copyRule": "复制规则",
@@ -250,15 +297,15 @@
"delete": "删除",
"editTitle": "编辑转发",
"addTitle": "添加转发",
"typeLocalDesc": "本机 → 远端",
"typeRemoteDesc": "远端 → 本机",
"typeLocalDesc": "访问远端服务",
"typeRemoteDesc": "暴露本机服务",
"typeDynamicDesc": "SOCKS5",
"selectType": "转发类型",
"drawerSubtitle": "经当前 SSH 建立隧道",
"ruleFields": "参数",
"dynamicHint": "本机 SOCKS5,默认 127.0.0.1:1080;端口可改。流量经当前 SSH 服务器出口 IP 访问外网。",
"dynamicSingleHint": "每台 SSH 仅一条动态转发;停止后可改监听端口。",
"dynamicPortHint": "端口被占用时可改为其他本机端口(如 1081)。",
"dynamicHint": "本机 SOCKS5(默认 :1080)。流量经当前 SSH 出口访问外网。",
"dynamicSingleHint": "每台 SSH 仅一条动态转发;停止后可改端口。",
"dynamicPortHint": "端口被占用时可改,例如 1081。",
"ruleList": "规则",
"ruleListEmpty": "暂无本地 / 远程规则",
"addSection": "新建",
@@ -292,17 +339,30 @@
"internet": "互联网",
"localCaption": "本地转发:经隧道访问远端端口,如同访问本机。",
"remoteCaption": "远程转发:远端访问经隧道转到本机服务。",
"dynamicCaption": "动态转发:本机变成 SOCKS5 代理,可经当前 SSH 服务器出口 IP 访问互联网。"
"dynamicCaption": "动态转发:本机 SOCKS5,经当前 SSH 出口访问外网。"
},
"ruleName": "名称",
"ruleNamePlaceholder": "例如 MySQL",
"localListenPort": "本机监听端口",
"localListenPortHint": "默认 localhost,等同 ssh -L 端口:…。一般只填端口。",
"localBindAdvanced": "高级:改本机绑定",
"localTargetPort": "本机目标端口",
"remoteTargetPort": "远端目标端口",
"remoteTargetPort": "目标端口",
"remoteListenPort": "远端监听端口",
"remoteListenPortHint": "默认仅远端 localhost,等同 ssh -R 端口:…。一般只填端口。",
"remoteListenAddress": "远端监听",
"remoteListenAddressPlaceholder": "127.0.0.1:18080",
"remoteListenAddressHint": "127.0.0.1 = 仅远端本机;0.0.0.0 = 远端内网可连(需 GatewayPorts)。",
"errorRemoteListenAddress": "请填写有效远端监听,如 127.0.0.1:18080",
"localTargetAddress": "本机 / 内网目标",
"localTargetAddressPlaceholder": "127.0.0.1:8080",
"localTargetAddressHint": "转到本机或内网服务,如 127.0.0.1:8080。勿填 0.0.0.0。",
"viaSessionRemote": "在 {{target}} 上监听(默认 localhost)",
"errorRemoteListenPort": "请填写有效远端监听端口(1–65535)",
"errorLocalTargetAddress": "请填写有效本机/内网目标,如 127.0.0.1:8080",
"portPlaceholder": "如 3306",
"remoteHost": "远端主机",
"remoteHostPlaceholder": "localhost 或 IP",
"remoteHost": "目标主机",
"remoteHostPlaceholder": "127.0.0.1",
"socksRuleName": "SOCKS5 代理",
"defaultLocalName": "本地转发",
"defaultRemoteName": "远程转发",
@@ -316,11 +376,35 @@
"deleteConfirm": "确定删除此规则?",
"errorNamePort": "请填写名称和有效端口(1–65535)",
"errorTargetPort": "请填写有效目标端口(1–65535)",
"errorRemoteHost": "请填写远端主机",
"errorRemoteHost": "请填写目标主机(相对当前 SSH 服务器)",
"errorNotConnected": "未连接到服务器",
"errorStartFailed": "启动失败",
"errorStopFailed": "停止失败",
"errorSocksRunning": "SOCKS5 已在运行",
"copySuffix": "副本"
"copySuffix": "副本",
"remoteBindHint": "0.0.0.0 需 GatewayPorts;未开启时常静默绑 127.0.0.1。目标勿填 0.0.0.0。",
"localToRemote": "本机 {{bind}}:{{local}} → 远端 {{host}}:{{remote}}",
"localToRemotePort": "本机 :{{local}} → 远端 {{host}}:{{remote}}",
"remoteHostHint": "相对 SSH 服务器。远端本机填 127.0.0.1,内网其它机填可达 IP。勿填 0.0.0.0。",
"localBindHost": "本地绑定",
"localBindHostPlaceholder": "127.0.0.1",
"localBindHostHint": "默认仅本机。填 0.0.0.0 或内网 IP 可让局域网访问。",
"errorTargetHostInvalid": "目标不能是 0.0.0.0,请填 127.0.0.1 或可达内网 IP",
"listenAddress": "本机监听",
"listenAddressPlaceholder": "127.0.0.1:8080",
"listenAddressHint": "默认仅本机;0.0.0.0 可让局域网访问。",
"targetAddress": "远端目标",
"targetAddressPlaceholder": "127.0.0.1:80",
"targetAddressHint": "相对 SSH 服务器。远端本机服务填 127.0.0.1:端口。",
"errorListenAddress": "请填写有效监听地址,如 127.0.0.1:8080",
"errorTargetAddress": "请填写有效目标,如 127.0.0.1:80",
"targetAddressHintVia": "经 {{target}}。远端本机服务填 127.0.0.1:端口(不会在远端新建端口)。",
"viaSession": "经当前会话 {{target}}",
"remoteToLocalPort": "远端 :{{remote}} → {{host}}:{{local}}",
"remoteBindAdvanced": "高级:改远端绑定",
"remoteBindHost": "远端绑定",
"remoteBindHostPlaceholder": "127.0.0.1",
"remoteBindHostHint": "默认仅远端本机。0.0.0.0 需 GatewayPorts;未开启时多数 sshd 仍只绑 127.0.0.1。",
"remoteGatewayPortsWarning": "已请求远端 0.0.0.0 监听。若未开 GatewayPorts,sshd 常会静默只绑 127.0.0.1。"
}
}
+11 -4
View File
@@ -15,10 +15,12 @@
"passwordOptional": "密码(可选)",
"width": "宽度",
"height": "高度",
"rdpFootnote": "原生 IronRDP:TCP → X.224 → TLS → CredSSP/NLA → MCS;握手超时 45s。证书校验当前为开发期宽松模式。",
"vncFootnote": "原生 vnc-rs RFB:支持 Tight JPEG 帧解码;剪贴板按 UTF-8 发送(极旧服务端可能乱码)。",
"rdpFootnote": "全屏或最大化时,会按当前窗口区域动态请求远端分辨率;也可在连接前用预设选择初始分辨率。证书校验当前为开发期宽松模式。",
"vncFootnote": "多数 VNC 服务端分辨率由远端固定,全屏仅本地缩放适配;连接前的偏好尺寸仅供参考。剪贴板按 UTF-8 发送。",
"errorHostRequired": "请输入主机地址",
"errorUsernameRequired": "请输入用户名"
"errorUsernameRequired": "请输入用户名",
"resolution": "分辨率",
"resolutionCustom": "自定义"
},
"toolbar": {
"pasteClipboard": "粘贴本机剪贴板到远端",
@@ -28,7 +30,12 @@
"openShareDir": "在本机打开共享目录(下载文件夹)",
"openShareDirAria": "打开共享目录",
"disconnect": "断开连接",
"disconnectAria": "断开连接"
"disconnectAria": "断开连接",
"fullscreen": "全屏",
"fullscreenAria": "进入全屏",
"exitFullscreen": "退出全屏",
"exitFullscreenAria": "退出全屏",
"exitFullscreenHint": "Esc / F11 退出"
},
"status": {
"connecting": "正在连接…",
+16 -3
View File
@@ -39,7 +39,9 @@
"closed": "连接已关闭",
"dnsFailed": "无法解析主机",
"refused": "连接被拒绝",
"disconnected": "连接已断开"
"disconnected": "连接已断开",
"keepaliveFailed": "SSH 心跳连续失败,连接已关闭",
"idleKicked": "远端 Shell 因空闲超时退出(TMOUT)"
},
"auth": {
"failed": "认证失败,请检查用户名和密码",
@@ -68,7 +70,10 @@
"forward": {
"failed": "端口转发设置失败",
"bindFailed": "端口绑定失败",
"alreadyInUse": "端口已被占用"
"alreadyInUse": "本地端口已被占用。请先暂停本规则或其它占用该端口的进程,再启动。",
"remoteDenied": "远端拒绝远程端口转发(AllowTcpForwarding / PermitListen、端口占用或绑定限制)。当前仅在远端 127.0.0.1 监听。",
"remoteDeniedPrivileged": "远端拒绝特权监听端口(<1024)。请改用 ≥1024,或以 root 监听,并检查 AllowTcpForwarding / PermitListen。",
"invalidTargetHost": "目标地址不能是 0.0.0.0,请填 127.0.0.1 或远端可达的内网 IP"
},
"sftp": {
"connectFailed": "SFTP 连接失败",
@@ -80,7 +85,15 @@
"writeFailed": "保存失败",
"renameFailed": "重命名失败",
"chmodFailed": "权限修改失败",
"apiUnavailable": "SFTP API 不可用"
"apiUnavailable": "SFTP API 不可用",
"channelFailed": "无法打开 SFTP 通道(服务器限制或会话繁忙),请重连后再试",
"sessionGone": "SFTP 会话已结束,请重新连接",
"busy": "正在传输文件,请稍后再试",
"editTooLarge": "文件过大,文本编辑上限约 2MB。请下载后用本地编辑器打开。",
"editBinary": "该文件像是二进制内容,无法用文本编辑器打开",
"editNotUtf8": "远程文件不是有效 UTF-8 文本",
"transferCancelled": "传输已取消",
"diskFull": "磁盘空间不足(本地或远程)"
},
"session": {
"notFound": "会话不存在",
+5 -3
View File
@@ -69,7 +69,7 @@
"confirm": "删除"
},
"welcome": {
"tagline": "远程终端 · SFTP · 端口转发",
"tagline": "简单好用 · 终端 · 传文件 · 远程桌面",
"sectionStart": "开始",
"sectionDesktop": "远程桌面",
"sectionRecent": "最近会话",
@@ -79,7 +79,7 @@
},
"newSession": {
"title": "新建会话",
"desc": "保存主机,侧栏双击连接"
"desc": "保存主机,侧栏双击即连"
},
"localShell": {
"title": "本地 Shell",
@@ -167,7 +167,9 @@
"jumpHost": "跳板机(可选)",
"jumpNone": "无跳板",
"jumpNoneAlt": "不使用跳板",
"jumpHint": "当前支持一个已保存会话作为跳板"
"jumpHint": "当前支持一个已保存会话作为跳板",
"resolution": "分辨率",
"resolutionCustom": "自定义"
},
"batch": {
"title": "批量执行",
+50 -18
View File
@@ -1,9 +1,7 @@
{
"nav": {
"general": "工作区",
"generalDesc": "布局与资源",
"appearance": "外观",
"appearanceDesc": "界面主题与语言",
"general": "通用",
"generalDesc": "主题、语言与布局",
"terminal": "终端",
"terminalDesc": "字体与主题色",
"shortcuts": "快捷键",
@@ -15,11 +13,13 @@
"ai": "大模型",
"aiDesc": "AI Provider",
"about": "关于",
"aboutDesc": "版本与数据"
"aboutDesc": "版本与数据",
"account": "账户",
"accountDesc": "邮箱、许可证与设备"
},
"title": "设置",
"search": {
"placeholder": "搜索设置..."
"placeholder": "搜索设置…"
},
"language": {
"label": "界面语言",
@@ -89,7 +89,7 @@
"ssh": {
"connection": "连接",
"keepAlive": "保持心跳",
"keepAliveDesc": "空闲时发送心跳,减少断线",
"keepAliveDesc": "空闲时发送 SSH 心跳;连续多次无响应才会断开",
"autoReconnect": "自动重连",
"autoReconnectDesc": "意外断开后自动尝试重连",
"timeout": "连接超时",
@@ -102,7 +102,9 @@
"maxBackground": "后台连接上限",
"maxBackgroundDesc": "超过上限时优先回收最久未使用的连接",
"suspend": "后台挂起",
"suspendDesc": "标签进入后台后多少分钟释放活跃通道"
"suspendDesc": "后台标签空闲多少分钟后挂起(有活跃 Shell/SFTP 时保持连接)",
"keepAliveInterval": "心跳间隔(秒)",
"keepAliveIntervalDesc": "向服务器发送心跳的频率(类似 ClientAliveInterval)。不稳定网络建议 ≤15 秒"
},
"security": {
"credentials": "凭据保护",
@@ -119,7 +121,7 @@
"clearConfirm": "确定清空全部已知主机密钥?下次连接将重新确认。"
},
"about": {
"tagline": "轻量原生的 SSH / SFTP 运维终端",
"tagline": "简单、便捷、人性化的原生运维终端",
"appVersion": "应用 v{{version}}",
"copyVersion": "复制版本信息",
"runtime": "运行环境",
@@ -127,8 +129,9 @@
"localData": "本地数据",
"sessionsSettings": "会话与设置",
"masterKeyPath": "加密主密钥",
"privacyNote": "密码与密钥口令由 Rust 使用 AES-256-GCM 加密。OpsXShell 不保存终端命令历史。",
"license": "MIT License · Rust · XTerm.js"
"privacyNote": "密码与密钥口令由 Rust 使用 AES-256-GCM 加密。不保存终端命令历史,也不做堡垒审计。",
"license": "MIT License · Rust · XTerm.js",
"logPath": "应用日志"
},
"ai": {
"presets": "供应商预设",
@@ -162,13 +165,42 @@
"apiKeySaveFailed": "API Key 保存失败",
"providerNotFound": "Provider 不存在",
"modelCatalogReadFailed": "模型目录读取失败",
"catalogUnavailable": "models.dev 暂不可用"
"catalogUnavailable": "models.dev 暂不可用",
"family": {
"openai_compatible": "OpenAI 兼容",
"standalone": "独立协议",
"plan": "套餐计划",
"local": "本地私有化",
"custom": "自定义"
}
},
"family": {
"openai_compatible": "OpenAI 兼容",
"standalone": "────────",
"plan": "Plan 计划",
"local": "私有化本地",
"custom": "Custom 自定义"
"account": {
"title": "账户",
"email": "邮箱",
"emailDesc": "结账与领取许可证用的联系邮箱",
"plan": "当前计划",
"planFree": "免费",
"planYearly": "专业版包年",
"planPerpetual": "专业版永久",
"planTrial": "专业版体验",
"expires": "有效期至 {{date}}",
"lifetime": "终身有效",
"devices": "设备席位:最多 {{count}} 台",
"deviceId": "本机设备 ID",
"saveEmail": "保存邮箱",
"activate": "激活许可证",
"pasteLicense": "粘贴 LIC- 许可证",
"clear": "清除本机许可证",
"deactivate": "停用本机激活",
"upgrade": "升级专业版",
"saved": "已保存",
"activateOk": "激活成功",
"deviceList": "已绑定设备",
"loadingDevices": "加载设备列表…",
"noDevices": "暂无绑定设备",
"thisDevice": "本机",
"removeDevice": "解除绑定",
"deviceRemoved": "已解除该设备绑定",
"seatFull": "设备席位已满。请先解除其他设备,再在新机器上激活。"
}
}
+52 -22
View File
@@ -3,8 +3,9 @@
"local": "本地",
"remote": "远程",
"notConnectedTitle": "未连接到远程服务器",
"notConnectedDesc": "请先连接 SSH 会话以使用 SFTP",
"ariaLabel": "{{title}}文件面板"
"notConnectedDesc": "先连上 SSH,再传文件、改配置",
"ariaLabel": "{{title}}文件面板",
"reconnectResumeDesc": "连接中断。一键重连后回到 {{path}}"
},
"connection": {
"selectServer": "选择服务器",
@@ -12,7 +13,9 @@
"createSessionHint": "请先在侧边栏创建会话",
"reconnect": "重新连接",
"notConnected": "未连接",
"connecting": "连接中..."
"connecting": "连接中...",
"resumeHint": "重连后将回到 {{path}}",
"reconnectingResume": "正在重连并恢复 {{path}}…"
},
"errors": {
"notConnected": "SFTP 尚未连接",
@@ -23,19 +26,14 @@
"selectDownloadFiles": "请先选择要下载的文件",
"uploadFailed": "上传失败",
"downloadFailed": "下载失败",
"mkdirFailed": "创建文件夹失败",
"fileError": "{{fileName}}: {{message}}"
},
"toolbar": {
"upload": "上传",
"uploadAria": "上传",
"download": "下载",
"downloadAria": "下载",
"downloadNeedSelection": "请先选择远程文件",
"downloadHint": "下载选中的远程文件",
"refresh": "刷新",
"refreshAria": "刷新",
"refreshAria": "刷新当前面板",
"newFolder": "新建文件夹",
"newFolderAria": "新建文件夹"
"newFolderAria": "在当前面板新建文件夹"
},
"sort": {
"name": "名称",
@@ -48,6 +46,7 @@
"back": "后退",
"forward": "前进",
"up": "上级目录",
"upAtRoot": "已在根目录",
"searchPlaceholder": "搜索文件名",
"clearSearch": "清除搜索",
"clearSearchAria": "清除搜索",
@@ -63,7 +62,8 @@
"filtered": "显示 {{shown}} / {{total}} 项",
"hiddenCount": "共 {{total}} 项(已隐藏 {{hidden}})",
"total": "共 {{count}} 项",
"filterHint": "筛选: {{query}}"
"filterHint": "筛选: {{query}}",
"refreshing": "正在刷新..."
},
"empty": {
"dirTitle": "目录为空",
@@ -99,7 +99,6 @@
"download": "下载",
"edit": "编辑",
"rename": "重命名",
"copyPath": "复制路径",
"properties": "属性",
"permissions": "权限",
"delete": "删除"
@@ -116,7 +115,18 @@
"chmodTitle": "权限编辑",
"chmodApply": "应用",
"pickUploadTitle": "选择要上传的文件或文件夹",
"pickUploadRzTitle": "选择要上传的文件(rz)"
"pickUploadRzTitle": "选择要上传的文件(rz)",
"overwriteTitle": "覆盖已有文件?",
"overwriteConfirm": "覆盖",
"overwriteSkip": "跳过",
"overwriteOneRemote": "远程已存在「{{name}}」,覆盖?",
"overwriteOneLocal": "本地已存在「{{name}}」,覆盖?",
"overwriteManyRemote": "远程已有 {{count}} 个同名项,覆盖全部?",
"overwriteManyLocal": "本地已有 {{count}} 个同名项,覆盖全部?",
"overwriteMore": "…另有 {{count}} 个",
"deleteTitle": "确认删除",
"deleteMessage": "将删除 {{count}} 项:{{names}}",
"deleteRecursiveWarn": "其中包含目录,会递归删除且无法撤销。"
},
"properties": {
"name": "名称",
@@ -152,27 +162,41 @@
"statusDone": "完成",
"statusFailed": "失败",
"statusCancelled": "已取消",
"dropUpload": "上传到 {{path}}",
"dropDownload": "下载到 {{path}}"
"dropUpload": "拖放到此处上传到 {{path}}",
"dropDownload": "拖放到此处下载到 {{path}}",
"railAria": "本地与远程之间传输",
"railUpload": "上传选中的本地文件(未选中时可打开文件选择器)",
"railDownload": "下载选中的远程文件到本地",
"railUploadAria": "上传到远程",
"railDownloadAria": "下载到本地",
"railDownloadNeedSelection": "请先选择远程文件",
"retry": "重试"
},
"editor": {
"readFailed": "读取失败",
"saveFailed": "保存失败",
"unsavedClose": "有未保存的修改,确定关闭?",
"unsavedTitle": "未保存的修改",
"discardAndClose": "放弃并关闭",
"reloadTitle": "重新加载",
"discardAndReload": "放弃并重新加载",
"saving": "保存中...",
"save": "保存",
"saved": "文件已保存",
"loadingEditor": "加载编辑器...",
"footer": "UTF-8 · Monaco · ⌘/Ctrl+S 保存 · 最大约 2MB",
"loadBlocked": "未能加载文件内容",
"footer": "UTF-8 · ⌘/Ctrl+S 保存 · Esc 关闭 · 最大约 2MB",
"charCount": "{{count}} 字符",
"unsavedMark": " · 未保存",
"savedMark": " · 已保存"
"savedMark": " · 已保存",
"title": "编辑 {{name}}",
"dirtyBadge": "未保存",
"reload": "重新加载",
"unsavedReload": "有未保存的修改,确定重新加载并丢弃?"
},
"toast": {
"renamed": "已重命名为 {{name}}",
"renameFailed": "重命名失败",
"pathCopied": "路径已复制到剪贴板",
"pathCopyFailed": "复制路径失败",
"chmodUpdated": "权限已更新为 {{mode}}",
"chmodFailed": "权限修改失败",
"uploadPartial": "{{action}}完成 {{completed}} 个,失败 {{failed}} 个:{{detail}}",
@@ -180,7 +204,13 @@
"uploadAction": "上传",
"downloadAction": "下载",
"noFolderUpload": "上传文件夹失败",
"noDragPath": "当前系统未提供拖拽文件路径,请使用“上传”按钮选择文件",
"noFolderRecursive": "文件夹递归传输失败,请重试或改用上传按钮"
"noDragPath": "当前系统未提供拖拽路径。请用中间 → 箭头或选择文件上传。",
"noFolderRecursive": "文件夹传输失败。请重试,或使用中间 → 箭头 / 文件选择器。",
"dropFailed": "拖放失败:未读到文件信息。请再试,或使用中间箭头传输。",
"folderCreated": "已创建文件夹 {{name}}",
"allSkippedExisting": "同名文件均已跳过",
"skippedExisting": "已跳过 {{count}} 个同名文件",
"deleteFailed": "删除失败",
"deleted": "已删除"
}
}
+3 -2
View File
@@ -34,7 +34,7 @@
"reopenShell": "重新打开 Shell",
"reopening": "正在打开…",
"disconnected": "连接已断开",
"disconnectedHint": "SSH 会话已结束或网络中断。点击下方一键重新连接。",
"disconnectedHint": "SSH 会话已结束或网络中断。点下方一键重新连接,即可继续工作。",
"reconnect": "重新连接",
"suspended": "连接已挂起",
"suspendedHint": "长时间未操作,连接已进入挂起以节省资源",
@@ -70,7 +70,8 @@
"splitRight": "向右分屏",
"splitDown": "向下分屏",
"maximizePane": "最大化当前分屏",
"restoreLayout": "恢复分屏布局"
"restoreLayout": "恢复分屏布局",
"openSftp": "打开 SFTP"
},
"search": {
"placeholder": "搜索...",
+114 -39
View File
@@ -78,7 +78,7 @@
"closeTab": "關閉目前分頁",
"closeAllTabs": "關閉所有分頁",
"portForward": "新增埠轉發",
"upgradePro": "升級 OpsXShell Pro",
"upgradePro": "升級 OpsXShell 專業版",
"editSession": "編輯連線: {{name}}"
}
},
@@ -90,6 +90,8 @@
"terminal": "終端機",
"batch": "批次執行",
"newTerminal": "新終端機",
"closeAria": "關閉 {{title}}",
"listAria": "已開啟的標籤",
"kind": {
"terminal": "終端機",
"sftp": "SFTP",
@@ -105,7 +107,8 @@
"closeRight": "關閉右側分頁",
"closeLeft": "關閉左側分頁",
"closeAll": "關閉全部",
"clone": "克隆分頁"
"clone": "克隆分頁",
"openSftp": "開啟 SFTP"
}
},
"sidebar": {
@@ -149,39 +152,44 @@
"disconnect": "中斷"
},
"pro": {
"upgrade": "升級 Pro",
"feature": "專業功能",
"unlock": "解鎖 {{feature}}",
"upgrade": "升級專業版",
"feature": "專業版功能",
"unlock": "解鎖專業版進階功能",
"comingSoon": "即將推出",
"activateSuccess": "啟用成功",
"activateFailed": "啟用失敗",
"licenseActivated": "Pro 授權已啟用",
"licenseActivated": "專業版授權已啟用",
"paymentPending": "付款完成後請貼上授權,或稍後再試啟用",
"invalidLicense": "啟用失敗:授權無效",
"goUpgrade": "前往付費升級",
"goUpgrade": "去升級專業版",
"haveLicense": "已有授權?啟用",
"title": "OpsXShell Pro · 解鎖專業維運能力",
"subtitleComingSoon": "{{feature}} 即將推出 · 升級 Pro 可優先體驗",
"subtitleUnlock": "正在解鎖:{{feature}}",
"subtitleDefault": "轉發、代理、序列埠、AI、批次與廣播",
"activated": "已啟用 Pro",
"title": "OpsXShell · 解鎖專業版",
"subtitleComingSoon": "進階功能即將推出 · 升級專業版可優先體驗",
"subtitleUnlock": "目前正在解鎖進階功能",
"subtitleDefault": "連接埠轉發、終端 AI、批次運維、主機清單與遠端桌面等專業版能力",
"activated": "已啟用專業版",
"expiresAt": " · 有效期至 {{date}}",
"lifetime": " · 終身授權",
"oneTimeFee": "一次性費用 · 本機終身授權 · 無需訂閱",
"oneTimeFee": "免費 / 專業版年繳 / 專業版永久",
"pasteLicense": "貼上授權",
"activateButton": "啟用",
"clearLicense": "清除本機授權",
"paymentNote": "付款由 Waffo 託管收銀台處理;本應用不收集或儲存信用卡資料。",
"testDeviceId": "測試環境 · 裝置 ID:{{deviceId}}",
"later": "稍後再說",
"viewPro": "檢視 Pro",
"wallComingSoonSuffix": " · 即將推出",
"wallUnlock": "解鎖 {{feature}}",
"wallMessageComingSoon": "此能力屬於 OpsXShell Pro,協定實現尚在開發中。升級後可優先體驗。",
"wallMessageDefault": "此功能屬於 OpsXShell Pro。升級後即可在本機使用。",
"viewPro": "查看專業版方案",
"wallComingSoonSuffix": "即將推出",
"wallUnlock": "解鎖專業版進階功能",
"wallMessageComingSoon": "此能力屬於 OpsXShell 專業版,相關實作尚在完善。升級專業版年繳或永久後,可優先體驗。",
"wallMessageDefault": "連接埠轉發、終端 AI、批次執行、主機清單與遠端桌面等均包含在專業版中。升級專業版年繳或永久後,即可在本機使用。",
"checkoutUnavailable": "結帳服務無法使用 ({{status}})",
"freeTier": "Free",
"proTier": "Pro",
"emailLabel": "電子郵件",
"emailRequired": "結帳前請先填寫電子郵件",
"claimPending": "正在領取授權…",
"invalidKeyFormat": "金鑰格式無效,請貼上 LIC- 開頭的授權碼",
"accountEmail": "帳戶:{{email}}",
"freeTier": "免費",
"proTier": "專業版",
"freeItems": {
"ssh": "SSH 終端機",
"sftp": "SFTP 檔案管理",
@@ -190,19 +198,40 @@
"import": "單筆 / ssh_config 匯入"
},
"proItems": {
"forward": "埠轉發",
"proxy": "連線代理 / SOCKS",
"serial": "序列埠終端機",
"ai": "終端機 AI 助手",
"forward": "連接埠轉發",
"proxy": "工作階段代理 / SOCKS",
"serial": "序列埠終端",
"ai": "終端 AI 助手",
"batch": "批次執行 / 廣播同步",
"broadcast": "廣播同步輸入",
"importExport": "批次匯入匯出主機清單",
"desktop": "RDP / VNC 遠端桌面"
}
"desktop": "遠端桌面(RDP / VNC)"
},
"planYearly": "專業版年繳",
"planYearlyDesc": "¥99 / 年 · 2 台裝置",
"planPerpetual": "專業版永久",
"planPerpetualDesc": "¥199 · 5 台裝置 · 終身",
"planTrial": "專業版體驗",
"devices": "最多 {{count}} 台裝置",
"goUpgradeYearly": "購買專業版年繳",
"goUpgradePerpetual": "購買專業版永久",
"activatedYearly": "已啟用專業版年繳",
"activatedPerpetual": "已啟用專業版永久",
"activatedTrial": "已啟用專業版體驗",
"choosePlan": "選擇方案:免費 / 專業版年繳 / 專業版永久",
"planFreePrice": "¥0",
"planFreeDesc": "SSH · SFTP · 本機終端",
"planFreeCta": "目前方案",
"planIncludesPro": "含全部專業版功能",
"planFree": "免費",
"subtitleUnlockDetail": "相關能力:{{feature}}",
"wallUnlockComingSoon": "專業版進階功能即將推出",
"wallMessageComingSoonFeature": "「{{feature}}」屬於專業版進階功能,相關實作尚在完善。升級專業版年繳或永久後,可優先體驗。",
"wallMessageFeature": "「{{feature}}」屬於專業版進階功能。升級專業版年繳或永久後,即可在本機使用。"
},
"launcher": {
"title": "快速啟動",
"description": "連線、本機 Shell 與裝置控制台統一入口",
"description": "常用入口集中:工作階段、本機 Shell、桌面、串列埠",
"cards": {
"quickConnect": {
"title": "快速連線",
@@ -215,6 +244,14 @@
"serial": {
"title": "序列埠終端機",
"desc": "鮑率與序列埠參數"
},
"rdp": {
"title": "RDP 桌面",
"desc": "遠端 Windows 桌面"
},
"vnc": {
"title": "VNC 桌面",
"desc": "遠端圖形桌面"
}
},
"sectionLocalShell": "本機 Shell",
@@ -229,6 +266,7 @@
"forwardOpenRunning": "SOCKS5 已開(:{{port}})· 點擊管理 · 右鍵複製",
"forwardStarted": "轉發已啟動",
"forwardStartedDynamic": "SOCKS5 已啟動:socks5://127.0.0.1:{{port}}",
"forwardResumed": "已恢復 {{count}} 條連接埠轉發",
"socksStartFailed": "啟動失敗:{{message}}",
"socksStopFailed": "停止失敗:{{message}}",
"socksCopied": "已複製 socks5://127.0.0.1:{{port}}"
@@ -249,7 +287,7 @@
"typeDynamic": "動態",
"running": "執行中",
"socksProxy": "SOCKS5:127.0.0.1:{{port}}",
"remoteToLocal": "遠端 {{remote}} → 本機 {{local}}",
"remoteToLocal": "遠端 {{bind}}:{{remote}} → {{host}}:{{local}}",
"stats": "{{connections}} 連線 · ↑{{up}} · ↓{{down}}",
"copyProxy": "複製代理",
"copyRule": "複製規則",
@@ -259,15 +297,15 @@
"delete": "刪除",
"editTitle": "編輯轉發",
"addTitle": "新增轉發",
"typeLocalDesc": "本機 → 遠端",
"typeRemoteDesc": "遠端 → 本機",
"typeLocalDesc": "存取遠端服務",
"typeRemoteDesc": "暴露本機服務",
"typeDynamicDesc": "SOCKS5",
"selectType": "轉發類型",
"drawerSubtitle": "經目前 SSH 建立通道",
"ruleFields": "參數",
"dynamicHint": "本機 SOCKS5:127.0.0.1:1080。流量經目前 SSH 伺服器出口 IP 存取外部網路。",
"dynamicSingleHint": "每台 SSH 僅一條動態轉發,連接埠固定 1080。",
"dynamicPortHint": "If the port is busy, pick another local port (e.g. 1081).",
"dynamicHint": "本機 SOCKS5(預設 :1080)。流量經目前 SSH 出口存取外網。",
"dynamicSingleHint": "每台 SSH 僅一條動態轉發;停止後可改連接埠。",
"dynamicPortHint": "連接埠被占用時可改,例如 1081。",
"ruleList": "規則",
"ruleListEmpty": "暫無本地 / 遠端規則",
"addSection": "新增",
@@ -301,17 +339,30 @@
"internet": "網際網路",
"localCaption": "本地轉發:經通道存取遠端連接埠,如同存取本機。",
"remoteCaption": "遠端轉發:遠端存取經通道轉到本機服務。",
"dynamicCaption": "動態轉發:本機變成 SOCKS5 代理,可經目前 SSH 伺服器出口 IP 存取網際網路。"
"dynamicCaption": "動態轉發:本機 SOCKS5,經目前 SSH 出口存取外網。"
},
"ruleName": "名稱",
"ruleNamePlaceholder": "例如 MySQL",
"localListenPort": "本機監聽連接埠",
"localListenPortHint": "預設 localhost,等同 ssh -L 連接埠:…。一般只填連接埠。",
"localBindAdvanced": "進階:改本機綁定",
"localTargetPort": "本機目標連接埠",
"remoteTargetPort": "遠端目標連接埠",
"remoteTargetPort": "目標埠",
"remoteListenPort": "遠端監聽連接埠",
"remoteListenPortHint": "預設僅遠端 localhost,等同 ssh -R 連接埠:…。一般只填連接埠。",
"remoteListenAddress": "遠端監聽",
"remoteListenAddressPlaceholder": "127.0.0.1:18080",
"remoteListenAddressHint": "127.0.0.1 = 僅遠端本機;0.0.0.0 = 遠端內網可連(需 GatewayPorts)。",
"errorRemoteListenAddress": "請填寫有效遠端監聽,如 127.0.0.1:18080",
"localTargetAddress": "本機 / 內網目標",
"localTargetAddressPlaceholder": "127.0.0.1:8080",
"localTargetAddressHint": "轉到本機或內網服務,如 127.0.0.1:8080。勿填 0.0.0.0。",
"viaSessionRemote": "在 {{target}} 上監聽(預設 localhost)",
"errorRemoteListenPort": "請填寫有效的遠端監聽連接埠(1–65535)",
"errorLocalTargetAddress": "請填寫有效本機/內網目標,如 127.0.0.1:8080",
"portPlaceholder": "如 3306",
"remoteHost": "遠端主機",
"remoteHostPlaceholder": "localhost 或 IP",
"remoteHost": "目標主機",
"remoteHostPlaceholder": "127.0.0.1",
"socksRuleName": "SOCKS5 代理",
"defaultLocalName": "本地轉發",
"defaultRemoteName": "遠端轉發",
@@ -325,11 +376,35 @@
"deleteConfirm": "確定刪除此規則?",
"errorNamePort": "請填寫名稱和有效連接埠(1–65535)",
"errorTargetPort": "請填寫有效目標連接埠(1–65535)",
"errorRemoteHost": "請填寫遠端主機",
"errorRemoteHost": "請填寫目標主機(相對目前 SSH 伺服器)",
"errorNotConnected": "未連線到伺服器",
"errorStartFailed": "啟動失敗",
"errorStopFailed": "停止失敗",
"errorSocksRunning": "SOCKS5 已在執行",
"copySuffix": "副本"
"copySuffix": "副本",
"remoteBindHint": "0.0.0.0 需 GatewayPorts;未開啟時常靜默繫 127.0.0.1。目標勿填 0.0.0.0。",
"localToRemote": "本機 {{bind}}:{{local}} → 遠端 {{host}}:{{remote}}",
"localToRemotePort": "本機 :{{local}} → 遠端 {{host}}:{{remote}}",
"remoteHostHint": "相對 SSH 伺服器。遠端本機填 127.0.0.1,內網其它機填可達 IP。勿填 0.0.0.0。",
"localBindHost": "本機綁定",
"localBindHostPlaceholder": "127.0.0.1",
"localBindHostHint": "預設僅本機。填 0.0.0.0 或內網 IP 可讓區網存取。",
"errorTargetHostInvalid": "目標不能是 0.0.0.0,請填 127.0.0.1 或可達內網 IP",
"listenAddress": "本機監聽",
"listenAddressPlaceholder": "127.0.0.1:8080",
"listenAddressHint": "預設僅本機;0.0.0.0 可讓區網存取。",
"targetAddress": "遠端目標",
"targetAddressPlaceholder": "127.0.0.1:80",
"targetAddressHint": "相對 SSH 伺服器。遠端本機服務填 127.0.0.1:連接埠。",
"errorListenAddress": "請填寫有效監聽位址,如 127.0.0.1:8080",
"errorTargetAddress": "請填寫有效目標,如 127.0.0.1:80",
"targetAddressHintVia": "經 {{target}}。遠端本機服務填 127.0.0.1:連接埠(不會在遠端新建連接埠)。",
"viaSession": "經目前工作階段 {{target}}",
"remoteToLocalPort": "遠端 :{{remote}} → {{host}}:{{local}}",
"remoteBindAdvanced": "進階:改遠端繫結",
"remoteBindHost": "遠端繫結",
"remoteBindHostPlaceholder": "127.0.0.1",
"remoteBindHostHint": "預設僅遠端本機。0.0.0.0 需 GatewayPorts;未開啟時多數 sshd 仍只繫 127.0.0.1。",
"remoteGatewayPortsWarning": "已請求遠端 0.0.0.0 監聽。若未開 GatewayPorts,sshd 常會靜默只繫 127.0.0.1。"
}
}
+11 -4
View File
@@ -15,10 +15,12 @@
"passwordOptional": "密碼(可選)",
"width": "寬度",
"height": "高度",
"rdpFootnote": "原生 IronRDP:TCP → X.224 → TLS → CredSSP/NLA → MCS;握手逾時 45s。憑證校驗目前為開發期寬鬆模式。",
"vncFootnote": "原生 vnc-rs RFB:支援 Tight JPEG 畫面解碼;剪貼簿按 UTF-8 傳送(極舊服務端可能亂碼)。",
"rdpFootnote": "全螢幕或最大化時,會依目前視窗區域動態請求遠端解析度;也可在連線前用預設選擇初始解析度。憑證驗證目前為開發期寬鬆模式。",
"vncFootnote": "多數 VNC 伺服器解析度由遠端固定,全螢幕僅本機縮放適配;連線前的偏好尺寸僅供參考。剪貼簿以 UTF-8 傳送。",
"errorHostRequired": "請輸入主機位址",
"errorUsernameRequired": "請輸入使用者名稱"
"errorUsernameRequired": "請輸入使用者名稱",
"resolution": "解析度",
"resolutionCustom": "自訂"
},
"toolbar": {
"pasteClipboard": "貼上本機剪貼簿到遠端",
@@ -28,7 +30,12 @@
"openShareDir": "在本機開啟共享目錄(下載資料夾)",
"openShareDirAria": "開啟共享目錄",
"disconnect": "中斷連線",
"disconnectAria": "中斷連線"
"disconnectAria": "中斷連線",
"fullscreen": "全螢幕",
"fullscreenAria": "進入全螢幕",
"exitFullscreen": "結束全螢幕",
"exitFullscreenAria": "結束全螢幕",
"exitFullscreenHint": "Esc / F11 結束"
},
"status": {
"connecting": "正在連線…",
+16 -3
View File
@@ -39,7 +39,9 @@
"closed": "連線已關閉",
"dnsFailed": "無法解析主機",
"refused": "連線被拒絕",
"disconnected": "連線已中斷"
"disconnected": "連線已中斷",
"keepaliveFailed": "SSH 心跳連續失敗,連線已關閉",
"idleKicked": "遠端 Shell 因閒置逾時退出(TMOUT)"
},
"auth": {
"failed": "認證失敗,請檢查使用者名稱和密碼",
@@ -68,7 +70,10 @@
"forward": {
"failed": "埠轉發設定失敗",
"bindFailed": "連接埠綁定失敗",
"alreadyInUse": "連接埠已被佔用"
"alreadyInUse": "本機埠已被占用。請先暫停本規則或其他占用該埠的行程,再啟動。",
"remoteDenied": "遠端拒絕遠端埠轉發(AllowTcpForwarding / PermitListen、埠占用或綁定限制)。目前僅在遠端 127.0.0.1 監聽。",
"remoteDeniedPrivileged": "遠端拒絕特權監聽埠(<1024)。請改用 ≥1024,或以 root 監聽,並檢查 AllowTcpForwarding / PermitListen。",
"invalidTargetHost": "目標位址不能是 0.0.0.0,請填 127.0.0.1 或遠端可達的內網 IP"
},
"sftp": {
"connectFailed": "SFTP 連線失敗",
@@ -80,7 +85,15 @@
"writeFailed": "儲存失敗",
"renameFailed": "重新命名失敗",
"chmodFailed": "權限修改失敗",
"apiUnavailable": "SFTP API 無法使用"
"apiUnavailable": "SFTP API 無法使用",
"channelFailed": "無法開啟 SFTP 通道(伺服器限制或工作階段忙碌),請重連後再試",
"sessionGone": "SFTP 工作階段已結束,請重新連線",
"busy": "正在傳輸檔案,請稍後再試",
"editTooLarge": "檔案過大,文字編輯上限約 2MB。請下載後用本機編輯器開啟。",
"editBinary": "此檔案像是二進位內容,無法用文字編輯器開啟",
"editNotUtf8": "遠端檔案不是有效 UTF-8 文字",
"transferCancelled": "傳輸已取消",
"diskFull": "磁碟空間不足(本機或遠端)"
},
"session": {
"notFound": "連線不存在",
+6 -4
View File
@@ -69,17 +69,17 @@
"confirm": "刪除"
},
"welcome": {
"tagline": "遠端終端機 · SFTP · 埠轉發",
"tagline": "簡單好用 · 終端機 · 傳檔 · 遠端桌面",
"sectionStart": "開始",
"sectionDesktop": "遠端桌面",
"sectionRecent": "最近連線",
"quickConnect": {
"title": "快速連線",
"desc": "臨時 SSH,不寫入連線庫"
"desc": "臨時 SSH,不寫入工作階段庫"
},
"newSession": {
"title": "新增連線",
"desc": "儲存主機,側欄雙擊連線"
"desc": "儲存主機,側欄雙擊即連"
},
"localShell": {
"title": "本機 Shell",
@@ -167,7 +167,9 @@
"jumpHost": "跳板機(可選)",
"jumpNone": "無跳板",
"jumpNoneAlt": "不使用跳板",
"jumpHint": "目前支援一個已儲存連線作為跳板"
"jumpHint": "目前支援一個已儲存連線作為跳板",
"resolution": "解析度",
"resolutionCustom": "自訂"
},
"batch": {
"title": "批次執行",
+51 -19
View File
@@ -1,9 +1,7 @@
{
"nav": {
"general": "工作區",
"generalDesc": "版面與資源",
"appearance": "外觀",
"appearanceDesc": "介面主題與語言",
"general": "一般",
"generalDesc": "主題、語言與版面",
"terminal": "終端機",
"terminalDesc": "字型與配色",
"shortcuts": "快捷鍵",
@@ -15,11 +13,13 @@
"ai": "大模型",
"aiDesc": "AI Provider",
"about": "關於",
"aboutDesc": "版本與資料"
"aboutDesc": "版本與資料",
"account": "帳戶",
"accountDesc": "電子郵件、授權與裝置"
},
"title": "設定",
"search": {
"placeholder": "搜尋設定..."
"placeholder": "搜尋設定…"
},
"language": {
"label": "介面語言",
@@ -89,7 +89,7 @@
"ssh": {
"connection": "連線",
"keepAlive": "保持心跳",
"keepAliveDesc": "閒置時發送心跳,減少斷線",
"keepAliveDesc": "閒置時發送 SSH 心跳;連續多次無回應才會斷線",
"autoReconnect": "自動重連",
"autoReconnectDesc": "意外斷線後自動嘗試重連",
"timeout": "連線逾時",
@@ -101,8 +101,10 @@
"maxConnectionsDesc": "SSH、SFTP 與批次連線共享此上限",
"maxBackground": "背景連線上限",
"maxBackgroundDesc": "超過上限時優先回收最久未使用的連線",
"suspend": "背景暫停",
"suspendDesc": "分頁進入背景後多少分鐘釋放活躍通道"
"suspend": "背景掛起",
"suspendDesc": "背景標籤閒置多少分鐘後掛起(有活躍 Shell/SFTP 時保持連線)",
"keepAliveInterval": "心跳間隔(秒)",
"keepAliveIntervalDesc": "向伺服器發送心跳的頻率(類似 ClientAliveInterval)。不穩定網路建議 ≤15 秒"
},
"security": {
"credentials": "憑證保護",
@@ -119,7 +121,7 @@
"clearConfirm": "確定清空全部已知主機金鑰?下次連線將重新確認。"
},
"about": {
"tagline": "輕量原生的 SSH / SFTP 維運終端機",
"tagline": "簡單、便捷、人性化的原生維運終端",
"appVersion": "應用 v{{version}}",
"copyVersion": "複製版本資訊",
"runtime": "執行環境",
@@ -127,8 +129,9 @@
"localData": "本機資料",
"sessionsSettings": "連線與設定",
"masterKeyPath": "加密主金鑰",
"privacyNote": "密碼與金鑰口令由 Rust 使用 AES-256-GCM 加密。OpsXShell 不儲存終端機命令歷史。",
"license": "MIT License · Rust · XTerm.js"
"privacyNote": "密碼與金鑰口令由 Rust 使用 AES-256-GCM 加密。不保存終端機指令歷史,也不做堡壘稽核。",
"license": "MIT License · Rust · XTerm.js",
"logPath": "應用程式日誌"
},
"ai": {
"presets": "供應商預設",
@@ -162,13 +165,42 @@
"apiKeySaveFailed": "API Key 儲存失敗",
"providerNotFound": "Provider 不存在",
"modelCatalogReadFailed": "模型目錄讀取失敗",
"catalogUnavailable": "models.dev 暫不可用"
"catalogUnavailable": "models.dev 暫不可用",
"family": {
"openai_compatible": "OpenAI 相容",
"standalone": "獨立協定",
"plan": "方案套餐",
"local": "本機私有化",
"custom": "自訂"
}
},
"family": {
"openai_compatible": "OpenAI 相容",
"standalone": "────────",
"plan": "Plan 計劃",
"local": "私有化本機",
"custom": "Custom 自訂"
"account": {
"title": "帳戶",
"email": "電子郵件",
"emailDesc": "用於結帳與領取授權",
"plan": "目前方案",
"planFree": "免費",
"planYearly": "專業版年繳",
"planPerpetual": "專業版永久",
"planTrial": "專業版體驗",
"expires": "有效至 {{date}}",
"lifetime": "終身有效",
"devices": "裝置席位:最多 {{count}} 台",
"deviceId": "本機裝置 ID",
"saveEmail": "儲存電子郵件",
"activate": "啟用授權",
"pasteLicense": "貼上 LIC- 授權碼",
"clear": "清除本機授權",
"deactivate": "停用本機啟用",
"upgrade": "升級專業版",
"saved": "已儲存",
"activateOk": "啟用成功",
"deviceList": "已綁定裝置",
"loadingDevices": "載入裝置列表…",
"noDevices": "暫無綁定裝置",
"thisDevice": "本機",
"removeDevice": "解除綁定",
"deviceRemoved": "已解除該裝置綁定",
"seatFull": "裝置席位已滿。請先解除其他裝置,再在新機器上啟用。"
}
}
+54 -24
View File
@@ -3,8 +3,9 @@
"local": "本機",
"remote": "遠端",
"notConnectedTitle": "未連線到遠端伺服器",
"notConnectedDesc": "請先連線 SSH 工作階段以使用 SFTP",
"ariaLabel": "{{title}}檔案面板"
"notConnectedDesc": "先連上 SSH,再傳檔、改設定",
"ariaLabel": "{{title}}檔案面板",
"reconnectResumeDesc": "連線中斷。一鍵重連後回到 {{path}}"
},
"connection": {
"selectServer": "選擇伺服器",
@@ -12,7 +13,9 @@
"createSessionHint": "請先在側邊欄建立連線",
"reconnect": "重新連線",
"notConnected": "未連線",
"connecting": "連線中..."
"connecting": "連線中...",
"resumeHint": "重連後將回到 {{path}}",
"reconnectingResume": "正在重連並恢復 {{path}}…"
},
"errors": {
"notConnected": "SFTP 尚未連線",
@@ -23,19 +26,14 @@
"selectDownloadFiles": "請先選擇要下載的檔案",
"uploadFailed": "上傳失敗",
"downloadFailed": "下載失敗",
"fileError": "{{fileName}}: {{message}}"
"fileError": "{{fileName}}: {{message}}",
"mkdirFailed": "建立資料夾失敗"
},
"toolbar": {
"upload": "上傳",
"uploadAria": "上傳",
"download": "下載",
"downloadAria": "下載",
"downloadNeedSelection": "請先選擇遠端檔案",
"downloadHint": "下載選中的遠端檔案",
"refresh": "重新整理",
"refreshAria": "重新整理",
"refreshAria": "重新整理目前面板",
"newFolder": "新增資料夾",
"newFolderAria": "新增資料夾"
"newFolderAria": "在目前面板新增資料夾"
},
"sort": {
"name": "名稱",
@@ -55,7 +53,8 @@
"hideHidden": "隱藏點檔案(.xxx)",
"showHiddenAria": "顯示隱藏檔案",
"hideHiddenAria": "隱藏點檔案",
"searchAria": "{{title}} 目前資料夾搜尋"
"searchAria": "{{title}} 目前資料夾搜尋",
"upAtRoot": "已在根目錄"
},
"status": {
"loading": "載入中...",
@@ -63,7 +62,8 @@
"filtered": "顯示 {{shown}} / {{total}} 項",
"hiddenCount": "共 {{total}} 項(已隱藏 {{hidden}})",
"total": "共 {{count}} 項",
"filterHint": "篩選: {{query}}"
"filterHint": "篩選: {{query}}",
"refreshing": "正在重新整理..."
},
"empty": {
"dirTitle": "目錄為空",
@@ -99,7 +99,6 @@
"download": "下載",
"edit": "編輯",
"rename": "重新命名",
"copyPath": "複製路徑",
"properties": "屬性",
"permissions": "權限",
"delete": "刪除"
@@ -116,7 +115,18 @@
"chmodTitle": "權限編輯",
"chmodApply": "套用",
"pickUploadTitle": "選擇要上傳的檔案或資料夾",
"pickUploadRzTitle": "選擇要上傳的檔案(rz)"
"pickUploadRzTitle": "選擇要上傳的檔案(rz)",
"overwriteTitle": "覆蓋既有檔案?",
"overwriteConfirm": "覆蓋",
"overwriteSkip": "跳過",
"overwriteOneRemote": "遠端已存在「{{name}}」,覆蓋?",
"overwriteOneLocal": "本機已存在「{{name}}」,覆蓋?",
"overwriteManyRemote": "遠端已有 {{count}} 個同名項目,覆蓋全部?",
"overwriteManyLocal": "本機已有 {{count}} 個同名項目,覆蓋全部?",
"overwriteMore": "…另有 {{count}} 個",
"deleteTitle": "確認刪除",
"deleteMessage": "將刪除 {{count}} 項:{{names}}",
"deleteRecursiveWarn": "其中包含目錄,會遞迴刪除且無法復原。"
},
"properties": {
"name": "名稱",
@@ -152,27 +162,41 @@
"statusDone": "完成",
"statusFailed": "失敗",
"statusCancelled": "已取消",
"dropUpload": "上傳到 {{path}}",
"dropDownload": "下載到 {{path}}"
"dropUpload": "拖放到此處上傳到 {{path}}",
"dropDownload": "拖放到此處下載到 {{path}}",
"railAria": "本機與遠端之間傳輸",
"railUpload": "上傳選取的本機檔案(未選取時可開啟檔案選擇器)",
"railDownload": "下載選取的遠端檔案到本機",
"railUploadAria": "上傳到遠端",
"railDownloadAria": "下載到本機",
"railDownloadNeedSelection": "請先選擇遠端檔案",
"retry": "重試"
},
"editor": {
"readFailed": "讀取失敗",
"saveFailed": "儲存失敗",
"unsavedClose": "有未儲存的修改,確定關閉?",
"unsavedTitle": "未儲存的修改",
"discardAndClose": "放棄並關閉",
"reloadTitle": "重新載入",
"discardAndReload": "放棄並重新載入",
"saving": "儲存中...",
"save": "儲存",
"saved": "檔案已儲存",
"loadingEditor": "載入編輯器...",
"footer": "UTF-8 · Monaco · ⌘/Ctrl+S 儲存 · 最大約 2MB",
"loadBlocked": "無法載入檔案內容",
"footer": "UTF-8 · ⌘/Ctrl+S 儲存 · Esc 關閉 · 最大約 2MB",
"charCount": "{{count}} 字元",
"unsavedMark": " · 未儲存",
"savedMark": " · 已儲存"
"savedMark": " · 已儲存",
"title": "編輯 {{name}}",
"dirtyBadge": "未儲存",
"reload": "重新載入",
"unsavedReload": "有未儲存的修改,確定重新載入並捨棄?"
},
"toast": {
"renamed": "已重新命名為 {{name}}",
"renameFailed": "重新命名失敗",
"pathCopied": "路徑已複製到剪貼簿",
"pathCopyFailed": "複製路徑失敗",
"chmodUpdated": "權限已更新為 {{mode}}",
"chmodFailed": "權限修改失敗",
"uploadPartial": "{{action}}完成 {{completed}} 個,失敗 {{failed}} 個:{{detail}}",
@@ -180,7 +204,13 @@
"uploadAction": "上傳",
"downloadAction": "下載",
"noFolderUpload": "上傳資料夾失敗",
"noDragPath": "目前系統未提供拖曳檔案路徑,請使用「上傳」按鈕選擇檔案",
"noFolderRecursive": "資料夾遞迴傳輸失敗,請重試或改用上傳按鈕"
"noDragPath": "目前系統未提供拖曳路徑。請用中間 → 箭頭或選擇檔案上傳。",
"noFolderRecursive": "資料夾傳輸失敗。請重試,或使用中間 → 箭頭 / 檔案選擇器。",
"dropFailed": "拖放失敗:無法讀取檔案資訊。請再試,或使用中間箭頭傳輸。",
"folderCreated": "已建立資料夾 {{name}}",
"allSkippedExisting": "同名檔案均已跳過",
"skippedExisting": "已跳過 {{count}} 個同名檔案",
"deleteFailed": "刪除失敗",
"deleted": "已刪除"
}
}
+3 -2
View File
@@ -34,7 +34,7 @@
"reopenShell": "重新開啟 Shell",
"reopening": "正在開啟…",
"disconnected": "連線已中斷",
"disconnectedHint": "SSH 連線已結束或網路中斷。點擊下方一鍵重新連線。",
"disconnectedHint": "SSH 連線已結束或網路中斷。點下方一鍵重新連線,即可繼續工作。",
"reconnect": "重新連線",
"suspended": "連線已暫停",
"suspendedHint": "長時間未操作,連線已進入暫停以節省資源",
@@ -70,7 +70,8 @@
"splitRight": "向右分割",
"splitDown": "向下分割",
"maximizePane": "最大化目前窗格",
"restoreLayout": "還原分割版面"
"restoreLayout": "還原分割版面",
"openSftp": "開啟 SFTP"
},
"search": {
"placeholder": "搜尋...",