diff --git a/webapp/public/flags/ja.svg b/webapp/public/flags/ja.svg new file mode 100644 index 00000000..e9b6d214 --- /dev/null +++ b/webapp/public/flags/ja.svg @@ -0,0 +1,17 @@ + + + + + + + + + \ No newline at end of file diff --git a/webapp/src/i18n.js b/webapp/src/i18n.js index b0cfcdcd..f6828708 100644 --- a/webapp/src/i18n.js +++ b/webapp/src/i18n.js @@ -5,6 +5,7 @@ import es from './locales/es.json' import fr from './locales/fr.json' import hi from './locales/hi.json' import it from './locales/it.json' +import ja from './locales/ja.json' import nl from './locales/nl.json' import pl from './locales/pl.json' import pt from './locales/pt.json' @@ -17,7 +18,7 @@ const i18n = createI18n({ globalInjection: true, // ensure $t is available in all templates locale: 'en', // default; overridden by loadSettings() before mount fallbackLocale: 'en', - messages: { de, en, es, fr, hi, it, nl, pl, pt, ru, sv, zh }, + messages: { de, en, es, fr, hi, it, ja, nl, pl, pt, ru, sv, zh }, }) /** diff --git a/webapp/src/locales/ja.json b/webapp/src/locales/ja.json new file mode 100644 index 00000000..3a44a414 --- /dev/null +++ b/webapp/src/locales/ja.json @@ -0,0 +1,427 @@ +{ + "common": { + "tryAgain": "再試行", + "copied": "コピーしました!", + "copyToClipboard": "クリップボードにコピー", + "copy": "コピー", + "copyAllLinks": "すべてのリンクをコピー", + "confirmAction": "操作の確認", + "confirm": "確認", + "cancel": "キャンセル", + "qrCode": "QRコード", + "close": "閉じる", + "loading": "読み込み中...", + "save": "保存", + "saving": "保存中...", + "remove": "削除", + "delete": "削除", + "upload": "アップロード", + "download": "ダウンロード", + "never": "なし", + "noFilesLimit": "ファイルサイズ制限なし", + "admin": "管理者", + "required": "必須", + "view": "表示", + "decrypt": "復号", + "add": "追加", + "nothingToPreview": "プレビューする内容がありません", + "preview": "プレビュー", + "code": "コード", + "write": "書き込み", + "readOnly": "読み取り専用", + "validate": "検証", + "valid": "有効", + "prettify": "整形", + "prettified": "整形済み", + "plainText": "プレーンテキスト", + "default": "デフォルト", + "unlimited": "無制限", + "defaultHint": "0 = デフォルト, -1 = 無制限", + "defaultHintValue": "0 = デフォルト ({value}), -1 = 無制限", + "timeDay": "{n} 日", + "timeHour": "{n} 時間", + "timeMinute": "{n} 分", + "timeSecond": "{n} 秒" + }, + "header": { + "upload": "アップロード", + "cli": "CLI", + "documentation": "ドキュメント", + "theme": "テーマ", + "language": "言語", + "account": "アカウント", + "admin": "管理者", + "login": "ログイン", + "impersonating": "なりすまし中", + "stopImpersonating": "なりすましを終了", + "loginFailed": "ログインに失敗しました" + }, + "uploadSidebar": { + "uploadSettings": "アップロード設定", + "destructAfterDownload": "ダウンロード後に削除", + "destructHelp": "ファイルは一度ダウンロードされると完全に削除されます", + "streaming": "ストリーミング", + "streamingHelp": "ファイルはサーバーに保存されず、ダウンローダーに直接ストリーミングされます", + "removable": "削除可能", + "removableHelp": "リンクを持っている人は誰でもアップロードされたファイルを削除できます", + "e2ee": "エンドツーエンド暗号化", + "e2eeHelp": "ファイルはアップロード前にブラウザで暗号化されます — パスフレーズを知っている人だけが復号できます", + "passphrase": "パスフレーズ", + "passphraseEmpty": "パスフレーズは空にできません", + "copyPassphrase": "パスフレーズをコピー", + "password": "パスワード", + "passwordHelp": "HTTP Basic認証の資格情報でアップロードを保護します", + "loginPlaceholder": "ログイン", + "passwordPlaceholder": "パスワード", + "copyPassword": "パスワードをコピー", + "comment": "コメント", + "commentHelp": "ダウンロードページにMarkdown形式のメッセージを追加します", + "extendTTL": "アクセス時にTTLを延長", + "extendTTLHelp": "ファイルがアクセスされるたびに有効期限のタイマーをリセットします", + "expiration": "有効期限", + "expirationHelp": "自動的に削除されるまでにアップロードが利用可能な期間", + "neverExpires": "期限なし", + "neverExpiresHelp": "アップロードは自動的に削除されません", + "minutes": "分", + "hours": "時間", + "days": "日", + "maxTTL": "最大: {value} {unit}" + }, + "downloadSidebar": { + "uploadInfo": "アップロード情報", + "neverExpires": "期限なし", + "expired": "期限切れ", + "expiresInDaysHours": "残り {days}日 {hours}時間", + "expiresInHours": "残り {hours}時間", + "expiresInMinutes": "残り {minutes}分", + "share": "共有", + "shared": "共有しました!", + "passphrase": "パスフレーズ", + "notSet": "未設定", + "editPassphrase": "パスフレーズを編集", + "includePassphraseInLink": "リンクにパスフレーズを含める", + "adminUrl": "管理者URL", + "adminUrlHelp": "このURLを他の人と共有すると、このアップロードにファイルを追加できます", + "actions": "アクション", + "zipArchive": "Zipアーカイブ", + "addFiles": "ファイルを追加", + "deleteUpload": "アップロードを削除", + "shareFailed": "共有に失敗しました", + "shareTitle": "共有", + "credentials": "資格情報", + "login": "ログイン", + "password": "パスワード" + }, + "fileRow": { + "uploaded": "アップロード済み", + "uploadFailed": "アップロードに失敗しました", + "retry": "再試行", + "removed": "削除されました", + "deleted": "削除されました", + "waitingForUpload": "アップロード待機中", + "uploading": "アップロード中…", + "toggleDetails": "詳細を切り替え", + "showQrCode": "QRコードを表示", + "viewFileContent": "ファイル内容を表示", + "cancelUpload": "アップロードをキャンセル", + "dismiss": "閉じる", + "removeFile": "ファイルを削除", + "decryptAndDownload": "復号してダウンロード", + "type": "種類:", + "md5": "MD5:", + "created": "作成日時:" + }, + "badges": { + "oneShot": "ワンショット", + "removable": "削除可能", + "stream": "ストリーム", + "extendTTL": "TTL延長", + "password": "パスワード", + "encrypted": "暗号化済み" + }, + "uploadView": { + "dropFilesHere": "ここにファイルをドロップ", + "dropPasteOrClick": "ドロップ、貼り付け、またはクリックしてファイルを選択", + "maxPerFile": "ファイルあたり最大 {size}", + "createEmptyUpload": "空のアップロードを作成", + "pasteText": "テキストを貼り付け", + "filesSelected": "{count} 個のファイルを選択", + "creatingUpload": "アップロードを作成中...", + "commentRequired": "コメントが必要です", + "e2eePassphraseEmpty": "E2EEが有効ですが、パスフレーズが空です", + "passwordCredentialsIncomplete": "パスワードが有効です — ログインとパスワードの両方が必要です", + "failedToCreateUpload": "アップロードの作成に失敗しました", + "textUpload": "テキストアップロード", + "filename": "ファイル名", + "pasteOrTypeHere": "ここにテキストを貼り付けまたは入力...", + "commentPlaceholder": "コメントを入力... (Markdown対応)", + "commentRequiredPlaceholder": "コメントを入力... (必須、Markdown対応)", + "fileSizeError": "ファイル \"{name}\" は大きすぎます ({size})。最大: {max}", + "createEmptyUploadTooltip": "作成後にアップロードへファイルを追加できるようにします" + }, + "downloadView": { + "loadingUpload": "アップロードを読み込み中...", + "comment": "コメント", + "e2eeIndicator": "{link} でエンドツーエンド暗号化", + "e2eeDecryptInBrowser": "ファイルはブラウザで復号されます", + "streamingUpload": "ストリーミングアップロード", + "streamingDescription": "ファイルはアップローダーからダウンローダーに直接ストリーミングされます — 転送を開始するには、アップロードリンクまたは個々のファイルリンクを共有してください。", + "streamTimeout": "ファイルのダウンロードを開始するまでに {timeout} あります。", + "decrypting": "復号中...", + "loadingFileContent": "ファイル内容を読み込み中...", + "noFilesInUpload": "このアップロードにファイルはありません", + "filesUploaded": "{uploaded}/{total} 個のファイルをアップロード済み", + "filesCount": "{count} 個のファイル", + "filesFailed": "{count} 個のファイルが失敗", + "filesLeftToUpload": "残り {count} 個のファイルをアップロード", + "filesToAdd": "追加する {count} 個のファイル", + "retryFailed": "失敗を再試行", + "cancelAll": "すべてキャンセル", + "uploadingFiles": "ファイルをアップロード中...", + "enterPassphrase": "パスフレーズを入力", + "e2eePassphrasePrompt": "このアップロードはエンドツーエンド暗号化されています。ファイルを復号するパスフレーズを入力してください。", + "passphrasePlaceholder": "パスフレーズ", + "deleteUploadTitle": "アップロードを削除", + "deleteUploadMessage": "このアップロードを削除してもよろしいですか?この操作は元に戻せません。", + "deleteFileTitle": "ファイルを削除", + "deleteFileMessage": "\"{name}\" を削除してもよろしいですか?この操作は元に戻せません。", + "failedToLoadUpload": "アップロードの読み込みに失敗しました", + "failedToDeleteUpload": "アップロードの削除に失敗しました", + "failedToDeleteFile": "ファイルの削除に失敗しました", + "decryptionFailed": "復号に失敗しました: {error}", + "wrongPassphrase": "パスフレーズが間違っていますか?", + "uploadLink": "アップロードリンク", + "previousFile": "前のファイル (←)", + "nextFile": "次のファイル (→)", + "closeViewer": "ビューアを閉じる (Esc)", + "copyLinkAtTime": "現在の時刻でリンクをコピー" + }, + "homeView": { + "stats": "統計", + "uploads": "アップロード", + "tokens": "トークン", + "signOut": "サインアウト", + "editAccount": "アカウントを編集", + "deleteUploads": "アップロードを削除", + "deleteAccount": "アカウントを削除", + "userConfiguration": "ユーザー設定", + "maxFileSize": "最大ファイルサイズ", + "maxUserSize": "ユーザー最大サイズ", + "defaultTTL": "デフォルトTTL", + "maxTTL": "最大TTL", + "userStatistics": "ユーザー統計", + "totalSize": "合計サイズ", + "files": "ファイル", + "noStatsAvailable": "統計はありません", + "loadingStats": "統計を読み込み中...", + "loadingUploads": "アップロードを読み込み中...", + "noUploadsYet": "アップロードはまだありません", + "loadMoreUploads": "さらにアップロードを読み込む", + "tokenDescription": "トークンはCLIクライアントの認証に使用されます。{config} ファイルに追加してください。", + "commentOptional": "コメント (任意)", + "createToken": "トークンを作成", + "loadingTokens": "トークンを読み込み中...", + "noTokensYet": "トークンはまだありません", + "loadMoreTokens": "さらにトークンを読み込む", + "deleteTokenUploads": "アップロードを削除", + "showUploadsForToken": "このトークンのアップロードを表示", + "revokeToken": "失効", + "deleteUploadConfirm": "アップロード {id} を削除しますか?", + "deleteAllUploadsConfirm": "{label} を削除しますか?この操作は元に戻せません。", + "allYourUploads": "すべてのアップロード", + "allUploadsForToken": "トークン {token} のすべてのアップロード", + "deleteTokenUploadsConfirm": "トークン \"{label}\" のすべてのアップロードを削除しますか?トークン自体は失効しません。", + "uploadsRemoved": "アップロードを削除しました", + "revokeTokenConfirm": "トークン {token}... を失効しますか?このトークンで作成されたアップロードは残ります。", + "deleteAccountConfirm": "アカウントとすべてのアップロードを削除しますか?この操作は元に戻せません。", + "editAccountTitle": "アカウントを編集", + "adminSettings": "管理者設定", + "failedToLoadStats": "ユーザー統計の読み込みに失敗しました", + "failedToLoadUploads": "アップロードを読み込めませんでした", + "failedToDeleteUpload": "アップロードを削除できませんでした", + "failedToDeleteUploads": "アップロードを削除できませんでした", + "failedToLoadTokens": "トークンを読み込めませんでした", + "failedToCreateToken": "トークンを作成できませんでした", + "failedToDeleteTokenUploads": "トークンのアップロードを削除できませんでした", + "failedToRevokeToken": "トークンを失効できませんでした", + "failedToDeleteAccount": "アカウントを削除できませんでした" + }, + "uploadCard": { + "uploaded": "アップロード:", + "expires": "有効期限:", + "user": "ユーザー:", + "token": "トークン:", + "noFiles": "ファイルなし", + "missing": "未着 — アップロード待機中", + "remove": "削除" + }, + "uploadControls": { + "sort": "並び替え:", + "date": "日付", + "size": "サイズ", + "order": "順序:", + "desc": "降順", + "asc": "昇順", + "filter": "フィルター:", + "oneShot": "ワンショット", + "removable": "削除可能", + "stream": "ストリーム", + "extendTTL": "TTL延長", + "password": "パスワード", + "encrypted": "暗号化済み" + }, + "loginView": { + "signInToAccount": "アカウントにサインイン", + "loginLabel": "ログイン", + "passwordLabel": "パスワード", + "enterLogin": "ログインを入力してください", + "enterPassword": "パスワードを入力してください", + "signingIn": "サインイン中...", + "signIn": "サインイン", + "orContinueWith": "または次で続行", + "signInWithGoogle": "Googleでサインイン", + "signInWithOvh": "OVHでサインイン", + "signInWithProvider": "{provider} でサインイン", + "backToUpload": "← アップロードに戻る", + "pleaseEnterCredentials": "ログインとパスワードを入力してください", + "invalidCredentials": "認証情報が無効です", + "loginFailed": "ログインに失敗しました", + "googleLoginFailed": "Googleログインに失敗しました", + "ovhLoginFailed": "OVHログインに失敗しました", + "oidcLoginFailed": "OIDCログインに失敗しました", + "signInWithGithub": "GitHubでサインイン", + "githubLoginFailed": "GitHubログインに失敗しました" + }, + "clientsView": { + "title": "CLIクライアント", + "subtitle": "お使いのプラットフォーム向けのPlikコマンドラインクライアントをダウンロードしてください。", + "quickStart": "クイックスタート", + "quickStartInstructions": "ダウンロード後、バイナリを実行可能にして実行してください:", + "quickStartConfig": "{config} でサーバーURLとトークンを設定してください", + "loadingClients": "クライアントを読み込み中...", + "noClientsAvailable": "利用可能なクライアントバイナリはありません。", + "failedToLoadClients": "クライアント一覧の読み込みに失敗しました" + }, + "cliAuth": { + "cliLogin": "CLIログイン", + "authorizeDescription": "CLIクライアントが {user} としてPlikにアクセスすることを承認します", + "verificationCode": "認証コード", + "tokenDescription": "トークンの説明", + "authorizing": "承認中…", + "authorizeCli": "CLIを承認", + "cliAuthorized": "CLIが承認されました!", + "authorizedDescription": "CLIクライアントが認証されました。このページを閉じてターミナルに戻ることができます。", + "returnToPlik": "Plikに戻る", + "authorizationFailed": "承認に失敗しました", + "failedToApprove": "CLIログインの承認に失敗しました", + "tryAgain": "再試行", + "defaultComment": "CLIクライアントから作成" + }, + "errorView": { + "goToUpload": "アップロードへ移動" + }, + "editUser": { + "editUser": "ユーザーを編集", + "quotas": "クォータ", + "provider": "プロバイダー", + "login": "ログイン", + "name": "名前", + "displayName": "表示名", + "email": "メールアドレス", + "password": "パスワード", + "leaveBlankToKeep": "現在の値を保持するには空白のままにしてください", + "maxFileSizeGB": "最大ファイルサイズ (GB)", + "maxUserSizeGB": "ユーザー最大サイズ (GB)", + "maxTTL": "最大TTL" + }, + "api": { + "networkError": "ネットワークエラー — サーバーに接続できません", + "uploadConnectionLost": "アップロード接続が切断されました — ネットワークを確認してください", + "uploadCancelled": "アップロードがキャンセルされました", + "uploadFailed": "アップロードに失敗しました ({status})", + "unknownError": "不明なエラー" + }, + "adminView": { + "plikServer": "Plikサーバー", + "stats": "統計", + "uploads": "アップロード", + "users": "ユーザー", + "createUser": "ユーザーを作成", + "loadingStats": "統計を読み込み中...", + "serverConfiguration": "サーバー設定", + "serverStatistics": "サーバー統計", + "maxFileSize": "最大ファイルサイズ", + "maxUserSize": "ユーザー最大サイズ", + "defaultTTL": "デフォルトTTL", + "maxTTL": "最大TTL", + "usersLabel": "ユーザー", + "uploadsLabel": "アップロード", + "anonymousUploads": "匿名アップロード", + "files": "ファイル", + "totalSize": "合計サイズ", + "anonymousSize": "匿名サイズ", + "searchUsersPlaceholder": "ログイン、名前、またはメールでユーザーを検索…", + "sort": "並び替え:", + "date": "日付", + "order": "順序:", + "desc": "降順", + "asc": "昇順", + "provider": "プロバイダー:", + "all": "すべて", + "role": "ロール:", + "nonAdmin": "非管理者", + "showingUsersOf": "{total} 人中 {shown} 人のユーザーを表示中", + "loadingUsers": "ユーザーを読み込み中...", + "noUsers": "ユーザーはいません", + "maxFileSizeLabel": "最大ファイルサイズ: {value}", + "maxUserSizeLabel": "ユーザー最大サイズ: {value}", + "maxTTLLabel": "最大TTL: {value}", + "viewUploads": "アップロードを表示", + "impersonate": "なりすまし", + "edit": "編集", + "loadMoreUsers": "さらにユーザーを読み込む", + "showingUploadsOf": "{total} 件中 {shown} 件のアップロードを表示中", + "loadingUploads": "アップロードを読み込み中...", + "noUploads": "アップロードはありません", + "loadMoreUploads": "さらにアップロードを読み込む", + "viewUserInUsersTab": "ユーザータブでユーザーを表示", + "deleteUserConfirm": "ユーザー \"{login}\" ({provider}) を削除しますか?すべてのアップロードとファイルが削除されます。", + "deleteUploadConfirm": "アップロード {id} を削除しますか?", + "failedToLoadStats": "サーバー統計を読み込めませんでした", + "failedToLoadUsers": "ユーザーを読み込めませんでした", + "failedToLoadUploads": "アップロードを読み込めませんでした", + "failedToLoadVersion": "バージョン情報を読み込めませんでした", + "failedToDeleteUser": "ユーザーを削除できませんでした", + "failedToDeleteUpload": "アップロードを削除できませんでした", + "failedToFindUser": "ユーザーが見つかりませんでした", + "failedToCreateUser": "ユーザーの作成に失敗しました", + "failedToUpdateUser": "ユーザーの更新に失敗しました", + "createUserTitle": "ユーザーを作成", + "loginPlaceholder": "4文字以上", + "passwordPlaceholder": "8文字以上", + "optional": "任意", + "quotas": "クォータ", + "creating": "作成中...", + "create": "作成", + "editUserTitle": "ユーザーを編集" + }, + "languagePicker": { + "switchLanguage": "言語を切り替え", + "de": "Deutsch", + "en": "English", + "es": "Español", + "fr": "Français", + "hi": "हिन्दी", + "it": "Italiano", + "ja": "日本語", + "nl": "Nederlands", + "pl": "Polski", + "pt": "Português", + "ru": "Русский", + "sv": "Svenska", + "zh": "中文" + }, + "footer": { + "abuseContact": "不正利用に関するお問い合わせは {link} まで" + } +} diff --git a/webapp/src/settings.js b/webapp/src/settings.js index 62d957d8..fccd3470 100644 --- a/webapp/src/settings.js +++ b/webapp/src/settings.js @@ -29,6 +29,7 @@ export const BUILTIN_LANGUAGES = [ { name: 'fr', label: 'Français', flag: 'flags/fr.svg' }, { name: 'hi', label: 'हिन्दी', flag: 'flags/hi.svg' }, { name: 'it', label: 'Italiano', flag: 'flags/it.svg' }, + { name: 'ja', label: '日本語', flag: 'flags/ja.svg' }, { name: 'nl', label: 'Nederlands', flag: 'flags/nl.svg' }, { name: 'pl', label: 'Polski', flag: 'flags/pl.svg' }, { name: 'pt', label: 'Português', flag: 'flags/pt.svg' },