diff --git a/packages/experimental/client-ui-forge/README.i18n.yaml b/packages/experimental/client-ui-forge/README.i18n.yaml index 5c5bedb185..4ee0008670 100644 --- a/packages/experimental/client-ui-forge/README.i18n.yaml +++ b/packages/experimental/client-ui-forge/README.i18n.yaml @@ -15,8 +15,8 @@ en: d152484eb41ac6b4 zh: 2f8a621b991260a1 /deepseek-ai-dsh-experimental-client-ui-forge/use-this-package: - en: 10cb328b8b92f077 - zh: 473121a22ce76dfb + en: 675b24649622d158 + zh: 3c27fc1d7e20731f /deepseek-ai-dsh-experimental-client-ui-forge/understand-the-implementation: en: 0cb26601d077a723 zh: af04ea90c3d3b704 diff --git a/packages/experimental/client-ui-forge/README.md b/packages/experimental/client-ui-forge/README.md index e2f55cbc0d..d0db60f333 100644 --- a/packages/experimental/client-ui-forge/README.md +++ b/packages/experimental/client-ui-forge/README.md @@ -27,6 +27,8 @@ This optional two-face package shows the change requests a Session created or pu Enable the [forge bundle](../forge-bundle/README.md) on the Plugins page; it composes this package with the forge registry, the GitHub provider, the Session bindings, and its own [worktree service](../worktree/README.md). +Panel text follows the application language: Chinese, English, Japanese, Spanish, French, German, Russian, or Portuguese. + - **Worktree option** — on the New Session screen, Worktree sits at the right end of the row with the workspace and mode pickers. Checking it shows the base branch, the current branch by default; the menu lists recent local branches. The option is disabled, with the reason in its tooltip, outside a Git checkout, in a read-only Session, and when the checkout or its Git directory lies outside the Session's writable root, as for a project that is itself a linked worktree. Sending the first message hands it to the Session at once, and it waits there while the branch `dsh--<4 random hexadecimal digits>` is created from the base under the repository's `.agents/worktrees/` and its checkout becomes the Session's working directory; the message's turn starts once the worktree exists. - **Creation card** — while the worktree is created, a card above the composer shows the new branch and its two steps, creating the branch and checking out files; More details adds the branch and base. Cancel stops the attempt. After a stopped or failed attempt the message keeps waiting, and the card shows the reason of a failure: Retry tries again with a new branch name, and Continue without a worktree withdraws the request so the message goes on in the current checkout. - **Removed worktree** — when the worktree the Session works in has been removed outside the Session, a card above the composer says so, and a message sent meanwhile waits without starting its turn until the worktree is restored or left; the card then says that the message goes on afterwards. Restore worktree, also offered as Restore in the tab, checks the branch out again at the same directory, or creates the branch again at the commit it started from when the branch is gone too; while it runs, the card follows its two steps, preparing the worktree and checking out files, and the tab's Restore turns into a spinner. Continue in the project moves the Session to the source checkout. Meanwhile the tab's first row shows a warning glyph. diff --git a/packages/experimental/client-ui-forge/README.zh.md b/packages/experimental/client-ui-forge/README.zh.md index 9ac8a38107..957bc62c47 100644 --- a/packages/experimental/client-ui-forge/README.zh.md +++ b/packages/experimental/client-ui-forge/README.zh.md @@ -27,6 +27,8 @@ kind: "package-reference" 在插件页启用 [forge 套件](../forge-bundle/README.zh.md);它把本包与 forge 注册表、GitHub 提供方、Session 绑定以及它自己的 [worktree 服务](../worktree/README.zh.md)组合在一起。 +面板文案跟随应用语言,支持中文、英文、日语、西班牙语、法语、德语、俄语和葡萄牙语。 + - **工作树选项**——在新会话页面上,“工作树”位于工作区与模式选择器那一行的右端。勾选后显示基准分支,默认为当前分支;菜单列出最近的本地分支。不在 Git 检出中、Session 为只读,或检出及其 Git 目录不在 Session 的可写根内(例如项目本身就是链接 worktree)时,该选项不可用,提示中说明原因。发送第一条消息后,消息立即交给 Session 并在那里等待,同时从基准分支在仓库的 `.agents/worktrees/` 下创建分支 `dsh--<4 位随机十六进制数>`,并把它的检出设为 Session 的工作目录;worktree 建好后这条消息的这一轮才开始。 - **创建卡片**——创建 worktree 期间,输入框上方的卡片显示新分支以及“创建分支”“检出文件”两个步骤;“更多详情”会列出分支与基准。“取消”停止这次尝试。尝试被停止或失败后,消息继续等待,失败时卡片显示原因:“重试”换一个新分支名再试;“不使用工作树”撤回请求,消息在当前检出中继续发送。 - **工作树已被删除**——Session 所在的 worktree 在 Session 之外被删除后,输入框上方的卡片会说明这一点;此期间发送的消息会等待、不开始这一轮,直到该 worktree 被恢复或离开,卡片也会说明消息之后会接着发送。“恢复工作树”(标签页中的“恢复”与之相同)在原目录重新检出该分支;分支也已删除时,从它开始时的提交重新创建分支;恢复期间卡片显示“准备工作树”“检出文件”两个步骤,标签页中的“恢复”变为加载状态。“在项目目录继续”把 Session 移回源检出。此期间标签页顶部一行显示警示图标。 diff --git a/packages/experimental/client-ui-forge/src/client/locales.ts b/packages/experimental/client-ui-forge/src/client/locales.ts index f10c40b6d0..b890dac394 100644 --- a/packages/experimental/client-ui-forge/src/client/locales.ts +++ b/packages/experimental/client-ui-forge/src/client/locales.ts @@ -412,3 +412,1203 @@ declare module '@deepseek-ai/dsh-client-ui-slots' { forgePanel: ForgePanelKey } } + +/** Japanese copy with the same keys. */ +export const ja: Record = { + 'tab.title': '変更リクエスト', + 'header.label': 'このセッションの変更リクエスト', + 'header.attention': 'このセッションの変更リクエストに対応が必要です', + 'checkout.worktree': 'ワークツリー', + 'checkout.worktreeFrom': 'ワークツリー · 基点 {base}', + 'checkout.project': 'プロジェクトディレクトリ', + 'checkout.detached': 'ブランチ上にありません', + 'checkout.restore': '復元', + 'checkout.copyWorktreePath': 'ワークツリーのパスをコピー', + 'checkout.copyProjectPath': 'プロジェクトのパスをコピー', + 'checkout.none': 'このディレクトリは Git リポジトリではありません', + 'checkout.failed': 'Git 情報を読み取れませんでした', + 'changes.title': 'このセッションの変更リクエスト · {count}', + 'changes.empty': 'このセッションにはまだ変更リクエストがありません', + 'changes.emptyHint': 'このセッションで作成、表示、編集、チェックアウトした変更リクエストや、現在のブランチまたはプッシュしたブランチで開いている変更リクエストがここに表示されます', + 'changes.local.title': '変更', + 'changes.local.refs': '{head} → {base}', + 'changes.local.files': '{count} ファイル', + 'changes.local.viewAria': 'このセッションの変更を表示:{count} ファイル、{added} 行追加、{deleted} 行削除', + 'changes.local.create': '変更リクエストを作成', + 'changes.local.prompt': 'このセッションの変更について変更リクエストを作成してください', + 'signin.title': '変更リクエストの状態を表示するには {host} にログインしてください', + 'signin.copy': 'ログインコマンドをコピー', + 'signin.unavailable': '{host} の変更リクエストを読み取れませんでした:{message}', + 'refresh': '状態を更新', + 'retry': '再試行', + 'stream.failed': '変更リクエストパネルを読み込めませんでした', + 'change.number': '#{number}', + 'change.stateAria': '変更リクエストの状態:{state}', + 'change.state.open': 'オープン', + 'change.state.blocked': '対応が必要', + 'change.state.draft': '下書き', + 'change.state.merged': 'マージ済み', + 'change.state.closed': 'クローズ済み', + 'change.state.unknown': '不明', + 'change.expand': '{name} を展開', + 'change.collapse': '{name} を折りたたむ', + 'change.ci.none': 'チェックなし', + 'change.ci.running': 'チェック実行中', + 'change.ci.passed': 'チェック成功', + 'change.ci.failed': '{count} 件のチェックが失敗', + 'change.ci.failedUnlisted': 'チェック失敗', + 'change.checks.failed': '{count} 件失敗', + 'change.checks.running': '{count} 件実行中', + 'change.checks.passed': '{count} 件成功', + 'change.checks.other': 'その他 {count} 件', + 'change.checks.truncated': '最初の {count} 件のみ表示', + 'change.check.running': '実行中', + 'change.check.queued': 'キュー待ち', + 'change.flag.changesRequested': '変更が要求されています', + 'change.flag.conflicting': '競合あり', + 'change.flag.draft': '下書き', + 'change.failure.unavailable': '変更リクエストの状態を読み取れませんでした', + 'change.failure.notFound': '変更リクエストが存在しないか、アクセス権がありません', + 'change.failure.unauthenticated': '状態を読むにはログインしてください', + 'change.unserved': 'このコードホストの変更リクエストの状態はまだサポートされていません', + 'change.view': 'ブラウザーで開く', + 'change.copy': '変更リクエストのリンクをコピー', + 'change.viewChangesAria': '{name} の変更を表示:{added} 行追加、{deleted} 行削除', + 'change.remove': 'このセッションから削除', + 'change.removeAria': 'このセッションから {name} を削除', + 'change.row.checks': 'チェック', + 'change.row.review': 'レビュー', + 'change.row.merge': 'マージ', + 'change.row.changes': '変更', + 'change.review.approved': '承認済み', + 'change.review.changesRequested': '変更が要求されています', + 'change.review.required': 'レビュー待ち', + 'change.review.none': 'レビュー未依頼', + 'change.review.threads': '{review} · 未解決 {count} 件', + 'change.merge.mergeable': '競合なし', + 'change.merge.conflicting': '{base} と競合', + 'change.merge.unknown': '競合を確認中', + 'change.mergedTo': '{base} にマージ済み', + 'change.markReady': 'レビュー可能にする', + 'change.merge': 'マージ', + 'change.mergeTitle': '{name} を {base} にマージ', + 'change.mergeMethod.squash': 'スカッシュしてマージ', + 'change.mergeMethod.merge': 'マージコミットを作成', + 'change.mergeMethod.rebase': 'リベースしてマージ', + 'change.mergeNote.squash': 'すべてのコミットを1つにまとめる', + 'change.mergeNote.merge': 'すべてのコミットを保持し、マージコミットを追加', + 'change.mergeNote.rebase': '各コミットを {base} 上にリベース', + 'change.mergeConfirm': 'マージを確認', + 'change.mergeChanged': '新しいコミットがあります。確認してからマージメニューを開き直してください', + 'diff.tab': '変更', + 'diff.tabNumbered': '#{number} の変更', + 'diff.scope.branch': 'ブランチ', + 'diff.scope.uncommitted': '未コミット', + 'diff.scope.unstaged': '未ステージ', + 'diff.scope.staged': 'ステージ済み', + 'diff.scopeNote.branch': '{base} と比較、未コミットの変更を含む', + 'diff.scopeNote.uncommitted': 'HEAD と比較、未追跡ファイルを含む', + 'diff.scopeNote.unstaged': 'インデックスと比較、未追跡ファイルを含む', + 'diff.scopeNote.staged': 'インデックスと HEAD を比較', + 'diff.allFiles': '全 {count} ファイル', + 'diff.refresh': '変更を更新', + 'diff.expandAll': 'すべてのファイルを展開', + 'diff.collapseAll': 'すべてのファイルを折りたたむ', + 'diff.split': '左右に並べて表示', + 'diff.unified': '1列で表示', + 'diff.splitAria': '左右表示', + 'diff.wrap': '長い行を折り返す', + 'diff.nowrap': '長い行を折り返さない', + 'diff.wrapAria': '行を折り返す', + 'diff.unchanged': '未変更 {count} 行', + 'diff.unchangedRest': '残りの未変更行', + 'diff.newFile': '新規ファイル', + 'diff.deletedFile': '削除済み', + 'diff.renamed': '{from} から名前変更', + 'diff.renamedPath': '{from} → {path}', + 'diff.badgeUncommitted': '未コミット', + 'diff.binary': 'バイナリファイルのため変更を表示できません', + 'diff.binaryLabel': 'バイナリ', + 'diff.largeCollapsed': '大きなファイル:変更された {count} 行を折りたたみました', + 'diff.fileTooLarge': 'ファイルが大きすぎて表示できません', + 'diff.error': '変更を読み取れませんでした', + 'diff.tooLarge': '変更が大きすぎるため、ここには表示できません', + 'diff.viewInBrowser': 'ブラウザーで表示', + 'diff.noForkPoint': 'このブランチの分岐点が見つかりません。別の範囲を選んでください', + 'diff.empty': '変更なし', + 'diff.omitted': 'ほかに {count} 個の未追跡ファイルがあります', + 'diff.stale': 'ローカルブランチに未プッシュのコミットが {count} 件あります。ここには変更リクエストの変更を表示しています', + 'diff.moreActions': '{name} のその他の操作', + 'diff.copyPath': 'パスをコピー', + 'diff.openFileInBrowser': 'ブラウザーでファイルを表示', + 'diff.openFileInSidebar': 'サイドバーでファイル全体を開く', + 'time.now': 'たった今', + 'time.minutes': '{n} 分前', + 'time.hours': '{n} 時間前', + 'time.days': '{n} 日前', + 'time.months': '{n} か月前', + 'time.years': '{n} 年前', + 'time.finished': '{state} · {time}', + 'duration.seconds': '{seconds}秒', + 'duration.minutes': '{minutes}分 {seconds}秒', + 'duration.hours': '{hours}時間 {minutes}分', + 'worktree.label': 'ワークツリー', + 'worktree.hint': 'このセッションを専用のワークツリーで実行します。送信時に選択したブランチから新しいブランチを作成するため、変更やコミットはプロジェクトディレクトリに影響しません', + 'worktree.blocked.not-git': 'このワークスペースは Git リポジトリではないため、ワークツリーを使用できません', + 'worktree.blocked.outside-writable-root': 'このワークスペースの Git データが書き込み可能なディレクトリ外にあります。ワークスペース自体がワークツリーである場合などは、まだワークツリーを使用できません', + 'worktree.blocked.read-only': '読み取り専用のセッションではワークツリーを使用できません', + 'worktree.base': '基点 {branch}', + 'worktree.baseHead': '現在の HEAD を基点にする', + 'worktree.baseMenu': '基準ブランチ', + 'worktree.currentBranch': '現在', + 'creation.title': 'ワークツリーを作成中', + 'creation.failed': 'ワークツリーを作成できませんでした', + 'creation.prepare': 'ブランチを作成', + 'creation.checkout': 'ファイルをチェックアウト', + 'creation.details': '詳細', + 'creation.branch': 'ブランチ', + 'creation.base': '基点', + 'creation.head': '現在の HEAD', + 'creation.error': '理由', + 'creation.skip': 'ワークツリーを使わずに続行', + 'creation.cancel': 'キャンセル', + 'creation.stopped': 'ワークツリーの作成を停止しました', + 'creation.retry': '再試行', + 'creation.waiting': 'ワークツリーの作成後にメッセージを送信します', + 'missing.title': 'ワークツリーを利用できません', + 'missing.unknown': 'ワークツリーの復元が未完了のため、ブランチ {branch} を確認できません。復元エラーを解消して再試行するか、プロジェクトで続行してください', + 'missing.kept': 'ブランチ {branch} のワークツリーを元の場所に復元できます。削除前の未コミットの変更は復元できません', + 'missing.recreated': 'ブランチ {branch} も削除されています。復元時はワークツリー作成時のコミットから再作成します。それ以降のコミットや未コミットの変更は復元されません', + 'missing.restore': 'ワークツリーを復元', + 'missing.leave': 'プロジェクトで続行', + 'missing.waiting': 'ワークツリーを復元するかプロジェクトで続行すると、メッセージが送信されます', + 'restoration.title': 'ワークツリーを復元中', + 'restoration.prepare': 'ワークツリーを準備', + 'branch.worktree': 'ワークツリー(基点 {base}):{path}', + 'branch.linked': 'ワークツリー:{path}', + 'branch.project': 'プロジェクトディレクトリ:{path}', + 'branch.missing': 'ワークツリー利用不可:{path}', + 'toast.removed': 'このセッションから {name} を削除しました', + 'toast.undo': '元に戻す', + 'toast.undoFailed': '元に戻せませんでした', + 'toast.removeFailed': '削除できませんでした', + 'toast.refreshFailed': '更新できませんでした', + 'toast.copied': 'リンクをコピーしました', + 'toast.copyFailed': 'コピーに失敗しました', + 'toast.branchesFailed': 'ブランチを読み取れませんでした', + 'toast.worktreeFailed': 'ワークツリーの設定を変更できませんでした', + 'toast.worktreeStarted': 'セッションが開始済みのため、ワークツリーに切り替えられません', + 'toast.restored': 'ワークツリーを復元しました', + 'toast.restoreFailed': 'ワークツリーを復元できませんでした:{message}', + 'toast.leaveFailed': 'プロジェクトディレクトリに切り替えられませんでした。再試行してください', + 'toast.markedReady': '{name} をレビュー可能にしました', + 'toast.markReadyFailed': 'レビュー可能にできませんでした:{message}', + 'toast.merged': '{name} をマージしました', + 'toast.mergeFailed': 'マージできませんでした:{message}', + 'toast.mergeStale': '{name} に新しいコミットがあります。確認してからマージしてください', + 'toast.pathCopied': 'パスをコピーしました', + 'toast.expandFailed': '未変更の行を表示できませんでした:{message}', + 'toast.expandStale': '変更の読み取り後にファイルが更新されています。更新してから展開してください', + 'toast.prompted': '送信しました:{text}', + 'toast.promptFailed': 'メッセージを送信できませんでした', +} + +/** Spanish copy with the same keys. */ +export const es: Record = { + 'tab.title': 'Solicitudes de cambio', + 'header.label': 'Solicitudes de cambio de esta sesión', + 'header.attention': 'Las solicitudes de cambio de esta sesión requieren atención', + 'checkout.worktree': 'Árbol de trabajo', + 'checkout.worktreeFrom': 'Árbol de trabajo · desde {base}', + 'checkout.project': 'Directorio del proyecto', + 'checkout.detached': 'Sin rama activa', + 'checkout.restore': 'Restaurar', + 'checkout.copyWorktreePath': 'Copiar ruta del árbol de trabajo', + 'checkout.copyProjectPath': 'Copiar ruta del proyecto', + 'checkout.none': 'Este directorio no es un repositorio Git', + 'checkout.failed': 'No se pudo leer la información de Git', + 'changes.title': 'Solicitudes de cambio de esta sesión · {count}', + 'changes.empty': 'Esta sesión aún no tiene solicitudes de cambio', + 'changes.emptyHint': 'Aquí aparecen las solicitudes vinculadas a esta sesión: creadas, consultadas, editadas o extraídas, o abiertas en sus ramas actuales o enviadas', + 'changes.local.title': 'Cambios', + 'changes.local.refs': '{head} → {base}', + 'changes.local.files': '{count} archivos', + 'changes.local.viewAria': 'Ver cambios de esta sesión: {count} archivos, {added} líneas añadidas y {deleted} eliminadas', + 'changes.local.create': 'Crear solicitud de cambio', + 'changes.local.prompt': 'Crea una solicitud de cambio con los cambios de esta sesión', + 'signin.title': 'Inicia sesión en {host} para ver el estado de las solicitudes', + 'signin.copy': 'Copiar comando de inicio de sesión', + 'signin.unavailable': 'No se pudieron leer las solicitudes de {host}: {message}', + 'refresh': 'Actualizar estado', + 'retry': 'Reintentar', + 'stream.failed': 'No se pudo cargar el panel de solicitudes de cambio', + 'change.number': '#{number}', + 'change.stateAria': 'Estado de la solicitud: {state}', + 'change.state.open': 'Abierta', + 'change.state.blocked': 'Requiere atención', + 'change.state.draft': 'Borrador', + 'change.state.merged': 'Fusionada', + 'change.state.closed': 'Cerrada', + 'change.state.unknown': 'Desconocida', + 'change.expand': 'Expandir {name}', + 'change.collapse': 'Contraer {name}', + 'change.ci.none': 'Sin comprobaciones', + 'change.ci.running': 'Comprobaciones en curso', + 'change.ci.passed': 'Comprobaciones superadas', + 'change.ci.failed': '{count} comprobaciones fallidas', + 'change.ci.failedUnlisted': 'Comprobaciones fallidas', + 'change.checks.failed': '{count} fallidas', + 'change.checks.running': '{count} en curso', + 'change.checks.passed': '{count} superadas', + 'change.checks.other': '{count} más', + 'change.checks.truncated': 'Solo se muestran las primeras {count}', + 'change.check.running': 'En curso', + 'change.check.queued': 'En cola', + 'change.flag.changesRequested': 'Cambios solicitados', + 'change.flag.conflicting': 'Conflictos', + 'change.flag.draft': 'Borrador', + 'change.failure.unavailable': 'No se pudo leer el estado de la solicitud', + 'change.failure.notFound': 'La solicitud no existe o no tienes acceso', + 'change.failure.unauthenticated': 'Inicia sesión para ver su estado', + 'change.unserved': 'Este servicio de código aún no permite consultar el estado de las solicitudes', + 'change.view': 'Abrir en el navegador', + 'change.copy': 'Copiar enlace de la solicitud', + 'change.viewChangesAria': 'Ver cambios de {name}: {added} líneas añadidas y {deleted} eliminadas', + 'change.remove': 'Quitar de esta sesión', + 'change.removeAria': 'Quitar {name} de esta sesión', + 'change.row.checks': 'Comprobaciones', + 'change.row.review': 'Revisión', + 'change.row.merge': 'Fusionar', + 'change.row.changes': 'Cambios', + 'change.review.approved': 'Aprobada', + 'change.review.changesRequested': 'Cambios solicitados', + 'change.review.required': 'Revisión requerida', + 'change.review.none': 'Sin revisión solicitada', + 'change.review.threads': '{review} · {count} sin resolver', + 'change.merge.mergeable': 'Sin conflictos', + 'change.merge.conflicting': 'Conflictos con {base}', + 'change.merge.unknown': 'Buscando conflictos', + 'change.mergedTo': 'Fusionada en {base}', + 'change.markReady': 'Lista para revisión', + 'change.merge': 'Fusionar', + 'change.mergeTitle': 'Fusionar {name} en {base}', + 'change.mergeMethod.squash': 'Fusionar con squash', + 'change.mergeMethod.merge': 'Crear un commit de fusión', + 'change.mergeMethod.rebase': 'Rebasar y fusionar', + 'change.mergeNote.squash': 'Combinar todos los commits en uno', + 'change.mergeNote.merge': 'Conservar todos los commits y añadir uno de fusión', + 'change.mergeNote.rebase': 'Aplicar cada commit sobre {base}', + 'change.mergeConfirm': 'Confirmar fusión', + 'change.mergeChanged': 'Hay nuevos commits. Revísalos antes de volver a abrir el menú de fusión', + 'diff.tab': 'Cambios', + 'diff.tabNumbered': 'Cambios en #{number}', + 'diff.scope.branch': 'Rama', + 'diff.scope.uncommitted': 'Sin confirmar', + 'diff.scope.unstaged': 'Sin preparar', + 'diff.scope.staged': 'Preparado', + 'diff.scopeNote.branch': 'Comparado con {base}, incluidos los cambios sin confirmar', + 'diff.scopeNote.uncommitted': 'Comparado con HEAD, incluidos los archivos sin seguimiento', + 'diff.scopeNote.unstaged': 'Comparado con el índice, incluidos los archivos sin seguimiento', + 'diff.scopeNote.staged': 'Índice comparado con HEAD', + 'diff.allFiles': 'Los {count} archivos', + 'diff.refresh': 'Actualizar cambios', + 'diff.expandAll': 'Expandir todos los archivos', + 'diff.collapseAll': 'Contraer todos los archivos', + 'diff.split': 'Mostrar en paralelo', + 'diff.unified': 'Mostrar en una columna', + 'diff.splitAria': 'Vista en paralelo', + 'diff.wrap': 'Ajustar líneas largas', + 'diff.nowrap': 'No ajustar líneas largas', + 'diff.wrapAria': 'Ajustar líneas', + 'diff.unchanged': '{count} líneas sin cambios', + 'diff.unchangedRest': 'Líneas restantes sin cambios', + 'diff.newFile': 'Archivo nuevo', + 'diff.deletedFile': 'Eliminado', + 'diff.renamed': 'Renombrado desde {from}', + 'diff.renamedPath': '{from} → {path}', + 'diff.badgeUncommitted': 'Sin confirmar', + 'diff.binary': 'Archivo binario; no se pueden mostrar sus cambios', + 'diff.binaryLabel': 'Binario', + 'diff.largeCollapsed': 'Archivo grande: {count} líneas modificadas contraídas', + 'diff.fileTooLarge': 'Este archivo es demasiado grande para mostrarlo', + 'diff.error': 'No se pudieron leer los cambios', + 'diff.tooLarge': 'Estos cambios son demasiado grandes para mostrarlos aquí', + 'diff.viewInBrowser': 'Ver en el navegador', + 'diff.noForkPoint': 'No se encontró el punto de bifurcación de esta rama; elige otro ámbito', + 'diff.empty': 'Sin cambios', + 'diff.omitted': 'No se muestran otros {count} archivos sin seguimiento', + 'diff.stale': 'La rama local tiene {count} commits sin enviar; se muestran los cambios de la solicitud', + 'diff.moreActions': 'Más acciones para {name}', + 'diff.copyPath': 'Copiar ruta', + 'diff.openFileInBrowser': 'Ver archivo en el navegador', + 'diff.openFileInSidebar': 'Abrir el archivo completo en la barra lateral', + 'time.now': 'ahora mismo', + 'time.minutes': 'hace {n} min', + 'time.hours': 'hace {n} h', + 'time.days': 'hace {n} d', + 'time.months': 'hace {n} meses', + 'time.years': 'hace {n} años', + 'time.finished': '{state} · {time}', + 'duration.seconds': '{seconds}s', + 'duration.minutes': '{minutes} min {seconds} s', + 'duration.hours': '{hours} h {minutes} min', + 'worktree.label': 'Árbol de trabajo', + 'worktree.hint': 'Ejecuta esta sesión en su propio árbol de trabajo: al enviar se crea una rama desde la elegida, sin que los cambios ni los commits afecten al directorio del proyecto', + 'worktree.blocked.not-git': 'Este espacio de trabajo no es un repositorio Git y no puede usar un árbol de trabajo', + 'worktree.blocked.outside-writable-root': 'Los datos Git están fuera de los directorios con permiso de escritura, como cuando el espacio ya es un árbol de trabajo; aún no se puede usar otro árbol', + 'worktree.blocked.read-only': 'Una sesión de solo lectura no puede usar un árbol de trabajo', + 'worktree.base': 'Desde {branch}', + 'worktree.baseHead': 'Desde el HEAD actual', + 'worktree.baseMenu': 'Rama base', + 'worktree.currentBranch': 'Actual', + 'creation.title': 'Creando el árbol de trabajo', + 'creation.failed': 'No se pudo crear el árbol de trabajo', + 'creation.prepare': 'Crear la rama', + 'creation.checkout': 'Extraer archivos', + 'creation.details': 'Más detalles', + 'creation.branch': 'Rama', + 'creation.base': 'Desde', + 'creation.head': 'HEAD actual', + 'creation.error': 'Razón', + 'creation.skip': 'Continuar sin árbol de trabajo', + 'creation.cancel': 'Cancelar', + 'creation.stopped': 'Creación del árbol de trabajo detenida', + 'creation.retry': 'Reintentar', + 'creation.waiting': 'El mensaje se enviará cuando exista el árbol de trabajo', + 'missing.title': 'El árbol de trabajo no está disponible', + 'missing.unknown': 'La restauración está incompleta y no se puede consultar la rama {branch}. Resuelve el error y reintenta, o continúa en el proyecto', + 'missing.kept': 'Se puede restaurar el árbol de la rama {branch} en su ubicación original. Los cambios sin confirmar anteriores a su eliminación no se pueden recuperar', + 'missing.recreated': 'La rama {branch} también se eliminó. Se recreará desde el commit inicial del árbol, sin los commits posteriores ni los cambios sin confirmar', + 'missing.restore': 'Restaurar árbol de trabajo', + 'missing.leave': 'Continuar en el proyecto', + 'missing.waiting': 'El mensaje se enviará cuando restaures el árbol o continúes en el proyecto', + 'restoration.title': 'Restaurando el árbol de trabajo', + 'restoration.prepare': 'Preparar el árbol de trabajo', + 'branch.worktree': 'Árbol de trabajo (desde {base}): {path}', + 'branch.linked': 'Árbol de trabajo: {path}', + 'branch.project': 'Directorio del proyecto: {path}', + 'branch.missing': 'Árbol de trabajo no disponible: {path}', + 'toast.removed': 'Se quitó {name} de esta sesión', + 'toast.undo': 'Deshacer', + 'toast.undoFailed': 'No se pudo deshacer', + 'toast.removeFailed': 'No se pudo quitar', + 'toast.refreshFailed': 'No se pudo actualizar', + 'toast.copied': 'Enlace copiado', + 'toast.copyFailed': 'Copia fallida', + 'toast.branchesFailed': 'No se pudieron leer las ramas', + 'toast.worktreeFailed': 'No se pudo cambiar la opción del árbol de trabajo', + 'toast.worktreeStarted': 'Esta sesión ya empezó y no puede pasar a un árbol de trabajo', + 'toast.restored': 'Árbol de trabajo restaurado', + 'toast.restoreFailed': 'No se pudo restaurar el árbol de trabajo: {message}', + 'toast.leaveFailed': 'No se pudo cambiar al directorio del proyecto; inténtalo de nuevo', + 'toast.markedReady': '{name} está lista para revisión', + 'toast.markReadyFailed': 'No se pudo marcar como lista: {message}', + 'toast.merged': 'Se fusionó {name}', + 'toast.mergeFailed': 'No se pudo fusionar: {message}', + 'toast.mergeStale': '{name} tiene nuevos commits; revísalos antes de fusionar', + 'toast.pathCopied': 'Ruta copiada', + 'toast.expandFailed': 'No se pudieron mostrar las líneas sin cambios: {message}', + 'toast.expandStale': 'El archivo cambió después de leer sus cambios; actualiza antes de expandir', + 'toast.prompted': 'Enviado: {text}', + 'toast.promptFailed': 'No se pudo enviar el mensaje', +} + +/** French copy with the same keys. */ +export const fr: Record = { + 'tab.title': 'Demandes de modification', + 'header.label': 'Demandes de modification de cette session', + 'header.attention': 'Les demandes de modification de cette session nécessitent une intervention', + 'checkout.worktree': 'Arbre de travail', + 'checkout.worktreeFrom': 'Arbre de travail · depuis {base}', + 'checkout.project': 'Dossier du projet', + 'checkout.detached': 'Aucune branche active', + 'checkout.restore': 'Restaurer', + 'checkout.copyWorktreePath': 'Copier le chemin de l’arbre de travail', + 'checkout.copyProjectPath': 'Copier le chemin du projet', + 'checkout.none': 'Ce dossier n’est pas un dépôt Git', + 'checkout.failed': 'Impossible de lire les informations Git', + 'changes.title': 'Demandes de modification de cette session · {count}', + 'changes.empty': 'Cette session n’a pas encore de demande de modification', + 'changes.emptyHint': 'Les demandes liées à cette session apparaissent ici : créées, consultées, modifiées ou extraites, ou ouvertes sur ses branches actuelles ou envoyées', + 'changes.local.title': 'Modifications', + 'changes.local.refs': '{head} → {base}', + 'changes.local.files': '{count} fichiers', + 'changes.local.viewAria': 'Voir les modifications de cette session : {count} fichiers, {added} lignes ajoutées et {deleted} supprimées', + 'changes.local.create': 'Créer une demande de modification', + 'changes.local.prompt': 'Créez une demande de modification pour les changements de cette session', + 'signin.title': 'Connectez-vous à {host} pour voir l’état des demandes', + 'signin.copy': 'Copier la commande de connexion', + 'signin.unavailable': 'Impossible de lire les demandes sur {host} : {message}', + 'refresh': 'Actualiser l’état', + 'retry': 'Réessayer', + 'stream.failed': 'Impossible de charger le panneau des demandes de modification', + 'change.number': '#{number}', + 'change.stateAria': 'État de la demande : {state}', + 'change.state.open': 'Ouverte', + 'change.state.blocked': 'Intervention requise', + 'change.state.draft': 'Brouillon', + 'change.state.merged': 'Fusionnée', + 'change.state.closed': 'Fermée', + 'change.state.unknown': 'Inconnue', + 'change.expand': 'Développer {name}', + 'change.collapse': 'Réduire {name}', + 'change.ci.none': 'Aucune vérification', + 'change.ci.running': 'Vérifications en cours', + 'change.ci.passed': 'Vérifications réussies', + 'change.ci.failed': '{count} vérifications échouées', + 'change.ci.failedUnlisted': 'Échec des vérifications', + 'change.checks.failed': '{count} échouées', + 'change.checks.running': '{count} en cours', + 'change.checks.passed': '{count} réussies', + 'change.checks.other': '{count} autres', + 'change.checks.truncated': 'Seules les {count} premières sont affichées', + 'change.check.running': 'En cours', + 'change.check.queued': 'En file d\'attente', + 'change.flag.changesRequested': 'Modifications demandées', + 'change.flag.conflicting': 'Conflits', + 'change.flag.draft': 'Brouillon', + 'change.failure.unavailable': 'Impossible de lire l’état de la demande', + 'change.failure.notFound': 'La demande n’existe pas ou n’est pas accessible', + 'change.failure.unauthenticated': 'Connectez-vous pour voir son état', + 'change.unserved': 'L’état des demandes n’est pas encore pris en charge pour cet hébergeur de code', + 'change.view': 'Ouvrir dans le navigateur', + 'change.copy': 'Copier le lien de la demande', + 'change.viewChangesAria': 'Voir les modifications de {name} : {added} lignes ajoutées et {deleted} supprimées', + 'change.remove': 'Retirer de cette session', + 'change.removeAria': 'Retirer {name} de cette session', + 'change.row.checks': 'Vérifications', + 'change.row.review': 'Revue', + 'change.row.merge': 'Fusionner', + 'change.row.changes': 'Modifications', + 'change.review.approved': 'Approuvée', + 'change.review.changesRequested': 'Modifications demandées', + 'change.review.required': 'Revue requise', + 'change.review.none': 'Aucune revue demandée', + 'change.review.threads': '{review} · {count} non résolus', + 'change.merge.mergeable': 'Aucun conflit', + 'change.merge.conflicting': 'Conflits avec {base}', + 'change.merge.unknown': 'Recherche de conflits', + 'change.mergedTo': 'Fusionnée dans {base}', + 'change.markReady': 'Prête pour la revue', + 'change.merge': 'Fusionner', + 'change.mergeTitle': 'Fusionner {name} dans {base}', + 'change.mergeMethod.squash': 'Fusionner par squash', + 'change.mergeMethod.merge': 'Créer un commit de fusion', + 'change.mergeMethod.rebase': 'Rebaser et fusionner', + 'change.mergeNote.squash': 'Regrouper tous les commits en un seul', + 'change.mergeNote.merge': 'Conserver tous les commits et ajouter un commit de fusion', + 'change.mergeNote.rebase': 'Rejouer chaque commit sur {base}', + 'change.mergeConfirm': 'Confirmer la fusion', + 'change.mergeChanged': 'De nouveaux commits sont arrivés. Vérifiez-les avant de rouvrir le menu de fusion', + 'diff.tab': 'Modifications', + 'diff.tabNumbered': 'Modifications de #{number}', + 'diff.scope.branch': 'Branche', + 'diff.scope.uncommitted': 'Non commité', + 'diff.scope.unstaged': 'Non indexé', + 'diff.scope.staged': 'Indexé', + 'diff.scopeNote.branch': 'Comparaison avec {base}, modifications non commitées incluses', + 'diff.scopeNote.uncommitted': 'Comparaison avec HEAD, fichiers non suivis inclus', + 'diff.scopeNote.unstaged': 'Comparaison avec l’index, fichiers non suivis inclus', + 'diff.scopeNote.staged': 'Comparaison de l’index avec HEAD', + 'diff.allFiles': 'Les {count} fichiers', + 'diff.refresh': 'Actualiser les modifications', + 'diff.expandAll': 'Développer tous les fichiers', + 'diff.collapseAll': 'Réduire tous les fichiers', + 'diff.split': 'Afficher côte à côte', + 'diff.unified': 'Afficher sur une colonne', + 'diff.splitAria': 'Côte à côte', + 'diff.wrap': 'Replier les lignes longues', + 'diff.nowrap': 'Ne pas replier les lignes longues', + 'diff.wrapAria': 'Activer le retour à la ligne', + 'diff.unchanged': '{count} lignes inchangées', + 'diff.unchangedRest': 'Lignes inchangées restantes', + 'diff.newFile': 'Nouveau fichier', + 'diff.deletedFile': 'Supprimé', + 'diff.renamed': 'Renommé depuis {from}', + 'diff.renamedPath': '{from} → {path}', + 'diff.badgeUncommitted': 'Non commité', + 'diff.binary': 'Fichier binaire ; ses modifications ne peuvent pas être affichées', + 'diff.binaryLabel': 'Binaire', + 'diff.largeCollapsed': 'Fichier volumineux : {count} lignes modifiées réduites', + 'diff.fileTooLarge': 'Ce fichier est trop volumineux pour être affiché', + 'diff.error': 'Impossible de lire les modifications', + 'diff.tooLarge': 'Ces modifications sont trop volumineuses pour être affichées ici', + 'diff.viewInBrowser': 'Voir dans le navigateur', + 'diff.noForkPoint': 'Le point de divergence de cette branche est introuvable ; choisissez une autre portée', + 'diff.empty': 'Aucune modification', + 'diff.omitted': '{count} autres fichiers non suivis ne sont pas affichés', + 'diff.stale': 'La branche locale contient {count} commits non envoyés ; les modifications de la demande sont affichées', + 'diff.moreActions': 'Autres actions pour {name}', + 'diff.copyPath': 'Copier le chemin', + 'diff.openFileInBrowser': 'Voir le fichier dans le navigateur', + 'diff.openFileInSidebar': 'Ouvrir le fichier entier dans la barre latérale', + 'time.now': 'à l’instant', + 'time.minutes': 'il y a {n} min', + 'time.hours': 'il y a {n} h', + 'time.days': 'il y a {n} j', + 'time.months': 'il y a {n} mois', + 'time.years': 'il y a {n} ans', + 'time.finished': '{state} · {time}', + 'duration.seconds': '{seconds}s', + 'duration.minutes': '{minutes} min {seconds} s', + 'duration.hours': '{hours} h {minutes} min', + 'worktree.label': 'Arbre de travail', + 'worktree.hint': 'Exécutez cette session dans son propre arbre de travail : l’envoi crée une branche depuis celle choisie, sans que les modifications ou les commits affectent le dossier du projet', + 'worktree.blocked.not-git': 'Cet espace de travail n’est pas un dépôt Git et ne peut pas utiliser d’arbre de travail', + 'worktree.blocked.outside-writable-root': 'Les données Git sont hors des dossiers accessibles en écriture, notamment lorsque l’espace est déjà un arbre de travail ; cette fonction n’est pas encore disponible', + 'worktree.blocked.read-only': 'Une session en lecture seule ne peut pas utiliser d’arbre de travail', + 'worktree.base': 'Depuis {branch}', + 'worktree.baseHead': 'Depuis le HEAD actuel', + 'worktree.baseMenu': 'Branche de base', + 'worktree.currentBranch': 'Actuelle', + 'creation.title': 'Création de l’arbre de travail', + 'creation.failed': 'Impossible de créer l’arbre de travail', + 'creation.prepare': 'Créer la branche', + 'creation.checkout': 'Extraire les fichiers', + 'creation.details': 'Plus de détails', + 'creation.branch': 'Branche', + 'creation.base': 'Depuis', + 'creation.head': 'HEAD actuel', + 'creation.error': 'Raison', + 'creation.skip': 'Continuer sans arbre de travail', + 'creation.cancel': 'Annuler', + 'creation.stopped': 'Création de l’arbre de travail arrêtée', + 'creation.retry': 'Réessayer', + 'creation.waiting': 'Le message sera envoyé après la création de l’arbre de travail', + 'missing.title': 'L’arbre de travail est indisponible', + 'missing.unknown': 'La restauration est incomplète et la branche {branch} ne peut pas être inspectée. Corrigez l’erreur puis réessayez, ou continuez dans le projet', + 'missing.kept': 'L’arbre de la branche {branch} peut être restauré à son emplacement initial. Les modifications non commitées avant sa suppression ne peuvent pas être récupérées', + 'missing.recreated': 'La branche {branch} a aussi été supprimée. Elle sera recréée depuis le commit initial de l’arbre, sans les commits ultérieurs ni les modifications non commitées', + 'missing.restore': 'Restaurer l’arbre de travail', + 'missing.leave': 'Continuer dans le projet', + 'missing.waiting': 'Le message sera envoyé après la restauration de l’arbre ou la poursuite dans le projet', + 'restoration.title': 'Restauration de l’arbre de travail', + 'restoration.prepare': 'Préparer l’arbre de travail', + 'branch.worktree': 'Arbre de travail (depuis {base}) : {path}', + 'branch.linked': 'Arbre de travail : {path}', + 'branch.project': 'Dossier du projet : {path}', + 'branch.missing': 'Arbre de travail indisponible : {path}', + 'toast.removed': '{name} a été retiré de cette session', + 'toast.undo': 'Annuler', + 'toast.undoFailed': 'Impossible d’annuler', + 'toast.removeFailed': 'Impossible de retirer', + 'toast.refreshFailed': 'Échec de l’actualisation', + 'toast.copied': 'Lien copié', + 'toast.copyFailed': 'Échec de la copie', + 'toast.branchesFailed': 'Impossible de lire les branches', + 'toast.worktreeFailed': 'Impossible de modifier l’option de l’arbre de travail', + 'toast.worktreeStarted': 'Cette session a déjà commencé et ne peut plus passer à un arbre de travail', + 'toast.restored': 'Arbre de travail restauré', + 'toast.restoreFailed': 'Impossible de restaurer l’arbre de travail : {message}', + 'toast.leaveFailed': 'Impossible de passer au dossier du projet ; réessayez', + 'toast.markedReady': '{name} est prête pour la revue', + 'toast.markReadyFailed': 'Impossible de la marquer comme prête : {message}', + 'toast.merged': '{name} a été fusionné', + 'toast.mergeFailed': 'Impossible de fusionner : {message}', + 'toast.mergeStale': '{name} contient de nouveaux commits ; vérifiez-les avant de fusionner', + 'toast.pathCopied': 'Chemin copié', + 'toast.expandFailed': 'Impossible d’afficher les lignes inchangées : {message}', + 'toast.expandStale': 'Le fichier a changé depuis la lecture des modifications ; actualisez avant de développer', + 'toast.prompted': 'Envoyé : {text}', + 'toast.promptFailed': 'Impossible d’envoyer le message', +} + +/** German copy with the same keys. */ +export const de: Record = { + 'tab.title': 'Änderungsanfragen', + 'header.label': 'Änderungsanfragen dieser Sitzung', + 'header.attention': 'Änderungsanfragen dieser Sitzung erfordern Aufmerksamkeit', + 'checkout.worktree': 'Arbeitsbaum', + 'checkout.worktreeFrom': 'Arbeitsbaum · aus {base}', + 'checkout.project': 'Projektverzeichnis', + 'checkout.detached': 'Auf keinem Branch', + 'checkout.restore': 'Wiederherstellen', + 'checkout.copyWorktreePath': 'Pfad des Arbeitsbaums kopieren', + 'checkout.copyProjectPath': 'Projektpfad kopieren', + 'checkout.none': 'Dieses Verzeichnis ist kein Git-Repository', + 'checkout.failed': 'Git-Informationen konnten nicht gelesen werden', + 'changes.title': 'Änderungsanfragen dieser Sitzung · {count}', + 'changes.empty': 'Diese Sitzung hat noch keine Änderungsanfragen', + 'changes.emptyHint': 'Hier erscheinen verknüpfte Änderungsanfragen: in dieser Sitzung erstellt, angesehen, bearbeitet oder ausgecheckt oder auf ihren aktuellen oder gepushten Branches geöffnet', + 'changes.local.title': 'Änderungen', + 'changes.local.refs': '{head} → {base}', + 'changes.local.files': '{count} Dateien', + 'changes.local.viewAria': 'Änderungen dieser Sitzung anzeigen: {count} Dateien, {added} Zeilen hinzugefügt, {deleted} Zeilen gelöscht', + 'changes.local.create': 'Änderungsanfrage erstellen', + 'changes.local.prompt': 'Erstelle eine Änderungsanfrage für die Änderungen dieser Sitzung', + 'signin.title': 'Bei {host} anmelden, um den Status der Änderungsanfragen anzuzeigen', + 'signin.copy': 'Anmeldebefehl kopieren', + 'signin.unavailable': 'Änderungsanfragen auf {host} konnten nicht gelesen werden: {message}', + 'refresh': 'Status aktualisieren', + 'retry': 'Erneut versuchen', + 'stream.failed': 'Das Panel für Änderungsanfragen konnte nicht geladen werden', + 'change.number': '#{number}', + 'change.stateAria': 'Status der Änderungsanfrage: {state}', + 'change.state.open': 'Offen', + 'change.state.blocked': 'Aufmerksamkeit erforderlich', + 'change.state.draft': 'Entwurf', + 'change.state.merged': 'Zusammengeführt', + 'change.state.closed': 'Geschlossen', + 'change.state.unknown': 'Unbekannt', + 'change.expand': '{name} aufklappen', + 'change.collapse': '{name} einklappen', + 'change.ci.none': 'Keine Prüfungen', + 'change.ci.running': 'Prüfungen laufen', + 'change.ci.passed': 'Prüfungen bestanden', + 'change.ci.failed': '{count} Prüfungen fehlgeschlagen', + 'change.ci.failedUnlisted': 'Prüfungen fehlgeschlagen', + 'change.checks.failed': '{count} fehlgeschlagen', + 'change.checks.running': '{count} laufen', + 'change.checks.passed': '{count} bestanden', + 'change.checks.other': '{count} weitere', + 'change.checks.truncated': 'Nur die ersten {count} werden angezeigt', + 'change.check.running': 'Läuft', + 'change.check.queued': 'In der Warteschlange', + 'change.flag.changesRequested': 'Änderungen angefordert', + 'change.flag.conflicting': 'Konflikte', + 'change.flag.draft': 'Entwurf', + 'change.failure.unavailable': 'Der Status der Änderungsanfrage konnte nicht gelesen werden', + 'change.failure.notFound': 'Die Änderungsanfrage existiert nicht oder ist nicht zugänglich', + 'change.failure.unauthenticated': 'Anmelden, um den Status zu lesen', + 'change.unserved': 'Der Status von Änderungsanfragen wird für diesen Code-Host noch nicht unterstützt', + 'change.view': 'Im Browser öffnen', + 'change.copy': 'Link zur Änderungsanfrage kopieren', + 'change.viewChangesAria': 'Änderungen von {name} anzeigen: {added} Zeilen hinzugefügt, {deleted} Zeilen gelöscht', + 'change.remove': 'Aus dieser Sitzung entfernen', + 'change.removeAria': '{name} aus dieser Sitzung entfernen', + 'change.row.checks': 'Prüfungen', + 'change.row.review': 'Review', + 'change.row.merge': 'Zusammenführen', + 'change.row.changes': 'Änderungen', + 'change.review.approved': 'Genehmigt', + 'change.review.changesRequested': 'Änderungen angefordert', + 'change.review.required': 'Review erforderlich', + 'change.review.none': 'Kein Review angefordert', + 'change.review.threads': '{review} · {count} ungelöst', + 'change.merge.mergeable': 'Keine Konflikte', + 'change.merge.conflicting': 'Konflikte mit {base}', + 'change.merge.unknown': 'Konflikte werden geprüft', + 'change.mergedTo': 'In {base} zusammengeführt', + 'change.markReady': 'Bereit zum Review', + 'change.merge': 'Zusammenführen', + 'change.mergeTitle': '{name} in {base} zusammenführen', + 'change.mergeMethod.squash': 'Squash und zusammenführen', + 'change.mergeMethod.merge': 'Merge-Commit erstellen', + 'change.mergeMethod.rebase': 'Rebase und zusammenführen', + 'change.mergeNote.squash': 'Alle Commits zu einem zusammenfassen', + 'change.mergeNote.merge': 'Alle Commits beibehalten und einen Merge-Commit hinzufügen', + 'change.mergeNote.rebase': 'Jeden Commit auf {base} neu anwenden', + 'change.mergeConfirm': 'Zusammenführung bestätigen', + 'change.mergeChanged': 'Neue Commits sind eingetroffen. Vor dem erneuten Öffnen des Merge-Menüs prüfen', + 'diff.tab': 'Änderungen', + 'diff.tabNumbered': 'Änderungen in #{number}', + 'diff.scope.branch': 'Branch', + 'diff.scope.uncommitted': 'Nicht committet', + 'diff.scope.unstaged': 'Nicht vorgemerkt', + 'diff.scope.staged': 'Vorgemerkt', + 'diff.scopeNote.branch': 'Vergleich mit {base}, einschließlich nicht committeter Änderungen', + 'diff.scopeNote.uncommitted': 'Vergleich mit HEAD, einschließlich nicht verfolgter Dateien', + 'diff.scopeNote.unstaged': 'Vergleich mit dem Index, einschließlich nicht verfolgter Dateien', + 'diff.scopeNote.staged': 'Vergleich des Index mit HEAD', + 'diff.allFiles': 'Alle {count} Dateien', + 'diff.refresh': 'Änderungen aktualisieren', + 'diff.expandAll': 'Alle Dateien aufklappen', + 'diff.collapseAll': 'Alle Dateien einklappen', + 'diff.split': 'Nebeneinander anzeigen', + 'diff.unified': 'In einer Spalte anzeigen', + 'diff.splitAria': 'Nebeneinander', + 'diff.wrap': 'Lange Zeilen umbrechen', + 'diff.nowrap': 'Lange Zeilen nicht umbrechen', + 'diff.wrapAria': 'Zeilen umbrechen', + 'diff.unchanged': '{count} unveränderte Zeilen', + 'diff.unchangedRest': 'Übrige unveränderte Zeilen', + 'diff.newFile': 'Neue Datei', + 'diff.deletedFile': 'Gelöscht', + 'diff.renamed': 'Umbenannt von {from}', + 'diff.renamedPath': '{from} → {path}', + 'diff.badgeUncommitted': 'Nicht committet', + 'diff.binary': 'Binärdatei; Änderungen können nicht angezeigt werden', + 'diff.binaryLabel': 'Binär', + 'diff.largeCollapsed': 'Große Datei: {count} geänderte Zeilen eingeklappt', + 'diff.fileTooLarge': 'Diese Datei ist zu groß zum Anzeigen', + 'diff.error': 'Änderungen konnten nicht gelesen werden', + 'diff.tooLarge': 'Diese Änderungen sind zu groß, um sie hier anzuzeigen', + 'diff.viewInBrowser': 'Im Browser ansehen', + 'diff.noForkPoint': 'Kein Verzweigungspunkt für diesen Branch gefunden; einen anderen Bereich wählen', + 'diff.empty': 'Keine Änderungen', + 'diff.omitted': '{count} weitere nicht verfolgte Dateien werden nicht angezeigt', + 'diff.stale': 'Der lokale Branch hat {count} nicht gepushte Commits; angezeigt werden die Änderungen der Änderungsanfrage', + 'diff.moreActions': 'Weitere Aktionen für {name}', + 'diff.copyPath': 'Pfad kopieren', + 'diff.openFileInBrowser': 'Datei im Browser ansehen', + 'diff.openFileInSidebar': 'Die gesamte Datei in der Seitenleiste öffnen', + 'time.now': 'gerade eben', + 'time.minutes': 'vor {n} Min.', + 'time.hours': 'vor {n} Std.', + 'time.days': 'vor {n} Tagen', + 'time.months': 'vor {n} Monaten', + 'time.years': 'vor {n} Jahren', + 'time.finished': '{state} · {time}', + 'duration.seconds': '{seconds} Sek.', + 'duration.minutes': '{minutes} Min. {seconds} Sek.', + 'duration.hours': '{hours} Std. {minutes} Min.', + 'worktree.label': 'Arbeitsbaum', + 'worktree.hint': 'Diese Sitzung in einem eigenen Arbeitsbaum ausführen: Beim Senden wird aus dem gewählten Branch ein neuer erstellt; Änderungen und Commits lassen das Projektverzeichnis unverändert', + 'worktree.blocked.not-git': 'Dieser Arbeitsbereich ist kein Git-Repository und kann keinen Arbeitsbaum verwenden', + 'worktree.blocked.outside-writable-root': 'Die Git-Daten liegen außerhalb der beschreibbaren Verzeichnisse, etwa wenn der Arbeitsbereich selbst ein Arbeitsbaum ist; Arbeitsbäume werden hier noch nicht unterstützt', + 'worktree.blocked.read-only': 'Eine schreibgeschützte Sitzung kann keinen Arbeitsbaum verwenden', + 'worktree.base': 'Aus {branch}', + 'worktree.baseHead': 'Aus dem aktuellen HEAD', + 'worktree.baseMenu': 'Basis-Branch', + 'worktree.currentBranch': 'Aktuell', + 'creation.title': 'Arbeitsbaum wird erstellt', + 'creation.failed': 'Arbeitsbaum konnte nicht erstellt werden', + 'creation.prepare': 'Branch erstellen', + 'creation.checkout': 'Dateien auschecken', + 'creation.details': 'Weitere Details', + 'creation.branch': 'Branch', + 'creation.base': 'Basis', + 'creation.head': 'Aktueller HEAD', + 'creation.error': 'Grund', + 'creation.skip': 'Ohne Arbeitsbaum fortfahren', + 'creation.cancel': 'Abbrechen', + 'creation.stopped': 'Erstellung des Arbeitsbaums angehalten', + 'creation.retry': 'Erneut versuchen', + 'creation.waiting': 'Die Nachricht wird gesendet, sobald der Arbeitsbaum erstellt ist', + 'missing.title': 'Arbeitsbaum nicht verfügbar', + 'missing.unknown': 'Die Wiederherstellung ist unvollständig und Branch {branch} kann nicht geprüft werden. Den Fehler beheben und erneut versuchen oder im Projekt fortfahren', + 'missing.kept': 'Der Arbeitsbaum von Branch {branch} kann am ursprünglichen Ort wiederhergestellt werden. Nicht committete Änderungen vor dem Entfernen können nicht wiederhergestellt werden', + 'missing.recreated': 'Branch {branch} wurde ebenfalls entfernt. Er wird vom ursprünglichen Commit des Arbeitsbaums neu erstellt, ohne spätere Commits oder nicht committete Änderungen', + 'missing.restore': 'Arbeitsbaum wiederherstellen', + 'missing.leave': 'Im Projekt fortfahren', + 'missing.waiting': 'Die Nachricht wird gesendet, nachdem der Arbeitsbaum wiederhergestellt wurde oder Sie im Projekt fortfahren', + 'restoration.title': 'Arbeitsbaum wird wiederhergestellt', + 'restoration.prepare': 'Arbeitsbaum vorbereiten', + 'branch.worktree': 'Arbeitsbaum (aus {base}): {path}', + 'branch.linked': 'Arbeitsbaum: {path}', + 'branch.project': 'Projektverzeichnis: {path}', + 'branch.missing': 'Arbeitsbaum nicht verfügbar: {path}', + 'toast.removed': '{name} wurde aus dieser Sitzung entfernt', + 'toast.undo': 'Rückgängig machen', + 'toast.undoFailed': 'Rückgängig machen fehlgeschlagen', + 'toast.removeFailed': 'Entfernen fehlgeschlagen', + 'toast.refreshFailed': 'Aktualisierung fehlgeschlagen', + 'toast.copied': 'Link kopiert', + 'toast.copyFailed': 'Das Kopieren ist fehlgeschlagen', + 'toast.branchesFailed': 'Branches konnten nicht gelesen werden', + 'toast.worktreeFailed': 'Die Arbeitsbaum-Option konnte nicht geändert werden', + 'toast.worktreeStarted': 'Diese Sitzung wurde bereits gestartet und kann nicht mehr zu einem Arbeitsbaum wechseln', + 'toast.restored': 'Arbeitsbaum wiederhergestellt', + 'toast.restoreFailed': 'Arbeitsbaum konnte nicht wiederhergestellt werden: {message}', + 'toast.leaveFailed': 'Wechsel zum Projektverzeichnis fehlgeschlagen; erneut versuchen', + 'toast.markedReady': '{name} ist zum Review bereit', + 'toast.markReadyFailed': 'Konnte nicht als bereit markiert werden: {message}', + 'toast.merged': '{name} wurde zusammengeführt', + 'toast.mergeFailed': 'Zusammenführung fehlgeschlagen: {message}', + 'toast.mergeStale': '{name} enthält neue Commits; vor dem Zusammenführen prüfen', + 'toast.pathCopied': 'Pfad kopiert', + 'toast.expandFailed': 'Unveränderte Zeilen konnten nicht angezeigt werden: {message}', + 'toast.expandStale': 'Die Datei wurde nach dem Lesen der Änderungen verändert; vor dem Aufklappen aktualisieren', + 'toast.prompted': 'Gesendet: {text}', + 'toast.promptFailed': 'Nachricht konnte nicht gesendet werden', +} + +/** Russian copy with the same keys. */ +export const ru: Record = { + 'tab.title': 'Запросы на изменение', + 'header.label': 'Запросы на изменение этого сеанса', + 'header.attention': 'Запросы на изменение этого сеанса требуют внимания', + 'checkout.worktree': 'Рабочее дерево', + 'checkout.worktreeFrom': 'Рабочее дерево · на основе {base}', + 'checkout.project': 'Каталог проекта', + 'checkout.detached': 'Вне ветки', + 'checkout.restore': 'Восстановить', + 'checkout.copyWorktreePath': 'Копировать путь рабочего дерева', + 'checkout.copyProjectPath': 'Копировать путь проекта', + 'checkout.none': 'Этот каталог не является репозиторием Git', + 'checkout.failed': 'Не удалось прочитать сведения Git', + 'changes.title': 'Запросы на изменение этого сеанса · {count}', + 'changes.empty': 'В этом сеансе пока нет запросов на изменение', + 'changes.emptyHint': 'Здесь отображаются связанные с сеансом запросы: созданные, просмотренные, изменённые или извлечённые, а также открытые для текущей или отправленной ветки', + 'changes.local.title': 'Изменения', + 'changes.local.refs': '{head} → {base}', + 'changes.local.files': 'Файлов: {count}', + 'changes.local.viewAria': 'Просмотреть изменения сеанса: файлов — {count}, добавлено строк — {added}, удалено — {deleted}', + 'changes.local.create': 'Создать запрос на изменение', + 'changes.local.prompt': 'Создай запрос на изменение для изменений этого сеанса', + 'signin.title': 'Войдите на {host}, чтобы увидеть состояние запросов', + 'signin.copy': 'Копировать команду входа', + 'signin.unavailable': 'Не удалось прочитать запросы на {host}: {message}', + 'refresh': 'Обновить состояние', + 'retry': 'Повторить', + 'stream.failed': 'Не удалось загрузить панель запросов на изменение', + 'change.number': '#{number}', + 'change.stateAria': 'Состояние запроса: {state}', + 'change.state.open': 'Открыт', + 'change.state.blocked': 'Требует внимания', + 'change.state.draft': 'Черновик', + 'change.state.merged': 'Объединён', + 'change.state.closed': 'Закрыт', + 'change.state.unknown': 'Неизвестен', + 'change.expand': 'Развернуть {name}', + 'change.collapse': 'Свернуть {name}', + 'change.ci.none': 'Нет проверок', + 'change.ci.running': 'Проверки выполняются', + 'change.ci.passed': 'Проверки пройдены', + 'change.ci.failed': 'Не пройдено проверок: {count}', + 'change.ci.failedUnlisted': 'Проверки не пройдены', + 'change.checks.failed': 'Не пройдено: {count}', + 'change.checks.running': 'Выполняется: {count}', + 'change.checks.passed': 'Пройдено: {count}', + 'change.checks.other': 'Других: {count}', + 'change.checks.truncated': 'Показаны только первые {count}', + 'change.check.running': 'Выполняется', + 'change.check.queued': 'В очереди', + 'change.flag.changesRequested': 'Запрошены изменения', + 'change.flag.conflicting': 'Конфликты', + 'change.flag.draft': 'Черновик', + 'change.failure.unavailable': 'Не удалось прочитать состояние запроса', + 'change.failure.notFound': 'Запрос не существует или недоступен', + 'change.failure.unauthenticated': 'Войдите, чтобы увидеть состояние', + 'change.unserved': 'Состояние запросов этого хостинга кода пока не поддерживается', + 'change.view': 'Открыть в браузере', + 'change.copy': 'Копировать ссылку на запрос', + 'change.viewChangesAria': 'Просмотреть изменения {name}: добавлено строк — {added}, удалено — {deleted}', + 'change.remove': 'Удалить из этого сеанса', + 'change.removeAria': 'Удалить {name} из этого сеанса', + 'change.row.checks': 'Проверки', + 'change.row.review': 'Ревью', + 'change.row.merge': 'Объединить', + 'change.row.changes': 'Изменения', + 'change.review.approved': 'Одобрен', + 'change.review.changesRequested': 'Запрошены изменения', + 'change.review.required': 'Требуется ревью', + 'change.review.none': 'Ревью не запрошено', + 'change.review.threads': '{review} · не решено: {count}', + 'change.merge.mergeable': 'Нет конфликтов', + 'change.merge.conflicting': 'Конфликты с {base}', + 'change.merge.unknown': 'Проверка конфликтов', + 'change.mergedTo': 'Объединён с {base}', + 'change.markReady': 'Готов к ревью', + 'change.merge': 'Объединить', + 'change.mergeTitle': 'Объединить {name} с {base}', + 'change.mergeMethod.squash': 'Объединить со сжатием', + 'change.mergeMethod.merge': 'Создать коммит слияния', + 'change.mergeMethod.rebase': 'Перебазировать и объединить', + 'change.mergeNote.squash': 'Объединить все коммиты в один', + 'change.mergeNote.merge': 'Сохранить все коммиты и добавить коммит слияния', + 'change.mergeNote.rebase': 'Перенести каждый коммит на {base}', + 'change.mergeConfirm': 'Подтвердить слияние', + 'change.mergeChanged': 'Появились новые коммиты. Проверьте их перед повторным открытием меню слияния', + 'diff.tab': 'Изменения', + 'diff.tabNumbered': 'Изменения в #{number}', + 'diff.scope.branch': 'Ветка', + 'diff.scope.uncommitted': 'Без коммита', + 'diff.scope.unstaged': 'Не в индексе', + 'diff.scope.staged': 'В индексе', + 'diff.scopeNote.branch': 'Сравнение с {base}, включая изменения без коммита', + 'diff.scopeNote.uncommitted': 'Сравнение с HEAD, включая неотслеживаемые файлы', + 'diff.scopeNote.unstaged': 'Сравнение с индексом, включая неотслеживаемые файлы', + 'diff.scopeNote.staged': 'Сравнение индекса с HEAD', + 'diff.allFiles': 'Все файлы: {count}', + 'diff.refresh': 'Обновить изменения', + 'diff.expandAll': 'Развернуть все файлы', + 'diff.collapseAll': 'Свернуть все файлы', + 'diff.split': 'Показать рядом', + 'diff.unified': 'Показать в один столбец', + 'diff.splitAria': 'Рядом', + 'diff.wrap': 'Переносить длинные строки', + 'diff.nowrap': 'Не переносить длинные строки', + 'diff.wrapAria': 'Переносить строки', + 'diff.unchanged': 'Неизменённых строк: {count}', + 'diff.unchangedRest': 'Остальные неизменённые строки', + 'diff.newFile': 'Новый файл', + 'diff.deletedFile': 'Удалено', + 'diff.renamed': 'Переименован из {from}', + 'diff.renamedPath': '{from} → {path}', + 'diff.badgeUncommitted': 'Без коммита', + 'diff.binary': 'Двоичный файл; невозможно показать изменения', + 'diff.binaryLabel': 'Двоичный', + 'diff.largeCollapsed': 'Большой файл: свёрнуто изменённых строк — {count}', + 'diff.fileTooLarge': 'Файл слишком большой для отображения', + 'diff.error': 'Не удалось прочитать изменения', + 'diff.tooLarge': 'Изменения слишком велики для отображения здесь', + 'diff.viewInBrowser': 'Посмотреть в браузере', + 'diff.noForkPoint': 'Не найдена точка ответвления этой ветки; выберите другую область', + 'diff.empty': 'Нет изменений', + 'diff.omitted': 'Не показано ещё неотслеживаемых файлов: {count}', + 'diff.stale': 'В локальной ветке {count} неотправленных коммитов; показаны изменения из запроса', + 'diff.moreActions': 'Другие действия для {name}', + 'diff.copyPath': 'Копировать путь', + 'diff.openFileInBrowser': 'Посмотреть файл в браузере', + 'diff.openFileInSidebar': 'Открыть весь файл в боковой панели', + 'time.now': 'только что', + 'time.minutes': '{n} мин назад', + 'time.hours': '{n} ч назад', + 'time.days': '{n} дн назад', + 'time.months': '{n} мес назад', + 'time.years': '{n} г назад', + 'time.finished': '{state} · {time}', + 'duration.seconds': '{seconds} с', + 'duration.minutes': '{minutes} мин {seconds} с', + 'duration.hours': '{hours} ч {minutes} мин', + 'worktree.label': 'Рабочее дерево', + 'worktree.hint': 'Запустить сеанс в отдельном рабочем дереве: при отправке будет создана ветка на основе выбранной, а изменения и коммиты не затронут каталог проекта', + 'worktree.blocked.not-git': 'Рабочая область не является репозиторием Git, поэтому рабочее дерево недоступно', + 'worktree.blocked.outside-writable-root': 'Данные Git находятся вне доступных для записи каталогов, например когда рабочая область сама является рабочим деревом; создание рабочего дерева пока недоступно', + 'worktree.blocked.read-only': 'Сеанс только для чтения не может использовать рабочее дерево', + 'worktree.base': 'На основе {branch}', + 'worktree.baseHead': 'На основе текущего HEAD', + 'worktree.baseMenu': 'Базовая ветка', + 'worktree.currentBranch': 'Текущая', + 'creation.title': 'Создание рабочего дерева', + 'creation.failed': 'Не удалось создать рабочее дерево', + 'creation.prepare': 'Создать ветку', + 'creation.checkout': 'Извлечь файлы', + 'creation.details': 'Подробнее', + 'creation.branch': 'Ветка', + 'creation.base': 'Основа', + 'creation.head': 'Текущий HEAD', + 'creation.error': 'Причина', + 'creation.skip': 'Продолжить без рабочего дерева', + 'creation.cancel': 'Отмена', + 'creation.stopped': 'Создание рабочего дерева остановлено', + 'creation.retry': 'Повторить', + 'creation.waiting': 'Сообщение будет отправлено после создания рабочего дерева', + 'missing.title': 'Рабочее дерево недоступно', + 'missing.unknown': 'Восстановление не завершено, ветка {branch} недоступна для проверки. Устраните ошибку и повторите попытку или продолжите в проекте', + 'missing.kept': 'Рабочее дерево ветки {branch} можно восстановить на прежнем месте. Изменения без коммита, существовавшие до удаления, восстановить нельзя', + 'missing.recreated': 'Ветка {branch} тоже удалена. Она будет создана заново из исходного коммита рабочего дерева, без последующих коммитов и изменений без коммита', + 'missing.restore': 'Восстановить рабочее дерево', + 'missing.leave': 'Продолжить в проекте', + 'missing.waiting': 'Сообщение будет отправлено после восстановления рабочего дерева или продолжения в проекте', + 'restoration.title': 'Восстановление рабочего дерева', + 'restoration.prepare': 'Подготовить рабочее дерево', + 'branch.worktree': 'Рабочее дерево (на основе {base}): {path}', + 'branch.linked': 'Рабочее дерево: {path}', + 'branch.project': 'Каталог проекта: {path}', + 'branch.missing': 'Рабочее дерево недоступно: {path}', + 'toast.removed': '{name} удалён из этого сеанса', + 'toast.undo': 'Отменить', + 'toast.undoFailed': 'Не удалось отменить', + 'toast.removeFailed': 'Не удалось удалить', + 'toast.refreshFailed': 'Не удалось обновить', + 'toast.copied': 'Ссылка скопирована', + 'toast.copyFailed': 'Не удалось скопировать', + 'toast.branchesFailed': 'Не удалось прочитать ветки', + 'toast.worktreeFailed': 'Не удалось изменить настройку рабочего дерева', + 'toast.worktreeStarted': 'Сеанс уже начат, переключение на рабочее дерево недоступно', + 'toast.restored': 'Рабочее дерево восстановлено', + 'toast.restoreFailed': 'Не удалось восстановить рабочее дерево: {message}', + 'toast.leaveFailed': 'Не удалось перейти в каталог проекта; повторите попытку', + 'toast.markedReady': '{name} готов к ревью', + 'toast.markReadyFailed': 'Не удалось отметить готовность: {message}', + 'toast.merged': '{name} объединён', + 'toast.mergeFailed': 'Не удалось объединить: {message}', + 'toast.mergeStale': 'В {name} есть новые коммиты; проверьте их перед слиянием', + 'toast.pathCopied': 'Путь скопирован', + 'toast.expandFailed': 'Не удалось показать неизменённые строки: {message}', + 'toast.expandStale': 'Файл изменился после чтения изменений; обновите перед разворачиванием', + 'toast.prompted': 'Отправлено: {text}', + 'toast.promptFailed': 'Не удалось отправить сообщение', +} + +/** Portuguese copy with the same keys. */ +export const pt: Record = { + 'tab.title': 'Solicitações de alteração', + 'header.label': 'Solicitações de alteração desta sessão', + 'header.attention': 'As solicitações de alteração desta sessão precisam de atenção', + 'checkout.worktree': 'Árvore de trabalho', + 'checkout.worktreeFrom': 'Árvore de trabalho · a partir de {base}', + 'checkout.project': 'Diretório do projeto', + 'checkout.detached': 'Fora de uma branch', + 'checkout.restore': 'Restaurar', + 'checkout.copyWorktreePath': 'Copiar caminho da árvore de trabalho', + 'checkout.copyProjectPath': 'Copiar caminho do projeto', + 'checkout.none': 'Este diretório não é um repositório Git', + 'checkout.failed': 'Não foi possível ler as informações do Git', + 'changes.title': 'Solicitações de alteração desta sessão · {count}', + 'changes.empty': 'Esta sessão ainda não tem solicitações de alteração', + 'changes.emptyHint': 'Aqui aparecem solicitações vinculadas à sessão: criadas, visualizadas, editadas ou usadas em checkout, ou abertas nas branches atuais ou enviadas', + 'changes.local.title': 'Alterações', + 'changes.local.refs': '{head} → {base}', + 'changes.local.files': '{count} arquivos', + 'changes.local.viewAria': 'Ver alterações desta sessão: {count} arquivos, {added} linhas adicionadas e {deleted} removidas', + 'changes.local.create': 'Criar solicitação de alteração', + 'changes.local.prompt': 'Crie uma solicitação de alteração para as alterações desta sessão', + 'signin.title': 'Entre em {host} para ver o status das solicitações', + 'signin.copy': 'Copiar comando de login', + 'signin.unavailable': 'Não foi possível ler as solicitações em {host}: {message}', + 'refresh': 'Atualizar status', + 'retry': 'Tentar novamente', + 'stream.failed': 'Não foi possível carregar o painel de solicitações de alteração', + 'change.number': '#{number}', + 'change.stateAria': 'Status da solicitação: {state}', + 'change.state.open': 'Aberta', + 'change.state.blocked': 'Precisa de atenção', + 'change.state.draft': 'Rascunho', + 'change.state.merged': 'Mesclada', + 'change.state.closed': 'Fechada', + 'change.state.unknown': 'Desconhecida', + 'change.expand': 'Expandir {name}', + 'change.collapse': 'Recolher {name}', + 'change.ci.none': 'Sem verificações', + 'change.ci.running': 'Verificações em andamento', + 'change.ci.passed': 'Verificações aprovadas', + 'change.ci.failed': '{count} verificações falharam', + 'change.ci.failedUnlisted': 'As verificações falharam', + 'change.checks.failed': '{count} falharam', + 'change.checks.running': '{count} em andamento', + 'change.checks.passed': '{count} aprovadas', + 'change.checks.other': '{count} outras', + 'change.checks.truncated': 'Apenas as primeiras {count} são exibidas', + 'change.check.running': 'Em andamento', + 'change.check.queued': 'Na fila', + 'change.flag.changesRequested': 'Alterações solicitadas', + 'change.flag.conflicting': 'Conflitos', + 'change.flag.draft': 'Rascunho', + 'change.failure.unavailable': 'Não foi possível ler o status da solicitação', + 'change.failure.notFound': 'A solicitação não existe ou não está acessível', + 'change.failure.unauthenticated': 'Entre para ver o status', + 'change.unserved': 'O status de solicitações deste serviço de código ainda não é compatível', + 'change.view': 'Abrir no navegador', + 'change.copy': 'Copiar link da solicitação', + 'change.viewChangesAria': 'Ver alterações de {name}: {added} linhas adicionadas e {deleted} removidas', + 'change.remove': 'Remover desta sessão', + 'change.removeAria': 'Remover {name} desta sessão', + 'change.row.checks': 'Verificações', + 'change.row.review': 'Revisão', + 'change.row.merge': 'Mesclar', + 'change.row.changes': 'Alterações', + 'change.review.approved': 'Aprovada', + 'change.review.changesRequested': 'Alterações solicitadas', + 'change.review.required': 'Revisão necessária', + 'change.review.none': 'Nenhuma revisão solicitada', + 'change.review.threads': '{review} · {count} não resolvidas', + 'change.merge.mergeable': 'Sem conflitos', + 'change.merge.conflicting': 'Conflitos com {base}', + 'change.merge.unknown': 'Verificando conflitos', + 'change.mergedTo': 'Mesclada em {base}', + 'change.markReady': 'Pronta para revisão', + 'change.merge': 'Mesclar', + 'change.mergeTitle': 'Mesclar {name} em {base}', + 'change.mergeMethod.squash': 'Mesclar com squash', + 'change.mergeMethod.merge': 'Criar um commit de merge', + 'change.mergeMethod.rebase': 'Rebase e merge', + 'change.mergeNote.squash': 'Combinar todos os commits em um', + 'change.mergeNote.merge': 'Manter todos os commits e adicionar um commit de merge', + 'change.mergeNote.rebase': 'Reaplicar cada commit sobre {base}', + 'change.mergeConfirm': 'Confirmar merge', + 'change.mergeChanged': 'Há novos commits. Revise-os antes de reabrir o menu de merge', + 'diff.tab': 'Alterações', + 'diff.tabNumbered': 'Alterações em #{number}', + 'diff.scope.branch': 'Branch', + 'diff.scope.uncommitted': 'Sem commit', + 'diff.scope.unstaged': 'Fora da área de stage', + 'diff.scope.staged': 'Na área de stage', + 'diff.scopeNote.branch': 'Comparação com {base}, incluindo alterações sem commit', + 'diff.scopeNote.uncommitted': 'Comparação com HEAD, incluindo arquivos não rastreados', + 'diff.scopeNote.unstaged': 'Comparação com o índice, incluindo arquivos não rastreados', + 'diff.scopeNote.staged': 'Comparação do índice com HEAD', + 'diff.allFiles': 'Todos os {count} arquivos', + 'diff.refresh': 'Atualizar alterações', + 'diff.expandAll': 'Expandir todos os arquivos', + 'diff.collapseAll': 'Recolher todos os arquivos', + 'diff.split': 'Mostrar lado a lado', + 'diff.unified': 'Mostrar em uma coluna', + 'diff.splitAria': 'Lado a lado', + 'diff.wrap': 'Quebrar linhas longas', + 'diff.nowrap': 'Não quebrar linhas longas', + 'diff.wrapAria': 'Quebrar linhas', + 'diff.unchanged': '{count} linhas sem alterações', + 'diff.unchangedRest': 'Demais linhas sem alterações', + 'diff.newFile': 'Novo arquivo', + 'diff.deletedFile': 'Excluído', + 'diff.renamed': 'Renomeado de {from}', + 'diff.renamedPath': '{from} → {path}', + 'diff.badgeUncommitted': 'Sem commit', + 'diff.binary': 'Arquivo binário; não é possível mostrar as alterações', + 'diff.binaryLabel': 'Binário', + 'diff.largeCollapsed': 'Arquivo grande: {count} linhas alteradas recolhidas', + 'diff.fileTooLarge': 'Este arquivo é grande demais para ser exibido', + 'diff.error': 'Não foi possível ler as alterações', + 'diff.tooLarge': 'Estas alterações são grandes demais para serem exibidas aqui', + 'diff.viewInBrowser': 'Ver no navegador', + 'diff.noForkPoint': 'Não foi encontrado o ponto de ramificação desta branch; escolha outro escopo', + 'diff.empty': 'Sem alterações', + 'diff.omitted': 'Outros {count} arquivos não rastreados não são exibidos', + 'diff.stale': 'A branch local tem {count} commits não enviados; são exibidas as alterações da solicitação', + 'diff.moreActions': 'Mais ações para {name}', + 'diff.copyPath': 'Copiar caminho', + 'diff.openFileInBrowser': 'Ver arquivo no navegador', + 'diff.openFileInSidebar': 'Abrir o arquivo inteiro na barra lateral', + 'time.now': 'agora mesmo', + 'time.minutes': 'há {n} min', + 'time.hours': 'há {n} h', + 'time.days': 'há {n} dias', + 'time.months': 'há {n} meses', + 'time.years': 'há {n} anos', + 'time.finished': '{state} · {time}', + 'duration.seconds': '{seconds}s', + 'duration.minutes': '{minutes} min {seconds} s', + 'duration.hours': '{hours} h {minutes} min', + 'worktree.label': 'Árvore de trabalho', + 'worktree.hint': 'Execute esta sessão em sua própria árvore de trabalho: o envio cria uma branch a partir da escolhida, sem que alterações e commits afetem o diretório do projeto', + 'worktree.blocked.not-git': 'Este espaço de trabalho não é um repositório Git e não pode usar uma árvore de trabalho', + 'worktree.blocked.outside-writable-root': 'Os dados Git estão fora dos diretórios graváveis, como quando o espaço já é uma árvore de trabalho; ainda não é possível usar outra árvore', + 'worktree.blocked.read-only': 'Uma sessão somente leitura não pode usar uma árvore de trabalho', + 'worktree.base': 'A partir de {branch}', + 'worktree.baseHead': 'A partir do HEAD atual', + 'worktree.baseMenu': 'Branch base', + 'worktree.currentBranch': 'Atual', + 'creation.title': 'Criando a árvore de trabalho', + 'creation.failed': 'Não foi possível criar a árvore de trabalho', + 'creation.prepare': 'Criar a branch', + 'creation.checkout': 'Fazer checkout dos arquivos', + 'creation.details': 'Mais detalhes', + 'creation.branch': 'Branch', + 'creation.base': 'Base', + 'creation.head': 'HEAD atual', + 'creation.error': 'Razão', + 'creation.skip': 'Continuar sem árvore de trabalho', + 'creation.cancel': 'Cancelar', + 'creation.stopped': 'Criação da árvore de trabalho interrompida', + 'creation.retry': 'Tentar novamente', + 'creation.waiting': 'A mensagem será enviada após a criação da árvore de trabalho', + 'missing.title': 'A árvore de trabalho está indisponível', + 'missing.unknown': 'A restauração está incompleta e não é possível inspecionar a branch {branch}. Corrija o erro e tente novamente ou continue no projeto', + 'missing.kept': 'A árvore da branch {branch} pode ser restaurada no local original. Alterações sem commit anteriores à remoção não podem ser recuperadas', + 'missing.recreated': 'A branch {branch} também foi removida. Ela será recriada a partir do commit inicial da árvore, sem commits posteriores ou alterações sem commit', + 'missing.restore': 'Restaurar árvore de trabalho', + 'missing.leave': 'Continuar no projeto', + 'missing.waiting': 'A mensagem será enviada após restaurar a árvore ou continuar no projeto', + 'restoration.title': 'Restaurando a árvore de trabalho', + 'restoration.prepare': 'Preparar a árvore de trabalho', + 'branch.worktree': 'Árvore de trabalho (a partir de {base}): {path}', + 'branch.linked': 'Árvore de trabalho: {path}', + 'branch.project': 'Diretório do projeto: {path}', + 'branch.missing': 'Árvore de trabalho indisponível: {path}', + 'toast.removed': '{name} foi removido desta sessão', + 'toast.undo': 'Desfazer', + 'toast.undoFailed': 'Não foi possível desfazer', + 'toast.removeFailed': 'Não foi possível remover', + 'toast.refreshFailed': 'Falha ao atualizar', + 'toast.copied': 'Link copiado', + 'toast.copyFailed': 'Falha na cópia', + 'toast.branchesFailed': 'Não foi possível ler as branches', + 'toast.worktreeFailed': 'Não foi possível alterar a opção da árvore de trabalho', + 'toast.worktreeStarted': 'Esta sessão já começou e não pode mais usar uma árvore de trabalho', + 'toast.restored': 'Árvore de trabalho restaurada', + 'toast.restoreFailed': 'Não foi possível restaurar a árvore de trabalho: {message}', + 'toast.leaveFailed': 'Não foi possível mudar para o diretório do projeto; tente novamente', + 'toast.markedReady': '{name} está pronta para revisão', + 'toast.markReadyFailed': 'Não foi possível marcar como pronta: {message}', + 'toast.merged': '{name} foi mesclada', + 'toast.mergeFailed': 'Não foi possível mesclar: {message}', + 'toast.mergeStale': '{name} tem novos commits; revise-os antes de mesclar', + 'toast.pathCopied': 'Caminho copiado', + 'toast.expandFailed': 'Não foi possível mostrar as linhas sem alterações: {message}', + 'toast.expandStale': 'O arquivo mudou após a leitura das alterações; atualize antes de expandir', + 'toast.prompted': 'Enviado: {text}', + 'toast.promptFailed': 'Não foi possível enviar a mensagem', +} diff --git a/packages/experimental/client-ui-forge/src/client/mount.ts b/packages/experimental/client-ui-forge/src/client/mount.ts index 6f0710fecf..2b858617a7 100644 --- a/packages/experimental/client-ui-forge/src/client/mount.ts +++ b/packages/experimental/client-ui-forge/src/client/mount.ts @@ -22,7 +22,7 @@ import { ChangesTabTitle } from './ChangesTabTitle.tsx' import { ForgeTab, type ForgeTabInjected } from './ForgeTab.tsx' import { ForgeTabTitle } from './ForgeTabTitle.tsx' import { HeaderButton, type HeaderButtonInjected } from './HeaderButton.tsx' -import { en, NS, zh, type ForgePanelKey } from './locales.ts' +import { de, en, es, fr, ja, NS, pt, ru, zh, type ForgePanelKey } from './locales.ts' import { createNoticeSource, createPanelSource, createVisibilitySource, type PanelSource, type VisibilitySource, } from './source.ts' @@ -55,7 +55,7 @@ interface SessionStores { } function registerUi(ctx: Context): void { - ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'forge-panel: dictionaries') + ctx.effect(() => ctx.locale.register(NS, { zh, en, ja, es, fr, de, ru, pt }), 'forge-panel: dictionaries') const t = ctx.locale.bind(NS) const notices = createNoticeSource() const stores = new Map() diff --git a/packages/experimental/client-ui-forge/tests/mount.client.spec.ts b/packages/experimental/client-ui-forge/tests/mount.client.spec.ts index 40e902f05a..a6f61dba6e 100644 --- a/packages/experimental/client-ui-forge/tests/mount.client.spec.ts +++ b/packages/experimental/client-ui-forge/tests/mount.client.spec.ts @@ -361,6 +361,8 @@ describe('mountForgePanel Session stores', () => { f.ctx.locale.addLanguage({ id: 'de', label: 'Deutsch', fallback: 'en' }) f.ctx.locale.setLocale('de') expect(locale.getSnapshot()).toBe('de') + expect(f.ctx.locale.bind(NS)('header.label')).toBe('Änderungsanfragen dieser Sitzung') + expect(f.ctx.locale.bind(NS)('change.mergeTitle', { name: '#7', base: 'main' })).toBe('#7 in main zusammenführen') expect(changed).toHaveBeenCalled() unsubscribe() f.sessions.scope.mockReturnValue(undefined)