type Locale = 'en' | 'zh-CN'; const LOCALE_STORAGE_KEY = 'nodewarden.locale'; const messages: Record> = { en: { nav_account_settings: "Account Settings", nav_admin_panel: "Admin Panel", nav_device_management: "Device Management", nav_my_vault: "My Vault", nav_sends: "Sends", nav_backup_strategy: "Cloud Backup", nav_import_export: "Import & Export", backup_strategy_title: "Cloud Backup", backup_strategy_under_construction: "Under construction.", import_export_title: "Import & Export", import_export_under_construction: "Under construction.", txt_backup_export: "Export Backup", txt_backup_import: "Restore", txt_backup_export_description: "Download a full instance backup ZIP for manual safekeeping.", txt_backup_import_description: "Upload a previously exported backup ZIP and restore it into this instance.", txt_backup_exporting: "Exporting...", txt_backup_importing: "Restoring...", txt_backup_restoring: "Restoring...", txt_backup_export_success: "Backup exported", txt_backup_import_success_relogin: "Backup restored. Please sign in again.", txt_backup_restore_success_relogin: "Backup restored. Please sign in again.", txt_backup_restore_skipped_summary: "{reason}. Skipped {attachments} attachment(s) and {sendFiles} Send file(s).", txt_backup_restore_skipped_reason_default: "Some files could not be restored", txt_backup_export_failed: "Backup export failed", txt_backup_import_failed: "Backup restore failed", txt_backup_restore_failed: "Backup restore failed", txt_backup_center_title: "Instance Backup", txt_backup_center_description: "Keep local exports for manual restore, and configure one daily remote backup target for unattended protection.", txt_backup_restore_note: "Restoring will overwrite the current instance if you choose the replace flow.", txt_backup_manual: "Manual Backup", txt_backup_manual_description: "Export a ZIP right now, or import a ZIP back into this instance.", txt_backup_destinations_title: "Backup Destinations", txt_backup_destinations_description: "Keep multiple WebDAV and E3 targets here. Select one on the left to edit or browse it.", txt_backup_recommend_title: "Recommended Storage", txt_backup_recommend_open_signup: "Open Signup", txt_backup_recommend_open_signup_aff: "Open Signup (AFF)", txt_backup_recommend_open_guide: "Open Guide", txt_backup_recommend_empty: "No recommendations yet.", txt_backup_recommend_referral_label: "Referral Code", txt_backup_recommend_referral_note: "Use it during signup to get 5 GB extra. The author receives 2 GB.", txt_backup_recommend_infinicloud_summary: "Only an email address is needed. 20 GB free, 25 GB total with the referral code.", txt_backup_recommend_infinicloud_step_1: "Register an InfiniCLOUD account with just your email address.", txt_backup_recommend_infinicloud_step_2_prefix: "Open", txt_backup_recommend_infinicloud_step_2_suffix: "and turn on Apps Connection.", txt_backup_recommend_infinicloud_step_3: "Use Connection ID as your WebDAV username and Apps Password as your WebDAV password.", txt_backup_recommend_infinicloud_step_4: "Enter referral code 2HC5E in Referral Bonus at the bottom of My Page to receive 5 GB extra.", txt_backup_recommend_open_password: "Password Settings", txt_backup_recommend_open_storage: "Open Storage", txt_backup_recommend_koofr_summary: "Only an email address is needed. 10 GB free, and it can bridge Google Drive, OneDrive, and Dropbox through WebDAV.", txt_backup_recommend_koofr_password_link: "Password Settings", txt_backup_recommend_koofr_storage_link: "Storage", txt_backup_recommend_koofr_step_1: "Register a Koofr account with just your email address.", txt_backup_recommend_koofr_step_2_prefix: "Open", txt_backup_recommend_koofr_step_2_suffix: ", generate a new app password, use your email address as the WebDAV username, and use the app password as the WebDAV password.", txt_backup_recommend_koofr_step_3: "Koofr's own WebDAV address is https://app.koofr.net/dav/Koofr.", txt_backup_recommend_koofr_step_4: "Koofr can also connect Google Drive, OneDrive, and Dropbox. Free users can connect up to two storage accounts.", txt_backup_recommend_koofr_step_5_prefix: "Open", txt_backup_recommend_koofr_step_5_suffix: ", click Connect in the left sidebar, and choose the cloud storage you want to attach.", txt_backup_recommend_koofr_dav_intro: "After a storage account is connected, keep the same email and app password, and only switch the WebDAV address:", txt_backup_recommend_koofr_dav_self: "Koofr", txt_backup_recommend_pcloud_summary: "Only an email address is needed. Up to 10 GB free, with standard WebDAV access.", txt_backup_recommend_pcloud_step_1: "Register a pCloud account with just your email address.", txt_backup_recommend_pcloud_step_2: "Use https://webdav.pcloud.com/ as the WebDAV server URL.", txt_backup_recommend_pcloud_step_3: "Use your registration email as the WebDAV username and your account password as the WebDAV password.", txt_backup_add_destination: "Add Destination", txt_backup_schedule_panel_title: "Automatic Schedule", txt_backup_schedule_panel_note: "Each destination can keep its own daily backup schedule.", txt_backup_scheduled_target: "Scheduled Target", txt_backup_destination_active_badge: "Auto On", txt_backup_destination_idle_badge: "Auto Off", txt_backup_destination_last_success: "Last success: {time}", txt_backup_destination_never_run: "No successful run yet", txt_backup_destination_detail_title: "Destination Details", txt_backup_destination_detail_note: "", txt_backup_destination_name: "Destination Name", txt_backup_set_scheduled_target: "Use For Daily Backup", txt_backup_delete_destination: "Delete", txt_backup_destination_deleted: "Backup destination deleted", txt_backup_delete_destination_confirm_message: "Delete backup destination \"{name}\"? This cannot be undone.", txt_backup_select_destination: "Select a backup destination from the list first.", txt_backup_remote_save_first: "Save this destination first before browsing its remote backup files.", txt_backup_automation: "Automatic Backup", txt_backup_automation_description: "Pick a destination, save the credentials, and let the worker upload one backup every day.", txt_backup_settings_saved: "Backup settings saved", txt_backup_settings_save_failed: "Saving backup settings failed", txt_backup_settings_load_failed: "Loading backup settings failed", txt_backup_save_settings: "Save Settings", txt_backup_saving: "Saving...", txt_backup_enable_action: "Enable", txt_backup_disable_action: "Disable", txt_backup_run_now: "Run Remote Backup Now", txt_backup_run_manual: "Run Manually", txt_backup_running_now: "Running...", txt_backup_remote_run_success: "Remote backup completed", txt_backup_remote_run_failed: "Remote backup failed", txt_backup_remote_title: "Remote Backups", txt_backup_remote_note: "Browse the saved destination and choose a backup ZIP to download or restore.", txt_backup_remote_saved_basis: "Remote browsing uses the last saved destination settings, not unsaved form edits.", txt_backup_remote_refresh: "Refresh", txt_backup_remote_root: "Root", txt_backup_remote_up: "Up", txt_backup_remote_open: "Open", txt_backup_remote_download: "Download", txt_backup_remote_downloading: "Downloading...", txt_backup_remote_restore: "Restore", txt_backup_remote_loading: "Loading remote backups...", txt_backup_remote_cached_empty: "Click Refresh to load this destination.", txt_backup_remote_empty: "No backup files found in this folder.", txt_backup_remote_folder: "Folder", txt_backup_remote_unknown_time: "Unknown time", txt_backup_remote_current_path: "Current Folder", txt_backup_remote_load_failed: "Loading remote backups failed", txt_backup_remote_invalid_response: "Invalid remote backup response", txt_backup_remote_download_failed: "Downloading remote backup failed", txt_backup_remote_delete_success: "Remote backup deleted", txt_backup_remote_delete_failed: "Deleting remote backup failed", txt_backup_remote_delete_confirm_message: "Delete backup file \"{name}\"? This cannot be undone.", txt_backup_remote_deleting: "Deleting...", txt_backup_remote_restore_failed: "Restoring remote backup failed", txt_backup_remote_restore_invalid_response: "Invalid remote backup restore response", txt_backup_remote_run_invalid_response: "Invalid remote backup run response", txt_backup_settings_invalid_response: "Invalid backup settings response", txt_backup_import_invalid_response: "Invalid backup import response", txt_backup_destination: "Backup Destination", txt_backup_protocol_webdav: "WebDAV", txt_backup_protocol_e3: "E3", txt_backup_recommend_group_webdav: "WebDAV", txt_backup_recommend_group_s3: "S3", txt_backup_destination_name_default_webdav: "WebDAV {index}", txt_backup_destination_name_default_e3: "E3 {index}", txt_backup_type: "Backup Type", txt_backup_destination_reserved: "Reserved Slot", txt_backup_time: "Backup Time", txt_backup_timezone: "Timezone", txt_backup_frequency: "Frequency", txt_backup_frequency_daily: "Daily", txt_backup_frequency_weekly: "Weekly", txt_backup_frequency_monthly: "Monthly", txt_backup_day_of_week: "Day of Week", txt_backup_day_of_month: "Day of Month", txt_backup_weekday_monday: "Monday", txt_backup_weekday_tuesday: "Tuesday", txt_backup_weekday_wednesday: "Wednesday", txt_backup_weekday_thursday: "Thursday", txt_backup_weekday_friday: "Friday", txt_backup_weekday_saturday: "Saturday", txt_backup_weekday_sunday: "Sunday", txt_backup_retention_count: "Keep", txt_backup_retention_count_suffix: "items", txt_backup_retention_count_hint: "Leave empty to keep all backup files. New destinations default to 30.", txt_backup_enable_schedule: "Enable automatic daily backup", txt_backup_schedule_note: "The worker checks the schedule every 5 minutes and runs the backup as soon as the selected time window is reached.", txt_backup_schedule_disabled: "Disabled", txt_backup_schedule_status: "Schedule", txt_backup_schedule_summary: "Daily at {time} ({timezone})", txt_backup_schedule_empty: "No automatic backup plans are enabled yet.", txt_backup_last_success: "Last Success", txt_backup_last_target: "Last Target", txt_backup_last_file: "Last File", txt_backup_last_error_prefix: "Last Error", txt_backup_none_yet: "No remote backup has completed yet", txt_backup_not_configured: "Not configured", txt_backup_never: "Never", txt_backup_unknown_size: "Unknown size", txt_backup_webdav_url: "WebDAV Server URL", txt_backup_webdav_username: "WebDAV Username", txt_backup_webdav_password: "WebDAV Password", txt_backup_webdav_path: "Remote Folder", txt_backup_e3_endpoint: "E3 Endpoint", txt_backup_e3_bucket: "Bucket", txt_backup_e3_region: "Region", txt_backup_e3_access_key: "Access Key", txt_backup_e3_secret_key: "Secret Key", txt_backup_e3_path: "Remote Path", txt_backup_reserved_name: "Reserved Provider Name", txt_backup_reserved_notes: "Reserved Notes", txt_backup_reserved_notes_placeholder: "Leave a note for the next destination type", txt_backup_reserved_hint: "This slot is reserved for a future destination. You can save notes now, but automatic uploads stay disabled.", txt_backup_file: "Backup File", txt_backup_file_required: "Please select a backup file", txt_backup_no_file_selected: "No backup file selected", txt_backup_selected_file_name: "Selected file: {name}", txt_backup_replace_confirm_title: "Replace Current Instance Data", txt_backup_replace_confirm_message: "The current instance already contains data. Clear it and restore the selected backup?", txt_backup_clear_and_import: "Clear and Import", txt_backup_clear_and_restore: "Clear and Restore", txt_access_count: "Access Count", txt_accessed_count_times: "Accessed {count} times", txt_actions: "Actions", txt_add: "Add", txt_add_field: "Add Field", txt_add_website: "Add Website", txt_added: "Added", txt_additional_options: "Additional Options", txt_address: "Address", txt_address_1: "Address 1", txt_address_2: "Address 2", txt_address_3: "Address 3", txt_all_device_authorizations_revoked: "All device trust revoked", txt_all_invites_deleted: "All invites deleted", txt_all_items: "All Items", txt_all_sends: "All Sends", txt_android: "Android", txt_are_you_sure_you_want_to_delete_count_selected_items: "Are you sure you want to delete {count} selected items?", txt_are_you_sure_you_want_to_delete_count_selected_items_permanently: "Are you sure you want to permanently delete {count} selected items?", txt_are_you_sure_you_want_to_delete_this_item: "Are you sure you want to delete this item?", txt_are_you_sure_you_want_to_log_out: "Are you sure you want to log out?", txt_authenticator_key: "Authenticator Key", txt_authorized_devices: "Authorized Devices", txt_auto_copy_link_after_save: "Auto copy link after save", txt_autofill_options: "Autofill Options", txt_back_to_login: "Back To Login", txt_ban: "Ban", txt_boolean: "Boolean", txt_brand: "Brand", txt_bulk_delete_failed: "Bulk delete failed", txt_bulk_permanent_delete_failed: "Bulk permanent delete failed", txt_bulk_restore_failed: "Bulk restore failed", txt_bulk_delete_sends_failed: "Bulk delete sends failed", txt_bulk_move_failed: "Bulk move failed", txt_cancel: "Cancel", txt_card: "Card", txt_card_details: "Card Details", txt_cardholder_name: "Cardholder Name", txt_change_master_password: "Change Master Password", txt_change_password: "Change Password", txt_change_password_failed: "Change password failed", txt_change_password_confirm_and_sign_out_all_devices: "Changing the master password will sign out all devices, including this web session. Continue?", txt_copy_failed: "Copy failed", txt_checked: "Checked", txt_choose_destination_folder: "Choose destination folder.", txt_chrome_browser: "Chrome Browser", txt_chrome_extension: "Chrome Extension", txt_city_town: "City / Town", txt_code: "Code", txt_company: "Company", txt_configure_custom_field_values: "Configure custom field values.", txt_confirm: "Confirm", txt_confirm_master_password: "Confirm Master Password", txt_confirm_password: "Confirm Password", txt_copy: "Copy", txt_code_copied: "Code copied", txt_copy_code: "Copy Code", txt_copy_link: "Copy Link", txt_copy_secret: "Copy Secret", txt_country: "Country", txt_create: "Create", txt_create_account: "Create Account", txt_registering: "Creating account...", txt_create_folder: "Create Folder", txt_create_folder_failed: "Create folder failed", txt_create_item_failed: "Create item failed", txt_create_send_failed: "Create send failed", txt_create_timed_invite: "Create Timed Invite", txt_created_value: "Created: {value}", txt_current_new_password_is_required: "Current/new password is required", txt_current_password: "Current Password", txt_custom_fields: "Custom Fields", txt_decrypt_failed: "(Decrypt failed)", txt_decrypt_failed_2: "Decrypt failed", txt_delete: "Delete", txt_delete_all: "Delete All", txt_delete_all_invite_codes_active_inactive: "Delete all invite codes (active/inactive)?", txt_delete_all_invites: "Delete all invites", txt_delete_item: "Delete Item", txt_delete_item_failed: "Delete item failed", txt_delete_permanently: "Delete Permanently", txt_delete_selected: "Delete Selected", txt_delete_selected_items: "Delete Selected Items", txt_delete_selected_items_permanently: "Delete Selected Items Permanently", txt_delete_send_failed: "Delete send failed", txt_delete_this_user_and_all_user_data: "Delete this user and all user data?", txt_delete_user: "Delete user", txt_deleted_selected_items: "Deleted selected items", txt_deleted_selected_items_permanently: "Permanently deleted selected items", txt_restored_selected_items: "Restored selected items", txt_deleted_selected_sends: "Deleted selected sends", txt_deletion_date: "Deletion Date", txt_deletion_days: "Deletion Days", txt_device: "Device", txt_device_authorization_revoked: "Device trust revoked", txt_device_management: "Device Management", txt_device_removed: "Device removed", txt_load_devices_failed: "Failed to load devices", txt_disable_this_send: "Disable this send", txt_disable_totp: "Disable TOTP", txt_disable_totp_failed: "Disable TOTP failed", txt_download: "Download", txt_downloading: "Downloading...", txt_downloading_percent: "Downloading {percent}%", txt_download_failed: "Download failed", txt_edge_browser: "Edge Browser", txt_edge_extension: "Edge Extension", txt_edit: "Edit", txt_edit_send: "Edit Send", txt_email: "Email", txt_email_password_and_recovery_code_are_required: "Email, password and recovery code are required", txt_enable_totp: "Enable TOTP", txt_enable_totp_failed: "Enable TOTP failed", txt_enabled: "Enabled", txt_encrypted_file: "Encrypted File", txt_encrypted_file_2: "Encrypted file", txt_enter_a_folder_name: "Enter a folder name.", txt_enter_master_password_to_disable_two_step_verification: "Enter master password to disable two-step verification.", txt_enter_master_password_to_view_this_item: "Enter master password to view this item.", txt_expiration_date: "Expiration Date", txt_expiration_days_0_never: "Expiration Days (0 = never)", txt_expires_at: "Expires At", txt_expires_at_value: "Expires at: {value}", txt_expiry: "Expiry", txt_expiry_month: "Expiry Month", txt_expiry_year: "Expiry Year", txt_failed_to_open_send: "Failed to open send", txt_favorite: "Favorite", txt_favorites: "Favorites", txt_field: "Field", txt_field_label: "Field Label", txt_field_label_is_required: "Field label is required.", txt_field_type: "Field Type", txt_field_value: "Field Value", txt_file: "File", txt_file_name: "File Name", txt_file_send: "File Send", txt_file_size: "File Size", txt_fingerprint: "Fingerprint", txt_firefox_browser: "Firefox Browser", txt_firefox_extension: "Firefox Extension", txt_first_name: "First Name", txt_folder: "Folder", txt_folder_created: "Folder created", txt_folder_name: "Folder Name", txt_folder_name_is_required: "Folder name is required", txt_folders: "Folders", txt_hidden: "Hidden", txt_hide: "Hide", txt_identity: "Identity", txt_identity_details: "Identity Details", txt_ie_browser: "IE Browser", txt_invite_code_optional: "Invite Code (Not required for the first account; required for all others)", txt_invite_created: "Invite created", txt_invite_revoked: "Invite revoked", txt_invite_validity_hours: "Invite validity (hours)", txt_invites: "Invites", txt_ios: "iOS", txt_item: "Item", txt_item_created: "Item created", txt_item_deleted: "Item deleted", txt_item_history: "Item History", txt_item_name_is_required: "Item name is required.", txt_item_updated: "Item updated", txt_last_edited_value: "Last edited: {value}", txt_last_name: "Last Name", txt_last_seen: "Last Seen", txt_license_number: "License Number", txt_link_copied: "Link copied", txt_linked: "Linked", txt_linux_desktop: "Linux Desktop", txt_loading: "Loading...", txt_loading_nodewarden: "Loading NodeWarden...", txt_jwt_warning_title: "Server Security Warning", txt_jwt_warning_subtitle: "JWT secret is not configured safely.", txt_jwt_title_missing: "JWT_SECRET is missing", txt_jwt_title_too_short: "JWT_SECRET is too short", txt_jwt_title_default: "JWT_SECRET is using the default value", txt_jwt_reason_missing: "JWT secret is missing.", txt_jwt_reason_default: "JWT secret is still the default/sample value.", txt_jwt_reason_too_short: "JWT secret is too short. Minimum length is {min}.", txt_jwt_how_to_fix_add: "How to add JWT_SECRET", txt_jwt_how_to_fix_replace: "How to replace JWT_SECRET", txt_jwt_add_step_1: "Use the 32-character generator below and copy a new key.", txt_jwt_add_step_2: "Cloudflare Dashboard -> Workers & Pages -> Your Service -> Settings -> Variables and Secrets, add JWT_SECRET.", txt_jwt_add_step_3: "Save and wait for redeploy, then refresh this page.", txt_jwt_replace_step_1: "Use the 32-character generator below and create a stronger key (minimum {min} characters).", txt_jwt_replace_step_2: "Cloudflare Dashboard -> Workers & Pages -> Your Service -> Settings -> Variables and Secrets, replace JWT_SECRET.", txt_jwt_replace_step_3: "Save and wait for redeploy, then refresh this page.", txt_how_to_fix: "How to fix", txt_jwt_fix_step_1: "Open your deployment environment variables.", txt_jwt_fix_step_2: "If your current key is not random enough, use the 32-character generator below.", txt_jwt_fix_step_3: "Cloudflare Dashboard -> Workers & Pages -> Your Service -> Settings -> Variables and Secrets, update JWT_SECRET.", txt_jwt_fix_step_4: "Save and wait for redeploy, then refresh this page to verify.", txt_random_secret_generator: "Random Secret Generator", txt_copied: "Copied", txt_log_in: "Log In", txt_logging_in: "Logging in...", txt_log_out: "Log Out", txt_lock: "Lock", txt_menu: "Menu", txt_settings: "Settings", txt_back: "Back", txt_login: "Login", txt_login_credentials: "Login Credentials", txt_login_failed: "Login failed", txt_login_success: "Login success", txt_macos_desktop: "macOS Desktop", txt_manage_authorized_devices_and_30_day_totp_trusted_sessions: "Manage authorized devices and 30-day TOTP trusted sessions.", txt_manage_device_sessions_and_30_day_totp_trusted_sessions: "Manage device sessions and 30-day TOTP trusted sessions.", txt_master_password: "Master Password", txt_master_password_changed_please_login_again: "Master password changed. Please login again.", txt_master_password_changed_signing_out_everywhere: "Master password changed. Signing out all devices.", txt_master_password_is_required: "Master password is required", txt_master_password_is_required_2: "Master password is required.", txt_master_password_must_be_at_least_12_chars: "Master password must be at least 12 chars", txt_master_password_reprompt: "Master password reprompt", txt_master_password_reprompt_2: "Master Password Reprompt", txt_max_access_count: "Max Access Count", txt_middle_name: "Middle Name", txt_move: "Move", txt_move_selected_items: "Move Selected Items", txt_moved_selected_items: "Moved selected items", txt_name: "Name", txt_name_is_required: "Name is required", txt_new_password: "New Password", txt_nothing_to_copy: "Nothing to copy", txt_new_password_must_be_at_least_12_chars: "New password must be at least 12 chars", txt_new_passwords_do_not_match: "New passwords do not match", txt_new_send: "New Send", txt_next: "Next", txt_no: "No", txt_no_devices_found: "No devices found.", txt_no_folder: "No Folder", txt_no_items: "No items", txt_no_username: "(No username)", txt_no_verification_codes: "No verification codes", txt_no_name: "(No Name)", txt_no_sends: "No sends", txt_nodewarden_send: "NodeWarden Send", txt_not_trusted: "Not trusted", txt_note: "Note", txt_notes: "Notes", txt_number: "Number", txt_open: "Open", txt_opera_browser: "Opera Browser", txt_opera_extension: "Opera Extension", txt_or: "or", txt_options: "Options", txt_passport_number: "Passport Number", txt_password: "Password", txt_password_is_already_verified: "Password is already verified.", txt_passwords_do_not_match: "Passwords do not match", txt_phone: "Phone", txt_please_input_email_and_password: "Please input email and password", txt_please_input_master_password: "Please input master password", txt_please_input_totp_code: "Please input TOTP code", txt_please_select_a_file: "Please select a file", txt_postal_code: "Postal Code", txt_prev: "Prev", txt_private_key: "Private Key", txt_profile: "Profile", txt_profile_unavailable: "Profile unavailable", txt_profile_updated: "Profile updated", txt_public_key: "Public Key", txt_recover_2fa_failed: "Recover 2FA failed", txt_recover_two_step_login: "Recover Two-step Login", txt_recovered_but_auto_login_failed_please_sign_in: "Recovered but auto-login failed, please sign in.", txt_recovery_code: "Recovery Code", txt_recovery_code_copied: "Recovery code copied", txt_recovery_code_is_empty: "Recovery code is empty", txt_recovery_code_loaded: "Recovery code loaded", txt_refresh: "Refresh", txt_refresh_in_seconds_s: "Refresh in {seconds}s", txt_regenerate: "Regenerate", txt_registration_succeeded_please_sign_in: "Registration succeeded. Please sign in.", txt_remove: "Remove", txt_remove_device: "Remove device", txt_remove_device_2: "Remove Device", txt_remove_all_devices: "Remove all devices", txt_remove_all_devices_and_clear_all_2fa_trust: "Remove all devices and clear all 2FA trust?", txt_remove_all_devices_and_sign_out_all_sessions: "Remove all devices, clear all trust, and sign out every device?", txt_remove_device_name_and_clear_its_2fa_trust: "Remove device \"{name}\" and clear its 2FA trust?", txt_remove_device_and_sign_out_name: "Remove device \"{name}\", clear its trust, and sign it out?", txt_reveal: "Reveal", txt_restore: "Restore", txt_revoke: "Revoke", txt_revoke_30_day_totp_trust_for_name: "Revoke 30-day TOTP trust for \"{name}\"?", txt_revoke_30_day_totp_trust_from_all_devices: "Revoke 30-day TOTP trust from all devices?", txt_revoke_all_trusted: "Revoke All Trusted", txt_revoke_all_trusted_devices: "Revoke all device trust", txt_revoke_device_authorization: "Revoke device trust", txt_revoke_device_trust_failed: "Failed to revoke device trust", txt_revoke_all_device_trust_failed: "Failed to revoke all device trust", txt_revoke_trust: "Revoke Trust", txt_role: "Role", txt_save: "Save", txt_save_profile: "Save Profile", txt_save_profile_failed: "Save profile failed", txt_search_sends: "Search sends...", txt_search_your_secure_vault: "Search your secure vault...", txt_sort: "Sort", txt_sort_last_edited: "Modified", txt_sort_created: "Created", txt_sort_name: "A-Z", txt_secret_and_code_are_required: "Secret and code are required", txt_secret_copied: "Secret copied", txt_secure_note: "Secure Note", txt_security_code: "Security Code", txt_security_code_cvv: "Security Code (CVV)", txt_select_all: "Select All", txt_select_an_item: "Select an item", txt_send_created: "Send created", txt_send_deleted: "Send deleted", txt_send_details: "Send Details", txt_send_file: "send-file", txt_send_unavailable: "Send unavailable.", txt_send_updated: "Send updated", txt_sign_out: "Sign Out", txt_ssh_key: "SSH Key", txt_ssn: "SSN", txt_state_province: "State / Province", txt_status: "Status", txt_online: "Online", txt_offline: "Offline", txt_submit: "Submit", txt_sync: "Sync", txt_sync_vault: "Sync Vault", txt_dash: "-", txt_text: "Text", txt_text_2fa_recovered: "2FA recovered", txt_text_2fa_recovered_new_recovery_code_code: "2FA recovered. New recovery code: {code}", txt_text_3: "------", txt_text_is_required: "Text is required", txt_text_send: "Text Send", txt_this_is_a_one_time_code_after_it_is_used_a_new_code_is_generated_automatically: "This is a one-time code. After it is used, a new code is generated automatically.", txt_this_item_requires_master_password_every_time_before_viewing_details: "This item requires master password every time before viewing details.", txt_this_link_is_missing_decryption_key: "This link is missing decryption key.", txt_this_send_is_password_protected: "This send is password protected.", txt_title: "Title", txt_totp: "TOTP", txt_totp_code: "TOTP Code", txt_totp_disabled: "TOTP disabled", txt_totp_enabled: "TOTP enabled", txt_totp_is_enabled_for_this_account: "TOTP is enabled for this account.", txt_total_items_count: "{count} items", txt_totp_secret: "TOTP Secret", txt_totp_verify_failed: "TOTP verify failed", txt_passkey: "Passkey", txt_passkey_created_at_value: "Created at {value}", txt_attachments: "Attachments", txt_upload_attachments: "Upload attachments", txt_new_attachments: "New attachments", txt_marked_for_removal_count: "{count} attachment(s) will be removed on save", txt_trash: "Trash", txt_trust_this_device_for_30_days: "Trust this device for 30 days", txt_trusted_until: "Trusted Until", txt_two_step_verification: "Two-step verification", txt_type: "Type", txt_type_type: "Type {type}", txt_unban: "Unban", txt_unchecked: "Unchecked", txt_unknown_device: "Unknown device", txt_unlock: "Unlock", txt_unlocking: "Unlocking...", txt_unlock_details: "Unlock Details", txt_unlock_failed: "Unlock failed", txt_unlock_failed_master_password_is_incorrect: "Unlock failed. Master password is incorrect.", txt_unlock_item: "Unlock Item", txt_unlock_send: "Unlock Send", txt_unlock_vault: "Unlock Vault", txt_unlocked: "Unlocked", txt_all_devices_removed: "All devices removed", txt_remove_device_failed: "Failed to remove device", txt_remove_all_devices_failed: "Failed to remove all devices", txt_update_item_failed: "Update item failed", txt_update_send_failed: "Update send failed", txt_use_recovery_code: "Use Recovery Code", txt_use_your_one_time_recovery_code_to_disable_two_step_verification: "Use your one-time recovery code to disable two-step verification.", txt_user_deleted: "User deleted", txt_user_status_updated: "User status updated", txt_username: "Username", txt_users: "Users", txt_vault_synced: "Vault synced", txt_verification_code: "Verification Code", txt_verify: "Verify", txt_view_recovery_code: "View Recovery Code", txt_web: "Web", txt_website: "Website", txt_websites: "Websites", txt_windows_desktop: "Windows Desktop", txt_yes: "Yes", }, 'zh-CN': {}, }; const zhCNOverrides: Record = { nav_my_vault: '我的密码库', nav_sends: 'Send', nav_admin_panel: '用户管理', nav_account_settings: '账户设置', nav_device_management: '设备管理', nav_backup_strategy: '云端备份', nav_import_export: '导入导出', backup_strategy_title: '云端备份', backup_strategy_under_construction: '正在搭建中', import_export_title: '导入导出', import_export_under_construction: '正在搭建中', txt_backup_export: '导出备份', txt_backup_import: '还原', txt_backup_export_description: '下载一个完整的实例备份 ZIP,手动保管即可。', txt_backup_import_description: '上传之前导出的备份 ZIP,并还原到当前实例。', txt_backup_exporting: '正在导出...', txt_backup_importing: '正在还原...', txt_backup_restoring: '正在还原...', txt_backup_export_success: '备份已导出', txt_backup_import_success_relogin: '备份已还原,请重新登录', txt_backup_restore_success_relogin: '备份已还原,请重新登录', txt_backup_restore_skipped_summary: '{reason},已跳过 {attachments} 个附件和 {sendFiles} 个 Send 文件', txt_backup_restore_skipped_reason_default: '部分文件无法还原', txt_backup_export_failed: '备份导出失败', txt_backup_import_failed: '备份还原失败', txt_backup_restore_failed: '备份还原失败', txt_backup_center_title: '实例备份', txt_backup_center_description: '把本地导出和远程自动备份放在一起管理,既方便手动恢复,也能每天自动留一份。', txt_backup_restore_note: '还原会覆盖当前实例;如果当前已有数据,系统会要求你确认“清空后还原”。', txt_backup_manual: '手动备份', txt_backup_manual_description: '现在就导出 ZIP,或者把之前导出的 ZIP 恢复到当前实例。', txt_backup_destinations_title: '备份地点', txt_backup_destinations_description: '把多个 WebDAV、E3 地点统一放在这里。左侧选一个,右侧编辑和浏览它。', txt_backup_recommend_title: '推荐储存库', txt_backup_recommend_open_signup: '前往注册', txt_backup_recommend_open_signup_aff: '前往注册(含 AFF)', txt_backup_recommend_open_guide: '查看教程', txt_backup_recommend_empty: '暂时没有推荐', txt_backup_recommend_referral_label: '推荐码', txt_backup_recommend_referral_note: '注册时填写可额外获得 5 GB,作者会收到 2 GB。', txt_backup_recommend_infinicloud_summary: '只需邮箱即可注册。免费 20 GB;填写推荐码后总计 25 GB。', txt_backup_recommend_infinicloud_step_1: '先用邮箱注册一个 InfiniCLOUD 账号。', txt_backup_recommend_infinicloud_step_2_prefix: '进入', txt_backup_recommend_infinicloud_step_2_suffix: ',然后开启 Turn on Apps Connection。', txt_backup_recommend_infinicloud_step_3: 'Connection ID 用作 WebDAV 用户名,Apps Password 用作 WebDAV 密码。', txt_backup_recommend_infinicloud_step_4: '在 My Page 最下面的 Referral Bonus 填入推荐码 2HC5E,可额外获得 5 GB。', txt_backup_recommend_open_password: '密码设置', txt_backup_recommend_open_storage: '打开储存连接', txt_backup_recommend_koofr_summary: '只需邮箱即可注册使用。免费 10 GB,并且可以通过 WebDAV 接到 Google Drive、OneDrive、Dropbox。', txt_backup_recommend_koofr_password_link: '密码设置', txt_backup_recommend_koofr_storage_link: 'Storage', txt_backup_recommend_koofr_step_1: '先用邮箱注册一个 Koofr 账号。', txt_backup_recommend_koofr_step_2_prefix: '打开', txt_backup_recommend_koofr_step_2_suffix: ',生成新的应用密码。注册邮箱用作 WebDAV 用户名,应用密码用作 WebDAV 密码。', txt_backup_recommend_koofr_step_3: 'Koofr 自己的 WebDAV 地址是 https://app.koofr.net/dav/Koofr。', txt_backup_recommend_koofr_step_4: 'Koofr 最方便的地方,是还能接 Google Drive、OneDrive、Dropbox 这三大云盘;免费用户最多能连接两个。', txt_backup_recommend_koofr_step_5_prefix: '打开', txt_backup_recommend_koofr_step_5_suffix: ',在左侧栏点击“连接”,选择你要连接的储存即可。', txt_backup_recommend_koofr_dav_intro: '连接好储存后,账号和应用密码都不变,只需要切换 WebDAV 地址:', txt_backup_recommend_koofr_dav_self: 'Koofr', txt_backup_recommend_pcloud_summary: '只需邮箱即可注册。免费最高 10 GB,并且自带标准 WebDAV 访问。', txt_backup_recommend_pcloud_step_1: '先用邮箱注册一个 pCloud 账号。', txt_backup_recommend_pcloud_step_2: 'WebDAV 地址填写 https://webdav.pcloud.com/ 。', txt_backup_recommend_pcloud_step_3: '注册邮箱用作 WebDAV 用户名,注册密码用作 WebDAV 密码。', txt_backup_add_destination: '新增地点', txt_backup_schedule_panel_title: '自动备份计划', txt_backup_schedule_panel_note: '每个备份地点都可以单独配置自己的每日自动备份计划。', txt_backup_scheduled_target: '当前计划目标', txt_backup_destination_active_badge: '已启用计划', txt_backup_destination_idle_badge: '未启用计划', txt_backup_destination_last_success: '上次成功:{time}', txt_backup_destination_never_run: '还没有成功执行过', txt_backup_destination_detail_title: '地点详情', txt_backup_destination_detail_note: '', txt_backup_destination_name: '地点名称', txt_backup_set_scheduled_target: '设为每日备份目标', txt_backup_delete_destination: '删除', txt_backup_destination_deleted: '备份地点已删除', txt_backup_delete_destination_confirm_message: '删除备份地点“{name}”?此操作不可撤销。', txt_backup_select_destination: '请先从左侧列表选择一个备份地点', txt_backup_remote_save_first: '请先保存这个备份地点,再浏览它的远端备份文件', txt_backup_automation: '自动备份', txt_backup_automation_description: '选择备份地点,保存连接信息后,系统会按设定时间每天自动上传一份备份。', txt_backup_settings_saved: '备份设置已保存', txt_backup_settings_save_failed: '备份设置保存失败', txt_backup_settings_load_failed: '备份设置加载失败', txt_backup_save_settings: '保存设置', txt_backup_saving: '正在保存...', txt_backup_enable_action: '启用', txt_backup_disable_action: '停用', txt_backup_run_now: '立即执行远程备份', txt_backup_run_manual: '手动执行', txt_backup_running_now: '执行中...', txt_backup_remote_run_success: '远程备份已完成', txt_backup_remote_run_failed: '远程备份失败', txt_backup_remote_title: '远端备份', txt_backup_remote_note: '浏览已保存的备份地点,选择某个备份 ZIP 后可以下载,也可以直接还原。', txt_backup_remote_saved_basis: '远端浏览使用的是“已保存”的备份地点配置,不会读取你当前未保存的表单内容。', txt_backup_remote_refresh: '刷新', txt_backup_remote_root: '根目录', txt_backup_remote_up: '上一级', txt_backup_remote_open: '打开', txt_backup_remote_download: '下载', txt_backup_remote_downloading: '下载中...', txt_backup_remote_restore: '还原', txt_backup_remote_loading: '正在读取远端备份...', txt_backup_remote_cached_empty: '点击“刷新”后读取', txt_backup_remote_empty: '这个目录下还没有备份文件', txt_backup_remote_folder: '文件夹', txt_backup_remote_unknown_time: '未知时间', txt_backup_remote_current_path: '当前目录', txt_backup_remote_load_failed: '读取远端备份失败', txt_backup_remote_invalid_response: '远端备份响应无效', txt_backup_remote_download_failed: '下载远端备份失败', txt_backup_remote_delete_success: '远端备份已删除', txt_backup_remote_delete_failed: '删除远端备份失败', txt_backup_remote_delete_confirm_message: '删除备份文件“{name}”?此操作不可撤销。', txt_backup_remote_deleting: '删除中...', txt_backup_remote_restore_failed: '还原远端备份失败', txt_backup_remote_restore_invalid_response: '远端备份还原响应无效', txt_backup_remote_run_invalid_response: '远端备份执行响应无效', txt_backup_settings_invalid_response: '备份设置响应无效', txt_backup_import_invalid_response: '备份还原响应无效', txt_backup_destination: '备份地点', txt_backup_protocol_webdav: 'WebDAV', txt_backup_protocol_e3: 'E3', txt_backup_recommend_group_webdav: 'WebDAV', txt_backup_recommend_group_s3: 'S3', txt_backup_destination_name_default_webdav: 'WebDAV {index}', txt_backup_destination_name_default_e3: 'E3 {index}', txt_backup_type: '备份类型', txt_backup_destination_reserved: '预留位置', txt_backup_time: '备份时间', txt_backup_timezone: '时区', txt_backup_frequency: '备份频率', txt_backup_frequency_daily: '每天', txt_backup_frequency_weekly: '每周', txt_backup_frequency_monthly: '每月', txt_backup_day_of_week: '星期', txt_backup_day_of_month: '日期', txt_backup_weekday_monday: '周一', txt_backup_weekday_tuesday: '周二', txt_backup_weekday_wednesday: '周三', txt_backup_weekday_thursday: '周四', txt_backup_weekday_friday: '周五', txt_backup_weekday_saturday: '周六', txt_backup_weekday_sunday: '周日', txt_backup_retention_count: '只保留', txt_backup_retention_count_suffix: '个', txt_backup_retention_count_hint: '留空表示不限,新建备份地点默认保留 30 个', txt_backup_enable_schedule: '启用每日自动备份', txt_backup_schedule_note: 'Worker 每 5 分钟检查一次计划,到达你设定的时间窗口后会尽快执行备份。', txt_backup_schedule_disabled: '未启用', txt_backup_schedule_status: '计划状态', txt_backup_schedule_summary: '每天 {time}({timezone})', txt_backup_schedule_empty: '还没有启用任何自动备份计划', txt_backup_last_success: '上次成功时间', txt_backup_last_target: '上次备份位置', txt_backup_last_file: '上次备份文件', txt_backup_last_error_prefix: '上次错误', txt_backup_none_yet: '还没有成功完成过远程备份', txt_backup_not_configured: '尚未配置', txt_backup_never: '从未', txt_backup_unknown_size: '大小未知', txt_backup_webdav_url: 'WebDAV 服务地址', txt_backup_webdav_username: 'WebDAV 用户名', txt_backup_webdav_password: 'WebDAV 密码', txt_backup_webdav_path: '远程目录', txt_backup_e3_endpoint: 'E3 Endpoint', txt_backup_e3_bucket: 'Bucket', txt_backup_e3_region: 'Region', txt_backup_e3_access_key: 'Access Key', txt_backup_e3_secret_key: 'Secret Key', txt_backup_e3_path: '远程路径', txt_backup_reserved_name: '预留类型名称', txt_backup_reserved_notes: '预留备注', txt_backup_reserved_notes_placeholder: '给下一个备份地点先留个说明', txt_backup_reserved_hint: '这个位置先预留给后续备份地点。你现在可以先保存备注,但自动上传不会启用。', txt_backup_file: '备份文件', txt_backup_file_required: '请选择备份文件', txt_backup_no_file_selected: '尚未选择备份文件', txt_backup_selected_file_name: '已选择文件:{name}', txt_backup_replace_confirm_title: '替换当前实例数据', txt_backup_replace_confirm_message: '当前实例里已经有数据。要先清空当前数据库和文件,再还原所选备份吗?', txt_backup_clear_and_import: '清空后导入', txt_backup_clear_and_restore: '清空后还原', txt_sign_out: '退出登录', txt_log_in: '登录', txt_logging_in: '正在登录...', txt_log_out: '退出', txt_create_account: '创建账户', txt_registering: '正在注册...', txt_back_to_login: '返回登录', txt_unlock: '解锁', txt_unlocking: '正在解锁...', txt_unlock_vault: '解锁密码库', txt_master_password: '主密码', txt_email: '邮箱', txt_name: '名称', txt_password: '密码', txt_confirm_password: '确认密码', txt_confirm_master_password: '确认主密码', txt_submit: '提交', txt_cancel: '取消', txt_yes: '是', txt_no: '否', txt_loading: '加载中...', txt_loading_nodewarden: '正在加载 NodeWarden...', txt_search_sends: '搜索发送...', txt_search_your_secure_vault: '搜索你的密码库...', txt_refresh: '刷新', txt_sync: '同步', txt_sync_vault: '同步', txt_add: '新增', txt_edit: '编辑', txt_delete: '删除', txt_save: '保存', txt_confirm: '确认', txt_move: '移动', txt_copy: '复制', txt_code_copied: '验证码已复制', txt_copy_link: '复制链接', txt_select_all: '全选', txt_delete_selected: '删除所选', txt_all_items: '所有项目', txt_favorites: '收藏', txt_trash: '回收站', txt_folder: '文件夹', txt_folders: '文件夹', txt_no_folder: '无文件夹', txt_no_items: '没有项目', txt_no_username: '无用户名', txt_no_verification_codes: '没有验证码', txt_no_sends: '没有发送', txt_select_an_item: '请选择一个项目', txt_login: '登录', txt_card: '银行卡', txt_identity: '身份', txt_note: '笔记', txt_secure_note: '安全笔记', txt_ssh_key: 'SSH 密钥', txt_login_credentials: '登录信息', txt_card_details: '银行卡详情', txt_identity_details: '身份详情', txt_autofill_options: '自动填充选项', txt_additional_options: '附加选项', txt_custom_fields: '自定义字段', txt_notes: '备注', txt_item_history: '项目历史', txt_last_edited_value: '最后编辑:{value}', txt_created_value: '创建于:{value}', txt_username: '用户名', txt_website: '网站', txt_websites: '网站', txt_open: '打开', txt_hide: '隐藏', txt_reveal: '显示', txt_restore: '恢复', txt_favorite: '收藏', txt_field: '字段', txt_field_type: '字段类型', txt_field_label: '字段标签', txt_field_value: '字段值', txt_add_field: '添加字段', txt_remove: '移除', txt_enabled: '已启用', txt_checked: '已勾选', txt_unchecked: '未勾选', txt_profile: '资料', txt_save_profile: '保存资料', txt_change_master_password: '修改主密码', txt_current_password: '当前密码', txt_new_password: '新密码', txt_nothing_to_copy: '没有可复制的内容', txt_change_password: '修改密码', txt_change_password_confirm_and_sign_out_all_devices: '修改主密码后会强制退出所有设备,包括当前网页端。确认继续吗', txt_copy_failed: '复制失败', txt_totp: 'TOTP', txt_enable_totp: '启用 TOTP', txt_disable_totp: '停用 TOTP', txt_totp_code: 'TOTP 验证码', txt_totp_secret: 'TOTP 密钥', txt_verification_code: '验证码', txt_recovery_code: '恢复代码', txt_view_recovery_code: '查看恢复代码', txt_copy_code: '复制代码', txt_device_management: '设备管理', txt_authorized_devices: '已授权设备', txt_device: '设备', txt_last_seen: '最后在线', txt_trusted_until: '信任至', txt_revoke_trust: '撤销信任', txt_remove_device_2: '移除设备', txt_not_trusted: '未信任', txt_unknown_device: '未知设备', txt_users: '用户', txt_invites: '邀请码', txt_ban: '封禁', txt_unban: '解封', txt_create_timed_invite: '创建时效邀请码', txt_invite_validity_hours: '邀请码有效期(小时)', txt_delete_all: '全部删除', txt_prev: '上一页', txt_next: '下一页', txt_send_details: '发送详情', txt_new_send: '新建发送', txt_edit_send: '编辑发送', txt_file_send: '文件发送', txt_text_send: '文本发送', txt_file: '文件', txt_text: '文本', txt_file_name: '文件名', txt_file_size: '文件大小', txt_access_count: '访问次数', txt_deletion_date: '删除日期', txt_expiration_date: '过期日期', txt_deletion_days: '删除天数', txt_expiration_days_0_never: '过期天数(0 表示不过期)', txt_max_access_count: '最大访问次数', txt_options: '选项', txt_disable_this_send: '禁用此发送', txt_auto_copy_link_after_save: '保存后自动复制链接', txt_unlock_send: '解锁发送', txt_nodewarden_send: 'NodeWarden 发送', txt_send_unavailable: '发送不可用。', txt_download: '下载', txt_downloading: '下载中...', txt_downloading_percent: '下载中 {percent}%', txt_expires_at: '过期时间', txt_expires_at_value: '过期于:{value}', txt_dash: '-', txt_or: '或', txt_no_name: '(无名称)', txt_are_you_sure_you_want_to_log_out: '确认要退出登录吗?', txt_delete_item: '删除项目', txt_delete_selected_items: '删除所选项目', txt_move_selected_items: '移动所选项目', txt_create_folder: '创建文件夹', txt_folder_name: '文件夹名称', txt_unlock_item: '解锁项目', txt_use_recovery_code: '使用恢复代码', txt_two_step_verification: '两步验证', txt_recover_two_step_login: '恢复两步登录', txt_title: '称谓', txt_first_name: '名', txt_middle_name: '中间名', txt_last_name: '姓', txt_company: '公司', txt_ssn: '社保号', txt_passport_number: '护照号', txt_license_number: '证件号', txt_private_key: '私钥', txt_public_key: '公钥', txt_fingerprint: '指纹', txt_master_password_reprompt: '主密码二次确认', txt_master_password_reprompt_2: '主密码二次确认', txt_configure_custom_field_values: '配置自定义字段值。', txt_hidden: '隐藏', txt_boolean: '布尔', txt_regenerate: '重新生成', txt_copy_secret: '复制密钥', txt_this_is_a_one_time_code_after_it_is_used_a_new_code_is_generated_automatically: '这是一次性恢复代码,使用后将自动生成新的恢复代码。', txt_manage_authorized_devices_and_30_day_totp_trusted_sessions: '管理已授权设备和 30 天 TOTP 受信会话。', txt_manage_device_sessions_and_30_day_totp_trusted_sessions: '管理设备会话和 30 天 TOTP 受信状态。', txt_role: '角色', txt_status: '状态', txt_online: '在线', txt_offline: '离线', txt_actions: '操作', txt_type: '类型', txt_revoke_all_trusted: '撤销全部受信任设备', txt_revoke_all_trusted_devices: '撤销所有设备信任', txt_revoke_30_day_totp_trust_from_all_devices: '确认撤销所有设备的 30 天 TOTP 信任吗?', txt_revoke_30_day_totp_trust_for_name: '确认撤销“{name}”的 30 天 TOTP 信任吗?', txt_remove_device_name_and_clear_its_2fa_trust: '确认移除设备“{name}”并清除其 2FA 信任吗?', txt_remove_all_devices: '移除所有设备', txt_remove_all_devices_and_clear_all_2fa_trust: '确认移除所有设备并清除全部 2FA 信任吗?', txt_remove_all_devices_and_sign_out_all_sessions: '确认移除所有设备、清除全部信任,并让所有设备重新登录吗?', txt_remove_device_and_sign_out_name: '确认移除设备“{name}”,清除其信任,并让它重新登录吗?', txt_role_admin: '管理员', txt_role_user: '用户', txt_status_active: '正常', txt_status_banned: '已封禁', txt_status_inactive: '未激活', txt_accessed_count_times: '已访问 {count} 次', txt_add_website: '添加网站', txt_added: '已添加', txt_address: '地址', txt_address_1: '地址 1', txt_address_2: '地址 2', txt_address_3: '地址 3', txt_all_device_authorizations_revoked: '已撤销所有设备信任', txt_all_invites_deleted: '已删除所有邀请码', txt_all_sends: '所有发送', txt_android: '安卓', txt_are_you_sure_you_want_to_delete_count_selected_items: '确认删除所选的 {count} 个项目?', txt_are_you_sure_you_want_to_delete_count_selected_items_permanently: '确认永久删除所选的 {count} 个项目?', txt_are_you_sure_you_want_to_delete_this_item: '确认删除此项目?', txt_authenticator_key: '验证器密钥', txt_brand: '品牌', txt_bulk_delete_failed: '批量删除失败', txt_bulk_permanent_delete_failed: '批量永久删除失败', txt_bulk_restore_failed: '批量恢复失败', txt_bulk_delete_sends_failed: '批量删除发送失败', txt_bulk_move_failed: '批量移动失败', txt_cardholder_name: '持卡人姓名', txt_change_password_failed: '修改密码失败', txt_choose_destination_folder: '选择目标文件夹。', txt_chrome_browser: 'Chrome 浏览器', txt_chrome_extension: 'Chrome 扩展', txt_city_town: '城市 / 城镇', txt_code: '代码', txt_country: '国家', txt_create: '创建', txt_create_folder_failed: '创建文件夹失败', txt_create_item_failed: '创建项目失败', txt_create_send_failed: '创建发送失败', txt_current_new_password_is_required: '需要输入当前密码和新密码', txt_decrypt_failed: '(解密失败)', txt_decrypt_failed_2: '解密失败', txt_delete_all_invite_codes_active_inactive: '删除所有邀请码(有效/无效)?', txt_delete_all_invites: '删除所有邀请码', txt_delete_item_failed: '删除项目失败', txt_delete_permanently: '永久删除', txt_delete_send_failed: '删除发送失败', txt_delete_this_user_and_all_user_data: '删除此用户及其所有数据?', txt_delete_user: '删除用户', txt_deleted_selected_items: '已删除所选项目', txt_deleted_selected_items_permanently: '已永久删除所选项目', txt_restored_selected_items: '已恢复所选项目', txt_deleted_selected_sends: '已删除所选发送', txt_device_authorization_revoked: '设备信任已撤销', txt_device_removed: '设备已移除', txt_load_devices_failed: '加载设备失败', txt_disable_totp_failed: '禁用 TOTP 失败', txt_download_failed: '下载失败', txt_edge_browser: 'Edge 浏览器', txt_edge_extension: 'Edge 扩展', txt_email_password_and_recovery_code_are_required: '需要输入邮箱、密码和恢复代码', txt_enable_totp_failed: '启用 TOTP 失败', txt_encrypted_file: '加密文件', txt_encrypted_file_2: '加密文件', txt_enter_a_folder_name: '请输入文件夹名称', txt_enter_master_password_to_disable_two_step_verification: '输入主密码以禁用两步验证', txt_enter_master_password_to_view_this_item: '输入主密码以查看此项目', txt_expiry: '有效期', txt_expiry_month: '有效期月', txt_expiry_year: '有效期年', txt_failed_to_open_send: '打开发送失败', txt_field_label_is_required: '字段标签不能为空', txt_firefox_browser: 'Firefox 浏览器', txt_firefox_extension: 'Firefox 扩展', txt_folder_created: '文件夹已创建', txt_folder_name_is_required: '文件夹名称不能为空', txt_ie_browser: 'IE 浏览器', txt_invite_code_optional: '邀请码(首位注册者无需填写,其他人必填)', txt_invite_created: '邀请码已创建', txt_invite_revoked: '邀请码已撤销', txt_ios: 'iOS', txt_item: '项目', txt_item_created: '项目已创建', txt_item_deleted: '项目已删除', txt_item_name_is_required: '项目名称不能为空', txt_item_updated: '项目已更新', txt_link_copied: '链接已复制', txt_linked: '已关联', txt_linux_desktop: 'Linux 桌面端', txt_login_failed: '登录失败', txt_login_success: '登录成功', txt_macos_desktop: 'macOS 桌面端', txt_master_password_changed_please_login_again: '主密码已修改,请重新登录', txt_master_password_changed_signing_out_everywhere: '主密码已修改,正在退出所有设备', txt_master_password_is_required: '主密码不能为空', txt_master_password_is_required_2: '请输入主密码', txt_master_password_must_be_at_least_12_chars: '主密码至少需要 12 个字符', txt_moved_selected_items: '已移动所选项目', txt_name_is_required: '名称不能为空', txt_new_password_must_be_at_least_12_chars: '新密码至少需要 12 个字符', txt_new_passwords_do_not_match: '两次输入的新密码不一致', txt_no_devices_found: '未找到设备', txt_number: '数字', txt_opera_browser: 'Opera 浏览器', txt_opera_extension: 'Opera 扩展', txt_password_is_already_verified: '密码已验证', txt_passwords_do_not_match: '两次输入的密码不一致', txt_phone: '电话', txt_please_input_email_and_password: '请输入邮箱和密码', txt_please_input_master_password: '请输入主密码', txt_please_input_totp_code: '请输入 TOTP 验证码', txt_please_select_a_file: '请选择文件', txt_postal_code: '邮政编码', txt_profile_unavailable: '资料不可用', txt_profile_updated: '资料已更新', txt_recover_2fa_failed: '恢复 2FA 失败', txt_recovered_but_auto_login_failed_please_sign_in: '已恢复,但自动登录失败,请手动登录', txt_recovery_code_copied: '恢复代码已复制', txt_recovery_code_is_empty: '恢复代码为空', txt_recovery_code_loaded: '恢复代码已加载', txt_refresh_in_seconds_s: '{seconds} 秒后刷新', txt_registration_succeeded_please_sign_in: '注册成功,请登录', txt_remove_device: '移除设备', txt_revoke: '撤销', txt_revoke_device_authorization: '撤销设备信任', txt_revoke_device_trust_failed: '撤销设备信任失败', txt_revoke_all_device_trust_failed: '撤销所有设备信任失败', txt_save_profile_failed: '保存资料失败', txt_secret_and_code_are_required: '密钥和代码不能为空', txt_secret_copied: '密钥已复制', txt_security_code: '安全码', txt_security_code_cvv: '安全码 (CVV)', txt_sort: '排序', txt_sort_last_edited: '最近修改', txt_sort_created: '最近创建', txt_sort_name: 'A-Z', txt_send_created: '发送已创建', txt_send_deleted: '发送已删除', txt_send_file: '发送文件', txt_send_updated: '发送已更新', txt_state_province: '省 / 州', txt_text_2fa_recovered: '2FA 已恢复', txt_text_2fa_recovered_new_recovery_code_code: '2FA 已恢复,新的恢复代码:{code}', txt_text_3: '------', txt_text_is_required: '文本不能为空', txt_this_item_requires_master_password_every_time_before_viewing_details: '每次查看详情前均需输入主密码', txt_this_link_is_missing_decryption_key: '此链接缺少解密密钥', txt_this_send_is_password_protected: '此发送受密码保护', txt_totp_disabled: 'TOTP 已禁用', txt_totp_enabled: 'TOTP 已启用', txt_totp_is_enabled_for_this_account: '此账户已启用 TOTP。', txt_total_items_count: '共 {count} 项', txt_totp_verify_failed: 'TOTP 验证失败', txt_trust_this_device_for_30_days: '信任此设备 30 天', txt_type_type: '类型 {type}', txt_unlock_details: '解锁详情', txt_unlock_failed: '解锁失败', txt_unlock_failed_master_password_is_incorrect: '解锁失败,主密码不正确。', txt_unlocked: '已解锁', txt_all_devices_removed: '已移除所有设备', txt_remove_device_failed: '移除设备失败', txt_remove_all_devices_failed: '移除所有设备失败', txt_update_item_failed: '更新项目失败', txt_update_send_failed: '更新发送失败', txt_use_your_one_time_recovery_code_to_disable_two_step_verification: '使用一次性恢复代码禁用两步验证。', txt_user_deleted: '用户已删除', txt_user_status_updated: '用户状态已更新', txt_vault_synced: '密码库已同步', txt_verify: '验证', txt_web: '网页', txt_windows_desktop: 'Windows 桌面端', txt_jwt_warning_title: 'JWT_SECRET 配置警告', txt_jwt_warning_subtitle: 'JWT 密钥当前不安全,请先修复后再继续。', txt_jwt_title_missing: '未检测到 JWT_SECRET', txt_jwt_title_too_short: 'JWT_SECRET 长度过短', txt_jwt_title_default: 'JWT_SECRET使用默认值', txt_jwt_reason_missing: '未检测到 JWT_SECRET。', txt_jwt_reason_default: 'JWT_SECRET 仍在使用默认示例值。', txt_jwt_reason_too_short: 'JWT_SECRET 长度过短,至少需要 {min} 位。', txt_jwt_how_to_fix_add: '处理步骤(添加 JWT_SECRET)', txt_jwt_how_to_fix_replace: '处理步骤(更换 JWT_SECRET)', txt_jwt_add_step_1: '使用下方 32 位随机生成器,复制一个新密钥。', txt_jwt_add_step_2: '到 Cloudflare 控制台 -> Workers 和 Pages -> 你的服务 -> 设置 -> 变量和机密,新增 JWT_SECRET。', txt_jwt_add_step_3: '保存并等待重新部署完成,然后刷新本页确认。', txt_jwt_replace_step_1: '使用下方 32 位随机生成器,生成更强的密钥(至少 {min} 位)。', txt_jwt_replace_step_2: '到 Cloudflare 控制台 -> Workers 和 Pages -> 你的服务 -> 设置 -> 变量和机密,替换 JWT_SECRET。', txt_jwt_replace_step_3: '保存并等待重新部署完成,然后刷新本页确认。', txt_how_to_fix: '处理步骤(添加 / 更换)', txt_jwt_fix_step_1: '你可以继续下一步,不影响使用。', txt_jwt_fix_step_2: '如果当前密钥不是强随机值,建议使用下方 32 位生成器。', txt_jwt_fix_step_3: '到 Cloudflare 控制台 -> Workers 和 Pages -> 你的服务 -> 设置 -> 变量和机密,更新 JWT_SECRET。', txt_jwt_fix_step_4: '保存并等待重新部署完成,然后刷新本页确认。', txt_random_secret_generator: '随机密钥生成器', txt_copied: '已复制', }; zhCNOverrides.txt_lock = '锁定'; zhCNOverrides.txt_menu = '菜单'; zhCNOverrides.txt_settings = '设置'; zhCNOverrides.txt_back = '返回'; zhCNOverrides.txt_passkey = 'Passkey'; zhCNOverrides.txt_passkey_created_at_value = '创建于 {value}'; zhCNOverrides.txt_attachments = '附件'; zhCNOverrides.txt_upload_attachments = '上传附件'; zhCNOverrides.txt_new_attachments = '待上传附件'; zhCNOverrides.txt_marked_for_removal_count = '保存后将删除 {count} 个附件'; messages.en.txt_import = 'Import'; messages.en.txt_export = 'Export'; messages.en.txt_format = 'Format'; messages.en.txt_source_file = 'Source file'; messages.en.txt_folder_handling = 'Folder handling'; messages.en.txt_import_folder_mode_original = 'Original path from import file'; messages.en.txt_import_folder_mode_none = 'No folder'; messages.en.txt_import_folder_mode_target = 'One selected folder'; messages.en.txt_target_folder = 'Target folder'; messages.en.txt_select_folder_placeholder = '-- Select folder --'; messages.en.txt_import_vault_data_hint = 'Import vault data into your current account.'; messages.en.txt_export_vault_data_hint = 'Export vault data from your current account.'; messages.en.txt_import_export_title = 'Import & Export'; messages.en.txt_encrypted_mode = 'Encrypted mode'; messages.en.txt_account_verification = 'Account verification'; messages.en.txt_password_verification = 'Password verification'; messages.en.txt_file_password = 'File password'; messages.en.txt_zip_password_optional = 'ZIP password (optional)'; messages.en.txt_zip_password = 'ZIP password'; messages.en.txt_close = 'Close'; messages.en.txt_total = 'Total'; messages.en.txt_import_success = 'Import successful'; messages.en.txt_import_success_number_of_items = 'Imported {count} item(s) in total.'; messages.en.txt_import_attachment_summary = 'Imported {imported} of {total} attachment(s).'; messages.en.txt_import_failed_attachments_title = '{count} attachment(s) were not imported:'; messages.en.txt_import_attachment_target_not_found = 'Matching imported item not found.'; messages.en.txt_upload_attachment_failed = 'Attachment upload failed.'; messages.en.txt_import_file_password_required = 'Please enter file password.'; messages.en.txt_import_invalid_zip_password = 'Invalid ZIP password.'; messages.en.txt_export_completed = 'Export completed'; messages.en.txt_export_failed = 'Export failed'; messages.en.txt_import_invalid_password_protected_file = 'Invalid password-protected export file.'; messages.en.txt_import_decrypt_failed = 'Failed to decrypt import file.'; messages.en.txt_import_empty_zip_archive = 'Empty zip archive.'; messages.en.txt_import_no_json_found_in_zip = 'No importable JSON data found in zip archive.'; messages.en.txt_import_data_json_not_found = 'data.json not found in zip archive.'; messages.en.txt_import_zip_password_required = 'ZIP password is required.'; messages.en.txt_import_invalid_json_file = 'Invalid JSON file'; messages.en.txt_import_failed = 'Import failed'; messages.en.txt_import_encrypted_file_title = 'Import encrypted file'; messages.en.txt_import_encrypted_file_message = 'This Bitwarden export is password-protected. Enter the export file password to continue.'; messages.en.txt_import_encrypted_zip_title = 'Import encrypted ZIP'; messages.en.txt_import_encrypted_zip_message = 'This ZIP archive is password-protected. Enter the ZIP password to continue.'; messages.en.txt_new_type_header = 'New {type}'; messages.en.txt_edit_type_header = 'Edit {type}'; messages.en.txt_delete_folder = 'Delete Folder'; messages.en.txt_delete_folder_message = 'Delete folder "{name}"? Items inside will move to No Folder.'; messages.en.txt_delete_all_folders = 'Delete All Folders'; messages.en.txt_delete_all_folders_message = 'Delete all folders? Items inside will move to No Folder.'; messages.en.txt_folder_not_found = 'Folder not found'; messages.en.txt_folder_deleted = 'Folder deleted'; messages.en.txt_folders_deleted = 'Folders deleted'; messages.en.txt_delete_folder_failed = 'Delete folder failed'; messages.en.txt_delete_all_folders_failed = 'Delete all folders failed'; messages.en.txt_other = 'Other'; messages.en.txt_vault_key_unavailable = 'Vault key unavailable. Please unlock vault and try again.'; messages.en.txt_vault_not_ready = 'Vault is not ready yet'; messages.en.txt_unsupported_export_format = 'Unsupported export format'; messages.en.txt_invalid_encrypted_export = 'Invalid encrypted export file.'; messages.en.txt_export_belongs_to_another_account = 'This encrypted export belongs to another account.'; messages.en.txt_invalid_argon2id_params = 'Invalid Argon2id parameters in export file.'; messages.en.txt_unsupported_kdf_type = 'Unsupported kdfType: {type}'; messages.en.txt_invalid_file_password = 'Invalid file password.'; messages.en.txt_failed_to_map_attachments = 'Failed to map {count} attachment(s) to imported items.'; zhCNOverrides.txt_import = '导入'; zhCNOverrides.txt_export = '导出'; zhCNOverrides.txt_format = '格式'; zhCNOverrides.txt_source_file = '源文件'; zhCNOverrides.txt_folder_handling = '文件夹处理'; zhCNOverrides.txt_import_folder_mode_original = '保留导入文件中的原始路径'; zhCNOverrides.txt_import_folder_mode_none = '不使用文件夹'; zhCNOverrides.txt_import_folder_mode_target = '导入到指定文件夹'; zhCNOverrides.txt_target_folder = '目标文件夹'; zhCNOverrides.txt_select_folder_placeholder = '-- 选择文件夹 --'; zhCNOverrides.txt_import_vault_data_hint = '将数据导入到当前账号。'; zhCNOverrides.txt_export_vault_data_hint = '从当前账号导出数据。'; zhCNOverrides.txt_encrypted_mode = '加密方式'; zhCNOverrides.txt_account_verification = '账号验证'; zhCNOverrides.txt_password_verification = '密码验证'; zhCNOverrides.txt_file_password = '文件密码'; zhCNOverrides.txt_zip_password_optional = 'ZIP 密码(可选)'; zhCNOverrides.txt_zip_password = 'ZIP 密码'; zhCNOverrides.txt_close = '关闭'; zhCNOverrides.txt_total = '总计'; zhCNOverrides.txt_import_success = '数据导入成功'; zhCNOverrides.txt_import_success_number_of_items = '一共导入了 {count} 个项目。'; zhCNOverrides.txt_import_attachment_summary = '附件已导入 {imported}/{total} 个。'; zhCNOverrides.txt_import_failed_attachments_title = '以下 {count} 个附件未导入:'; zhCNOverrides.txt_import_attachment_target_not_found = '没有找到对应的导入项目。'; zhCNOverrides.txt_upload_attachment_failed = '附件上传失败。'; zhCNOverrides.txt_import_file_password_required = '请输入文件密码。'; zhCNOverrides.txt_import_invalid_zip_password = 'ZIP 密码错误。'; zhCNOverrides.txt_export_completed = '导出完成'; zhCNOverrides.txt_export_failed = '导出失败'; zhCNOverrides.txt_import_invalid_password_protected_file = '密码保护导出文件格式无效。'; zhCNOverrides.txt_import_decrypt_failed = '导入文件解密失败。'; zhCNOverrides.txt_import_empty_zip_archive = 'ZIP 压缩包为空。'; zhCNOverrides.txt_import_no_json_found_in_zip = 'ZIP 内未找到可导入的 JSON 数据。'; zhCNOverrides.txt_import_data_json_not_found = 'ZIP 内未找到 data.json。'; zhCNOverrides.txt_import_zip_password_required = '该 ZIP 需要密码。'; zhCNOverrides.txt_import_invalid_json_file = 'JSON 文件无效'; zhCNOverrides.txt_import_failed = '导入失败'; zhCNOverrides.txt_import_encrypted_file_title = '导入加密文件'; zhCNOverrides.txt_import_encrypted_file_message = '该 Bitwarden 导出文件已加密,请输入文件密码继续。'; zhCNOverrides.txt_import_encrypted_zip_title = '导入加密 ZIP'; zhCNOverrides.txt_import_encrypted_zip_message = '该 ZIP 压缩包已加密,请输入 ZIP 密码继续。'; zhCNOverrides.txt_import_export_title = '导入导出'; zhCNOverrides.txt_new_type_header = '新建{type}'; zhCNOverrides.txt_edit_type_header = '编辑{type}'; zhCNOverrides.txt_delete_folder = '删除文件夹'; zhCNOverrides.txt_delete_folder_message = '删除文件夹「{name}」?其中的项目将移至无文件夹。'; zhCNOverrides.txt_delete_all_folders = '删除全部文件夹'; zhCNOverrides.txt_delete_all_folders_message = '确认删除全部文件夹吗?其中的项目将移至无文件夹。'; zhCNOverrides.txt_folder_not_found = '文件夹不存在'; zhCNOverrides.txt_folder_deleted = '文件夹已删除'; zhCNOverrides.txt_folders_deleted = '文件夹已删除'; zhCNOverrides.txt_delete_folder_failed = '删除文件夹失败'; zhCNOverrides.txt_delete_all_folders_failed = '删除全部文件夹失败'; zhCNOverrides.txt_other = '其他'; zhCNOverrides.txt_vault_key_unavailable = '账户密钥不可用,请先解锁密码库后重试。'; zhCNOverrides.txt_vault_not_ready = '密码库数据尚未就绪'; zhCNOverrides.txt_unsupported_export_format = '不支持的导出格式'; zhCNOverrides.txt_invalid_encrypted_export = '加密导出文件无效。'; zhCNOverrides.txt_export_belongs_to_another_account = '此加密导出文件属于另一个账号。'; zhCNOverrides.txt_invalid_argon2id_params = '导出文件中的 Argon2id 参数无效。'; zhCNOverrides.txt_unsupported_kdf_type = '不支持的 KDF 类型:{type}'; zhCNOverrides.txt_invalid_file_password = '文件密码错误。'; zhCNOverrides.txt_failed_to_map_attachments = '无法将 {count} 个附件匹配到导入项目。'; messages['zh-CN'] = { ...messages.en, ...zhCNOverrides }; function resolveInitialLocale(): Locale { try { const saved = localStorage.getItem(LOCALE_STORAGE_KEY); if (saved === 'en' || saved === 'zh-CN') return saved; } catch { // ignore storage errors } if (typeof navigator !== 'undefined') { const langs = Array.isArray(navigator.languages) ? navigator.languages : [navigator.language]; for (const lang of langs) { if (String(lang || '').toLowerCase().startsWith('zh')) return 'zh-CN'; } } return 'en'; } let locale: Locale = resolveInitialLocale(); export type I18nParams = Record; export function t(key: string, params?: I18nParams): string { const template = messages[locale][key] ?? key; if (!params) return template; return template.replace(/\{(\w+)\}/g, (_, name: string) => String(params[name] ?? '')); } export function getLocale(): Locale { return locale; } export function setLocale(next: Locale): void { locale = next; try { localStorage.setItem(LOCALE_STORAGE_KEY, next); } catch { // ignore storage errors } }