diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 604c023be7..3c17b90c57 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -89,9 +89,13 @@ running terminals: see [development](docs/development.md#checks). - **Theme colors:** edit them only in the theme blocks of `src/styles.css`. Never edit `src/lib/themes.generated.ts` or the generated copies in DESIGN.md, `index.html` and `public/manifest.webmanifest`; run `bun run generate:themes`. -- **UI text:** every new `t("…")` string needs an entry in `src/lib/i18n.ko.ts`, `i18n.ja.ts` - and `i18n.zh.ts`, with the same placeholders. `bun run test:unit` fails on a missing, unused or - untranslated entry. +- **UI text:** every new `t("…")` string needs a Korean, Japanese and Simplified Chinese entry with + the same placeholders. A string that only one feature's files use goes in that feature's files in + `src/lib/i18n/` when it has them (`settings.ko.ts`, `settings.ja.ts` and `settings.zh.ts` for the + Settings dialog; each file's header lists its feature's files). Any other string goes in + `src/lib/i18n.ko.ts`, `i18n.ja.ts` and `i18n.zh.ts`, and so does a feature's string once another + feature uses it too. `bun run test:unit` fails on a missing, unused or untranslated entry, and on one + the three languages keep in different files. - **UI languages:** the app keeps English, Korean, Japanese and Simplified Chinese and does not take new ones. Every language has to translate each later string, so a PR that adds a language is closed. diff --git a/src/lib/i18n.ja.ts b/src/lib/i18n.ja.ts index 2484aad9f3..a1f9461791 100644 --- a/src/lib/i18n.ja.ts +++ b/src/lib/i18n.ja.ts @@ -1,5 +1,9 @@ +import { SETTINGS_JA } from "./i18n/settings.ja.ts"; + /** - * Japanese for every `t("…")` in src/. The English string is the key. Grouped by where the text + * Japanese for every `t("…")` in src/ that no part in lib/i18n/ holds: keys more than one feature + * uses, and the app shell's. JA at the end is this and the parts together. The English string is + * the key. Grouped by where the text * shows; within a group, roughly in the order it appears. Register: labels and buttons as concise * nouns or verbs, sentences in です・ます調. Fixed terms: ペイン, ワークスペース, エージェント, * ターミナル, チャット, ペアリング, デバイス, セッション, 入力欄, キー (SSH key; 秘密鍵 for private @@ -7,7 +11,7 @@ * labels (Star, Issue), acronyms (SSH, CLI, HTTPS, QR) and names like Markdown, Enter, Skill ツール stay * in English. Placeholders in braces keep their English names. */ -export const JA: Record = { +const BASE: Record = { "Could not load sign-in options": "ログイン方法を読み込めませんでした", "On the server PC": "サーバーPCでログイン", "Install {cli} on the server PC first.": "先にサーバーPCに{cli}をインストールしてください。", @@ -86,18 +90,7 @@ export const JA: Record = { "Waiting for terminal input…": "端末の入力準備中…", "Paused while you use another window": "別のウィンドウを使っている間は一時停止中", "View only while you use another window · click to type": "別のウィンドウを使っている間は表示のみ · クリックで入力", - "Direct typing": "直接入力", "Input line": "入力欄", - "Terminal input mode": "端末入力モード", - "Reset shortcuts": "ショートカットをリセット", - "Bindings apply to this browser and device. Mod+Shift chords leave the terminal its keys; Record also takes other chords with Ctrl, Alt or (on a Mac) ⌘, exactly as pressed.": "ショートカットはこのブラウザーとデバイスに適用されます。Mod+Shiftの組み合わせはターミナルのキーを奪いません。記録ではCtrl、Alt、または(Macでは)⌘を使う他の組み合わせも押したとおりに保存できます。", - "Text selection in focused fields stays native; Tab/list keys are UI-local, not global shortcuts.": "フォーカス中の入力欄でのテキスト選択は標準動作のままです。Tabやリストのキーは UI 内でのみ使い、グローバルショートカットではありません。", - "The mobile key bar sends terminal keys, not app actions.": "モバイルのキー列はアプリ操作ではなく、端末にキーを送ります。", - "Your browser or operating system may intercept {keys}.": "ブラウザーや OS が {keys} を先に処理する場合があります。", - "Reserved": "予約済み", - "Already assigned": "割り当て済み", - "Send keys to terminal": "キーを端末に送る", - "Default": "既定", "Password or PIN": "パスワードまたは PIN", "Enter a single-line password or PIN.": "改行を含まないパスワードまたは PIN を入力してください。", "Update this PC to use masked input.": "伏せ字の入力欄を使うには、この PC のアプリを更新してください。", @@ -105,36 +98,6 @@ export const JA: Record = { "Sent directly to this terminal. Never saved as a draft or queued.": "このターミナルに直接送信します。下書きや送信待ちには保存しません。", // ---- settings ---- "Settings": "設定", - "Close settings": "設定を閉じる", - "Appearance": "外観", - "Theme": "テーマ", - "Dark": "ダーク", - "Light": "ライト", - "System": "システム", - "Dark theme": "ダークテーマ", - "Light theme": "ライトテーマ", - "Shown in dark mode": "ダークモードで表示されます", - "Shown in light mode": "ライトモードで表示されます", - "Charcoal": "チャコール", - "Codex": "Codex", - "Amber": "アンバー", - "Catppuccin": "Catppuccin", - "Catppuccin Latte": "Catppuccin Latte", - "Tokyo Night": "Tokyo Night", - "Tokyo Night Day": "Tokyo Night Day", - "Gruvbox": "Gruvbox", - "Gruvbox Light": "Gruvbox Light", - "One Dark": "One Dark", - "One Light": "One Light", - "Solarized": "Solarized", - "Solarized Light": "Solarized Light", - "Kanagawa": "Kanagawa", - "Kanagawa Lotus": "Kanagawa Lotus", - "Rosé Pine": "Rosé Pine", - "Rosé Pine Dawn": "Rosé Pine Dawn", - "Dracula": "Dracula", - "Nord": "Nord", - "Vesper": "Vesper", "Pin agent": "エージェントを固定", "Unpin agent": "エージェントの固定を解除", "Pin workspace": "ワークスペースを固定", @@ -142,72 +105,12 @@ export const JA: Record = { "Pinned": "固定済み", "Message from another session: {name}": "別のセッションからのメッセージ: {name}", "Message from another session": "別のセッションからのメッセージ", - "Density": "表示密度", - "Comfortable": "ゆったり", - "Compact": "コンパクト", - "Language": "言語", - "Follows the browser unless you choose one": "選択しない場合はブラウザーの言語に従います", - "Terminal font size": "ターミナルのフォントサイズ", - "Applied to every terminal pane": "すべてのターミナルペインに適用されます", - "Decrease terminal font size": "ターミナルの文字を小さく", - "Increase terminal font size": "ターミナルの文字を大きく", - "Wheel scroll speed": "ホイールのスクロール速度", - "How far one turn of the wheel scrolls the terminal": "ホイール1回でターミナルが動く量", - "Slower wheel scrolling": "ホイールスクロールを遅く", - "Faster wheel scrolling": "ホイールスクロールを速く", - "Terminal font": "ターミナルのフォント", - "Comma-separated, tried in order. A font this device does not have falls back to the default.": "カンマ区切りで、先頭から順に使います。このデバイスにないフォントは既定のフォントで表示します。", - "Composer": "入力欄", - "Enter sends": "Enter で送信", - "Return inserts a new line": "Return で改行", - "When on, use Send or hardware Mod+Enter to send.": "オンの場合は送信ボタン、またはハードウェアキーボードの Mod+Enter で送信します。", - "When off, Mod+Enter sends": "オフの場合は Mod+Enter で送信します", "Only the first {count} of {total} files were taken.": "{total} 個のファイルのうち先頭の {count} 個だけを受け取りました。", "Chat": "チャット", - "Panes open in": "ペインを開く表示", - "Every pane on this device. Switching a pane's lens keeps it there until this changes. Auto: chat for an agent on a touch screen, else the terminal.": "この端末のすべてのペインに適用されます。ペインで表示を切り替えると、この設定を変えるまでその表示で開きます。自動: タッチ画面のエージェントはチャット、それ以外はターミナル。", - "Auto": "自動", - "Show thinking": "思考を表示", - "Include the agent's reasoning blocks": "エージェントの推論ブロックも表示します", - "Chat width": "チャットの幅", - "How wide the conversation and the message box run on a large screen": "大きな画面で会話と入力欄が広がる幅", - "Narrow": "狭い", - "Wide": "広い", - "Full": "全幅", - "Chat font size": "チャットのフォントサイズ", - "Messages, code, prompt cards and the message box in the chat view": "チャット画面のメッセージ、コード、質問カード、入力欄", - "Decrease chat font size": "チャットの文字を小さく", - "Increase chat font size": "チャットの文字を大きく", - "Chat font": "チャットのフォント", - "Message text; code stays monospace. Comma-separated, tried in order. A font this device does not have falls back to the default.": "メッセージ本文に適用され、コードは等幅フォントのままです。カンマ区切りで、先頭から順に使います。このデバイスにないフォントは既定のフォントで表示します。", - "File viewer": "ファイルビューア", - "Wrap long lines": "長い行を折り返す", - "Markdown width": "Markdown の幅", - "Full width": "全幅", - "New agents": "新しいエージェント", - "Applies to agents started from New workspace, New tab and New worktree. Agent default adds no flag, so the agent's own configuration decides.": "新しいワークスペース、新しいタブ、新しいワークツリーから起動するエージェントに適用されます。エージェントの既定はフラグを付けないため、エージェント自身の設定に従います。", - "Permission mode": "権限モード", - "Sandbox and approvals": "サンドボックスと承認", "Agent default": "エージェントの既定", - "Accept edits": "編集を自動で許可", - "Don't ask": "確認しない", - "Bypass permissions": "権限確認をスキップ", - "Read only": "読み取り専用", - "Full access": "フルアクセス", "Show source": "ソースを表示", - "Shortcuts": "ショートカット", - "Phone": "スマートフォン", - "Devices": "デバイス", "Phone & devices": "スマートフォンとデバイス", - "Install": "インストール", - "Installed": "インストール済み", "Install app": "アプリをインストール", - "About": "情報", - "Star on GitHub": "GitHub で Star する", - "Remote PCs": "リモート PC", - "Connect another PC over an SSH alias or user@host. Its workspaces join the sidebar.": "SSH エイリアスまたは user@host で別の PC を接続します。接続した PC のワークスペースはサイドバーに並びます。", - "Update PC bridges automatically": "PC ブリッジを自動更新", - "When an app update needs a newer bridge, PCs that connect with their saved key are updated in the background. PCs that need a password ask first.": "アプリの更新で新しいブリッジが必要になった場合、保存済みのキーで接続する PC はバックグラウンドで更新されます。パスワードが必要な PC では先に確認します。", // ---- shortcuts (lib/shortcuts.ts labels) ---- "Command palette": "コマンドパレット", @@ -272,11 +175,7 @@ export const JA: Record = { "That link's workspace is closed": "そのリンクのワークスペースは閉じられています", "That link's PC is not set up here": "そのリンクの PC はここに設定されていません", "Command palette (⌘⇧K)": "コマンドパレット (⌘⇧K)", - "Sign out": "サインアウト", "Could not sign out. Try again.": "サインアウトできませんでした。もう一度お試しください。", - "Sign out of this browser?": "このブラウザーからサインアウトしますか?", - "Getting back in takes the access token, or a pairing code from the PC: Settings → Phone & devices there, or the pair command in its terminal.": "再び入るにはアクセストークンか、PC のペアリングコードが必要です。コードは PC の設定 → Phone & devices か、PC のターミナルの pair コマンドで表示されます。", - "Forget this browser's sign-in. Getting back in takes the access token or a pairing code.": "このブラウザーのサインインを消去します。再び入るにはアクセストークンかペアリングコードが必要です。", "Retry": "再試行", "Enable notifications": "通知を有効にする", "Notify me when a pane needs input or finishes": "ペインが入力を待っているときや完了したときに通知します", @@ -308,22 +207,6 @@ export const JA: Record = { "Reorder workspace {name}": "ワークスペース {name} を並べ替え", "Expand {name}": "{name} を展開", "Collapse {name}": "{name} を折りたたむ", - "Sidebar rows": "サイドバーの行", - "One line": "1 行", - "Two lines": "2 行", - "Agents order": "エージェントの並び順", - "Activity keeps a waiting agent on top, then the one that changed last; herdr's own order is not changed": "アクティビティ順では、応答待ちのエージェントを一番上に、その後は最近変化した順に並べます。herdr 自体の順序は変わりません", - "Workspaces": "ワークスペース順", - "Activity": "アクティビティ順", - "Agent logos": "エージェントのロゴ", - "Draw each agent's logo in its brand colors, or without color": "各エージェントのロゴをブランドの色、または色なしで表示します", - "Color": "カラー", - "Mono": "モノクロ", - "Status indicators": "状態インジケーター", - "Classic marks only the states that ask for a look; Dots and Symbols draw every state as herdr's TUI does": "クラシックは確認が必要な状態だけを示します。ドットと記号は herdr の TUI と同じくすべての状態を示します", - "Classic": "クラシック", - "Dots": "ドット", - "Symbols": "記号", "Drag to reorder · Alt+↑/↓": "ドラッグで並べ替え · Alt+↑/↓", "Resize sidebar": "サイドバーの幅を変更", "Resize file panel": "ファイルパネルの幅を変更", @@ -463,11 +346,6 @@ export const JA: Record = { "Running…": "実行中…", "{action} failed: {detail}": "{action} に失敗しました: {detail}", "{action} failed (exit code {code})": "{action} に失敗しました (終了コード {code})", - "herdr plugins": "herdr プラグイン", - "The command palette and its plugin actions are not available in the phone touch UI. Use a wider screen or a keyboard's command palette shortcut.": "スマートフォンのタッチUIでは、コマンドパレットとプラグインの操作は利用できません。より広い画面か、キーボードのコマンドパレット用ショートカットを使ってください。", - "No actions": "操作なし", - "Enabled": "有効", - "Disabled": "無効", "No matching panes or actions": "一致するペインや操作はありません", // ---- new workspace ---- @@ -654,28 +532,6 @@ export const JA: Record = { "Tilde": "チルダ", "Slash": "スラッシュ", "Control": "コントロール", - "Key bar": "キーバー", - "Edit key bar": "キーバーを編集", - "Back to settings": "設定に戻る", - "Keys, order and custom combinations for the terminal.": "ターミナルのキー、並び順、キーの組み合わせを設定します。", - "Choose the keys and their order under the terminal. The keyboard mode button stays first.": "ターミナルの下に表示するキーと順序を選びます。キーボードモードのボタンは先頭に固定されます。", - "Key bar keys": "キーバーのキー", - "Held modifier": "固定する修飾キー", - "Saved combination": "保存した組み合わせ", - "Remove {name}": "{name} を削除", - "No keys selected.": "キーが選択されていません。", - "Add key": "キーを追加", - "All keys added": "すべてのキーを追加済み", - "Held modifiers": "固定する修飾キー", - "Custom combination": "カスタムキーの組み合わせ", - "Saved combinations use only the selected modifiers. Other keys use held modifiers.": "保存した組み合わせには選択した修飾キーだけを使います。その他のキーには固定中の修飾キーが適用されます。", - "Base key": "基本キー", - "Single character": "1文字", - "Character": "文字", - "Combination modifiers": "組み合わせの修飾キー", - "Enter one character.": "1文字を入力してください。", - "Add combination": "組み合わせを追加", - "Already added": "追加済み", "Press {key}": "{key} を押す", // ---- prompt card ---- @@ -745,10 +601,6 @@ export const JA: Record = { "Attach files": "ファイルを添付", "Next turn": "次のターン", "Waits for Send now": "「今すぐ送信」で送信します", - "Send queued messages automatically": "送信待ちメッセージを自動で送信", - "A message sent while the agent works goes by itself when the turn ends. When off, it waits until you press Send now.": "エージェントの作業中に送ったメッセージは、ターンが終わると自動で送信されます。オフにすると、「今すぐ送信」を押すまで待ちます。", - "New tab button": "新しいタブボタン", - "A button in the message box opens New tab with an agent… on the pane's workspace. The tab menu offers it either way.": "入力欄のボタンで、このペインのワークスペースに「エージェント付きの新しいタブ…」を開きます。タブメニューからはいつでも開けます。", "Discard saved copy": "保存したコピーを破棄", "Update this PC to send messages in the next turn. Your draft stayed here.": "次のターンにメッセージを送るには、このPCを更新してください。入力したメッセージはここに残っています。", "Send now": "今すぐ送信", @@ -802,12 +654,6 @@ export const JA: Record = { "beginning of conversation": "会話の始まり", "Conversation unavailable — show terminal output": "会話を読み取れません。ターミナルの出力を表示", "Last checked {when}": "最終確認: {when}", - "Clipboard from a pane": "ペインからクリップボードへ", - "A program in a pane that copies (vim, tmux, Claude Code) puts its text on this device's clipboard, as a copy you made yourself would. Turn it off if a pane runs output you do not trust: it could replace what you paste next.": "ペインでコピーするプログラム(vim、tmux、Claude Code)は、自分でコピーしたときと同じようにこのデバイスのクリップボードにテキストを入れます。信頼できない出力を実行するペインがある場合はオフにしてください。次に貼り付ける内容が置き換えられることがあります。", - "Use alongside herdr's own window": "ターミナルの herdr と併用", - "Turn this on if this PC also shows herdr in a terminal window. A second after you switch to another window, this tab only watches the pane, so herdr's window keeps the pane at its own size instead of this window's. Click the tab to type again. While it watches, the pane is drawn at herdr's size and may not fill this window.": "この PC のターミナルウィンドウでも herdr を使うならオンにします。別のウィンドウに切り替えて 1 秒たつと、このタブはペインを表示するだけになり、herdr のウィンドウはペインをこのウィンドウではなく自分のサイズのまま保ちます。入力するにはタブをクリックしてください。表示中のペインは herdr のサイズで描かれるため、このウィンドウを埋めないことがあります。", - "Follow herdr's focus": "herdr のフォーカスに追従", - "When herdr moves to another pane, by a click in its window, a herdr command or a script, this device opens that pane too. Only on the PC open here, and only on this device.": "herdr が別のペインに移ると(herdr のウィンドウでのクリック、herdr コマンド、スクリプト)、このデバイスもそのペインを開きます。ここで開いている PC だけで、このデバイスだけに適用されます。", "What should {agent} do in {folder}?": "{folder} で {agent} に何を頼みますか?", "No conversation yet — say something below": "まだ会話はありません。下から話しかけてください", "terminal ended": "ターミナルが終了しました", @@ -869,44 +715,22 @@ export const JA: Record = { "Use the install icon in the address bar, or the browser menu's Install option.": "アドレスバーのインストールアイコン、またはブラウザーメニューのインストール項目を使用してください。", // ---- voice input ---- - "Without a key the browser recognizes the speech: Chrome and Edge send the audio to Google or Microsoft. Nothing is recorded until you press the mic.": "キーがない場合はブラウザが音声を認識します。Chrome と Edge は音声を Google または Microsoft に送信します。マイクを押すまで録音されません。", "The dictation does not fit in the box": "音声入力の内容が入力欄の上限を超えるため挿入しませんでした", "No speech was heard": "音声が聞こえませんでした", - "Drops fillers and fixes spacing; code and paths stay as spoken": "言いよどみを除き、スペースを整えます。コードとパスはそのまま残します", - "In chat": "チャット", - "Auto: in the chat on a desktop, where dictation can work. On: on a phone and in the terminal input line too.": "自動: デスクトップのチャットで、音声入力が使えるときだけ表示。オン: スマートフォンとターミナルの入力行にも表示。", - "On": "オン", - "In the terminal": "ターミナル", - "Off keeps a command exactly as transcribed": "オフにするとコマンドを書き起こしたまま残します", - "Tidy dictated text": "音声入力テキストを整える", "Add an OpenAI API key in Settings > Voice input": "設定 > 音声入力で OpenAI API キーを追加してください", - "Audio is sent to OpenAI with your key. Nothing is recorded until you press the mic.": "音声はあなたのキーを使って OpenAI に送信されます。マイクを押すまで録音されません。", "Cancel dictation": "音声入力をキャンセル", "Dictate (hold)": "音声入力(長押し)", "Insert dictation": "音声入力を挿入", - "Microphone button": "マイクボタン", "Microphone permission was denied": "マイクの使用が許可されませんでした", - "Dictation language": "音声入力の言語", - "Auto listens for the app's language, or for the browser's when the app is not translated into it": "自動ではアプリの言語を聞き取ります。ブラウザの言語にアプリが翻訳されていない場合は、ブラウザの言語を聞き取ります", - "Auto ({language})": "自動({language})", - "No OpenAI key: the browser's speech recognition is used": "OpenAI キーがないため、ブラウザーの音声認識を使用します", "No microphone found": "マイクが見つかりません", "No microphone input": "マイク入力がありません", - "OpenAI API key": "OpenAI API キー", - "OpenAI key saved on this PC": "OpenAI キーをこの PC に保存しました", - "OpenAI key set by OVIS_OPENAI_API_KEY": "OVIS_OPENAI_API_KEY で OpenAI キーが設定されています", "Ready…": "準備完了…", "Recording": "録音中", "Recording is too long": "録音が長すぎます", - "Remove key": "キーを削除", - "Save key": "キーを保存", "The OpenAI key was refused": "OpenAI キーが拒否されました", "This browser cannot record audio": "このブラウザーでは音声を録音できません", - "Tidy dictated text in chat": "チャットの音声入力テキストを整える", - "Tidy dictated text in the terminal": "ターミナルの音声入力テキストを整える", "Transcribing…": "文字起こし中…", "Transcription failed": "文字起こしに失敗しました", - "Voice input": "音声入力", "Voice input needs HTTPS": "音声入力には HTTPS が必要です", // ---- errors (lib/userError.ts) ---- "This browser is not signed in to this PC any more. Pair it again in Settings → Phone & devices.": "このブラウザーはもうこの PC にサインインしていません。設定 → スマートフォンとデバイスでもう一度ペアリングしてください。", @@ -930,8 +754,6 @@ export const JA: Record = { "Check your connection, then try again.": "接続を確認してからもう一度お試しください。", "Try again; if it keeps failing, restart Ovis on the PC.": "もう一度お試しください。失敗が続く場合は PC で Ovis を再起動してください。", "The server cannot save settings: check that its state folder is writable.": "サーバーが設定を保存できません。サーバーの状態フォルダーに書き込めるか確認してください。", - "Not saved on the server yet; reloading or closing this page can undo the change.": "まだサーバーに保存されていません。このページを再読み込みするか閉じると、変更が取り消されることがあります。", - "Sending the change to the server…": "変更をサーバーに送信しています…", // ---- sign-in ---- "Enter all 6 digits of the pairing code.": "ペアリングコードの 6 桁をすべて入力してください。", @@ -1018,10 +840,6 @@ export const JA: Record = { "…": "…", "Alerts": "通知", "Needs you": "応答が必要", - "Keep screen on": "画面をオンのままにする", - "While a terminal or chat pane is open.": "ターミナルやチャットのペインを開いている間、画面をオンに保ちます。", - "Needs HTTPS or localhost.": "HTTPS または localhost が必要です。", - "This browser can't keep the screen on.": "このブラウザーでは画面をオンに保てません。", "Test notification": "テスト通知", "Check whether this device can receive push alerts": "このデバイスでプッシュ通知を受け取れるか確認します", "Sending…": "送信中…", @@ -1034,30 +852,12 @@ export const JA: Record = { "Allow notifications to test alerts on this device.": "このデバイスで通知をテストするには、通知を許可してください。", "Could not send the test notification. Try again.": "テスト通知を送信できませんでした。もう一度お試しください。", "Turn alerts on again": "通知をもう一度オンにする", - "For this device. An alert waits a little first, and none comes when the pane changes meanwhile, as when you answer at the PC.": "このデバイスに適用されます。通知は少し待ってから送られ、その間に PC で回答するなどしてペインの状態が変わった場合は送られません。", "Needs input": "入力が必要", - "An agent waits for an answer or a permission": "エージェントが回答や許可を待っているとき", "Finished": "完了", - "Long turns: only work that took a minute or more": "長いターン: 1 分以上かかった作業のみ", - "Off": "オフ", - "Long turns": "長いターン", - "Every turn": "毎ターン", - "In the app": "アプリ内", - "While the app is open, these drop in from the top of the screen at once. Tap one to open its pane.": "アプリを開いている間は、画面の上からすぐに表示されます。タップするとそのペインを開きます。", - "Sound": "サウンド", - "While a tab of the app is open, it chimes for these alerts, also when a Focus or Do Not Disturb silences notifications.": "アプリのタブを開いている間は、これらの通知ごとに音を鳴らします。集中モードやおやすみモードで通知が消音されていても聞こえます。", "Open pane": "ペインを開く", "Quick replies": "クイック返信", - "One-tap messages above the message box, on this device. Each is sent as if typed: queued while the agent works, an answer when a question is open.": "メッセージ入力欄の上に表示されるワンタップのメッセージで、このデバイスに適用されます。入力したときと同じように送信され、エージェントの作業中はキューに入り、質問が開いているときは回答になります。", - "Quick reply {number}": "クイック返信 {number}", - "Remove quick reply {number}": "クイック返信 {number} を削除", - "Add reply": "返信を追加", - "Suggestion chip": "提案チップ", - "A chip above the message box puts the prompt Claude Code suggests next into the box. With a keyboard, Tab does it.": "入力欄の上のチップで、Claude Code が次に提案するプロンプトを入力欄に入れます。キーボードでは Tab で入れます。", "Use the suggestion": "提案を使う", "Send “{reply}”": "「{reply}」を送信", - "Show above the message box": "入力欄の上に表示", - "Restore defaults": "デフォルトに戻す", "Context {percent}% left": "コンテキスト残り {percent}%", "{used} of {window} tokens": "{used} / {window} トークン", "failed": "失敗", @@ -1249,22 +1049,6 @@ export const JA: Record = { "It is the last tab of {workspace}: the workspace closes with it, and the agents and shells in it stop.": "{workspace} の最後のタブです。ワークスペースも一緒に閉じ、その中のエージェントとシェルが停止します。", "Tabs of {workspace}": "{workspace} のタブ", "{n} panes": "{n} 個のペイン", - "Ovis sends anonymous usage counts.": "Ovis は匿名の利用集計を送信します。", - "What is sent": "送信内容", - "Anonymous usage counts": "匿名の利用集計", - "Turned off on this PC by OVIS_TELEMETRY=0, DO_NOT_TRACK or a CI environment.": "この PC では OVIS_TELEMETRY=0、DO_NOT_TRACK または CI 環境によりオフになっています。", - "Send anonymous usage counts": "匿名の利用集計を送る", - "Once on install and once per update, with the last browser's app settings, and once a day you open the app, with the kinds of coding agents running in herdr (such as claude or codex). Custom fonts, shortcuts and replies are reported only as customization flags or counts, never their text. Account identifiers, terminal content and files are excluded. The receiver stores the country, not the IP address.": "インストール時に 1 回、更新ごとに 1 回、最後に使用したブラウザーのアプリ設定とともに送信し、アプリを開いた日に 1 回、herdr で動いているコーディングエージェントの種類(claude や codex など)とともに送信します。カスタムフォント、ショートカット、返信は、内容そのものではなく、カスタマイズの有無を示すフラグまたは件数としてのみ報告されます。アカウント識別子、ターミナルの内容、ファイルは含まれません。受信側が保存するのは国であり、IP アドレスではありません。", - "Once a day you open the app:": "アプリを開いた日に 1 回:", - "The receiver adds the country this message comes from (two letters, such as KR). It does not store the address.": "受信側が、このメッセージの送信元の国(KR のような 2 文字)を付け加えます。アドレスは保存しません。", - "This version has already been counted. The next event is sent after an update.": "このバージョンは集計済みです。次の送信は更新の後です。", - "Agent integrations": "エージェント連携", - "This PC's bridge does not offer agent integrations yet. It will after its next runtime update.": "この PC のブリッジはまだエージェント連携に対応していません。次のランタイム更新後に利用できます。", - "herdr's integrations let it resume each agent's session after a restart. This page only reads them: run a command in a terminal on the PC herdr runs on, then reopen this page.": "herdr の連携があると、再起動後に各エージェントのセッションを再開できます。このページは状態を読むだけです。herdr が動いている PC のターミナルでコマンドを実行してから、このページを開き直してください。", - "Not found on this PC": "この PC には見つかりません", - "Installed, but older than this herdr: run this to update it": "インストール済みですが、この herdr より古い版です。このコマンドで更新してください", - "Not installed": "未インストール", - "Copy the command for {name}": "{name} のコマンドをコピー", "Clear pane name": "ペイン名をクリア", "Swap with focused pane": "フォーカス中のペインと入れ替え", "Pane actions for {name}": "{name}のペインメニュー", @@ -1278,7 +1062,6 @@ export const JA: Record = { "Expand": "展開", "Shell": "シェル", "Settings (⌘⇧,)": "設定 (⌘⇧,)", - "Name each workspace on one line, or show what its agent is doing with the workspace under it": "ワークスペース名だけを 1 行で表示するか、エージェントの作業を上に、ワークスペースを下に表示します", "The computer this app runs on": "このアプリが動作しているコンピューター", "Host": "ホスト", "Move tab left": "タブを左に移動", @@ -1298,7 +1081,6 @@ export const JA: Record = { "Copy details": "詳細をコピー", "This pane can't be shown.": "このペインを表示できません。", "The sidebar can't be shown.": "サイドバーを表示できません。", - "Settings can't be shown.": "設定を表示できません。", "Show": "表示", "Changes": "変更", "Changed files": "変更されたファイル", @@ -1338,16 +1120,8 @@ export const JA: Record = { "Changes to {name}": "{name} の変更", "Close diff": "差分を閉じる", "Diff layout": "差分の表示形式", - "Open files": "ファイルを開く", - "On a wide window, text and code can open beside the pane. Media, PDFs and folders always open in a popup, and the viewer's header button moves the file open now.": "広いウィンドウでは、テキストとコードをペインの横に開けます。メディア、PDF、フォルダーは常にポップアップで開き、ビューアー上部のボタンで今開いているファイルを移動できます。", - "In a popup": "ポップアップで", - "Web links": "Web リンク", - "Only a page this PC serves, such as a dev server on localhost, opens beside the pane. Shift-click opens it the other way.": "localhost の開発サーバーなど、この PC が配信するページだけがペインの横に開きます。Shift キーを押しながらクリックすると、もう一方で開きます。", - "Beside the pane": "ペインの横", - "In a new tab": "新しいタブ", "Unified": "1列", "Split": "並べて表示", - "A phone shows one column either way.": "スマートフォンではどちらでも1列で表示します。", "Split view needs a wider screen": "並べて表示にはもっと広い画面が必要です", "Split view needs a wider screen; showing one column.": "並べて表示にはもっと広い画面が必要なため、1列で表示しています。", "Fold context": "周辺行をたたむ", @@ -1375,58 +1149,14 @@ export const JA: Record = { "Copy path": "パスをコピー", "Path copied": "パスをコピーしました", "Path": "パス", - "theme themes palette dark light mode colors density language sidebar logos": "テーマ パレット palette ダーク ライト モード 色 密度 言語 サイドバー ロゴ", - "chat font size message width composer enter send thinking code": "チャット フォント 文字サイズ メッセージ 幅 入力欄 エンター 送信 思考 コード", - "terminal font size key bar keyboard clipboard": "ターミナル フォント 文字サイズ キーバー キーボード クリップボード", - "notifications sound push bell needs input finished": "通知 サウンド プッシュ ベル 入力待ち 完了", - "dictation microphone speech openai": "音声入力 マイク 音声 openai", - "plan limits quota meters": "プラン 上限 クォータ メーター", - "keyboard keys bindings hotkeys": "キーボード キー ショートカット キー割り当て", - "phone install keep screen on app": "スマホ インストール 画面オン維持 アプリ", - "machines computers ssh bridge plugins": "マシン コンピューター ssh ブリッジ プラグイン", - "agents hooks claude codex": "エージェント フック claude codex", - "version update release herdr": "バージョン アップデート リリース herdr", - "create workspace session start": "作成 ワークスペース セッション 開始", - "create tab add": "作成 タブ 追加", - "divide pane layout side": "分割 ペイン レイアウト 横", - "divide pane layout below": "分割 ペイン レイアウト 下", - "maximize fullscreen full screen focus": "最大化 フルスクリーン 全画面 フォーカス", - "lens chat terminal conversation": "表示 チャット ターミナル 会話", - "panel drawer hide show": "パネル ドロワー 非表示 表示", - "dark light mode appearance colors": "ダーク ライト モード 外観 色", - "preferences options config": "環境設定 オプション 設定", - "remote machine computer connect ssh": "リモート マシン コンピューター 接続 ssh", - "alerts push bell": "アラート プッシュ ベル", - "logout log out lock": "ログアウト ロック", - "folder explorer open file": "フォルダ エクスプローラー ファイルを開く", - "reload update sync": "再読み込み 更新 同期", - "Search shortcuts": "ショートカットを検索", - "No shortcuts match.": "一致するショートカットはありません。", - "Record": "記録", - "Press keys…": "キーを押してください…", - "Record shortcut for {name}": "{name}のショートカットを記録", - "Press the new shortcut, or Escape to cancel.": "新しいショートカットを押すか、Escapeでキャンセルします。", - "Hold ⌘, Ctrl or ⌥, with or without Shift, and press a key.": "⌘、Ctrl、または⌥を(Shiftの有無にかかわらず)押したままキーを押してください。", - "Hold Ctrl or Alt, with or without Shift, and press a key.": "CtrlまたはAltを(Shiftの有無にかかわらず)押したままキーを押してください。", - "{keys} is a terminal key: shells, editors and agents use it. Once saved, it no longer reaches the pane.": "{keys}はターミナルのキーで、シェル、エディター、エージェントが使います。保存すると、ペインには届かなくなります。", - "Save anyway": "このまま保存", - "That key cannot be a shortcut.": "このキーはショートカットにできません。", - "Your browser or operating system keeps that shortcut.": "このショートカットはブラウザまたはOSが使用します。", "Browse folders": "フォルダを参照", - "Browse installed fonts for {label}": "{label}にインストール済みのフォントを参照", "Collapse all folders": "すべてのフォルダを折りたたむ", "Dismiss notice": "通知を閉じる", "Expand all folders": "すべてのフォルダを展開", "Folders": "フォルダ", - "Installed fonts": "インストール済みのフォント", - "Installed fonts could not be listed. Type the name instead.": "インストール済みのフォントを一覧表示できませんでした。名前を直接入力してください。", - "No fonts found": "フォントが見つかりません", "Notices": "お知らせ", "Open in Files": "ファイルで開く", "Pinned folders": "固定したフォルダ", - "Search fonts": "フォントを検索", - "Showing the first {count} fonts. Search to narrow the list.": "最初の {count} 件のフォントを表示しています。検索して絞り込めます。", - "{font} is not monospace. The terminal needs a fixed-width font, so the current font was kept.": "{font} は等幅フォントではありません。ターミナルには等幅フォントが必要なため、現在のフォントを維持しました。", // t3code ports (d) "Image viewer": "画像ビューア", "Copy image": "画像をコピー", @@ -1434,11 +1164,6 @@ export const JA: Record = { "Next image": "次の画像", "{n} of {count}": "{count} 枚中 {n} 枚目", "Couldn't copy the image. Download it instead.": "画像をコピーできませんでした。代わりにダウンロードしてください。", - "Typography": "タイポグラフィ", - "Interface font size": "インターフェースの文字サイズ", - "Menus, lists, dialogs and the sidebar. The chat follows it until it has a size of its own; the terminal keeps its own.": "メニュー、リスト、ダイアログ、サイドバーに適用されます。チャットは独自のサイズを設定するまでこれに従い、ターミナルは独自のサイズを保ちます。", - "Decrease interface font size": "インターフェースの文字サイズを小さく", - "Increase interface font size": "インターフェースの文字サイズを大きく", "Working folder": "作業フォルダ", "Worktree": "ワークツリー", "Browse folders in the palette": "パレットでフォルダを参照", @@ -1446,6 +1171,12 @@ export const JA: Record = { "Go to turn {n}": "ターン {n} へ移動", "Show full message": "メッセージ全体を表示", "Change PC": "PCを切り替え", - "This is the demo. Go back to the app's list of PCs to open yours.": "これはデモです。アプリのPC一覧に戻って、ご自分のPCを開いてください。", - "This app shows {address}. Go back to its list of PCs to open another.": "このアプリは {address} を表示しています。PC一覧に戻ると別のPCを開けます。", }; + +/** The parts JA is made of; src/lib/i18n.test.ts fails when a key is in two parts, since a spread keeps only the last. */ +export const JA_PARTS: Record> = { + base: BASE, + settings: SETTINGS_JA, +}; + +export const JA: Record = Object.assign({}, ...Object.values(JA_PARTS)); diff --git a/src/lib/i18n.ko.ts b/src/lib/i18n.ko.ts index 19219f1f47..3b83d8799b 100644 --- a/src/lib/i18n.ko.ts +++ b/src/lib/i18n.ko.ts @@ -1,11 +1,15 @@ +import { SETTINGS_KO } from "./i18n/settings.ko.ts"; + /** - * Korean for every `t("…")` in src/. The English string is the key. Grouped by where the text + * Korean for every `t("…")` in src/ that no part in lib/i18n/ holds: keys more than one feature + * uses, and the app shell's. KO at the end is this and the parts together. The English string is + * the key. Grouped by where the text * shows; within a group, roughly in the order it appears. Register: labels and buttons as nouns * or ~하기, sentences in 합니다체. Fixed terms: 패널, 워크스페이스, 에이전트, 터미널, 채팅, 페어링, * 기기; product names (herdr, Tailscale, Codex, Claude Code) stay as they are. Placeholders in * braces keep their English names. */ -export const KO: Record = { +const BASE: Record = { "Could not load sign-in options": "로그인 방법을 불러오지 못했습니다", "On the server PC": "서버 PC에서 로그인", "Install {cli} on the server PC first.": "먼저 서버 PC에 {cli}를 설치하세요.", @@ -84,18 +88,7 @@ export const KO: Record = { "Waiting for terminal input…": "터미널 입력 준비 중…", "Paused while you use another window": "다른 창을 쓰는 동안 일시 정지됨", "View only while you use another window · click to type": "다른 창을 쓰는 동안 보기 전용 · 클릭하면 입력", - "Direct typing": "직접 입력", "Input line": "입력창", - "Terminal input mode": "터미널 입력 방식", - "Reset shortcuts": "단축키 초기화", - "Bindings apply to this browser and device. Mod+Shift chords leave the terminal its keys; Record also takes other chords with Ctrl, Alt or (on a Mac) ⌘, exactly as pressed.": "단축키는 이 브라우저와 기기에 적용됩니다. Mod+Shift 조합은 터미널 키를 그대로 남겨 두며, 기록 기능으로는 Ctrl, Alt 또는 (Mac에서는) ⌘를 쓰는 다른 조합도 누른 그대로 저장할 수 있습니다.", - "Text selection in focused fields stays native; Tab/list keys are UI-local, not global shortcuts.": "포커스된 입력란의 텍스트 선택은 기본 동작을 따릅니다. Tab/목록 키는 UI 안에서만 작동하며 전역 단축키가 아닙니다.", - "The mobile key bar sends terminal keys, not app actions.": "모바일 키 바는 앱 동작이 아닌 터미널 키를 보냅니다.", - "Your browser or operating system may intercept {keys}.": "브라우저나 운영체제가 {keys} 입력을 가로챌 수 있습니다.", - "Reserved": "예약됨", - "Already assigned": "이미 지정됨", - "Send keys to terminal": "키를 터미널로 전달", - "Default": "기본값", "Password or PIN": "비밀번호 또는 PIN", "Enter a single-line password or PIN.": "한 줄의 비밀번호 또는 PIN을 입력하세요.", "Update this PC to use masked input.": "비밀번호 입력창을 사용하려면 이 PC의 앱을 업데이트하세요.", @@ -103,36 +96,6 @@ export const KO: Record = { "Sent directly to this terminal. Never saved as a draft or queued.": "이 터미널로 바로 보냅니다. 초안이나 전송 대기열에 저장하지 않습니다.", // ---- settings ---- "Settings": "설정", - "Close settings": "설정 닫기", - "Appearance": "모양", - "Theme": "테마", - "Dark": "어둡게", - "Light": "밝게", - "System": "시스템", - "Dark theme": "다크 테마", - "Light theme": "라이트 테마", - "Shown in dark mode": "다크 모드에서 표시됩니다", - "Shown in light mode": "라이트 모드에서 표시됩니다", - "Charcoal": "차콜", - "Codex": "Codex", - "Amber": "앰버", - "Catppuccin": "Catppuccin", - "Catppuccin Latte": "Catppuccin Latte", - "Tokyo Night": "Tokyo Night", - "Tokyo Night Day": "Tokyo Night Day", - "Gruvbox": "Gruvbox", - "Gruvbox Light": "Gruvbox Light", - "One Dark": "One Dark", - "One Light": "One Light", - "Solarized": "Solarized", - "Solarized Light": "Solarized Light", - "Kanagawa": "Kanagawa", - "Kanagawa Lotus": "Kanagawa Lotus", - "Rosé Pine": "Rosé Pine", - "Rosé Pine Dawn": "Rosé Pine Dawn", - "Dracula": "Dracula", - "Nord": "Nord", - "Vesper": "Vesper", "Pin agent": "에이전트 고정", "Unpin agent": "에이전트 고정 해제", "Pin workspace": "워크스페이스 고정", @@ -140,72 +103,12 @@ export const KO: Record = { "Pinned": "고정됨", "Message from another session: {name}": "다른 세션에서 온 메시지: {name}", "Message from another session": "다른 세션에서 온 메시지", - "Density": "밀도", - "Comfortable": "여유", - "Compact": "촘촘", - "Language": "언어", - "Follows the browser unless you choose one": "따로 고르지 않으면 브라우저 언어를 따릅니다", - "Terminal font size": "터미널 글자 크기", - "Applied to every terminal pane": "모든 터미널 패널에 적용됩니다", - "Decrease terminal font size": "터미널 글자 작게", - "Increase terminal font size": "터미널 글자 크게", - "Wheel scroll speed": "휠 스크롤 속도", - "How far one turn of the wheel scrolls the terminal": "휠을 한 번 굴릴 때 터미널이 움직이는 정도", - "Slower wheel scrolling": "휠 스크롤 느리게", - "Faster wheel scrolling": "휠 스크롤 빠르게", - "Terminal font": "터미널 글꼴", - "Comma-separated, tried in order. A font this device does not have falls back to the default.": "쉼표로 구분하며 앞에서부터 차례로 사용합니다. 이 기기에 없는 글꼴은 기본 글꼴로 대체합니다.", - "Composer": "입력창", - "Enter sends": "Enter로 보내기", - "Return inserts a new line": "Return으로 줄바꿈", - "When on, use Send or hardware Mod+Enter to send.": "켜면 전송 버튼이나 하드웨어 키보드의 Mod+Enter로 전송합니다.", - "When off, Mod+Enter sends": "끄면 Mod+Enter로 보냅니다", "Only the first {count} of {total} files were taken.": "파일 {total}개 중 앞의 {count}개만 가져왔습니다.", "Chat": "채팅", - "Panes open in": "패널 기본 화면", - "Every pane on this device. Switching a pane's lens keeps it there until this changes. Auto: chat for an agent on a touch screen, else the terminal.": "이 기기의 모든 패널에 적용됩니다. 패널에서 화면을 바꾸면 이 설정을 다시 바꿀 때까지 그 화면으로 열립니다. 자동: 터치 화면의 에이전트는 채팅, 그 밖에는 터미널.", - "Auto": "자동", - "Show thinking": "생각 표시", - "Include the agent's reasoning blocks": "에이전트의 추론 블록을 함께 보여줍니다", - "Chat width": "채팅 너비", - "How wide the conversation and the message box run on a large screen": "큰 화면에서 대화와 입력창이 차지하는 너비", - "Narrow": "좁게", - "Wide": "넓게", - "Full": "전체", - "Chat font size": "채팅 글자 크기", - "Messages, code, prompt cards and the message box in the chat view": "채팅 화면의 메시지, 코드, 프롬프트 카드, 입력창", - "Decrease chat font size": "채팅 글자 작게", - "Increase chat font size": "채팅 글자 크게", - "Chat font": "채팅 글꼴", - "Message text; code stays monospace. Comma-separated, tried in order. A font this device does not have falls back to the default.": "메시지 본문에 적용되며 코드는 고정폭 글꼴을 유지합니다. 쉼표로 구분하며 앞에서부터 차례로 사용합니다. 이 기기에 없는 글꼴은 기본 글꼴로 대체합니다.", - "File viewer": "파일 뷰어", - "Wrap long lines": "긴 줄 바꿈", - "Markdown width": "Markdown 너비", - "Full width": "전체 너비", - "New agents": "새 에이전트", - "Applies to agents started from New workspace, New tab and New worktree. Agent default adds no flag, so the agent's own configuration decides.": "새 워크스페이스, 새 탭, 새 워크트리에서 시작하는 에이전트에 적용됩니다. 에이전트 기본값은 플래그를 붙이지 않으므로 에이전트 자체 설정을 따릅니다.", - "Permission mode": "권한 모드", - "Sandbox and approvals": "샌드박스와 승인", "Agent default": "에이전트 기본값", - "Accept edits": "편집 자동 허용", - "Don't ask": "묻지 않기", - "Bypass permissions": "권한 확인 건너뛰기", - "Read only": "읽기 전용", - "Full access": "전체 권한", "Show source": "소스 보기", - "Shortcuts": "단축키", - "Phone": "폰", - "Devices": "기기", "Phone & devices": "폰 및 기기", - "Install": "설치", - "Installed": "설치됨", "Install app": "앱 설치", - "About": "정보", - "Star on GitHub": "GitHub에서 Star 누르기", - "Remote PCs": "원격 PC", - "Connect another PC over an SSH alias or user@host. Its workspaces join the sidebar.": "SSH 별칭이나 user@host로 다른 PC를 연결합니다. 연결한 PC의 워크스페이스는 사이드바에 함께 보입니다.", - "Update PC bridges automatically": "PC 브리지 자동 업데이트", - "When an app update needs a newer bridge, PCs that connect with their saved key are updated in the background. PCs that need a password ask first.": "앱 업데이트에 새 브리지가 필요하면, 저장된 키로 연결되는 PC는 뒤에서 업데이트됩니다. 비밀번호가 필요한 PC는 먼저 묻습니다.", // ---- shortcuts (lib/shortcuts.ts labels) ---- "Command palette": "명령 팔레트", @@ -270,11 +173,7 @@ export const KO: Record = { "That link's workspace is closed": "그 링크의 워크스페이스는 닫혔습니다", "That link's PC is not set up here": "그 링크의 PC는 여기에 설정되어 있지 않습니다", "Command palette (⌘⇧K)": "명령 팔레트 (⌘⇧K)", - "Sign out": "로그아웃", "Could not sign out. Try again.": "로그아웃하지 못했습니다. 다시 시도해 주세요.", - "Sign out of this browser?": "이 브라우저에서 로그아웃할까요?", - "Getting back in takes the access token, or a pairing code from the PC: Settings → Phone & devices there, or the pair command in its terminal.": "다시 들어오려면 액세스 토큰이나 PC의 페어링 코드가 필요합니다. 코드는 PC의 설정 → Phone & devices나 PC 터미널의 pair 명령에서 받습니다.", - "Forget this browser's sign-in. Getting back in takes the access token or a pairing code.": "이 브라우저의 로그인을 지웁니다. 다시 들어오려면 액세스 토큰이나 페어링 코드가 필요합니다.", "Retry": "다시 시도", "Enable notifications": "알림 켜기", "Notify me when a pane needs input or finishes": "패널이 입력을 기다리거나 끝나면 알려줍니다", @@ -306,22 +205,6 @@ export const KO: Record = { "Reorder workspace {name}": "워크스페이스 {name} 순서 바꾸기", "Expand {name}": "{name} 펼치기", "Collapse {name}": "{name} 접기", - "Sidebar rows": "사이드바 행", - "One line": "한 줄", - "Two lines": "두 줄", - "Agents order": "에이전트 정렬", - "Activity keeps a waiting agent on top, then the one that changed last; herdr's own order is not changed": "활동순은 응답을 기다리는 에이전트를 맨 위에 두고, 그다음 가장 최근에 바뀐 순서로 놓습니다. herdr 자체의 순서는 바뀌지 않습니다", - "Workspaces": "워크스페이스순", - "Activity": "활동순", - "Agent logos": "에이전트 로고", - "Draw each agent's logo in its brand colors, or without color": "각 에이전트의 로고를 브랜드 색상 또는 색 없이 표시합니다", - "Color": "색상", - "Mono": "단색", - "Status indicators": "상태 표시", - "Classic marks only the states that ask for a look; Dots and Symbols draw every state as herdr's TUI does": "기본은 확인이 필요한 상태만 표시합니다. 점과 기호는 herdr TUI처럼 모든 상태를 표시합니다", - "Classic": "기본", - "Dots": "점", - "Symbols": "기호", "Drag to reorder · Alt+↑/↓": "끌어서 순서 바꾸기 · Alt+↑/↓", "Resize sidebar": "사이드바 너비 조절", "Resize file panel": "파일 패널 너비 조절", @@ -461,11 +344,6 @@ export const KO: Record = { "Running…": "실행 중…", "{action} failed: {detail}": "{action} 실패: {detail}", "{action} failed (exit code {code})": "{action} 실패 (종료 코드 {code})", - "herdr plugins": "herdr 플러그인", - "The command palette and its plugin actions are not available in the phone touch UI. Use a wider screen or a keyboard's command palette shortcut.": "휴대전화 터치 UI에서는 명령 팔레트와 플러그인 동작을 사용할 수 없습니다. 더 넓은 화면이나 키보드의 명령 팔레트 단축키를 사용하세요.", - "No actions": "동작 없음", - "Enabled": "사용 중", - "Disabled": "사용 안 함", "No matching panes or actions": "일치하는 패널이나 동작이 없습니다", // ---- new workspace ---- @@ -652,28 +530,6 @@ export const KO: Record = { "Tilde": "물결표", "Slash": "슬래시", "Control": "컨트롤", - "Key bar": "키 바", - "Edit key bar": "키 바 편집", - "Back to settings": "설정으로 돌아가기", - "Keys, order and custom combinations for the terminal.": "터미널 키와 순서, 사용자 조합을 설정합니다.", - "Choose the keys and their order under the terminal. The keyboard mode button stays first.": "터미널 아래에 표시할 키와 순서를 고릅니다. 키보드 모드 버튼은 맨 앞에 유지됩니다.", - "Key bar keys": "키 바의 키", - "Held modifier": "고정 보조 키", - "Saved combination": "저장된 조합", - "Remove {name}": "{name} 제거", - "No keys selected.": "선택한 키가 없습니다.", - "Add key": "키 추가", - "All keys added": "모든 키가 추가됨", - "Held modifiers": "고정 보조 키", - "Custom combination": "사용자 키 조합", - "Saved combinations use only the selected modifiers. Other keys use held modifiers.": "저장된 조합은 선택한 보조 키만 사용합니다. 나머지 키에는 고정한 보조 키가 적용됩니다.", - "Base key": "기본 키", - "Single character": "한 글자", - "Character": "문자", - "Combination modifiers": "조합에 사용할 보조 키", - "Enter one character.": "한 글자를 입력하세요.", - "Add combination": "조합 추가", - "Already added": "이미 추가됨", "Press {key}": "{key} 누르기", // ---- prompt card ---- @@ -743,10 +599,6 @@ export const KO: Record = { "Attach files": "파일 첨부", "Next turn": "다음 차례", "Waits for Send now": "지금 보내기를 누르면 보냅니다", - "Send queued messages automatically": "대기 메시지 자동 전송", - "A message sent while the agent works goes by itself when the turn ends. When off, it waits until you press Send now.": "에이전트가 작업 중일 때 보낸 메시지는 턴이 끝나면 저절로 전송됩니다. 끄면 지금 보내기를 누를 때까지 기다립니다.", - "New tab button": "새 탭 버튼", - "A button in the message box opens New tab with an agent… on the pane's workspace. The tab menu offers it either way.": "입력창의 버튼으로 이 패널의 워크스페이스에 에이전트와 함께 새 탭…을 엽니다. 탭 메뉴에서는 언제든 열 수 있습니다.", "Discard saved copy": "저장된 사본 버리기", "Update this PC to send messages in the next turn. Your draft stayed here.": "다음 차례에 메시지를 보내려면 이 PC를 업데이트하세요. 작성한 메시지는 여기에 남아 있습니다.", "Send now": "지금 보내기", @@ -800,12 +652,6 @@ export const KO: Record = { "beginning of conversation": "대화의 시작", "Conversation unavailable — show terminal output": "대화를 읽을 수 없습니다. 터미널 출력 보기", "Last checked {when}": "마지막 확인: {when}", - "Clipboard from a pane": "패널에서 클립보드로 복사", - "A program in a pane that copies (vim, tmux, Claude Code) puts its text on this device's clipboard, as a copy you made yourself would. Turn it off if a pane runs output you do not trust: it could replace what you paste next.": "패널에서 복사하는 프로그램(vim, tmux, Claude Code)은 직접 복사한 것과 같이 이 기기의 클립보드에 텍스트를 넣습니다. 믿을 수 없는 출력을 실행하는 패널이 있다면 끄세요. 다음에 붙여 넣을 내용이 바뀔 수 있습니다.", - "Use alongside herdr's own window": "터미널의 herdr와 같이 쓰기", - "Turn this on if this PC also shows herdr in a terminal window. A second after you switch to another window, this tab only watches the pane, so herdr's window keeps the pane at its own size instead of this window's. Click the tab to type again. While it watches, the pane is drawn at herdr's size and may not fill this window.": "이 PC의 터미널 창에서도 herdr를 띄워 쓴다면 켜세요. 다른 창으로 옮기고 1초가 지나면 이 탭은 패널을 보기만 해서, herdr 창이 패널을 이 창 크기가 아닌 자기 크기로 유지합니다. 다시 입력하려면 탭을 클릭하세요. 보는 동안 패널은 herdr 크기로 그려져 이 창을 다 채우지 않을 수 있습니다.", - "Follow herdr's focus": "herdr 포커스 따라가기", - "When herdr moves to another pane, by a click in its window, a herdr command or a script, this device opens that pane too. Only on the PC open here, and only on this device.": "herdr가 다른 패널로 옮겨 가면(herdr 창에서 클릭, herdr 명령, 스크립트) 이 기기도 그 패널을 엽니다. 여기서 연 PC에서만, 이 기기에서만 적용됩니다.", "What should {agent} do in {folder}?": "{folder}에서 {agent}에게 무엇을 맡길까요?", "No conversation yet — say something below": "아직 대화가 없습니다. 아래에 말을 걸어 보세요", "terminal ended": "터미널 종료됨", @@ -867,44 +713,22 @@ export const KO: Record = { "Use the install icon in the address bar, or the browser menu's Install option.": "주소창의 설치 아이콘이나 브라우저 메뉴의 설치 항목을 쓰세요.", // ---- voice input ---- - "Without a key the browser recognizes the speech: Chrome and Edge send the audio to Google or Microsoft. Nothing is recorded until you press the mic.": "키가 없으면 브라우저가 음성을 인식합니다. Chrome과 Edge는 오디오를 Google이나 Microsoft로 보냅니다. 마이크를 누르기 전에는 녹음되지 않습니다.", "The dictation does not fit in the box": "받아쓴 내용이 입력창 한도를 넘어 넣지 않았습니다", "No speech was heard": "말소리가 들리지 않았습니다", - "Drops fillers and fixes spacing; code and paths stay as spoken": "군말을 지우고 띄어쓰기를 고칩니다. 코드와 경로는 말한 그대로 둡니다", - "In chat": "채팅", - "Auto: in the chat on a desktop, where dictation can work. On: on a phone and in the terminal input line too.": "자동: 데스크톱 채팅에서 받아쓰기가 가능할 때만 표시. 켜기: 휴대폰과 터미널 입력줄에도 표시.", - "On": "켜기", - "In the terminal": "터미널", - "Off keeps a command exactly as transcribed": "끄면 명령을 받아쓴 그대로 둡니다", - "Tidy dictated text": "받아쓴 텍스트 다듬기", "Add an OpenAI API key in Settings > Voice input": "설정 > 음성 입력에서 OpenAI API 키를 추가하세요", - "Audio is sent to OpenAI with your key. Nothing is recorded until you press the mic.": "오디오가 사용자의 키로 OpenAI에 전송됩니다. 마이크를 누르기 전에는 녹음되지 않습니다.", "Cancel dictation": "받아쓰기 취소", "Dictate (hold)": "받아쓰기 (길게 누르기)", "Insert dictation": "받아쓰기 내용 삽입", - "Microphone button": "마이크 버튼", "Microphone permission was denied": "마이크 권한이 거부되었습니다", - "Dictation language": "받아쓰기 언어", - "Auto listens for the app's language, or for the browser's when the app is not translated into it": "자동은 앱 언어로 듣고, 앱이 브라우저 언어로 번역되어 있지 않으면 브라우저 언어로 듣습니다", - "Auto ({language})": "자동 ({language})", - "No OpenAI key: the browser's speech recognition is used": "OpenAI 키가 없어 브라우저의 음성 인식을 사용합니다", "No microphone found": "마이크를 찾을 수 없습니다", "No microphone input": "마이크 입력 없음", - "OpenAI API key": "OpenAI API 키", - "OpenAI key saved on this PC": "OpenAI 키가 이 PC에 저장되었습니다", - "OpenAI key set by OVIS_OPENAI_API_KEY": "OVIS_OPENAI_API_KEY 환경 변수에 OpenAI 키가 설정되어 있습니다", "Ready…": "준비…", "Recording": "녹음 중", "Recording is too long": "녹음이 너무 깁니다", - "Remove key": "키 삭제", - "Save key": "키 저장", "The OpenAI key was refused": "OpenAI 키가 거부되었습니다", "This browser cannot record audio": "이 브라우저에서는 오디오를 녹음할 수 없습니다", - "Tidy dictated text in chat": "채팅 받아쓰기 텍스트 다듬기", - "Tidy dictated text in the terminal": "터미널 받아쓰기 텍스트 다듬기", "Transcribing…": "음성 변환 중…", "Transcription failed": "음성 변환에 실패했습니다", - "Voice input": "음성 입력", "Voice input needs HTTPS": "음성 입력에는 HTTPS가 필요합니다", // ---- errors (lib/userError.ts) ---- "This browser is not signed in to this PC any more. Pair it again in Settings → Phone & devices.": "이 브라우저는 더 이상 이 PC에 로그인되어 있지 않습니다. 설정 → 폰 및 기기에서 다시 페어링하세요.", @@ -928,8 +752,6 @@ export const KO: Record = { "Check your connection, then try again.": "연결을 확인한 뒤 다시 시도하세요.", "Try again; if it keeps failing, restart Ovis on the PC.": "다시 시도하고, 계속 실패하면 PC에서 Ovis를 다시 시작하세요.", "The server cannot save settings: check that its state folder is writable.": "서버가 설정을 저장할 수 없습니다. 서버의 상태 폴더에 쓸 수 있는지 확인하세요.", - "Not saved on the server yet; reloading or closing this page can undo the change.": "서버에\u00a0아직 저장되지\u00a0않았습니다. 이\u00a0페이지를 새로\u00a0고치거나\u00a0닫으면 변경이\u00a0취소될\u00a0수\u00a0있습니다.", - "Sending the change to the server…": "변경을 서버로\u00a0보내는\u00a0중…", // ---- sign-in ---- "Enter all 6 digits of the pairing code.": "페어링 코드 6자리를 모두 입력하세요.", @@ -1016,10 +838,6 @@ export const KO: Record = { "…": "…", "Alerts": "알림", "Needs you": "내 응답 필요", - "Keep screen on": "화면 켜짐 유지", - "While a terminal or chat pane is open.": "터미널이나 채팅 패널을 보는 동안 화면을 켜 둡니다.", - "Needs HTTPS or localhost.": "HTTPS 또는 localhost가 필요합니다.", - "This browser can't keep the screen on.": "이 브라우저는 화면을 켜 둘 수 없습니다.", "Test notification": "테스트 알림", "Check whether this device can receive push alerts": "이 기기가 푸시 알림을 받을 수 있는지 확인합니다", "Sending…": "보내는 중…", @@ -1032,30 +850,12 @@ export const KO: Record = { "Allow notifications to test alerts on this device.": "이 기기에서 알림을 테스트하려면 알림을 허용하세요.", "Could not send the test notification. Try again.": "테스트 알림을 보내지 못했습니다. 다시 시도하세요.", "Turn alerts on again": "알림 다시 켜기", - "For this device. An alert waits a little first, and none comes when the pane changes meanwhile, as when you answer at the PC.": "이 기기에 적용됩니다. 알림은 잠시 기다렸다가 보내며, 그사이 PC에서 답하는 등 pane 상태가 바뀌면 보내지 않습니다.", "Needs input": "입력 필요", - "An agent waits for an answer or a permission": "에이전트가 답이나 권한을 기다릴 때", "Finished": "작업 완료", - "Long turns: only work that took a minute or more": "긴 작업: 1분 이상 걸린 작업만", - "Off": "끄기", - "Long turns": "긴 작업", - "Every turn": "매번", - "In the app": "앱 안에서", - "While the app is open, these drop in from the top of the screen at once. Tap one to open its pane.": "앱을 열어 둔 동안에는 화면 위에서 바로 내려옵니다. 누르면 그 패널을 엽니다.", - "Sound": "소리", - "While a tab of the app is open, it chimes for these alerts, also when a Focus or Do Not Disturb silences notifications.": "앱 탭을 열어 둔 동안에는 이 알림마다 소리를 냅니다. 집중 모드나 방해 금지 모드로 알림이 꺼져 있어도 들립니다.", "Open pane": "패널 열기", "Quick replies": "빠른 답장", - "One-tap messages above the message box, on this device. Each is sent as if typed: queued while the agent works, an answer when a question is open.": "메시지 입력창 위에 놓이는 한 번 탭 메시지로, 이 기기에 적용됩니다. 직접 입력한 것처럼 보내므로 에이전트가 작업 중이면 대기열에 들어가고, 질문이 열려 있으면 답으로 쓰입니다.", - "Quick reply {number}": "빠른 답장 {number}", - "Remove quick reply {number}": "빠른 답장 {number} 삭제", - "Add reply": "답장 추가", - "Suggestion chip": "제안 칩", - "A chip above the message box puts the prompt Claude Code suggests next into the box. With a keyboard, Tab does it.": "입력창 위의 칩을 누르면 Claude Code가 제안한 다음 프롬프트가 입력창에 들어갑니다. 키보드에서는 Tab으로 넣습니다.", "Use the suggestion": "제안 사용", "Send “{reply}”": "“{reply}” 보내기", - "Show above the message box": "입력창 위에 표시", - "Restore defaults": "기본값으로 되돌리기", "Context {percent}% left": "컨텍스트 {percent}% 남음", "{used} of {window} tokens": "{window} 토큰 중 {used}", "failed": "실패", @@ -1247,22 +1047,6 @@ export const KO: Record = { "It is the last tab of {workspace}: the workspace closes with it, and the agents and shells in it stop.": "{workspace}의 마지막 탭입니다. 워크스페이스도 함께 닫히고, 그 안의 에이전트와 셸이 멈춥니다.", "Tabs of {workspace}": "{workspace}의 탭", "{n} panes": "패널 {n}개", - "Ovis sends anonymous usage counts.": "Ovis는 사용 현황을 익명으로 집계합니다.", - "What is sent": "보내는 내용", - "Anonymous usage counts": "익명 사용 집계", - "Turned off on this PC by OVIS_TELEMETRY=0, DO_NOT_TRACK or a CI environment.": "이 PC에서는 OVIS_TELEMETRY=0, DO_NOT_TRACK 또는 CI 환경 때문에 꺼져 있습니다.", - "Send anonymous usage counts": "익명 사용 집계 보내기", - "Once on install and once per update, with the last browser's app settings, and once a day you open the app, with the kinds of coding agents running in herdr (such as claude or codex). Custom fonts, shortcuts and replies are reported only as customization flags or counts, never their text. Account identifiers, terminal content and files are excluded. The receiver stores the country, not the IP address.": "앱 설치 시 한 번, 업데이트마다 한 번, 마지막으로 사용한 브라우저의 앱 설정과 함께 보내고, 앱을 여는 날마다 한 번, herdr에서 실행 중인 코딩 에이전트의 종류(claude, codex 등)와 함께 보냅니다. 사용자 지정 글꼴, 바로 가기 및 답변은 텍스트가 아니라 사용자 지정 여부 플래그나 개수로만 보고됩니다. 계정 식별자, 터미널 내용 및 파일은 제외됩니다. 받는 쪽은 IP 주소가 아닌 국가를 저장합니다.", - "Once a day you open the app:": "앱을 여는 날마다 한 번:", - "The receiver adds the country this message comes from (two letters, such as KR). It does not store the address.": "받는 쪽에서 이 메시지를 보낸 국가(KR 같은 두 글자)를 덧붙입니다. 주소는 저장하지 않습니다.", - "This version has already been counted. The next event is sent after an update.": "이 버전은 이미 집계되었습니다. 다음 전송은 업데이트 후입니다.", - "Agent integrations": "에이전트 통합", - "herdr's integrations let it resume each agent's session after a restart. This page only reads them: run a command in a terminal on the PC herdr runs on, then reopen this page.": "herdr 통합이 있으면 재시작 후 각 에이전트의 세션을 이어서 열 수 있습니다. 이 페이지는 상태를 읽기만 합니다. herdr가 실행되는 PC의 터미널에서 명령을 실행한 뒤 이 페이지를 다시 여세요.", - "Not found on this PC": "이 PC에서 찾을 수 없음", - "Installed, but older than this herdr: run this to update it": "설치되어 있지만 이 herdr보다 오래되었습니다. 이 명령으로 업데이트하세요", - "Not installed": "설치되지 않음", - "Copy the command for {name}": "{name} 명령 복사", - "This PC's bridge does not offer agent integrations yet. It will after its next runtime update.": "이 PC의 브리지는 아직 에이전트 통합을 제공하지 않습니다. 다음 런타임 업데이트 후에 사용할 수 있습니다.", "Clear pane name": "패널 이름 지우기", "Swap with focused pane": "선택된 패널과 자리 바꾸기", "Pane actions for {name}": "{name} 패널 메뉴", @@ -1276,7 +1060,6 @@ export const KO: Record = { "Expand": "펼치기", "Shell": "셸", "Settings (⌘⇧,)": "설정 (⌘⇧,)", - "Name each workspace on one line, or show what its agent is doing with the workspace under it": "워크스페이스 이름만 한 줄로 보여주거나, 에이전트가 하는 작업을 위에 두고 워크스페이스를 아래에 보여줍니다", "The computer this app runs on": "이 앱이 실행되는 컴퓨터", "Host": "호스트", "Move tab left": "탭을 왼쪽으로 이동", @@ -1296,7 +1079,6 @@ export const KO: Record = { "Copy details": "자세한 내용 복사", "This pane can't be shown.": "이 패널을 표시할 수 없습니다.", "The sidebar can't be shown.": "사이드바를 표시할 수 없습니다.", - "Settings can't be shown.": "설정을 표시할 수 없습니다.", "Show": "보기", "Changes": "변경 사항", "Changed files": "변경된 파일", @@ -1336,16 +1118,8 @@ export const KO: Record = { "Changes to {name}": "{name} 변경 사항", "Close diff": "비교 닫기", "Diff layout": "비교 보기 방식", - "Open files": "파일 열기", - "On a wide window, text and code can open beside the pane. Media, PDFs and folders always open in a popup, and the viewer's header button moves the file open now.": "넓은 창에서는 텍스트와 코드를 창 옆에 열 수 있습니다. 미디어, PDF, 폴더는 항상 팝업으로 열리고, 뷰어 위쪽 버튼으로 지금 연 파일을 옮길 수 있습니다.", - "In a popup": "팝업으로", - "Web links": "웹 링크", - "Only a page this PC serves, such as a dev server on localhost, opens beside the pane. Shift-click opens it the other way.": "localhost 개발 서버처럼 이 PC가 여는 페이지만 창 옆에 열립니다. Shift-클릭하면 반대쪽으로 엽니다.", - "Beside the pane": "창 옆에", - "In a new tab": "새 탭에서", "Unified": "한 열", "Split": "나란히", - "A phone shows one column either way.": "휴대전화에서는 어느 쪽이든 한 열로 표시됩니다.", "Split view needs a wider screen": "나란히 보기에는 더 넓은 화면이 필요합니다", "Split view needs a wider screen; showing one column.": "나란히 보기에는 더 넓은 화면이 필요해 한 열로 표시합니다.", "Fold context": "문맥 접기", @@ -1373,58 +1147,14 @@ export const KO: Record = { "Copy path": "경로 복사", "Path copied": "경로를 복사했습니다", "Path": "경로", - "theme themes palette dark light mode colors density language sidebar logos": "테마 팔레트 palette 다크 라이트 모드 색상 밀도 언어 사이드바 로고", - "chat font size message width composer enter send thinking code": "채팅 글꼴 글자 크기 메시지 너비 입력창 엔터 보내기 생각 코드", - "terminal font size key bar keyboard clipboard": "터미널 글꼴 글자 크기 키 바 키보드 클립보드", - "notifications sound push bell needs input finished": "알림 소리 푸시 벨 입력 필요 완료", - "dictation microphone speech openai": "받아쓰기 마이크 음성 openai", - "plan limits quota meters": "요금제 한도 할당량 미터", - "keyboard keys bindings hotkeys": "키보드 키 단축키 바인딩", - "phone install keep screen on app": "휴대폰 설치 화면 켜짐 유지 앱", - "machines computers ssh bridge plugins": "기기 컴퓨터 ssh 브리지 플러그인", - "agents hooks claude codex": "에이전트 훅 claude codex", - "version update release herdr": "버전 업데이트 릴리스 herdr", - "create workspace session start": "만들기 워크스페이스 세션 시작", - "create tab add": "만들기 탭 추가", - "divide pane layout side": "나누기 패널 레이아웃 옆", - "divide pane layout below": "나누기 패널 레이아웃 아래", - "maximize fullscreen full screen focus": "최대화 전체 화면 집중", - "lens chat terminal conversation": "보기 채팅 터미널 대화", - "panel drawer hide show": "패널 서랍 숨기기 보기", - "dark light mode appearance colors": "다크 라이트 모드 외관 색상", - "preferences options config": "환경설정 옵션 구성", - "remote machine computer connect ssh": "원격 기기 컴퓨터 연결 ssh", - "alerts push bell": "알림 푸시 벨", - "logout log out lock": "로그아웃 잠금", - "folder explorer open file": "폴더 탐색기 파일 열기", - "reload update sync": "새로고침 업데이트 동기화", - "Search shortcuts": "단축키 검색", - "No shortcuts match.": "일치하는 단축키가 없습니다.", - "Record": "기록", - "Press keys…": "키를 누르세요…", - "Record shortcut for {name}": "{name}의 단축키 기록", - "Press the new shortcut, or Escape to cancel.": "새 단축키를 누르거나 Escape로 취소하세요.", - "Hold ⌘, Ctrl or ⌥, with or without Shift, and press a key.": "⌘, Ctrl 또는 ⌥를 누른 채 키를 누르세요. Shift는 함께 눌러도 되고 안 눌러도 됩니다.", - "Hold Ctrl or Alt, with or without Shift, and press a key.": "Ctrl 또는 Alt를 누른 채 키를 누르세요. Shift는 함께 눌러도 되고 안 눌러도 됩니다.", - "{keys} is a terminal key: shells, editors and agents use it. Once saved, it no longer reaches the pane.": "{keys} 키는 터미널 키입니다. 셸, 편집기, 에이전트가 사용하며, 저장하면 더 이상 패널로 전달되지 않습니다.", - "Save anyway": "그래도 저장", - "That key cannot be a shortcut.": "이 키는 단축키로 쓸 수 없습니다.", - "Your browser or operating system keeps that shortcut.": "브라우저나 운영 체제가 이 단축키를 사용합니다.", "Browse folders": "폴더 찾아보기", - "Browse installed fonts for {label}": "{label}에 설치된 글꼴 찾아보기", "Collapse all folders": "모든 폴더 접기", "Dismiss notice": "알림 닫기", "Expand all folders": "모든 폴더 펼치기", "Folders": "폴더", - "Installed fonts": "설치된 글꼴", - "Installed fonts could not be listed. Type the name instead.": "설치된 글꼴을 불러오지 못했습니다. 이름을 직접 입력하세요.", - "No fonts found": "글꼴을 찾을 수 없습니다", "Notices": "알림 메시지", "Open in Files": "파일에서 열기", "Pinned folders": "고정한 폴더", - "Search fonts": "글꼴 검색", - "Showing the first {count} fonts. Search to narrow the list.": "처음 {count}개의 글꼴을 표시합니다. 검색해서 목록을 좁히세요.", - "{font} is not monospace. The terminal needs a fixed-width font, so the current font was kept.": "{font} 글꼴은 고정폭이 아닙니다. 터미널에는 고정폭 글꼴이 필요하여 현재 글꼴을 유지했습니다.", // t3code ports (d) "Image viewer": "이미지 보기", "Copy image": "이미지 복사", @@ -1432,11 +1162,6 @@ export const KO: Record = { "Next image": "다음 이미지", "{n} of {count}": "{count}개 중 {n}번째", "Couldn't copy the image. Download it instead.": "이미지를 복사하지 못했습니다. 대신 내려받으세요.", - "Typography": "타이포그래피", - "Interface font size": "인터페이스 글자 크기", - "Menus, lists, dialogs and the sidebar. The chat follows it until it has a size of its own; the terminal keeps its own.": "메뉴, 목록, 대화 상자, 사이드바에 적용됩니다. 채팅은 별도 크기를 정하기 전까지 이 크기를 따르고, 터미널은 자체 크기를 유지합니다.", - "Decrease interface font size": "인터페이스 글자 크기 줄이기", - "Increase interface font size": "인터페이스 글자 크기 키우기", "Working folder": "작업 폴더", "Worktree": "워크트리", "Browse folders in the palette": "팔레트에서 폴더 탐색", @@ -1444,6 +1169,12 @@ export const KO: Record = { "Go to turn {n}": "{n}번째 턴으로 이동", "Show full message": "전체 메시지 보기", "Change PC": "PC 바꾸기", - "This is the demo. Go back to the app's list of PCs to open yours.": "데모 화면입니다. 앱의 PC 목록으로 돌아가 내 PC를 여세요.", - "This app shows {address}. Go back to its list of PCs to open another.": "이 앱은 {address}를 보여 주고 있습니다. PC 목록으로 돌아가 다른 PC를 열 수 있습니다.", }; + +/** The parts KO is made of; src/lib/i18n.test.ts fails when a key is in two parts, since a spread keeps only the last. */ +export const KO_PARTS: Record> = { + base: BASE, + settings: SETTINGS_KO, +}; + +export const KO: Record = Object.assign({}, ...Object.values(KO_PARTS)); diff --git a/src/lib/i18n.test.ts b/src/lib/i18n.test.ts index fd056553f5..b8a0ef4c17 100644 --- a/src/lib/i18n.test.ts +++ b/src/lib/i18n.test.ts @@ -1,9 +1,9 @@ import { describe, expect, it } from "bun:test"; import { readFileSync } from "node:fs"; import { join } from "node:path"; -import { JA } from "./i18n.ja.ts"; -import { KO } from "./i18n.ko.ts"; -import { ZH } from "./i18n.zh.ts"; +import { JA, JA_PARTS } from "./i18n.ja.ts"; +import { KO, KO_PARTS } from "./i18n.ko.ts"; +import { ZH, ZH_PARTS } from "./i18n.zh.ts"; import { resolveLanguage, translate } from "./i18n.ts"; const root = join(import.meta.dir, ".."); @@ -16,7 +16,8 @@ const root = join(import.meta.dir, ".."); function keysInCode(): Map { const found = new Map(); for (const file of new Bun.Glob("**/*.{ts,tsx}").scanSync({ cwd: root })) { - if (file.endsWith(".test.ts") || /i18n\.\w+\.ts$/.test(file)) continue; + // the dictionaries: i18n.ko.ts and the like, and the parts in lib/i18n/ + if (file.endsWith(".test.ts") || /i18n\.\w+\.ts$/.test(file) || /^lib[\\/]i18n[\\/]/.test(file)) continue; const text = readFileSync(join(root, file), "utf8"); for (const match of text.matchAll(/(? { + it.each(Object.entries(PARTS))("%s keeps each key in one part", (_name, [dictionary, parts]) => { + // the dictionary is the parts spread together, and a spread keeps only the last copy of a key + const seen = new Map(); + const twice = Object.entries(parts).flatMap(([part, entries]) => Object.keys(entries).flatMap((key) => { + const first = seen.get(key); + seen.set(key, part); + return first === undefined ? [] : [`${key} (${first}, ${part})`]; + })); + expect(twice).toEqual([]); + expect(Object.keys(dictionary).length).toBe(seen.size); + }); + + it("puts each key in the same part in every language", () => { + const placement = (parts: Record>) => Object.fromEntries(Object.entries(parts).map(([part, entries]) => [part, Object.keys(entries).sort()])); + expect(placement(JA_PARTS)).toEqual(placement(KO_PARTS)); + expect(placement(ZH_PARTS)).toEqual(placement(KO_PARTS)); + }); + + it("keeps each part file at 400 lines or fewer", () => { + const long = [...new Bun.Glob("lib/i18n/*.ts").scanSync({ cwd: root })].filter((file) => readFileSync(join(root, file), "utf8").split("\n").length > 400); + expect(long).toEqual([]); + }); +}); + describe("translate", () => { it("fills placeholders, falls back to English, and leaves unknown placeholders alone", () => { expect(translate("en", "Worked for {duration}", { duration: "7s" })).toBe("Worked for 7s"); diff --git a/src/lib/i18n.zh.ts b/src/lib/i18n.zh.ts index 50909f13f0..4179dfe57d 100644 --- a/src/lib/i18n.zh.ts +++ b/src/lib/i18n.zh.ts @@ -1,5 +1,9 @@ +import { SETTINGS_ZH } from "./i18n/settings.zh.ts"; + /** - * Simplified Chinese for every `t("…")` in src/. The English string is the key. Grouped by where + * Simplified Chinese for every `t("…")` in src/ that no part in lib/i18n/ holds: keys more than + * one feature uses, and the app shell's. ZH at the end is this and the parts together. The English + * string is the key. Grouped by where * the text shows; within a group, roughly in the order it appears. Register: zh-CN software UI * (like VS Code 简体中文): concise labels and buttons, plain declarative sentences, full-width * punctuation in Chinese sentences, a half-width space between Chinese and Latin words. Fixed @@ -9,7 +13,7 @@ * product names (herdr, Tailscale, Codex, Claude Code, GitHub) and key caps stay as they are. * Placeholders in braces keep their English names. */ -export const ZH: Record = { +const BASE: Record = { "Could not load sign-in options": "无法加载登录方式", "On the server PC": "在服务器 PC 上登录", "Install {cli} on the server PC first.": "请先在服务器 PC 上安装 {cli}。", @@ -88,18 +92,7 @@ export const ZH: Record = { "Waiting for terminal input…": "正在准备终端输入…", "Paused while you use another window": "使用其他窗口时已暂停", "View only while you use another window · click to type": "使用其他窗口时仅查看 · 点击即可输入", - "Direct typing": "直接输入", "Input line": "输入框", - "Terminal input mode": "终端输入模式", - "Reset shortcuts": "重置快捷键", - "Bindings apply to this browser and device. Mod+Shift chords leave the terminal its keys; Record also takes other chords with Ctrl, Alt or (on a Mac) ⌘, exactly as pressed.": "快捷键仅应用于此浏览器和设备。Mod+Shift 组合不会占用终端按键;录制时也可使用 Ctrl、Alt 或(在 Mac 上)⌘ 的其他组合,按原样保存。", - "Text selection in focused fields stays native; Tab/list keys are UI-local, not global shortcuts.": "焦点位于文本输入框时,文本选择仍由系统处理;Tab/列表按键仅在界面内生效,不是全局快捷键。", - "The mobile key bar sends terminal keys, not app actions.": "手机上的按键栏发送终端按键,不会触发应用操作。", - "Your browser or operating system may intercept {keys}.": "浏览器或操作系统可能会拦截 {keys}。", - "Reserved": "系统保留", - "Already assigned": "已分配", - "Send keys to terminal": "将按键发送到终端", - "Default": "默认", "Password or PIN": "密码或 PIN", "Enter a single-line password or PIN.": "请输入不含换行的密码或 PIN。", "Update this PC to use masked input.": "请更新此电脑上的应用以使用密码输入框。", @@ -107,36 +100,6 @@ export const ZH: Record = { "Sent directly to this terminal. Never saved as a draft or queued.": "直接发送到此终端,不会存为草稿或加入待发队列。", // ---- settings ---- "Settings": "设置", - "Close settings": "关闭设置", - "Appearance": "外观", - "Theme": "主题", - "Dark": "深色", - "Light": "浅色", - "System": "跟随系统", - "Dark theme": "深色主题", - "Light theme": "浅色主题", - "Shown in dark mode": "在深色模式下显示", - "Shown in light mode": "在浅色模式下显示", - "Charcoal": "炭灰", - "Codex": "Codex", - "Amber": "琥珀", - "Catppuccin": "Catppuccin", - "Catppuccin Latte": "Catppuccin Latte", - "Tokyo Night": "Tokyo Night", - "Tokyo Night Day": "Tokyo Night Day", - "Gruvbox": "Gruvbox", - "Gruvbox Light": "Gruvbox Light", - "One Dark": "One Dark", - "One Light": "One Light", - "Solarized": "Solarized", - "Solarized Light": "Solarized Light", - "Kanagawa": "Kanagawa", - "Kanagawa Lotus": "Kanagawa Lotus", - "Rosé Pine": "Rosé Pine", - "Rosé Pine Dawn": "Rosé Pine Dawn", - "Dracula": "Dracula", - "Nord": "Nord", - "Vesper": "Vesper", "Pin agent": "固定 Agent", "Unpin agent": "取消固定 Agent", "Pin workspace": "固定工作区", @@ -144,72 +107,12 @@ export const ZH: Record = { "Pinned": "已固定", "Message from another session: {name}": "来自另一个会话的消息:{name}", "Message from another session": "来自另一个会话的消息", - "Density": "密度", - "Comfortable": "宽松", - "Compact": "紧凑", - "Language": "语言", - "Follows the browser unless you choose one": "未选择时跟随浏览器语言", - "Terminal font size": "终端字号", - "Applied to every terminal pane": "应用于所有终端窗格", - "Decrease terminal font size": "减小终端字号", - "Increase terminal font size": "增大终端字号", - "Wheel scroll speed": "滚轮滚动速度", - "How far one turn of the wheel scrolls the terminal": "滚轮滚动一次时终端移动的距离", - "Slower wheel scrolling": "滚轮滚动更慢", - "Faster wheel scrolling": "滚轮滚动更快", - "Terminal font": "终端字体", - "Comma-separated, tried in order. A font this device does not have falls back to the default.": "以逗号分隔,按顺序使用。此设备上没有的字体会回退到默认字体。", - "Composer": "输入框", - "Enter sends": "按 Enter 发送", - "Return inserts a new line": "按 Return 换行", - "When on, use Send or hardware Mod+Enter to send.": "开启后,点击发送按钮或使用实体键盘按 Mod+Enter 发送。", - "When off, Mod+Enter sends": "关闭后按 Mod+Enter 发送", "Only the first {count} of {total} files were taken.": "{total} 个文件中只取了前 {count} 个。", "Chat": "聊天", - "Panes open in": "窗格默认视图", - "Every pane on this device. Switching a pane's lens keeps it there until this changes. Auto: chat for an agent on a touch screen, else the terminal.": "适用于此设备上的所有窗格。在窗格中切换视图后,在更改此设置之前都会以该视图打开。自动:触屏上的智能体为聊天,其余为终端。", - "Auto": "自动", - "Show thinking": "显示思考过程", - "Include the agent's reasoning blocks": "一并显示 Agent 的推理块", - "Chat width": "聊天宽度", - "How wide the conversation and the message box run on a large screen": "大屏幕上对话和输入框的宽度", - "Narrow": "窄", - "Wide": "宽", - "Full": "全宽", - "Chat font size": "聊天字号", - "Messages, code, prompt cards and the message box in the chat view": "聊天视图中的消息、代码、提问卡片和输入框", - "Decrease chat font size": "减小聊天字号", - "Increase chat font size": "增大聊天字号", - "Chat font": "聊天字体", - "Message text; code stays monospace. Comma-separated, tried in order. A font this device does not have falls back to the default.": "用于消息正文,代码仍使用等宽字体。以逗号分隔,按顺序使用。此设备上没有的字体会回退到默认字体。", - "File viewer": "文件查看器", - "Wrap long lines": "长行自动换行", - "Markdown width": "Markdown 宽度", - "Full width": "全宽", - "New agents": "新代理", - "Applies to agents started from New workspace, New tab and New worktree. Agent default adds no flag, so the agent's own configuration decides.": "适用于从新建工作区、新建标签页和新建工作树启动的代理。代理默认不添加任何参数,由代理自身的配置决定。", - "Permission mode": "权限模式", - "Sandbox and approvals": "沙箱与审批", "Agent default": "代理默认", - "Accept edits": "自动接受编辑", - "Don't ask": "不询问", - "Bypass permissions": "跳过权限检查", - "Read only": "只读", - "Full access": "完全访问", "Show source": "显示源代码", - "Shortcuts": "快捷键", - "Phone": "手机", - "Devices": "设备", "Phone & devices": "手机和设备", - "Install": "安装", - "Installed": "已安装", "Install app": "安装应用", - "About": "关于", - "Star on GitHub": "在 GitHub 上点 Star", - "Remote PCs": "远程 PC", - "Connect another PC over an SSH alias or user@host. Its workspaces join the sidebar.": "通过 SSH 别名或 user@host 连接另一台 PC。连接后,它的工作区会显示在侧栏中。", - "Update PC bridges automatically": "自动更新 PC 的 bridge", - "When an app update needs a newer bridge, PCs that connect with their saved key are updated in the background. PCs that need a password ask first.": "当应用更新需要更新的 bridge 时,使用已保存密钥连接的 PC 会在后台更新。需要密码的 PC 会先询问。", // ---- shortcuts (lib/shortcuts.ts labels) ---- "Command palette": "命令面板", @@ -274,11 +177,7 @@ export const ZH: Record = { "That link's workspace is closed": "该链接的工作区已关闭", "That link's PC is not set up here": "该链接的电脑未在此处设置", "Command palette (⌘⇧K)": "命令面板 (⌘⇧K)", - "Sign out": "退出登录", "Could not sign out. Try again.": "无法退出登录,请重试。", - "Sign out of this browser?": "要从此浏览器退出登录吗?", - "Getting back in takes the access token, or a pairing code from the PC: Settings → Phone & devices there, or the pair command in its terminal.": "再次进入需要访问令牌,或 PC 上的配对码:在 PC 的设置 → Phone & devices 中,或在其终端运行 pair 命令获取。", - "Forget this browser's sign-in. Getting back in takes the access token or a pairing code.": "清除此浏览器的登录。再次进入需要访问令牌或配对码。", "Retry": "重试", "Enable notifications": "开启通知", "Notify me when a pane needs input or finishes": "窗格需要输入或完成时通知我", @@ -310,22 +209,6 @@ export const ZH: Record = { "Reorder workspace {name}": "调整工作区 {name} 的顺序", "Expand {name}": "展开 {name}", "Collapse {name}": "折叠 {name}", - "Sidebar rows": "侧边栏行", - "One line": "单行", - "Two lines": "双行", - "Agents order": "代理排序", - "Activity keeps a waiting agent on top, then the one that changed last; herdr's own order is not changed": "按活动排序会把等待回应的代理放在最上面,其余按最近变化排序;herdr 自身的顺序不会改变", - "Workspaces": "工作区顺序", - "Activity": "按活动", - "Agent logos": "代理标志", - "Draw each agent's logo in its brand colors, or without color": "用品牌颜色或无色显示每个代理的标志", - "Color": "彩色", - "Mono": "单色", - "Status indicators": "状态指示", - "Classic marks only the states that ask for a look; Dots and Symbols draw every state as herdr's TUI does": "经典只标出需要查看的状态;圆点和符号像 herdr 的 TUI 一样显示每种状态", - "Classic": "经典", - "Dots": "圆点", - "Symbols": "符号", "Drag to reorder · Alt+↑/↓": "拖动以调整顺序 · Alt+↑/↓", "Resize sidebar": "调整侧边栏宽度", "Resize file panel": "调整文件面板宽度", @@ -465,11 +348,6 @@ export const ZH: Record = { "Running…": "正在运行…", "{action} failed: {detail}": "{action} 失败:{detail}", "{action} failed (exit code {code})": "{action} 失败(退出码 {code})", - "herdr plugins": "herdr 插件", - "The command palette and its plugin actions are not available in the phone touch UI. Use a wider screen or a keyboard's command palette shortcut.": "手机触控界面不提供命令面板及其中的插件操作。请使用更宽的屏幕,或通过键盘的命令面板快捷键打开。", - "No actions": "无操作", - "Enabled": "已启用", - "Disabled": "已停用", "No matching panes or actions": "没有匹配的窗格或操作", // ---- new workspace ---- @@ -656,28 +534,6 @@ export const ZH: Record = { "Tilde": "波浪号", "Slash": "斜杠", "Control": "控制键", - "Key bar": "按键栏", - "Edit key bar": "编辑按键栏", - "Back to settings": "返回设置", - "Keys, order and custom combinations for the terminal.": "设置终端按键、顺序和自定义组合。", - "Choose the keys and their order under the terminal. The keyboard mode button stays first.": "选择终端下方显示的按键及其顺序。键盘模式按钮固定在最前面。", - "Key bar keys": "按键栏中的按键", - "Held modifier": "保持按下的修饰键", - "Saved combination": "已保存的组合键", - "Remove {name}": "移除 {name}", - "No keys selected.": "未选择任何按键。", - "Add key": "添加按键", - "All keys added": "所有按键均已添加", - "Held modifiers": "保持按下的修饰键", - "Custom combination": "自定义组合键", - "Saved combinations use only the selected modifiers. Other keys use held modifiers.": "已保存的组合键仅使用选定的修饰键。其他按键使用当前保持按下的修饰键。", - "Base key": "基本按键", - "Single character": "单个字符", - "Character": "字符", - "Combination modifiers": "组合键的修饰键", - "Enter one character.": "请输入一个字符。", - "Add combination": "添加组合键", - "Already added": "已添加", "Press {key}": "按下 {key}", // ---- prompt card ---- @@ -747,10 +603,6 @@ export const ZH: Record = { "Attach files": "附加文件", "Next turn": "下一轮", "Waits for Send now": "按“立即发送”后发送", - "Send queued messages automatically": "自动发送排队消息", - "A message sent while the agent works goes by itself when the turn ends. When off, it waits until you press Send now.": "智能体工作时发送的消息会在本轮结束后自动发出。关闭后,消息会等到你按下“立即发送”。", - "New tab button": "新标签页按钮", - "A button in the message box opens New tab with an agent… on the pane's workspace. The tab menu offers it either way.": "输入框中的按钮可在该面板的工作区打开“带代理的新标签页…”。标签页菜单中始终可用。", "Discard saved copy": "丢弃已保存的副本", "Update this PC to send messages in the next turn. Your draft stayed here.": "请更新这台电脑后再发送下一轮消息。草稿仍保留在这里。", "Send now": "立即发送", @@ -804,12 +656,6 @@ export const ZH: Record = { "beginning of conversation": "对话开始", "Conversation unavailable — show terminal output": "对话不可用。显示终端输出", "Last checked {when}": "上次检查:{when}", - "Clipboard from a pane": "从窗格写入剪贴板", - "A program in a pane that copies (vim, tmux, Claude Code) puts its text on this device's clipboard, as a copy you made yourself would. Turn it off if a pane runs output you do not trust: it could replace what you paste next.": "窗格中执行复制的程序(vim、tmux、Claude Code)会像你自己复制一样把文本写入此设备的剪贴板。如果窗格运行你不信任的输出,请关闭它:它可能替换你下次粘贴的内容。", - "Use alongside herdr's own window": "与终端里的 herdr 一起使用", - "Turn this on if this PC also shows herdr in a terminal window. A second after you switch to another window, this tab only watches the pane, so herdr's window keeps the pane at its own size instead of this window's. Click the tab to type again. While it watches, the pane is drawn at herdr's size and may not fill this window.": "如果这台电脑的终端窗口里也开着 herdr,请打开此项。切换到其他窗口一秒后,此标签页只查看窗格,herdr 窗口会按自己的尺寸而不是此窗口的尺寸保留窗格。点击标签页即可再次输入。查看期间窗格按 herdr 的尺寸绘制,可能不会填满此窗口。", - "Follow herdr's focus": "跟随 herdr 的焦点", - "When herdr moves to another pane, by a click in its window, a herdr command or a script, this device opens that pane too. Only on the PC open here, and only on this device.": "herdr 切换到另一个窗格时(在 herdr 窗口中点击、herdr 命令或脚本),此设备也会打开该窗格。仅适用于这里打开的 PC,且仅适用于此设备。", "What should {agent} do in {folder}?": "要让 {agent} 在 {folder} 做什么?", "No conversation yet — say something below": "暂无对话。在下方说点什么吧", "terminal ended": "终端已结束", @@ -871,44 +717,22 @@ export const ZH: Record = { "Use the install icon in the address bar, or the browser menu's Install option.": "使用地址栏中的安装图标,或浏览器菜单中的“安装”选项。", // ---- voice input ---- - "Without a key the browser recognizes the speech: Chrome and Edge send the audio to Google or Microsoft. Nothing is recorded until you press the mic.": "没有密钥时由浏览器识别语音:Chrome 和 Edge 会把音频发送给 Google 或 Microsoft。按下麦克风前不会录音。", "The dictation does not fit in the box": "听写内容超出输入框上限,未插入", "No speech was heard": "没有听到语音", - "Drops fillers and fixes spacing; code and paths stay as spoken": "去掉口头禅并修正空格;代码和路径保持原样", - "In chat": "聊天", - "Auto: in the chat on a desktop, where dictation can work. On: on a phone and in the terminal input line too.": "自动:仅在桌面端聊天中、可以听写时显示。开启:在手机和终端输入行也显示。", - "On": "开启", - "In the terminal": "终端", - "Off keeps a command exactly as transcribed": "关闭后命令保持转写原样", - "Tidy dictated text": "整理听写文本", "Add an OpenAI API key in Settings > Voice input": "请在设置 > 语音输入中添加 OpenAI API 密钥", - "Audio is sent to OpenAI with your key. Nothing is recorded until you press the mic.": "音频会使用你的密钥发送到 OpenAI。按下麦克风前不会录音。", "Cancel dictation": "取消听写", "Dictate (hold)": "听写(按住)", "Insert dictation": "插入听写内容", - "Microphone button": "麦克风按钮", "Microphone permission was denied": "麦克风权限已被拒绝", - "Dictation language": "听写语言", - "Auto listens for the app's language, or for the browser's when the app is not translated into it": "自动时识别应用的语言;若应用没有浏览器语言的译文,则识别浏览器的语言", - "Auto ({language})": "自动({language})", - "No OpenAI key: the browser's speech recognition is used": "未设置 OpenAI 密钥,将使用浏览器的语音识别", "No microphone found": "未找到麦克风", "No microphone input": "没有麦克风输入", - "OpenAI API key": "OpenAI API 密钥", - "OpenAI key saved on this PC": "OpenAI 密钥已保存在此电脑上", - "OpenAI key set by OVIS_OPENAI_API_KEY": "已通过 OVIS_OPENAI_API_KEY 设置 OpenAI 密钥", "Ready…": "就绪…", "Recording": "录音中", "Recording is too long": "录音时间过长", - "Remove key": "移除密钥", - "Save key": "保存密钥", "The OpenAI key was refused": "OpenAI 密钥被拒绝", "This browser cannot record audio": "此浏览器无法录制音频", - "Tidy dictated text in chat": "整理聊天中的听写文本", - "Tidy dictated text in the terminal": "整理终端中的听写文本", "Transcribing…": "正在转录…", "Transcription failed": "转录失败", - "Voice input": "语音输入", "Voice input needs HTTPS": "语音输入需要 HTTPS", // ---- errors (lib/userError.ts) ---- "This browser is not signed in to this PC any more. Pair it again in Settings → Phone & devices.": "此浏览器已不再登录此电脑。请在设置 → 手机和设备中重新配对。", @@ -932,8 +756,6 @@ export const ZH: Record = { "Check your connection, then try again.": "请检查网络连接后重试。", "Try again; if it keeps failing, restart Ovis on the PC.": "请重试;如果一直失败,请在电脑上重启 Ovis。", "The server cannot save settings: check that its state folder is writable.": "服务器无法保存设置:请检查其状态文件夹是否可写。", - "Not saved on the server yet; reloading or closing this page can undo the change.": "尚未保存到服务器;重新加载或关闭此页面可能会撤销此更改。", - "Sending the change to the server…": "正在将更改发送到服务器…", // ---- sign-in ---- "Enter all 6 digits of the pairing code.": "请输入配对码的全部 6 位数字。", @@ -1020,10 +842,6 @@ export const ZH: Record = { "…": "…", "Alerts": "提醒", "Needs you": "需要你回应", - "Keep screen on": "保持屏幕常亮", - "While a terminal or chat pane is open.": "打开终端或聊天窗格时保持屏幕常亮。", - "Needs HTTPS or localhost.": "需要 HTTPS 或 localhost。", - "This browser can't keep the screen on.": "此浏览器无法保持屏幕常亮。", "Test notification": "测试通知", "Check whether this device can receive push alerts": "检查此设备能否接收推送通知", "Sending…": "正在发送…", @@ -1036,30 +854,12 @@ export const ZH: Record = { "Allow notifications to test alerts on this device.": "请允许通知,以便在此设备上测试提醒。", "Could not send the test notification. Try again.": "无法发送测试通知。请重试。", "Turn alerts on again": "重新开启提醒", - "For this device. An alert waits a little first, and none comes when the pane changes meanwhile, as when you answer at the PC.": "仅适用于此设备。提醒会先稍等片刻,如果期间窗格状态发生变化(例如你已在 PC 上回答),则不会发送。", "Needs input": "需要输入", - "An agent waits for an answer or a permission": "Agent 在等待回答或授权时", "Finished": "已完成", - "Long turns: only work that took a minute or more": "长任务:仅限耗时 1 分钟或以上的工作", - "Off": "关闭", - "Long turns": "长任务", - "Every turn": "每一轮", - "In the app": "应用内", - "While the app is open, these drop in from the top of the screen at once. Tap one to open its pane.": "应用打开时,这些提醒会立即从屏幕顶部落下。点按即可打开对应的窗格。", - "Sound": "声音", - "While a tab of the app is open, it chimes for these alerts, also when a Focus or Do Not Disturb silences notifications.": "应用的标签页打开时,每条提醒都会响起提示音。即使专注模式或勿扰模式让通知静音,也能听到。", "Open pane": "打开窗格", "Quick replies": "快捷回复", - "One-tap messages above the message box, on this device. Each is sent as if typed: queued while the agent works, an answer when a question is open.": "显示在消息输入框上方的一键消息,仅适用于此设备。每条消息都像手动输入一样发送:Agent 工作时加入队列,有未关闭的问题时作为回答。", - "Quick reply {number}": "快捷回复 {number}", - "Remove quick reply {number}": "删除快捷回复 {number}", - "Add reply": "添加回复", - "Suggestion chip": "建议标签", - "A chip above the message box puts the prompt Claude Code suggests next into the box. With a keyboard, Tab does it.": "输入框上方的标签会把 Claude Code 建议的下一条提示填入输入框。使用键盘时按 Tab 即可。", "Use the suggestion": "使用建议", "Send “{reply}”": "发送“{reply}”", - "Show above the message box": "显示在输入框上方", - "Restore defaults": "恢复默认值", "Context {percent}% left": "上下文剩余 {percent}%", "{used} of {window} tokens": "{used} / {window} Token", "failed": "失败", @@ -1251,22 +1051,6 @@ export const ZH: Record = { "It is the last tab of {workspace}: the workspace closes with it, and the agents and shells in it stop.": "这是 {workspace} 的最后一个标签页:工作区会随之关闭,其中的代理和 shell 会停止。", "Tabs of {workspace}": "{workspace} 的标签页", "{n} panes": "{n} 个窗格", - "Ovis sends anonymous usage counts.": "Ovis 会匿名发送使用统计。", - "What is sent": "发送的内容", - "Anonymous usage counts": "匿名使用统计", - "Turned off on this PC by OVIS_TELEMETRY=0, DO_NOT_TRACK or a CI environment.": "此电脑因 OVIS_TELEMETRY=0、DO_NOT_TRACK 或 CI 环境而已关闭。", - "Send anonymous usage counts": "发送匿名使用统计", - "Once on install and once per update, with the last browser's app settings, and once a day you open the app, with the kinds of coding agents running in herdr (such as claude or codex). Custom fonts, shortcuts and replies are reported only as customization flags or counts, never their text. Account identifiers, terminal content and files are excluded. The receiver stores the country, not the IP address.": "应用安装时发送一次,每次更新发送一次,并附带最后使用的浏览器中的应用设置;在你打开应用的每一天再发送一次,并附带 herdr 中正在运行的编码代理类型(例如 claude 或 codex)。自定义字体、快捷键和快捷回复仅以自定义标记或数量的形式上报,不会上报其文本。账户标识符、终端内容和文件均不包含在内。接收端保存国家/地区,而非 IP 地址。", - "Once a day you open the app:": "在你打开应用的每一天发送一次:", - "The receiver adds the country this message comes from (two letters, such as KR). It does not store the address.": "接收端会附加这条消息来自的国家(两个字母,例如 KR)。不保存地址。", - "This version has already been counted. The next event is sent after an update.": "此版本已统计。下一次发送在更新之后。", - "Agent integrations": "代理集成", - "This PC's bridge does not offer agent integrations yet. It will after its next runtime update.": "这台 PC 的桥接服务暂不提供代理集成。下次运行时更新后即可使用。", - "herdr's integrations let it resume each agent's session after a restart. This page only reads them: run a command in a terminal on the PC herdr runs on, then reopen this page.": "有了 herdr 集成,重启后可以恢复每个代理的会话。此页面只读取状态:请在运行 herdr 的 PC 的终端中执行命令,然后重新打开此页面。", - "Not found on this PC": "此 PC 上未找到", - "Installed, but older than this herdr: run this to update it": "已安装,但比此 herdr 旧:运行此命令以更新", - "Not installed": "未安装", - "Copy the command for {name}": "复制 {name} 的命令", "Clear pane name": "清除面板名称", "Swap with focused pane": "与当前面板交换位置", "Pane actions for {name}": "{name} 面板菜单", @@ -1280,7 +1064,6 @@ export const ZH: Record = { "Expand": "展开", "Shell": "Shell", "Settings (⌘⇧,)": "设置 (⌘⇧,)", - "Name each workspace on one line, or show what its agent is doing with the workspace under it": "每个工作区只显示一行名称,或在上方显示智能体正在做的事、下方显示工作区", "The computer this app runs on": "运行此应用的计算机", "Host": "主机", "Move tab left": "向左移动标签页", @@ -1300,7 +1083,6 @@ export const ZH: Record = { "Copy details": "复制详细信息", "This pane can't be shown.": "无法显示此窗格。", "The sidebar can't be shown.": "无法显示侧边栏。", - "Settings can't be shown.": "无法显示设置。", "Show": "显示", "Changes": "更改", "Changed files": "已更改的文件", @@ -1340,16 +1122,8 @@ export const ZH: Record = { "Changes to {name}": "{name} 的更改", "Close diff": "关闭差异", "Diff layout": "差异布局", - "Open files": "打开文件", - "On a wide window, text and code can open beside the pane. Media, PDFs and folders always open in a popup, and the viewer's header button moves the file open now.": "在宽窗口中,文本和代码可以在窗格旁打开。媒体、PDF 和文件夹始终以弹窗打开,查看器顶部的按钮可以移动当前打开的文件。", - "In a popup": "以弹窗", - "Web links": "网页链接", - "Only a page this PC serves, such as a dev server on localhost, opens beside the pane. Shift-click opens it the other way.": "只有这台 PC 提供的页面(例如 localhost 上的开发服务器)会在窗格旁打开。按住 Shift 点击则以另一种方式打开。", - "Beside the pane": "在窗格旁", - "In a new tab": "在新标签页中", "Unified": "单栏", "Split": "并排", - "A phone shows one column either way.": "手机上无论如何都显示为单栏。", "Split view needs a wider screen": "并排视图需要更宽的屏幕", "Split view needs a wider screen; showing one column.": "并排视图需要更宽的屏幕,当前显示为单栏。", "Fold context": "折叠上下文", @@ -1377,58 +1151,14 @@ export const ZH: Record = { "Copy path": "复制路径", "Path copied": "已复制路径", "Path": "路径", - "theme themes palette dark light mode colors density language sidebar logos": "主题 调色板 palette 深色 浅色 模式 颜色 密度 语言 侧边栏 徽标", - "chat font size message width composer enter send thinking code": "聊天 字体 字号 消息 宽度 输入框 回车 发送 思考 代码", - "terminal font size key bar keyboard clipboard": "终端 字体 字号 按键栏 键盘 剪贴板", - "notifications sound push bell needs input finished": "通知 声音 推送 铃 需要输入 完成", - "dictation microphone speech openai": "听写 麦克风 语音 openai", - "plan limits quota meters": "套餐 限额 配额 计量", - "keyboard keys bindings hotkeys": "键盘 按键 快捷键 绑定", - "phone install keep screen on app": "手机 安装 屏幕常亮 应用", - "machines computers ssh bridge plugins": "机器 电脑 ssh 桥接 插件", - "agents hooks claude codex": "Agent 钩子 claude codex", - "version update release herdr": "版本 更新 发布 herdr", - "create workspace session start": "创建 工作区 会话 开始", - "create tab add": "创建 标签页 添加", - "divide pane layout side": "拆分 窗格 布局 侧边", - "divide pane layout below": "拆分 窗格 布局 下方", - "maximize fullscreen full screen focus": "最大化 全屏 专注", - "lens chat terminal conversation": "视图 聊天 终端 对话", - "panel drawer hide show": "侧边栏 抽屉 隐藏 显示", - "dark light mode appearance colors": "深色 浅色 模式 外观 颜色", - "preferences options config": "偏好 选项 配置", - "remote machine computer connect ssh": "远程 机器 电脑 连接 ssh", - "alerts push bell": "提醒 推送 铃", - "logout log out lock": "退出 登出 锁定", - "folder explorer open file": "文件夹 资源管理器 打开文件", - "reload update sync": "重新加载 更新 同步", - "Search shortcuts": "搜索快捷键", - "No shortcuts match.": "没有匹配的快捷键。", - "Record": "录制", - "Press keys…": "请按键…", - "Record shortcut for {name}": "录制 {name} 的快捷键", - "Press the new shortcut, or Escape to cancel.": "请按下新的快捷键,或按 Escape 取消。", - "Hold ⌘, Ctrl or ⌥, with or without Shift, and press a key.": "按住 ⌘、Ctrl 或 ⌥(可同时按 Shift),再按一个键。", - "Hold Ctrl or Alt, with or without Shift, and press a key.": "按住 Ctrl 或 Alt(可同时按 Shift),再按一个键。", - "{keys} is a terminal key: shells, editors and agents use it. Once saved, it no longer reaches the pane.": "{keys} 是终端按键:Shell、编辑器和 Agent 都会使用它。保存后,它将不再传给窗格。", - "Save anyway": "仍然保存", - "That key cannot be a shortcut.": "该键不能用作快捷键。", - "Your browser or operating system keeps that shortcut.": "该快捷键由浏览器或操作系统占用。", "Browse folders": "浏览文件夹", - "Browse installed fonts for {label}": "浏览 {label} 的已安装字体", "Collapse all folders": "折叠所有文件夹", "Dismiss notice": "关闭提示", "Expand all folders": "展开所有文件夹", "Folders": "文件夹", - "Installed fonts": "已安装的字体", - "Installed fonts could not be listed. Type the name instead.": "无法列出已安装的字体。请直接输入名称。", - "No fonts found": "未找到字体", "Notices": "提示", "Open in Files": "在文件中打开", "Pinned folders": "已固定的文件夹", - "Search fonts": "搜索字体", - "Showing the first {count} fonts. Search to narrow the list.": "显示前 {count} 个字体。请搜索以缩小范围。", - "{font} is not monospace. The terminal needs a fixed-width font, so the current font was kept.": "{font} 不是等宽字体。终端需要等宽字体,因此保留了当前字体。", // t3code ports (d) "Image viewer": "图片查看器", "Copy image": "复制图片", @@ -1436,11 +1166,6 @@ export const ZH: Record = { "Next image": "下一张图片", "{n} of {count}": "第 {n} 张,共 {count} 张", "Couldn't copy the image. Download it instead.": "无法复制图片。请改为下载。", - "Typography": "字体排印", - "Interface font size": "界面字号", - "Menus, lists, dialogs and the sidebar. The chat follows it until it has a size of its own; the terminal keeps its own.": "适用于菜单、列表、对话框和侧边栏。聊天在设置自己的字号前跟随此值;终端保留自己的字号。", - "Decrease interface font size": "减小界面字号", - "Increase interface font size": "增大界面字号", "Working folder": "工作文件夹", "Worktree": "工作树", "Browse folders in the palette": "在命令面板中浏览文件夹", @@ -1448,6 +1173,12 @@ export const ZH: Record = { "Go to turn {n}": "跳到第 {n} 轮", "Show full message": "显示完整消息", "Change PC": "切换电脑", - "This is the demo. Go back to the app's list of PCs to open yours.": "这是演示。回到应用的电脑列表即可打开你自己的电脑。", - "This app shows {address}. Go back to its list of PCs to open another.": "此应用正在显示 {address}。回到电脑列表可打开其他电脑。", }; + +/** The parts ZH is made of; src/lib/i18n.test.ts fails when a key is in two parts, since a spread keeps only the last. */ +export const ZH_PARTS: Record> = { + base: BASE, + settings: SETTINGS_ZH, +}; + +export const ZH: Record = Object.assign({}, ...Object.values(ZH_PARTS)); diff --git a/src/lib/i18n/settings.ja.ts b/src/lib/i18n/settings.ja.ts new file mode 100644 index 0000000000..f1ddfb8f62 --- /dev/null +++ b/src/lib/i18n/settings.ja.ts @@ -0,0 +1,289 @@ +/** + * Japanese for the keys only the settings files use: + * components/SettingsDialog.tsx (with THEME_NAMES), components/KeyBarSettings.tsx, + * components/SettingsControls.tsx, components/TelemetryControls.tsx, lib/paletteSettings.ts. + * Register and fixed terms follow ../i18n.ja.ts; a key another feature also uses goes there. + */ +export const SETTINGS_JA: Record = { + "Direct typing": "直接入力", + "Terminal input mode": "端末入力モード", + "Reset shortcuts": "ショートカットをリセット", + "Bindings apply to this browser and device. Mod+Shift chords leave the terminal its keys; Record also takes other chords with Ctrl, Alt or (on a Mac) ⌘, exactly as pressed.": "ショートカットはこのブラウザーとデバイスに適用されます。Mod+Shiftの組み合わせはターミナルのキーを奪いません。記録ではCtrl、Alt、または(Macでは)⌘を使う他の組み合わせも押したとおりに保存できます。", + "Text selection in focused fields stays native; Tab/list keys are UI-local, not global shortcuts.": "フォーカス中の入力欄でのテキスト選択は標準動作のままです。Tabやリストのキーは UI 内でのみ使い、グローバルショートカットではありません。", + "The mobile key bar sends terminal keys, not app actions.": "モバイルのキー列はアプリ操作ではなく、端末にキーを送ります。", + "Your browser or operating system may intercept {keys}.": "ブラウザーや OS が {keys} を先に処理する場合があります。", + "Reserved": "予約済み", + "Already assigned": "割り当て済み", + "Send keys to terminal": "キーを端末に送る", + "Default": "既定", + "Close settings": "設定を閉じる", + "Appearance": "外観", + "Theme": "テーマ", + "Dark": "ダーク", + "Light": "ライト", + "System": "システム", + "Dark theme": "ダークテーマ", + "Light theme": "ライトテーマ", + "Shown in dark mode": "ダークモードで表示されます", + "Shown in light mode": "ライトモードで表示されます", + "Charcoal": "チャコール", + "Codex": "Codex", + "Amber": "アンバー", + "Catppuccin": "Catppuccin", + "Catppuccin Latte": "Catppuccin Latte", + "Tokyo Night": "Tokyo Night", + "Tokyo Night Day": "Tokyo Night Day", + "Gruvbox": "Gruvbox", + "Gruvbox Light": "Gruvbox Light", + "One Dark": "One Dark", + "One Light": "One Light", + "Solarized": "Solarized", + "Solarized Light": "Solarized Light", + "Kanagawa": "Kanagawa", + "Kanagawa Lotus": "Kanagawa Lotus", + "Rosé Pine": "Rosé Pine", + "Rosé Pine Dawn": "Rosé Pine Dawn", + "Dracula": "Dracula", + "Nord": "Nord", + "Vesper": "Vesper", + "Density": "表示密度", + "Comfortable": "ゆったり", + "Compact": "コンパクト", + "Language": "言語", + "Follows the browser unless you choose one": "選択しない場合はブラウザーの言語に従います", + "Terminal font size": "ターミナルのフォントサイズ", + "Applied to every terminal pane": "すべてのターミナルペインに適用されます", + "Decrease terminal font size": "ターミナルの文字を小さく", + "Increase terminal font size": "ターミナルの文字を大きく", + "Wheel scroll speed": "ホイールのスクロール速度", + "How far one turn of the wheel scrolls the terminal": "ホイール1回でターミナルが動く量", + "Slower wheel scrolling": "ホイールスクロールを遅く", + "Faster wheel scrolling": "ホイールスクロールを速く", + "Terminal font": "ターミナルのフォント", + "Comma-separated, tried in order. A font this device does not have falls back to the default.": "カンマ区切りで、先頭から順に使います。このデバイスにないフォントは既定のフォントで表示します。", + "Composer": "入力欄", + "Enter sends": "Enter で送信", + "Return inserts a new line": "Return で改行", + "When on, use Send or hardware Mod+Enter to send.": "オンの場合は送信ボタン、またはハードウェアキーボードの Mod+Enter で送信します。", + "When off, Mod+Enter sends": "オフの場合は Mod+Enter で送信します", + "Panes open in": "ペインを開く表示", + "Every pane on this device. Switching a pane's lens keeps it there until this changes. Auto: chat for an agent on a touch screen, else the terminal.": "この端末のすべてのペインに適用されます。ペインで表示を切り替えると、この設定を変えるまでその表示で開きます。自動: タッチ画面のエージェントはチャット、それ以外はターミナル。", + "Auto": "自動", + "Show thinking": "思考を表示", + "Include the agent's reasoning blocks": "エージェントの推論ブロックも表示します", + "Chat width": "チャットの幅", + "How wide the conversation and the message box run on a large screen": "大きな画面で会話と入力欄が広がる幅", + "Narrow": "狭い", + "Wide": "広い", + "Full": "全幅", + "Chat font size": "チャットのフォントサイズ", + "Messages, code, prompt cards and the message box in the chat view": "チャット画面のメッセージ、コード、質問カード、入力欄", + "Decrease chat font size": "チャットの文字を小さく", + "Increase chat font size": "チャットの文字を大きく", + "Chat font": "チャットのフォント", + "Message text; code stays monospace. Comma-separated, tried in order. A font this device does not have falls back to the default.": "メッセージ本文に適用され、コードは等幅フォントのままです。カンマ区切りで、先頭から順に使います。このデバイスにないフォントは既定のフォントで表示します。", + "File viewer": "ファイルビューア", + "Wrap long lines": "長い行を折り返す", + "Markdown width": "Markdown の幅", + "Full width": "全幅", + "New agents": "新しいエージェント", + "Applies to agents started from New workspace, New tab and New worktree. Agent default adds no flag, so the agent's own configuration decides.": "新しいワークスペース、新しいタブ、新しいワークツリーから起動するエージェントに適用されます。エージェントの既定はフラグを付けないため、エージェント自身の設定に従います。", + "Permission mode": "権限モード", + "Sandbox and approvals": "サンドボックスと承認", + "Accept edits": "編集を自動で許可", + "Don't ask": "確認しない", + "Bypass permissions": "権限確認をスキップ", + "Read only": "読み取り専用", + "Full access": "フルアクセス", + "Shortcuts": "ショートカット", + "Phone": "スマートフォン", + "Devices": "デバイス", + "Install": "インストール", + "Installed": "インストール済み", + "About": "情報", + "Star on GitHub": "GitHub で Star する", + "Remote PCs": "リモート PC", + "Connect another PC over an SSH alias or user@host. Its workspaces join the sidebar.": "SSH エイリアスまたは user@host で別の PC を接続します。接続した PC のワークスペースはサイドバーに並びます。", + "Update PC bridges automatically": "PC ブリッジを自動更新", + "When an app update needs a newer bridge, PCs that connect with their saved key are updated in the background. PCs that need a password ask first.": "アプリの更新で新しいブリッジが必要になった場合、保存済みのキーで接続する PC はバックグラウンドで更新されます。パスワードが必要な PC では先に確認します。", + "Sign out": "サインアウト", + "Sign out of this browser?": "このブラウザーからサインアウトしますか?", + "Getting back in takes the access token, or a pairing code from the PC: Settings → Phone & devices there, or the pair command in its terminal.": "再び入るにはアクセストークンか、PC のペアリングコードが必要です。コードは PC の設定 → Phone & devices か、PC のターミナルの pair コマンドで表示されます。", + "Forget this browser's sign-in. Getting back in takes the access token or a pairing code.": "このブラウザーのサインインを消去します。再び入るにはアクセストークンかペアリングコードが必要です。", + "Sidebar rows": "サイドバーの行", + "One line": "1 行", + "Two lines": "2 行", + "Agents order": "エージェントの並び順", + "Activity keeps a waiting agent on top, then the one that changed last; herdr's own order is not changed": "アクティビティ順では、応答待ちのエージェントを一番上に、その後は最近変化した順に並べます。herdr 自体の順序は変わりません", + "Workspaces": "ワークスペース順", + "Activity": "アクティビティ順", + "Agent logos": "エージェントのロゴ", + "Draw each agent's logo in its brand colors, or without color": "各エージェントのロゴをブランドの色、または色なしで表示します", + "Color": "カラー", + "Mono": "モノクロ", + "Status indicators": "状態インジケーター", + "Classic marks only the states that ask for a look; Dots and Symbols draw every state as herdr's TUI does": "クラシックは確認が必要な状態だけを示します。ドットと記号は herdr の TUI と同じくすべての状態を示します", + "Classic": "クラシック", + "Dots": "ドット", + "Symbols": "記号", + "herdr plugins": "herdr プラグイン", + "The command palette and its plugin actions are not available in the phone touch UI. Use a wider screen or a keyboard's command palette shortcut.": "スマートフォンのタッチUIでは、コマンドパレットとプラグインの操作は利用できません。より広い画面か、キーボードのコマンドパレット用ショートカットを使ってください。", + "No actions": "操作なし", + "Enabled": "有効", + "Disabled": "無効", + "Key bar": "キーバー", + "Edit key bar": "キーバーを編集", + "Back to settings": "設定に戻る", + "Keys, order and custom combinations for the terminal.": "ターミナルのキー、並び順、キーの組み合わせを設定します。", + "Choose the keys and their order under the terminal. The keyboard mode button stays first.": "ターミナルの下に表示するキーと順序を選びます。キーボードモードのボタンは先頭に固定されます。", + "Key bar keys": "キーバーのキー", + "Held modifier": "固定する修飾キー", + "Saved combination": "保存した組み合わせ", + "Remove {name}": "{name} を削除", + "No keys selected.": "キーが選択されていません。", + "Add key": "キーを追加", + "All keys added": "すべてのキーを追加済み", + "Held modifiers": "固定する修飾キー", + "Custom combination": "カスタムキーの組み合わせ", + "Saved combinations use only the selected modifiers. Other keys use held modifiers.": "保存した組み合わせには選択した修飾キーだけを使います。その他のキーには固定中の修飾キーが適用されます。", + "Base key": "基本キー", + "Single character": "1文字", + "Character": "文字", + "Combination modifiers": "組み合わせの修飾キー", + "Enter one character.": "1文字を入力してください。", + "Add combination": "組み合わせを追加", + "Already added": "追加済み", + "Send queued messages automatically": "送信待ちメッセージを自動で送信", + "A message sent while the agent works goes by itself when the turn ends. When off, it waits until you press Send now.": "エージェントの作業中に送ったメッセージは、ターンが終わると自動で送信されます。オフにすると、「今すぐ送信」を押すまで待ちます。", + "New tab button": "新しいタブボタン", + "A button in the message box opens New tab with an agent… on the pane's workspace. The tab menu offers it either way.": "入力欄のボタンで、このペインのワークスペースに「エージェント付きの新しいタブ…」を開きます。タブメニューからはいつでも開けます。", + "Clipboard from a pane": "ペインからクリップボードへ", + "A program in a pane that copies (vim, tmux, Claude Code) puts its text on this device's clipboard, as a copy you made yourself would. Turn it off if a pane runs output you do not trust: it could replace what you paste next.": "ペインでコピーするプログラム(vim、tmux、Claude Code)は、自分でコピーしたときと同じようにこのデバイスのクリップボードにテキストを入れます。信頼できない出力を実行するペインがある場合はオフにしてください。次に貼り付ける内容が置き換えられることがあります。", + "Use alongside herdr's own window": "ターミナルの herdr と併用", + "Turn this on if this PC also shows herdr in a terminal window. A second after you switch to another window, this tab only watches the pane, so herdr's window keeps the pane at its own size instead of this window's. Click the tab to type again. While it watches, the pane is drawn at herdr's size and may not fill this window.": "この PC のターミナルウィンドウでも herdr を使うならオンにします。別のウィンドウに切り替えて 1 秒たつと、このタブはペインを表示するだけになり、herdr のウィンドウはペインをこのウィンドウではなく自分のサイズのまま保ちます。入力するにはタブをクリックしてください。表示中のペインは herdr のサイズで描かれるため、このウィンドウを埋めないことがあります。", + "Follow herdr's focus": "herdr のフォーカスに追従", + "When herdr moves to another pane, by a click in its window, a herdr command or a script, this device opens that pane too. Only on the PC open here, and only on this device.": "herdr が別のペインに移ると(herdr のウィンドウでのクリック、herdr コマンド、スクリプト)、このデバイスもそのペインを開きます。ここで開いている PC だけで、このデバイスだけに適用されます。", + "Without a key the browser recognizes the speech: Chrome and Edge send the audio to Google or Microsoft. Nothing is recorded until you press the mic.": "キーがない場合はブラウザが音声を認識します。Chrome と Edge は音声を Google または Microsoft に送信します。マイクを押すまで録音されません。", + "Drops fillers and fixes spacing; code and paths stay as spoken": "言いよどみを除き、スペースを整えます。コードとパスはそのまま残します", + "In chat": "チャット", + "Auto: in the chat on a desktop, where dictation can work. On: on a phone and in the terminal input line too.": "自動: デスクトップのチャットで、音声入力が使えるときだけ表示。オン: スマートフォンとターミナルの入力行にも表示。", + "On": "オン", + "In the terminal": "ターミナル", + "Off keeps a command exactly as transcribed": "オフにするとコマンドを書き起こしたまま残します", + "Tidy dictated text": "音声入力テキストを整える", + "Audio is sent to OpenAI with your key. Nothing is recorded until you press the mic.": "音声はあなたのキーを使って OpenAI に送信されます。マイクを押すまで録音されません。", + "Microphone button": "マイクボタン", + "Dictation language": "音声入力の言語", + "Auto listens for the app's language, or for the browser's when the app is not translated into it": "自動ではアプリの言語を聞き取ります。ブラウザの言語にアプリが翻訳されていない場合は、ブラウザの言語を聞き取ります", + "Auto ({language})": "自動({language})", + "No OpenAI key: the browser's speech recognition is used": "OpenAI キーがないため、ブラウザーの音声認識を使用します", + "OpenAI API key": "OpenAI API キー", + "OpenAI key saved on this PC": "OpenAI キーをこの PC に保存しました", + "OpenAI key set by OVIS_OPENAI_API_KEY": "OVIS_OPENAI_API_KEY で OpenAI キーが設定されています", + "Remove key": "キーを削除", + "Save key": "キーを保存", + "Tidy dictated text in chat": "チャットの音声入力テキストを整える", + "Tidy dictated text in the terminal": "ターミナルの音声入力テキストを整える", + "Voice input": "音声入力", + "Not saved on the server yet; reloading or closing this page can undo the change.": "まだサーバーに保存されていません。このページを再読み込みするか閉じると、変更が取り消されることがあります。", + "Sending the change to the server…": "変更をサーバーに送信しています…", + "Keep screen on": "画面をオンのままにする", + "While a terminal or chat pane is open.": "ターミナルやチャットのペインを開いている間、画面をオンに保ちます。", + "Needs HTTPS or localhost.": "HTTPS または localhost が必要です。", + "This browser can't keep the screen on.": "このブラウザーでは画面をオンに保てません。", + "For this device. An alert waits a little first, and none comes when the pane changes meanwhile, as when you answer at the PC.": "このデバイスに適用されます。通知は少し待ってから送られ、その間に PC で回答するなどしてペインの状態が変わった場合は送られません。", + "An agent waits for an answer or a permission": "エージェントが回答や許可を待っているとき", + "Long turns: only work that took a minute or more": "長いターン: 1 分以上かかった作業のみ", + "Off": "オフ", + "Long turns": "長いターン", + "Every turn": "毎ターン", + "In the app": "アプリ内", + "While the app is open, these drop in from the top of the screen at once. Tap one to open its pane.": "アプリを開いている間は、画面の上からすぐに表示されます。タップするとそのペインを開きます。", + "Sound": "サウンド", + "While a tab of the app is open, it chimes for these alerts, also when a Focus or Do Not Disturb silences notifications.": "アプリのタブを開いている間は、これらの通知ごとに音を鳴らします。集中モードやおやすみモードで通知が消音されていても聞こえます。", + "One-tap messages above the message box, on this device. Each is sent as if typed: queued while the agent works, an answer when a question is open.": "メッセージ入力欄の上に表示されるワンタップのメッセージで、このデバイスに適用されます。入力したときと同じように送信され、エージェントの作業中はキューに入り、質問が開いているときは回答になります。", + "Quick reply {number}": "クイック返信 {number}", + "Remove quick reply {number}": "クイック返信 {number} を削除", + "Add reply": "返信を追加", + "Suggestion chip": "提案チップ", + "A chip above the message box puts the prompt Claude Code suggests next into the box. With a keyboard, Tab does it.": "入力欄の上のチップで、Claude Code が次に提案するプロンプトを入力欄に入れます。キーボードでは Tab で入れます。", + "Show above the message box": "入力欄の上に表示", + "Restore defaults": "デフォルトに戻す", + "Ovis sends anonymous usage counts.": "Ovis は匿名の利用集計を送信します。", + "What is sent": "送信内容", + "Anonymous usage counts": "匿名の利用集計", + "Turned off on this PC by OVIS_TELEMETRY=0, DO_NOT_TRACK or a CI environment.": "この PC では OVIS_TELEMETRY=0、DO_NOT_TRACK または CI 環境によりオフになっています。", + "Send anonymous usage counts": "匿名の利用集計を送る", + "Once on install and once per update, with the last browser's app settings, and once a day you open the app, with the kinds of coding agents running in herdr (such as claude or codex). Custom fonts, shortcuts and replies are reported only as customization flags or counts, never their text. Account identifiers, terminal content and files are excluded. The receiver stores the country, not the IP address.": "インストール時に 1 回、更新ごとに 1 回、最後に使用したブラウザーのアプリ設定とともに送信し、アプリを開いた日に 1 回、herdr で動いているコーディングエージェントの種類(claude や codex など)とともに送信します。カスタムフォント、ショートカット、返信は、内容そのものではなく、カスタマイズの有無を示すフラグまたは件数としてのみ報告されます。アカウント識別子、ターミナルの内容、ファイルは含まれません。受信側が保存するのは国であり、IP アドレスではありません。", + "Once a day you open the app:": "アプリを開いた日に 1 回:", + "The receiver adds the country this message comes from (two letters, such as KR). It does not store the address.": "受信側が、このメッセージの送信元の国(KR のような 2 文字)を付け加えます。アドレスは保存しません。", + "This version has already been counted. The next event is sent after an update.": "このバージョンは集計済みです。次の送信は更新の後です。", + "Agent integrations": "エージェント連携", + "This PC's bridge does not offer agent integrations yet. It will after its next runtime update.": "この PC のブリッジはまだエージェント連携に対応していません。次のランタイム更新後に利用できます。", + "herdr's integrations let it resume each agent's session after a restart. This page only reads them: run a command in a terminal on the PC herdr runs on, then reopen this page.": "herdr の連携があると、再起動後に各エージェントのセッションを再開できます。このページは状態を読むだけです。herdr が動いている PC のターミナルでコマンドを実行してから、このページを開き直してください。", + "Not found on this PC": "この PC には見つかりません", + "Installed, but older than this herdr: run this to update it": "インストール済みですが、この herdr より古い版です。このコマンドで更新してください", + "Not installed": "未インストール", + "Copy the command for {name}": "{name} のコマンドをコピー", + "Name each workspace on one line, or show what its agent is doing with the workspace under it": "ワークスペース名だけを 1 行で表示するか、エージェントの作業を上に、ワークスペースを下に表示します", + "Settings can't be shown.": "設定を表示できません。", + "Open files": "ファイルを開く", + "On a wide window, text and code can open beside the pane. Media, PDFs and folders always open in a popup, and the viewer's header button moves the file open now.": "広いウィンドウでは、テキストとコードをペインの横に開けます。メディア、PDF、フォルダーは常にポップアップで開き、ビューアー上部のボタンで今開いているファイルを移動できます。", + "In a popup": "ポップアップで", + "Web links": "Web リンク", + "Only a page this PC serves, such as a dev server on localhost, opens beside the pane. Shift-click opens it the other way.": "localhost の開発サーバーなど、この PC が配信するページだけがペインの横に開きます。Shift キーを押しながらクリックすると、もう一方で開きます。", + "Beside the pane": "ペインの横", + "In a new tab": "新しいタブ", + "A phone shows one column either way.": "スマートフォンではどちらでも1列で表示します。", + "theme themes palette dark light mode colors density language sidebar logos": "テーマ パレット palette ダーク ライト モード 色 密度 言語 サイドバー ロゴ", + "chat font size message width composer enter send thinking code": "チャット フォント 文字サイズ メッセージ 幅 入力欄 エンター 送信 思考 コード", + "terminal font size key bar keyboard clipboard": "ターミナル フォント 文字サイズ キーバー キーボード クリップボード", + "notifications sound push bell needs input finished": "通知 サウンド プッシュ ベル 入力待ち 完了", + "dictation microphone speech openai": "音声入力 マイク 音声 openai", + "plan limits quota meters": "プラン 上限 クォータ メーター", + "keyboard keys bindings hotkeys": "キーボード キー ショートカット キー割り当て", + "phone install keep screen on app": "スマホ インストール 画面オン維持 アプリ", + "machines computers ssh bridge plugins": "マシン コンピューター ssh ブリッジ プラグイン", + "agents hooks claude codex": "エージェント フック claude codex", + "version update release herdr": "バージョン アップデート リリース herdr", + "create workspace session start": "作成 ワークスペース セッション 開始", + "create tab add": "作成 タブ 追加", + "divide pane layout side": "分割 ペイン レイアウト 横", + "divide pane layout below": "分割 ペイン レイアウト 下", + "maximize fullscreen full screen focus": "最大化 フルスクリーン 全画面 フォーカス", + "lens chat terminal conversation": "表示 チャット ターミナル 会話", + "panel drawer hide show": "パネル ドロワー 非表示 表示", + "dark light mode appearance colors": "ダーク ライト モード 外観 色", + "preferences options config": "環境設定 オプション 設定", + "remote machine computer connect ssh": "リモート マシン コンピューター 接続 ssh", + "alerts push bell": "アラート プッシュ ベル", + "logout log out lock": "ログアウト ロック", + "folder explorer open file": "フォルダ エクスプローラー ファイルを開く", + "reload update sync": "再読み込み 更新 同期", + "Search shortcuts": "ショートカットを検索", + "No shortcuts match.": "一致するショートカットはありません。", + "Record": "記録", + "Press keys…": "キーを押してください…", + "Record shortcut for {name}": "{name}のショートカットを記録", + "Press the new shortcut, or Escape to cancel.": "新しいショートカットを押すか、Escapeでキャンセルします。", + "Hold ⌘, Ctrl or ⌥, with or without Shift, and press a key.": "⌘、Ctrl、または⌥を(Shiftの有無にかかわらず)押したままキーを押してください。", + "Hold Ctrl or Alt, with or without Shift, and press a key.": "CtrlまたはAltを(Shiftの有無にかかわらず)押したままキーを押してください。", + "{keys} is a terminal key: shells, editors and agents use it. Once saved, it no longer reaches the pane.": "{keys}はターミナルのキーで、シェル、エディター、エージェントが使います。保存すると、ペインには届かなくなります。", + "Save anyway": "このまま保存", + "That key cannot be a shortcut.": "このキーはショートカットにできません。", + "Your browser or operating system keeps that shortcut.": "このショートカットはブラウザまたはOSが使用します。", + "Browse installed fonts for {label}": "{label}にインストール済みのフォントを参照", + "Installed fonts": "インストール済みのフォント", + "Installed fonts could not be listed. Type the name instead.": "インストール済みのフォントを一覧表示できませんでした。名前を直接入力してください。", + "No fonts found": "フォントが見つかりません", + "Search fonts": "フォントを検索", + "Showing the first {count} fonts. Search to narrow the list.": "最初の {count} 件のフォントを表示しています。検索して絞り込めます。", + "{font} is not monospace. The terminal needs a fixed-width font, so the current font was kept.": "{font} は等幅フォントではありません。ターミナルには等幅フォントが必要なため、現在のフォントを維持しました。", + "Typography": "タイポグラフィ", + "Interface font size": "インターフェースの文字サイズ", + "Menus, lists, dialogs and the sidebar. The chat follows it until it has a size of its own; the terminal keeps its own.": "メニュー、リスト、ダイアログ、サイドバーに適用されます。チャットは独自のサイズを設定するまでこれに従い、ターミナルは独自のサイズを保ちます。", + "Decrease interface font size": "インターフェースの文字サイズを小さく", + "Increase interface font size": "インターフェースの文字サイズを大きく", + "This is the demo. Go back to the app's list of PCs to open yours.": "これはデモです。アプリのPC一覧に戻って、ご自分のPCを開いてください。", + "This app shows {address}. Go back to its list of PCs to open another.": "このアプリは {address} を表示しています。PC一覧に戻ると別のPCを開けます。", +}; diff --git a/src/lib/i18n/settings.ko.ts b/src/lib/i18n/settings.ko.ts new file mode 100644 index 0000000000..19a48dcf6e --- /dev/null +++ b/src/lib/i18n/settings.ko.ts @@ -0,0 +1,289 @@ +/** + * Korean for the keys only the settings files use: + * components/SettingsDialog.tsx (with THEME_NAMES), components/KeyBarSettings.tsx, + * components/SettingsControls.tsx, components/TelemetryControls.tsx, lib/paletteSettings.ts. + * Register and fixed terms follow ../i18n.ko.ts; a key another feature also uses goes there. + */ +export const SETTINGS_KO: Record = { + "Direct typing": "직접 입력", + "Terminal input mode": "터미널 입력 방식", + "Reset shortcuts": "단축키 초기화", + "Bindings apply to this browser and device. Mod+Shift chords leave the terminal its keys; Record also takes other chords with Ctrl, Alt or (on a Mac) ⌘, exactly as pressed.": "단축키는 이 브라우저와 기기에 적용됩니다. Mod+Shift 조합은 터미널 키를 그대로 남겨 두며, 기록 기능으로는 Ctrl, Alt 또는 (Mac에서는) ⌘를 쓰는 다른 조합도 누른 그대로 저장할 수 있습니다.", + "Text selection in focused fields stays native; Tab/list keys are UI-local, not global shortcuts.": "포커스된 입력란의 텍스트 선택은 기본 동작을 따릅니다. Tab/목록 키는 UI 안에서만 작동하며 전역 단축키가 아닙니다.", + "The mobile key bar sends terminal keys, not app actions.": "모바일 키 바는 앱 동작이 아닌 터미널 키를 보냅니다.", + "Your browser or operating system may intercept {keys}.": "브라우저나 운영체제가 {keys} 입력을 가로챌 수 있습니다.", + "Reserved": "예약됨", + "Already assigned": "이미 지정됨", + "Send keys to terminal": "키를 터미널로 전달", + "Default": "기본값", + "Close settings": "설정 닫기", + "Appearance": "모양", + "Theme": "테마", + "Dark": "어둡게", + "Light": "밝게", + "System": "시스템", + "Dark theme": "다크 테마", + "Light theme": "라이트 테마", + "Shown in dark mode": "다크 모드에서 표시됩니다", + "Shown in light mode": "라이트 모드에서 표시됩니다", + "Charcoal": "차콜", + "Codex": "Codex", + "Amber": "앰버", + "Catppuccin": "Catppuccin", + "Catppuccin Latte": "Catppuccin Latte", + "Tokyo Night": "Tokyo Night", + "Tokyo Night Day": "Tokyo Night Day", + "Gruvbox": "Gruvbox", + "Gruvbox Light": "Gruvbox Light", + "One Dark": "One Dark", + "One Light": "One Light", + "Solarized": "Solarized", + "Solarized Light": "Solarized Light", + "Kanagawa": "Kanagawa", + "Kanagawa Lotus": "Kanagawa Lotus", + "Rosé Pine": "Rosé Pine", + "Rosé Pine Dawn": "Rosé Pine Dawn", + "Dracula": "Dracula", + "Nord": "Nord", + "Vesper": "Vesper", + "Density": "밀도", + "Comfortable": "여유", + "Compact": "촘촘", + "Language": "언어", + "Follows the browser unless you choose one": "따로 고르지 않으면 브라우저 언어를 따릅니다", + "Terminal font size": "터미널 글자 크기", + "Applied to every terminal pane": "모든 터미널 패널에 적용됩니다", + "Decrease terminal font size": "터미널 글자 작게", + "Increase terminal font size": "터미널 글자 크게", + "Wheel scroll speed": "휠 스크롤 속도", + "How far one turn of the wheel scrolls the terminal": "휠을 한 번 굴릴 때 터미널이 움직이는 정도", + "Slower wheel scrolling": "휠 스크롤 느리게", + "Faster wheel scrolling": "휠 스크롤 빠르게", + "Terminal font": "터미널 글꼴", + "Comma-separated, tried in order. A font this device does not have falls back to the default.": "쉼표로 구분하며 앞에서부터 차례로 사용합니다. 이 기기에 없는 글꼴은 기본 글꼴로 대체합니다.", + "Composer": "입력창", + "Enter sends": "Enter로 보내기", + "Return inserts a new line": "Return으로 줄바꿈", + "When on, use Send or hardware Mod+Enter to send.": "켜면 전송 버튼이나 하드웨어 키보드의 Mod+Enter로 전송합니다.", + "When off, Mod+Enter sends": "끄면 Mod+Enter로 보냅니다", + "Panes open in": "패널 기본 화면", + "Every pane on this device. Switching a pane's lens keeps it there until this changes. Auto: chat for an agent on a touch screen, else the terminal.": "이 기기의 모든 패널에 적용됩니다. 패널에서 화면을 바꾸면 이 설정을 다시 바꿀 때까지 그 화면으로 열립니다. 자동: 터치 화면의 에이전트는 채팅, 그 밖에는 터미널.", + "Auto": "자동", + "Show thinking": "생각 표시", + "Include the agent's reasoning blocks": "에이전트의 추론 블록을 함께 보여줍니다", + "Chat width": "채팅 너비", + "How wide the conversation and the message box run on a large screen": "큰 화면에서 대화와 입력창이 차지하는 너비", + "Narrow": "좁게", + "Wide": "넓게", + "Full": "전체", + "Chat font size": "채팅 글자 크기", + "Messages, code, prompt cards and the message box in the chat view": "채팅 화면의 메시지, 코드, 프롬프트 카드, 입력창", + "Decrease chat font size": "채팅 글자 작게", + "Increase chat font size": "채팅 글자 크게", + "Chat font": "채팅 글꼴", + "Message text; code stays monospace. Comma-separated, tried in order. A font this device does not have falls back to the default.": "메시지 본문에 적용되며 코드는 고정폭 글꼴을 유지합니다. 쉼표로 구분하며 앞에서부터 차례로 사용합니다. 이 기기에 없는 글꼴은 기본 글꼴로 대체합니다.", + "File viewer": "파일 뷰어", + "Wrap long lines": "긴 줄 바꿈", + "Markdown width": "Markdown 너비", + "Full width": "전체 너비", + "New agents": "새 에이전트", + "Applies to agents started from New workspace, New tab and New worktree. Agent default adds no flag, so the agent's own configuration decides.": "새 워크스페이스, 새 탭, 새 워크트리에서 시작하는 에이전트에 적용됩니다. 에이전트 기본값은 플래그를 붙이지 않으므로 에이전트 자체 설정을 따릅니다.", + "Permission mode": "권한 모드", + "Sandbox and approvals": "샌드박스와 승인", + "Accept edits": "편집 자동 허용", + "Don't ask": "묻지 않기", + "Bypass permissions": "권한 확인 건너뛰기", + "Read only": "읽기 전용", + "Full access": "전체 권한", + "Shortcuts": "단축키", + "Phone": "폰", + "Devices": "기기", + "Install": "설치", + "Installed": "설치됨", + "About": "정보", + "Star on GitHub": "GitHub에서 Star 누르기", + "Remote PCs": "원격 PC", + "Connect another PC over an SSH alias or user@host. Its workspaces join the sidebar.": "SSH 별칭이나 user@host로 다른 PC를 연결합니다. 연결한 PC의 워크스페이스는 사이드바에 함께 보입니다.", + "Update PC bridges automatically": "PC 브리지 자동 업데이트", + "When an app update needs a newer bridge, PCs that connect with their saved key are updated in the background. PCs that need a password ask first.": "앱 업데이트에 새 브리지가 필요하면, 저장된 키로 연결되는 PC는 뒤에서 업데이트됩니다. 비밀번호가 필요한 PC는 먼저 묻습니다.", + "Sign out": "로그아웃", + "Sign out of this browser?": "이 브라우저에서 로그아웃할까요?", + "Getting back in takes the access token, or a pairing code from the PC: Settings → Phone & devices there, or the pair command in its terminal.": "다시 들어오려면 액세스 토큰이나 PC의 페어링 코드가 필요합니다. 코드는 PC의 설정 → Phone & devices나 PC 터미널의 pair 명령에서 받습니다.", + "Forget this browser's sign-in. Getting back in takes the access token or a pairing code.": "이 브라우저의 로그인을 지웁니다. 다시 들어오려면 액세스 토큰이나 페어링 코드가 필요합니다.", + "Sidebar rows": "사이드바 행", + "One line": "한 줄", + "Two lines": "두 줄", + "Agents order": "에이전트 정렬", + "Activity keeps a waiting agent on top, then the one that changed last; herdr's own order is not changed": "활동순은 응답을 기다리는 에이전트를 맨 위에 두고, 그다음 가장 최근에 바뀐 순서로 놓습니다. herdr 자체의 순서는 바뀌지 않습니다", + "Workspaces": "워크스페이스순", + "Activity": "활동순", + "Agent logos": "에이전트 로고", + "Draw each agent's logo in its brand colors, or without color": "각 에이전트의 로고를 브랜드 색상 또는 색 없이 표시합니다", + "Color": "색상", + "Mono": "단색", + "Status indicators": "상태 표시", + "Classic marks only the states that ask for a look; Dots and Symbols draw every state as herdr's TUI does": "기본은 확인이 필요한 상태만 표시합니다. 점과 기호는 herdr TUI처럼 모든 상태를 표시합니다", + "Classic": "기본", + "Dots": "점", + "Symbols": "기호", + "herdr plugins": "herdr 플러그인", + "The command palette and its plugin actions are not available in the phone touch UI. Use a wider screen or a keyboard's command palette shortcut.": "휴대전화 터치 UI에서는 명령 팔레트와 플러그인 동작을 사용할 수 없습니다. 더 넓은 화면이나 키보드의 명령 팔레트 단축키를 사용하세요.", + "No actions": "동작 없음", + "Enabled": "사용 중", + "Disabled": "사용 안 함", + "Key bar": "키 바", + "Edit key bar": "키 바 편집", + "Back to settings": "설정으로 돌아가기", + "Keys, order and custom combinations for the terminal.": "터미널 키와 순서, 사용자 조합을 설정합니다.", + "Choose the keys and their order under the terminal. The keyboard mode button stays first.": "터미널 아래에 표시할 키와 순서를 고릅니다. 키보드 모드 버튼은 맨 앞에 유지됩니다.", + "Key bar keys": "키 바의 키", + "Held modifier": "고정 보조 키", + "Saved combination": "저장된 조합", + "Remove {name}": "{name} 제거", + "No keys selected.": "선택한 키가 없습니다.", + "Add key": "키 추가", + "All keys added": "모든 키가 추가됨", + "Held modifiers": "고정 보조 키", + "Custom combination": "사용자 키 조합", + "Saved combinations use only the selected modifiers. Other keys use held modifiers.": "저장된 조합은 선택한 보조 키만 사용합니다. 나머지 키에는 고정한 보조 키가 적용됩니다.", + "Base key": "기본 키", + "Single character": "한 글자", + "Character": "문자", + "Combination modifiers": "조합에 사용할 보조 키", + "Enter one character.": "한 글자를 입력하세요.", + "Add combination": "조합 추가", + "Already added": "이미 추가됨", + "Send queued messages automatically": "대기 메시지 자동 전송", + "A message sent while the agent works goes by itself when the turn ends. When off, it waits until you press Send now.": "에이전트가 작업 중일 때 보낸 메시지는 턴이 끝나면 저절로 전송됩니다. 끄면 지금 보내기를 누를 때까지 기다립니다.", + "New tab button": "새 탭 버튼", + "A button in the message box opens New tab with an agent… on the pane's workspace. The tab menu offers it either way.": "입력창의 버튼으로 이 패널의 워크스페이스에 에이전트와 함께 새 탭…을 엽니다. 탭 메뉴에서는 언제든 열 수 있습니다.", + "Clipboard from a pane": "패널에서 클립보드로 복사", + "A program in a pane that copies (vim, tmux, Claude Code) puts its text on this device's clipboard, as a copy you made yourself would. Turn it off if a pane runs output you do not trust: it could replace what you paste next.": "패널에서 복사하는 프로그램(vim, tmux, Claude Code)은 직접 복사한 것과 같이 이 기기의 클립보드에 텍스트를 넣습니다. 믿을 수 없는 출력을 실행하는 패널이 있다면 끄세요. 다음에 붙여 넣을 내용이 바뀔 수 있습니다.", + "Use alongside herdr's own window": "터미널의 herdr와 같이 쓰기", + "Turn this on if this PC also shows herdr in a terminal window. A second after you switch to another window, this tab only watches the pane, so herdr's window keeps the pane at its own size instead of this window's. Click the tab to type again. While it watches, the pane is drawn at herdr's size and may not fill this window.": "이 PC의 터미널 창에서도 herdr를 띄워 쓴다면 켜세요. 다른 창으로 옮기고 1초가 지나면 이 탭은 패널을 보기만 해서, herdr 창이 패널을 이 창 크기가 아닌 자기 크기로 유지합니다. 다시 입력하려면 탭을 클릭하세요. 보는 동안 패널은 herdr 크기로 그려져 이 창을 다 채우지 않을 수 있습니다.", + "Follow herdr's focus": "herdr 포커스 따라가기", + "When herdr moves to another pane, by a click in its window, a herdr command or a script, this device opens that pane too. Only on the PC open here, and only on this device.": "herdr가 다른 패널로 옮겨 가면(herdr 창에서 클릭, herdr 명령, 스크립트) 이 기기도 그 패널을 엽니다. 여기서 연 PC에서만, 이 기기에서만 적용됩니다.", + "Without a key the browser recognizes the speech: Chrome and Edge send the audio to Google or Microsoft. Nothing is recorded until you press the mic.": "키가 없으면 브라우저가 음성을 인식합니다. Chrome과 Edge는 오디오를 Google이나 Microsoft로 보냅니다. 마이크를 누르기 전에는 녹음되지 않습니다.", + "Drops fillers and fixes spacing; code and paths stay as spoken": "군말을 지우고 띄어쓰기를 고칩니다. 코드와 경로는 말한 그대로 둡니다", + "In chat": "채팅", + "Auto: in the chat on a desktop, where dictation can work. On: on a phone and in the terminal input line too.": "자동: 데스크톱 채팅에서 받아쓰기가 가능할 때만 표시. 켜기: 휴대폰과 터미널 입력줄에도 표시.", + "On": "켜기", + "In the terminal": "터미널", + "Off keeps a command exactly as transcribed": "끄면 명령을 받아쓴 그대로 둡니다", + "Tidy dictated text": "받아쓴 텍스트 다듬기", + "Audio is sent to OpenAI with your key. Nothing is recorded until you press the mic.": "오디오가 사용자의 키로 OpenAI에 전송됩니다. 마이크를 누르기 전에는 녹음되지 않습니다.", + "Microphone button": "마이크 버튼", + "Dictation language": "받아쓰기 언어", + "Auto listens for the app's language, or for the browser's when the app is not translated into it": "자동은 앱 언어로 듣고, 앱이 브라우저 언어로 번역되어 있지 않으면 브라우저 언어로 듣습니다", + "Auto ({language})": "자동 ({language})", + "No OpenAI key: the browser's speech recognition is used": "OpenAI 키가 없어 브라우저의 음성 인식을 사용합니다", + "OpenAI API key": "OpenAI API 키", + "OpenAI key saved on this PC": "OpenAI 키가 이 PC에 저장되었습니다", + "OpenAI key set by OVIS_OPENAI_API_KEY": "OVIS_OPENAI_API_KEY 환경 변수에 OpenAI 키가 설정되어 있습니다", + "Remove key": "키 삭제", + "Save key": "키 저장", + "Tidy dictated text in chat": "채팅 받아쓰기 텍스트 다듬기", + "Tidy dictated text in the terminal": "터미널 받아쓰기 텍스트 다듬기", + "Voice input": "음성 입력", + "Not saved on the server yet; reloading or closing this page can undo the change.": "서버에\u00a0아직 저장되지\u00a0않았습니다. 이\u00a0페이지를 새로\u00a0고치거나\u00a0닫으면 변경이\u00a0취소될\u00a0수\u00a0있습니다.", + "Sending the change to the server…": "변경을 서버로\u00a0보내는\u00a0중…", + "Keep screen on": "화면 켜짐 유지", + "While a terminal or chat pane is open.": "터미널이나 채팅 패널을 보는 동안 화면을 켜 둡니다.", + "Needs HTTPS or localhost.": "HTTPS 또는 localhost가 필요합니다.", + "This browser can't keep the screen on.": "이 브라우저는 화면을 켜 둘 수 없습니다.", + "For this device. An alert waits a little first, and none comes when the pane changes meanwhile, as when you answer at the PC.": "이 기기에 적용됩니다. 알림은 잠시 기다렸다가 보내며, 그사이 PC에서 답하는 등 pane 상태가 바뀌면 보내지 않습니다.", + "An agent waits for an answer or a permission": "에이전트가 답이나 권한을 기다릴 때", + "Long turns: only work that took a minute or more": "긴 작업: 1분 이상 걸린 작업만", + "Off": "끄기", + "Long turns": "긴 작업", + "Every turn": "매번", + "In the app": "앱 안에서", + "While the app is open, these drop in from the top of the screen at once. Tap one to open its pane.": "앱을 열어 둔 동안에는 화면 위에서 바로 내려옵니다. 누르면 그 패널을 엽니다.", + "Sound": "소리", + "While a tab of the app is open, it chimes for these alerts, also when a Focus or Do Not Disturb silences notifications.": "앱 탭을 열어 둔 동안에는 이 알림마다 소리를 냅니다. 집중 모드나 방해 금지 모드로 알림이 꺼져 있어도 들립니다.", + "One-tap messages above the message box, on this device. Each is sent as if typed: queued while the agent works, an answer when a question is open.": "메시지 입력창 위에 놓이는 한 번 탭 메시지로, 이 기기에 적용됩니다. 직접 입력한 것처럼 보내므로 에이전트가 작업 중이면 대기열에 들어가고, 질문이 열려 있으면 답으로 쓰입니다.", + "Quick reply {number}": "빠른 답장 {number}", + "Remove quick reply {number}": "빠른 답장 {number} 삭제", + "Add reply": "답장 추가", + "Suggestion chip": "제안 칩", + "A chip above the message box puts the prompt Claude Code suggests next into the box. With a keyboard, Tab does it.": "입력창 위의 칩을 누르면 Claude Code가 제안한 다음 프롬프트가 입력창에 들어갑니다. 키보드에서는 Tab으로 넣습니다.", + "Show above the message box": "입력창 위에 표시", + "Restore defaults": "기본값으로 되돌리기", + "Ovis sends anonymous usage counts.": "Ovis는 사용 현황을 익명으로 집계합니다.", + "What is sent": "보내는 내용", + "Anonymous usage counts": "익명 사용 집계", + "Turned off on this PC by OVIS_TELEMETRY=0, DO_NOT_TRACK or a CI environment.": "이 PC에서는 OVIS_TELEMETRY=0, DO_NOT_TRACK 또는 CI 환경 때문에 꺼져 있습니다.", + "Send anonymous usage counts": "익명 사용 집계 보내기", + "Once on install and once per update, with the last browser's app settings, and once a day you open the app, with the kinds of coding agents running in herdr (such as claude or codex). Custom fonts, shortcuts and replies are reported only as customization flags or counts, never their text. Account identifiers, terminal content and files are excluded. The receiver stores the country, not the IP address.": "앱 설치 시 한 번, 업데이트마다 한 번, 마지막으로 사용한 브라우저의 앱 설정과 함께 보내고, 앱을 여는 날마다 한 번, herdr에서 실행 중인 코딩 에이전트의 종류(claude, codex 등)와 함께 보냅니다. 사용자 지정 글꼴, 바로 가기 및 답변은 텍스트가 아니라 사용자 지정 여부 플래그나 개수로만 보고됩니다. 계정 식별자, 터미널 내용 및 파일은 제외됩니다. 받는 쪽은 IP 주소가 아닌 국가를 저장합니다.", + "Once a day you open the app:": "앱을 여는 날마다 한 번:", + "The receiver adds the country this message comes from (two letters, such as KR). It does not store the address.": "받는 쪽에서 이 메시지를 보낸 국가(KR 같은 두 글자)를 덧붙입니다. 주소는 저장하지 않습니다.", + "This version has already been counted. The next event is sent after an update.": "이 버전은 이미 집계되었습니다. 다음 전송은 업데이트 후입니다.", + "Agent integrations": "에이전트 통합", + "herdr's integrations let it resume each agent's session after a restart. This page only reads them: run a command in a terminal on the PC herdr runs on, then reopen this page.": "herdr 통합이 있으면 재시작 후 각 에이전트의 세션을 이어서 열 수 있습니다. 이 페이지는 상태를 읽기만 합니다. herdr가 실행되는 PC의 터미널에서 명령을 실행한 뒤 이 페이지를 다시 여세요.", + "Not found on this PC": "이 PC에서 찾을 수 없음", + "Installed, but older than this herdr: run this to update it": "설치되어 있지만 이 herdr보다 오래되었습니다. 이 명령으로 업데이트하세요", + "Not installed": "설치되지 않음", + "Copy the command for {name}": "{name} 명령 복사", + "This PC's bridge does not offer agent integrations yet. It will after its next runtime update.": "이 PC의 브리지는 아직 에이전트 통합을 제공하지 않습니다. 다음 런타임 업데이트 후에 사용할 수 있습니다.", + "Name each workspace on one line, or show what its agent is doing with the workspace under it": "워크스페이스 이름만 한 줄로 보여주거나, 에이전트가 하는 작업을 위에 두고 워크스페이스를 아래에 보여줍니다", + "Settings can't be shown.": "설정을 표시할 수 없습니다.", + "Open files": "파일 열기", + "On a wide window, text and code can open beside the pane. Media, PDFs and folders always open in a popup, and the viewer's header button moves the file open now.": "넓은 창에서는 텍스트와 코드를 창 옆에 열 수 있습니다. 미디어, PDF, 폴더는 항상 팝업으로 열리고, 뷰어 위쪽 버튼으로 지금 연 파일을 옮길 수 있습니다.", + "In a popup": "팝업으로", + "Web links": "웹 링크", + "Only a page this PC serves, such as a dev server on localhost, opens beside the pane. Shift-click opens it the other way.": "localhost 개발 서버처럼 이 PC가 여는 페이지만 창 옆에 열립니다. Shift-클릭하면 반대쪽으로 엽니다.", + "Beside the pane": "창 옆에", + "In a new tab": "새 탭에서", + "A phone shows one column either way.": "휴대전화에서는 어느 쪽이든 한 열로 표시됩니다.", + "theme themes palette dark light mode colors density language sidebar logos": "테마 팔레트 palette 다크 라이트 모드 색상 밀도 언어 사이드바 로고", + "chat font size message width composer enter send thinking code": "채팅 글꼴 글자 크기 메시지 너비 입력창 엔터 보내기 생각 코드", + "terminal font size key bar keyboard clipboard": "터미널 글꼴 글자 크기 키 바 키보드 클립보드", + "notifications sound push bell needs input finished": "알림 소리 푸시 벨 입력 필요 완료", + "dictation microphone speech openai": "받아쓰기 마이크 음성 openai", + "plan limits quota meters": "요금제 한도 할당량 미터", + "keyboard keys bindings hotkeys": "키보드 키 단축키 바인딩", + "phone install keep screen on app": "휴대폰 설치 화면 켜짐 유지 앱", + "machines computers ssh bridge plugins": "기기 컴퓨터 ssh 브리지 플러그인", + "agents hooks claude codex": "에이전트 훅 claude codex", + "version update release herdr": "버전 업데이트 릴리스 herdr", + "create workspace session start": "만들기 워크스페이스 세션 시작", + "create tab add": "만들기 탭 추가", + "divide pane layout side": "나누기 패널 레이아웃 옆", + "divide pane layout below": "나누기 패널 레이아웃 아래", + "maximize fullscreen full screen focus": "최대화 전체 화면 집중", + "lens chat terminal conversation": "보기 채팅 터미널 대화", + "panel drawer hide show": "패널 서랍 숨기기 보기", + "dark light mode appearance colors": "다크 라이트 모드 외관 색상", + "preferences options config": "환경설정 옵션 구성", + "remote machine computer connect ssh": "원격 기기 컴퓨터 연결 ssh", + "alerts push bell": "알림 푸시 벨", + "logout log out lock": "로그아웃 잠금", + "folder explorer open file": "폴더 탐색기 파일 열기", + "reload update sync": "새로고침 업데이트 동기화", + "Search shortcuts": "단축키 검색", + "No shortcuts match.": "일치하는 단축키가 없습니다.", + "Record": "기록", + "Press keys…": "키를 누르세요…", + "Record shortcut for {name}": "{name}의 단축키 기록", + "Press the new shortcut, or Escape to cancel.": "새 단축키를 누르거나 Escape로 취소하세요.", + "Hold ⌘, Ctrl or ⌥, with or without Shift, and press a key.": "⌘, Ctrl 또는 ⌥를 누른 채 키를 누르세요. Shift는 함께 눌러도 되고 안 눌러도 됩니다.", + "Hold Ctrl or Alt, with or without Shift, and press a key.": "Ctrl 또는 Alt를 누른 채 키를 누르세요. Shift는 함께 눌러도 되고 안 눌러도 됩니다.", + "{keys} is a terminal key: shells, editors and agents use it. Once saved, it no longer reaches the pane.": "{keys} 키는 터미널 키입니다. 셸, 편집기, 에이전트가 사용하며, 저장하면 더 이상 패널로 전달되지 않습니다.", + "Save anyway": "그래도 저장", + "That key cannot be a shortcut.": "이 키는 단축키로 쓸 수 없습니다.", + "Your browser or operating system keeps that shortcut.": "브라우저나 운영 체제가 이 단축키를 사용합니다.", + "Browse installed fonts for {label}": "{label}에 설치된 글꼴 찾아보기", + "Installed fonts": "설치된 글꼴", + "Installed fonts could not be listed. Type the name instead.": "설치된 글꼴을 불러오지 못했습니다. 이름을 직접 입력하세요.", + "No fonts found": "글꼴을 찾을 수 없습니다", + "Search fonts": "글꼴 검색", + "Showing the first {count} fonts. Search to narrow the list.": "처음 {count}개의 글꼴을 표시합니다. 검색해서 목록을 좁히세요.", + "{font} is not monospace. The terminal needs a fixed-width font, so the current font was kept.": "{font} 글꼴은 고정폭이 아닙니다. 터미널에는 고정폭 글꼴이 필요하여 현재 글꼴을 유지했습니다.", + "Typography": "타이포그래피", + "Interface font size": "인터페이스 글자 크기", + "Menus, lists, dialogs and the sidebar. The chat follows it until it has a size of its own; the terminal keeps its own.": "메뉴, 목록, 대화 상자, 사이드바에 적용됩니다. 채팅은 별도 크기를 정하기 전까지 이 크기를 따르고, 터미널은 자체 크기를 유지합니다.", + "Decrease interface font size": "인터페이스 글자 크기 줄이기", + "Increase interface font size": "인터페이스 글자 크기 키우기", + "This is the demo. Go back to the app's list of PCs to open yours.": "데모 화면입니다. 앱의 PC 목록으로 돌아가 내 PC를 여세요.", + "This app shows {address}. Go back to its list of PCs to open another.": "이 앱은 {address}를 보여 주고 있습니다. PC 목록으로 돌아가 다른 PC를 열 수 있습니다.", +}; diff --git a/src/lib/i18n/settings.zh.ts b/src/lib/i18n/settings.zh.ts new file mode 100644 index 0000000000..376231eaa2 --- /dev/null +++ b/src/lib/i18n/settings.zh.ts @@ -0,0 +1,289 @@ +/** + * Simplified Chinese for the keys only the settings files use: + * components/SettingsDialog.tsx (with THEME_NAMES), components/KeyBarSettings.tsx, + * components/SettingsControls.tsx, components/TelemetryControls.tsx, lib/paletteSettings.ts. + * Register and fixed terms follow ../i18n.zh.ts; a key another feature also uses goes there. + */ +export const SETTINGS_ZH: Record = { + "Direct typing": "直接输入", + "Terminal input mode": "终端输入模式", + "Reset shortcuts": "重置快捷键", + "Bindings apply to this browser and device. Mod+Shift chords leave the terminal its keys; Record also takes other chords with Ctrl, Alt or (on a Mac) ⌘, exactly as pressed.": "快捷键仅应用于此浏览器和设备。Mod+Shift 组合不会占用终端按键;录制时也可使用 Ctrl、Alt 或(在 Mac 上)⌘ 的其他组合,按原样保存。", + "Text selection in focused fields stays native; Tab/list keys are UI-local, not global shortcuts.": "焦点位于文本输入框时,文本选择仍由系统处理;Tab/列表按键仅在界面内生效,不是全局快捷键。", + "The mobile key bar sends terminal keys, not app actions.": "手机上的按键栏发送终端按键,不会触发应用操作。", + "Your browser or operating system may intercept {keys}.": "浏览器或操作系统可能会拦截 {keys}。", + "Reserved": "系统保留", + "Already assigned": "已分配", + "Send keys to terminal": "将按键发送到终端", + "Default": "默认", + "Close settings": "关闭设置", + "Appearance": "外观", + "Theme": "主题", + "Dark": "深色", + "Light": "浅色", + "System": "跟随系统", + "Dark theme": "深色主题", + "Light theme": "浅色主题", + "Shown in dark mode": "在深色模式下显示", + "Shown in light mode": "在浅色模式下显示", + "Charcoal": "炭灰", + "Codex": "Codex", + "Amber": "琥珀", + "Catppuccin": "Catppuccin", + "Catppuccin Latte": "Catppuccin Latte", + "Tokyo Night": "Tokyo Night", + "Tokyo Night Day": "Tokyo Night Day", + "Gruvbox": "Gruvbox", + "Gruvbox Light": "Gruvbox Light", + "One Dark": "One Dark", + "One Light": "One Light", + "Solarized": "Solarized", + "Solarized Light": "Solarized Light", + "Kanagawa": "Kanagawa", + "Kanagawa Lotus": "Kanagawa Lotus", + "Rosé Pine": "Rosé Pine", + "Rosé Pine Dawn": "Rosé Pine Dawn", + "Dracula": "Dracula", + "Nord": "Nord", + "Vesper": "Vesper", + "Density": "密度", + "Comfortable": "宽松", + "Compact": "紧凑", + "Language": "语言", + "Follows the browser unless you choose one": "未选择时跟随浏览器语言", + "Terminal font size": "终端字号", + "Applied to every terminal pane": "应用于所有终端窗格", + "Decrease terminal font size": "减小终端字号", + "Increase terminal font size": "增大终端字号", + "Wheel scroll speed": "滚轮滚动速度", + "How far one turn of the wheel scrolls the terminal": "滚轮滚动一次时终端移动的距离", + "Slower wheel scrolling": "滚轮滚动更慢", + "Faster wheel scrolling": "滚轮滚动更快", + "Terminal font": "终端字体", + "Comma-separated, tried in order. A font this device does not have falls back to the default.": "以逗号分隔,按顺序使用。此设备上没有的字体会回退到默认字体。", + "Composer": "输入框", + "Enter sends": "按 Enter 发送", + "Return inserts a new line": "按 Return 换行", + "When on, use Send or hardware Mod+Enter to send.": "开启后,点击发送按钮或使用实体键盘按 Mod+Enter 发送。", + "When off, Mod+Enter sends": "关闭后按 Mod+Enter 发送", + "Panes open in": "窗格默认视图", + "Every pane on this device. Switching a pane's lens keeps it there until this changes. Auto: chat for an agent on a touch screen, else the terminal.": "适用于此设备上的所有窗格。在窗格中切换视图后,在更改此设置之前都会以该视图打开。自动:触屏上的智能体为聊天,其余为终端。", + "Auto": "自动", + "Show thinking": "显示思考过程", + "Include the agent's reasoning blocks": "一并显示 Agent 的推理块", + "Chat width": "聊天宽度", + "How wide the conversation and the message box run on a large screen": "大屏幕上对话和输入框的宽度", + "Narrow": "窄", + "Wide": "宽", + "Full": "全宽", + "Chat font size": "聊天字号", + "Messages, code, prompt cards and the message box in the chat view": "聊天视图中的消息、代码、提问卡片和输入框", + "Decrease chat font size": "减小聊天字号", + "Increase chat font size": "增大聊天字号", + "Chat font": "聊天字体", + "Message text; code stays monospace. Comma-separated, tried in order. A font this device does not have falls back to the default.": "用于消息正文,代码仍使用等宽字体。以逗号分隔,按顺序使用。此设备上没有的字体会回退到默认字体。", + "File viewer": "文件查看器", + "Wrap long lines": "长行自动换行", + "Markdown width": "Markdown 宽度", + "Full width": "全宽", + "New agents": "新代理", + "Applies to agents started from New workspace, New tab and New worktree. Agent default adds no flag, so the agent's own configuration decides.": "适用于从新建工作区、新建标签页和新建工作树启动的代理。代理默认不添加任何参数,由代理自身的配置决定。", + "Permission mode": "权限模式", + "Sandbox and approvals": "沙箱与审批", + "Accept edits": "自动接受编辑", + "Don't ask": "不询问", + "Bypass permissions": "跳过权限检查", + "Read only": "只读", + "Full access": "完全访问", + "Shortcuts": "快捷键", + "Phone": "手机", + "Devices": "设备", + "Install": "安装", + "Installed": "已安装", + "About": "关于", + "Star on GitHub": "在 GitHub 上点 Star", + "Remote PCs": "远程 PC", + "Connect another PC over an SSH alias or user@host. Its workspaces join the sidebar.": "通过 SSH 别名或 user@host 连接另一台 PC。连接后,它的工作区会显示在侧栏中。", + "Update PC bridges automatically": "自动更新 PC 的 bridge", + "When an app update needs a newer bridge, PCs that connect with their saved key are updated in the background. PCs that need a password ask first.": "当应用更新需要更新的 bridge 时,使用已保存密钥连接的 PC 会在后台更新。需要密码的 PC 会先询问。", + "Sign out": "退出登录", + "Sign out of this browser?": "要从此浏览器退出登录吗?", + "Getting back in takes the access token, or a pairing code from the PC: Settings → Phone & devices there, or the pair command in its terminal.": "再次进入需要访问令牌,或 PC 上的配对码:在 PC 的设置 → Phone & devices 中,或在其终端运行 pair 命令获取。", + "Forget this browser's sign-in. Getting back in takes the access token or a pairing code.": "清除此浏览器的登录。再次进入需要访问令牌或配对码。", + "Sidebar rows": "侧边栏行", + "One line": "单行", + "Two lines": "双行", + "Agents order": "代理排序", + "Activity keeps a waiting agent on top, then the one that changed last; herdr's own order is not changed": "按活动排序会把等待回应的代理放在最上面,其余按最近变化排序;herdr 自身的顺序不会改变", + "Workspaces": "工作区顺序", + "Activity": "按活动", + "Agent logos": "代理标志", + "Draw each agent's logo in its brand colors, or without color": "用品牌颜色或无色显示每个代理的标志", + "Color": "彩色", + "Mono": "单色", + "Status indicators": "状态指示", + "Classic marks only the states that ask for a look; Dots and Symbols draw every state as herdr's TUI does": "经典只标出需要查看的状态;圆点和符号像 herdr 的 TUI 一样显示每种状态", + "Classic": "经典", + "Dots": "圆点", + "Symbols": "符号", + "herdr plugins": "herdr 插件", + "The command palette and its plugin actions are not available in the phone touch UI. Use a wider screen or a keyboard's command palette shortcut.": "手机触控界面不提供命令面板及其中的插件操作。请使用更宽的屏幕,或通过键盘的命令面板快捷键打开。", + "No actions": "无操作", + "Enabled": "已启用", + "Disabled": "已停用", + "Key bar": "按键栏", + "Edit key bar": "编辑按键栏", + "Back to settings": "返回设置", + "Keys, order and custom combinations for the terminal.": "设置终端按键、顺序和自定义组合。", + "Choose the keys and their order under the terminal. The keyboard mode button stays first.": "选择终端下方显示的按键及其顺序。键盘模式按钮固定在最前面。", + "Key bar keys": "按键栏中的按键", + "Held modifier": "保持按下的修饰键", + "Saved combination": "已保存的组合键", + "Remove {name}": "移除 {name}", + "No keys selected.": "未选择任何按键。", + "Add key": "添加按键", + "All keys added": "所有按键均已添加", + "Held modifiers": "保持按下的修饰键", + "Custom combination": "自定义组合键", + "Saved combinations use only the selected modifiers. Other keys use held modifiers.": "已保存的组合键仅使用选定的修饰键。其他按键使用当前保持按下的修饰键。", + "Base key": "基本按键", + "Single character": "单个字符", + "Character": "字符", + "Combination modifiers": "组合键的修饰键", + "Enter one character.": "请输入一个字符。", + "Add combination": "添加组合键", + "Already added": "已添加", + "Send queued messages automatically": "自动发送排队消息", + "A message sent while the agent works goes by itself when the turn ends. When off, it waits until you press Send now.": "智能体工作时发送的消息会在本轮结束后自动发出。关闭后,消息会等到你按下“立即发送”。", + "New tab button": "新标签页按钮", + "A button in the message box opens New tab with an agent… on the pane's workspace. The tab menu offers it either way.": "输入框中的按钮可在该面板的工作区打开“带代理的新标签页…”。标签页菜单中始终可用。", + "Clipboard from a pane": "从窗格写入剪贴板", + "A program in a pane that copies (vim, tmux, Claude Code) puts its text on this device's clipboard, as a copy you made yourself would. Turn it off if a pane runs output you do not trust: it could replace what you paste next.": "窗格中执行复制的程序(vim、tmux、Claude Code)会像你自己复制一样把文本写入此设备的剪贴板。如果窗格运行你不信任的输出,请关闭它:它可能替换你下次粘贴的内容。", + "Use alongside herdr's own window": "与终端里的 herdr 一起使用", + "Turn this on if this PC also shows herdr in a terminal window. A second after you switch to another window, this tab only watches the pane, so herdr's window keeps the pane at its own size instead of this window's. Click the tab to type again. While it watches, the pane is drawn at herdr's size and may not fill this window.": "如果这台电脑的终端窗口里也开着 herdr,请打开此项。切换到其他窗口一秒后,此标签页只查看窗格,herdr 窗口会按自己的尺寸而不是此窗口的尺寸保留窗格。点击标签页即可再次输入。查看期间窗格按 herdr 的尺寸绘制,可能不会填满此窗口。", + "Follow herdr's focus": "跟随 herdr 的焦点", + "When herdr moves to another pane, by a click in its window, a herdr command or a script, this device opens that pane too. Only on the PC open here, and only on this device.": "herdr 切换到另一个窗格时(在 herdr 窗口中点击、herdr 命令或脚本),此设备也会打开该窗格。仅适用于这里打开的 PC,且仅适用于此设备。", + "Without a key the browser recognizes the speech: Chrome and Edge send the audio to Google or Microsoft. Nothing is recorded until you press the mic.": "没有密钥时由浏览器识别语音:Chrome 和 Edge 会把音频发送给 Google 或 Microsoft。按下麦克风前不会录音。", + "Drops fillers and fixes spacing; code and paths stay as spoken": "去掉口头禅并修正空格;代码和路径保持原样", + "In chat": "聊天", + "Auto: in the chat on a desktop, where dictation can work. On: on a phone and in the terminal input line too.": "自动:仅在桌面端聊天中、可以听写时显示。开启:在手机和终端输入行也显示。", + "On": "开启", + "In the terminal": "终端", + "Off keeps a command exactly as transcribed": "关闭后命令保持转写原样", + "Tidy dictated text": "整理听写文本", + "Audio is sent to OpenAI with your key. Nothing is recorded until you press the mic.": "音频会使用你的密钥发送到 OpenAI。按下麦克风前不会录音。", + "Microphone button": "麦克风按钮", + "Dictation language": "听写语言", + "Auto listens for the app's language, or for the browser's when the app is not translated into it": "自动时识别应用的语言;若应用没有浏览器语言的译文,则识别浏览器的语言", + "Auto ({language})": "自动({language})", + "No OpenAI key: the browser's speech recognition is used": "未设置 OpenAI 密钥,将使用浏览器的语音识别", + "OpenAI API key": "OpenAI API 密钥", + "OpenAI key saved on this PC": "OpenAI 密钥已保存在此电脑上", + "OpenAI key set by OVIS_OPENAI_API_KEY": "已通过 OVIS_OPENAI_API_KEY 设置 OpenAI 密钥", + "Remove key": "移除密钥", + "Save key": "保存密钥", + "Tidy dictated text in chat": "整理聊天中的听写文本", + "Tidy dictated text in the terminal": "整理终端中的听写文本", + "Voice input": "语音输入", + "Not saved on the server yet; reloading or closing this page can undo the change.": "尚未保存到服务器;重新加载或关闭此页面可能会撤销此更改。", + "Sending the change to the server…": "正在将更改发送到服务器…", + "Keep screen on": "保持屏幕常亮", + "While a terminal or chat pane is open.": "打开终端或聊天窗格时保持屏幕常亮。", + "Needs HTTPS or localhost.": "需要 HTTPS 或 localhost。", + "This browser can't keep the screen on.": "此浏览器无法保持屏幕常亮。", + "For this device. An alert waits a little first, and none comes when the pane changes meanwhile, as when you answer at the PC.": "仅适用于此设备。提醒会先稍等片刻,如果期间窗格状态发生变化(例如你已在 PC 上回答),则不会发送。", + "An agent waits for an answer or a permission": "Agent 在等待回答或授权时", + "Long turns: only work that took a minute or more": "长任务:仅限耗时 1 分钟或以上的工作", + "Off": "关闭", + "Long turns": "长任务", + "Every turn": "每一轮", + "In the app": "应用内", + "While the app is open, these drop in from the top of the screen at once. Tap one to open its pane.": "应用打开时,这些提醒会立即从屏幕顶部落下。点按即可打开对应的窗格。", + "Sound": "声音", + "While a tab of the app is open, it chimes for these alerts, also when a Focus or Do Not Disturb silences notifications.": "应用的标签页打开时,每条提醒都会响起提示音。即使专注模式或勿扰模式让通知静音,也能听到。", + "One-tap messages above the message box, on this device. Each is sent as if typed: queued while the agent works, an answer when a question is open.": "显示在消息输入框上方的一键消息,仅适用于此设备。每条消息都像手动输入一样发送:Agent 工作时加入队列,有未关闭的问题时作为回答。", + "Quick reply {number}": "快捷回复 {number}", + "Remove quick reply {number}": "删除快捷回复 {number}", + "Add reply": "添加回复", + "Suggestion chip": "建议标签", + "A chip above the message box puts the prompt Claude Code suggests next into the box. With a keyboard, Tab does it.": "输入框上方的标签会把 Claude Code 建议的下一条提示填入输入框。使用键盘时按 Tab 即可。", + "Show above the message box": "显示在输入框上方", + "Restore defaults": "恢复默认值", + "Ovis sends anonymous usage counts.": "Ovis 会匿名发送使用统计。", + "What is sent": "发送的内容", + "Anonymous usage counts": "匿名使用统计", + "Turned off on this PC by OVIS_TELEMETRY=0, DO_NOT_TRACK or a CI environment.": "此电脑因 OVIS_TELEMETRY=0、DO_NOT_TRACK 或 CI 环境而已关闭。", + "Send anonymous usage counts": "发送匿名使用统计", + "Once on install and once per update, with the last browser's app settings, and once a day you open the app, with the kinds of coding agents running in herdr (such as claude or codex). Custom fonts, shortcuts and replies are reported only as customization flags or counts, never their text. Account identifiers, terminal content and files are excluded. The receiver stores the country, not the IP address.": "应用安装时发送一次,每次更新发送一次,并附带最后使用的浏览器中的应用设置;在你打开应用的每一天再发送一次,并附带 herdr 中正在运行的编码代理类型(例如 claude 或 codex)。自定义字体、快捷键和快捷回复仅以自定义标记或数量的形式上报,不会上报其文本。账户标识符、终端内容和文件均不包含在内。接收端保存国家/地区,而非 IP 地址。", + "Once a day you open the app:": "在你打开应用的每一天发送一次:", + "The receiver adds the country this message comes from (two letters, such as KR). It does not store the address.": "接收端会附加这条消息来自的国家(两个字母,例如 KR)。不保存地址。", + "This version has already been counted. The next event is sent after an update.": "此版本已统计。下一次发送在更新之后。", + "Agent integrations": "代理集成", + "This PC's bridge does not offer agent integrations yet. It will after its next runtime update.": "这台 PC 的桥接服务暂不提供代理集成。下次运行时更新后即可使用。", + "herdr's integrations let it resume each agent's session after a restart. This page only reads them: run a command in a terminal on the PC herdr runs on, then reopen this page.": "有了 herdr 集成,重启后可以恢复每个代理的会话。此页面只读取状态:请在运行 herdr 的 PC 的终端中执行命令,然后重新打开此页面。", + "Not found on this PC": "此 PC 上未找到", + "Installed, but older than this herdr: run this to update it": "已安装,但比此 herdr 旧:运行此命令以更新", + "Not installed": "未安装", + "Copy the command for {name}": "复制 {name} 的命令", + "Name each workspace on one line, or show what its agent is doing with the workspace under it": "每个工作区只显示一行名称,或在上方显示智能体正在做的事、下方显示工作区", + "Settings can't be shown.": "无法显示设置。", + "Open files": "打开文件", + "On a wide window, text and code can open beside the pane. Media, PDFs and folders always open in a popup, and the viewer's header button moves the file open now.": "在宽窗口中,文本和代码可以在窗格旁打开。媒体、PDF 和文件夹始终以弹窗打开,查看器顶部的按钮可以移动当前打开的文件。", + "In a popup": "以弹窗", + "Web links": "网页链接", + "Only a page this PC serves, such as a dev server on localhost, opens beside the pane. Shift-click opens it the other way.": "只有这台 PC 提供的页面(例如 localhost 上的开发服务器)会在窗格旁打开。按住 Shift 点击则以另一种方式打开。", + "Beside the pane": "在窗格旁", + "In a new tab": "在新标签页中", + "A phone shows one column either way.": "手机上无论如何都显示为单栏。", + "theme themes palette dark light mode colors density language sidebar logos": "主题 调色板 palette 深色 浅色 模式 颜色 密度 语言 侧边栏 徽标", + "chat font size message width composer enter send thinking code": "聊天 字体 字号 消息 宽度 输入框 回车 发送 思考 代码", + "terminal font size key bar keyboard clipboard": "终端 字体 字号 按键栏 键盘 剪贴板", + "notifications sound push bell needs input finished": "通知 声音 推送 铃 需要输入 完成", + "dictation microphone speech openai": "听写 麦克风 语音 openai", + "plan limits quota meters": "套餐 限额 配额 计量", + "keyboard keys bindings hotkeys": "键盘 按键 快捷键 绑定", + "phone install keep screen on app": "手机 安装 屏幕常亮 应用", + "machines computers ssh bridge plugins": "机器 电脑 ssh 桥接 插件", + "agents hooks claude codex": "Agent 钩子 claude codex", + "version update release herdr": "版本 更新 发布 herdr", + "create workspace session start": "创建 工作区 会话 开始", + "create tab add": "创建 标签页 添加", + "divide pane layout side": "拆分 窗格 布局 侧边", + "divide pane layout below": "拆分 窗格 布局 下方", + "maximize fullscreen full screen focus": "最大化 全屏 专注", + "lens chat terminal conversation": "视图 聊天 终端 对话", + "panel drawer hide show": "侧边栏 抽屉 隐藏 显示", + "dark light mode appearance colors": "深色 浅色 模式 外观 颜色", + "preferences options config": "偏好 选项 配置", + "remote machine computer connect ssh": "远程 机器 电脑 连接 ssh", + "alerts push bell": "提醒 推送 铃", + "logout log out lock": "退出 登出 锁定", + "folder explorer open file": "文件夹 资源管理器 打开文件", + "reload update sync": "重新加载 更新 同步", + "Search shortcuts": "搜索快捷键", + "No shortcuts match.": "没有匹配的快捷键。", + "Record": "录制", + "Press keys…": "请按键…", + "Record shortcut for {name}": "录制 {name} 的快捷键", + "Press the new shortcut, or Escape to cancel.": "请按下新的快捷键,或按 Escape 取消。", + "Hold ⌘, Ctrl or ⌥, with or without Shift, and press a key.": "按住 ⌘、Ctrl 或 ⌥(可同时按 Shift),再按一个键。", + "Hold Ctrl or Alt, with or without Shift, and press a key.": "按住 Ctrl 或 Alt(可同时按 Shift),再按一个键。", + "{keys} is a terminal key: shells, editors and agents use it. Once saved, it no longer reaches the pane.": "{keys} 是终端按键:Shell、编辑器和 Agent 都会使用它。保存后,它将不再传给窗格。", + "Save anyway": "仍然保存", + "That key cannot be a shortcut.": "该键不能用作快捷键。", + "Your browser or operating system keeps that shortcut.": "该快捷键由浏览器或操作系统占用。", + "Browse installed fonts for {label}": "浏览 {label} 的已安装字体", + "Installed fonts": "已安装的字体", + "Installed fonts could not be listed. Type the name instead.": "无法列出已安装的字体。请直接输入名称。", + "No fonts found": "未找到字体", + "Search fonts": "搜索字体", + "Showing the first {count} fonts. Search to narrow the list.": "显示前 {count} 个字体。请搜索以缩小范围。", + "{font} is not monospace. The terminal needs a fixed-width font, so the current font was kept.": "{font} 不是等宽字体。终端需要等宽字体,因此保留了当前字体。", + "Typography": "字体排印", + "Interface font size": "界面字号", + "Menus, lists, dialogs and the sidebar. The chat follows it until it has a size of its own; the terminal keeps its own.": "适用于菜单、列表、对话框和侧边栏。聊天在设置自己的字号前跟随此值;终端保留自己的字号。", + "Decrease interface font size": "减小界面字号", + "Increase interface font size": "增大界面字号", + "This is the demo. Go back to the app's list of PCs to open yours.": "这是演示。回到应用的电脑列表即可打开你自己的电脑。", + "This app shows {address}. Go back to its list of PCs to open another.": "此应用正在显示 {address}。回到电脑列表可打开其他电脑。", +};